diff --git a/SDWebImageAVIFCoder/Classes/Public/SDImageAVIFCoder.h b/SDWebImageAVIFCoder/Classes/Public/SDImageAVIFCoder.h index b146fd1..79a84df 100644 --- a/SDWebImageAVIFCoder/Classes/Public/SDImageAVIFCoder.h +++ b/SDWebImageAVIFCoder/Classes/Public/SDImageAVIFCoder.h @@ -13,6 +13,12 @@ static const SDImageFormat SDImageFormatAVIF = 15; // AV1-codec based HEIF +/// A `avifCodecChoice` enum which specify the custom codec for AVIF decoding, defaults to 0 (`AVIF_CODEC_CHOICE_AUTO`) +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderAVIFDecodeCodecChoice; + +/// A `avifCodecChoice` enum which specify the custom codec for AVIF encoding, defaults to 0 (`AVIF_CODEC_CHOICE_AUTO`) +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderAVIFEncodeCodecChoice; + /// Supports AVIF static image and AVIFS animated image @interface SDImageAVIFCoder : NSObject diff --git a/SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m b/SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m index d5c30af..d413328 100644 --- a/SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m +++ b/SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m @@ -61,6 +61,9 @@ #endif #endif +SDImageCoderOption _Nonnull const SDImageCoderAVIFDecodeCodecChoice = @"avifDecodeCodecChoice"; +SDImageCoderOption _Nonnull const SDImageCoderAVIFEncodeCodecChoice = @"avifEncodeCodecChoice"; + @implementation SDImageAVIFCoder { avifDecoder *_decoder; NSData *_imageData; @@ -122,9 +125,17 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *) preserveAspectRatio = preserveAspectRatioValue.boolValue; } + avifCodecChoice codecChoice = AVIF_CODEC_CHOICE_AUTO; + NSNumber *codecChoiceValue = options[SDImageCoderAVIFDecodeCodecChoice]; + if (codecChoiceValue != nil) { + codecChoice = [codecChoiceValue intValue]; + } + // Decode it avifDecoder * decoder = avifDecoderCreate(); avifDecoderSetIOMemory(decoder, data.bytes, data.length); + decoder->maxThreads = 2; + decoder->codecChoice = codecChoice; // Disable strict mode to keep some AVIF image compatible decoder->strictFlags = AVIF_STRICT_DISABLED; avifResult decodeResult = avifDecoderParse(decoder); @@ -270,6 +281,12 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm return nil; } + avifCodecChoice codecChoice = AVIF_CODEC_CHOICE_AUTO; + NSNumber *codecChoiceValue = options[SDImageCoderAVIFEncodeCodecChoice]; + if (codecChoiceValue != nil) { + codecChoice = [codecChoiceValue intValue]; + } + avifPixelFormat avifFormat = AVIF_PIXEL_FORMAT_YUV444; avifImage *avif = avifImageCreate((int)width, (int)height, 8, avifFormat); @@ -300,6 +317,7 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm avifRWData raw = AVIF_DATA_EMPTY; avifEncoder *encoder = avifEncoderCreate(); + encoder->codecChoice = codecChoice; encoder->minQuantizer = rescaledQuality; encoder->maxQuantizer = rescaledQuality; encoder->minQuantizerAlpha = rescaledQuality; @@ -324,8 +342,15 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm - (instancetype)initWithAnimatedImageData:(NSData *)data options:(SDImageCoderOptions *)options { self = [super init]; if (self) { + avifCodecChoice codecChoice = AVIF_CODEC_CHOICE_AUTO; + NSNumber *codecChoiceValue = options[SDImageCoderAVIFDecodeCodecChoice]; + if (codecChoiceValue != nil) { + codecChoice = [codecChoiceValue intValue]; + } avifDecoder *decoder = avifDecoderCreate(); avifDecoderSetIOMemory(decoder, data.bytes, data.length); + decoder->maxThreads = 2; + decoder->codecChoice = codecChoice; // Disable strict mode to keep some AVIF image compatible decoder->strictFlags = AVIF_STRICT_DISABLED; avifResult decodeResult = avifDecoderParse(decoder);