Commit ef5aaf44 authored by zaggy1024's avatar zaggy1024
Browse files

Bug 1813466 - Store AVIF prefs as default decoder flags in RasterImage. r=tnikkel

This prevents a crash that would occur if a redecode of an animated AVIF happened after changing the `sequences.enabled` pref from `true` to `false`.

Differential Revision: https://phabricator.services.mozilla.com/D170190
parent b2f1baf7
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -100,6 +100,24 @@ DecoderType DecoderFactory::GetDecoderType(const char* aMimeType) {
  return type;
}

/* static */
DecoderFlags DecoderFactory::GetDefaultDecoderFlagsForType(DecoderType aType) {
  auto flags = DefaultDecoderFlags();

#ifdef MOZ_AV1
  if (aType == DecoderType::AVIF) {
    if (StaticPrefs::image_avif_sequence_enabled()) {
      flags |= DecoderFlags::AVIF_SEQUENCES_ENABLED;
    }
    if (StaticPrefs::image_avif_sequence_animate_avif_major_branded_images()) {
      flags |= DecoderFlags::AVIF_ANIMATE_AVIF_MAJOR;
    }
  }
#endif

  return flags;
}

/* static */
already_AddRefed<Decoder> DecoderFactory::GetDecoder(DecoderType aType,
                                                     RasterImage* aImage,
@@ -294,7 +312,7 @@ already_AddRefed<Decoder> DecoderFactory::CloneAnimationDecoder(

/* static */
already_AddRefed<IDecodingTask> DecoderFactory::CreateMetadataDecoder(
    DecoderType aType, NotNull<RasterImage*> aImage,
    DecoderType aType, NotNull<RasterImage*> aImage, DecoderFlags aFlags,
    NotNull<SourceBuffer*> aSourceBuffer) {
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
@@ -306,6 +324,7 @@ already_AddRefed<IDecodingTask> DecoderFactory::CreateMetadataDecoder(

  // Initialize the decoder.
  decoder->SetMetadataDecode(true);
  decoder->SetDecoderFlags(aFlags);
  decoder->SetIterator(aSourceBuffer->Iterator());

  if (NS_FAILED(decoder->Init())) {
+4 −1
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ class DecoderFactory {
  /// @return the type of decoder which is appropriate for @aMimeType.
  static DecoderType GetDecoderType(const char* aMimeType);

  /// @return the default flags to use when creating a decoder of @aType.
  static DecoderFlags GetDefaultDecoderFlagsForType(DecoderType aType);

  /**
   * Creates and initializes a decoder for non-animated images of type @aType.
   * (If the image *is* animated, only the first frame will be decoded.) The
@@ -128,7 +131,7 @@ class DecoderFactory {
   *                      from.
   */
  static already_AddRefed<IDecodingTask> CreateMetadataDecoder(
      DecoderType aType, NotNull<RasterImage*> aImage,
      DecoderType aType, NotNull<RasterImage*> aImage, DecoderFlags aFlags,
      NotNull<SourceBuffer*> aSourceBuffer);

  /**
+11 −0
Original line number Diff line number Diff line
@@ -31,6 +31,17 @@ enum class DecoderFlags : uint8_t {
   * set.
   */
  CANNOT_SUBSTITUTE = 1 << 4,

#ifdef MOZ_AV1
  // The flags below are stored in RasterImage to allow a decoded image to
  // remain consistent in whether it is animated or not.

  // Set according to the "image.avif.sequence.enabled" preference.
  AVIF_SEQUENCES_ENABLED = 1 << 5,
  // Set according to the
  // "image.avif.sequence.animate_avif_major_branded_images" preference.
  AVIF_ANIMATE_AVIF_MAJOR = 1 << 6,
#endif
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DecoderFlags)

+7 −2
Original line number Diff line number Diff line
@@ -130,6 +130,11 @@ nsresult RasterImage::Init(const char* aMimeType, uint32_t aFlags) {
    SurfaceCache::LockImage(ImageKey(this));
  }

  // Set the default flags according to the decoder type to allow preferences to
  // be stored if necessary.
  mDefaultDecoderFlags =
      DecoderFactory::GetDefaultDecoderFlagsForType(mDecoderType);

  // Mark us as initialized
  mInitialized = true;

@@ -1173,7 +1178,7 @@ void RasterImage::Decode(const OrientedIntSize& aSize, uint32_t aFlags,
  SurfaceCache::UnlockEntries(ImageKey(this));

  // Determine which flags we need to decode this image with.
  DecoderFlags decoderFlags = DefaultDecoderFlags();
  DecoderFlags decoderFlags = mDefaultDecoderFlags;
  if (aFlags & FLAG_ASYNC_NOTIFY) {
    decoderFlags |= DecoderFlags::ASYNC_NOTIFY;
  }
@@ -1257,7 +1262,7 @@ RasterImage::DecodeMetadata(uint32_t aFlags) {

  // Create a decoder.
  RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder(
      mDecoderType, WrapNotNull(this), mSourceBuffer);
      mDecoderType, WrapNotNull(this), mDefaultDecoderFlags, mSourceBuffer);

  // Make sure DecoderFactory was able to create a decoder successfully.
  if (!task) {
+6 −0
Original line number Diff line number Diff line
@@ -416,6 +416,12 @@ class RasterImage final : public ImageResource,

  TimeStamp mDrawStartTime;

  // This field is set according to the DecoderType of this image once when
  // initialized so that a decoder's flags can be set according to any
  // preferences that affect its behavior in a way that would otherwise cause
  // errors, such as enabling or disabling animation.
  DecoderFlags mDefaultDecoderFlags = DefaultDecoderFlags();

  //////////////////////////////////////////////////////////////////////////////
  // Scaling.
  //////////////////////////////////////////////////////////////////////////////
Loading