@@ -67,7 +67,10 @@ @implementation SDImageAVIFCoder {
6767 CGFloat _scale;
6868 NSUInteger _loopCount;
6969 NSUInteger _frameCount;
70+ BOOL _hasAnimation;
7071 SD_LOCK_DECLARE (_lock);
72+ BOOL _preserveAspectRatio;
73+ CGSize _thumbnailSize;
7174}
7275
7376- (void )dealloc {
@@ -93,14 +96,32 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)
9396 if (!data) {
9497 return nil ;
9598 }
99+ BOOL decodeFirstFrame = [options[SDImageCoderDecodeFirstFrameOnly] boolValue ];
96100 CGFloat scale = 1 ;
97- if ([options valueForKey: SDImageCoderDecodeScaleFactor]) {
98- scale = [[options valueForKey: SDImageCoderDecodeScaleFactor] doubleValue ];
101+ NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];
102+ if (scaleFactor != nil ) {
103+ scale = [scaleFactor doubleValue ];
99104 if (scale < 1 ) {
100105 scale = 1 ;
101106 }
102107 }
103108
109+ CGSize thumbnailSize = CGSizeZero;
110+ NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];
111+ if (thumbnailSizeValue != nil ) {
112+ #if SD_MAC
113+ thumbnailSize = thumbnailSizeValue.sizeValue ;
114+ #else
115+ thumbnailSize = thumbnailSizeValue.CGSizeValue ;
116+ #endif
117+ }
118+
119+ BOOL preserveAspectRatio = YES ;
120+ NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];
121+ if (preserveAspectRatioValue != nil ) {
122+ preserveAspectRatio = preserveAspectRatioValue.boolValue ;
123+ }
124+
104125 // Decode it
105126 avifDecoder * decoder = avifDecoderCreate ();
106127 avifDecoderSetIOMemory (decoder, data.bytes , data.length );
@@ -113,15 +134,27 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)
113134 return nil ;
114135 }
115136
137+ BOOL hasAnimation = decoder->imageCount > 1 ;
138+ uint32_t width = decoder->image ->width ;
139+ uint32_t height = decoder->image ->height ;
140+ CGSize scaledSize = [SDImageCoderHelper scaledSizeWithImageSize: CGSizeMake (width, height) scaleSize: thumbnailSize preserveAspectRatio: preserveAspectRatio shouldScaleUp: NO ];
141+
116142 // Static image
117- if (decoder-> imageCount <= 1 ) {
143+ if (!hasAnimation || decodeFirstFrame ) {
118144 avifResult nextImageResult = avifDecoderNextImage (decoder);
119145 if (nextImageResult != AVIF_RESULT_OK) {
120146 NSLog (@" Failed to decode image: %s " , avifResultToString (nextImageResult));
121147 avifDecoderDestroy (decoder);
122148 return nil ;
123149 }
124- CGImageRef imageRef = SDCreateCGImageFromAVIF (decoder->image );
150+ CGImageRef originImageRef = SDCreateCGImageFromAVIF (decoder->image );
151+ if (!originImageRef) {
152+ avifDecoderDestroy (decoder);
153+ return nil ;
154+ }
155+ // TODO: optimization using vImageScale directly during transform
156+ CGImageRef imageRef = [SDImageCoderHelper CGImageCreateScaled: originImageRef size: scaledSize];
157+ CGImageRelease (originImageRef);
125158 if (!imageRef) {
126159 avifDecoderDestroy (decoder);
127160 return nil ;
@@ -140,7 +173,13 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)
140173 NSMutableArray <SDImageFrame *> *frames = [NSMutableArray array ];
141174 while (avifDecoderNextImage (decoder) == AVIF_RESULT_OK) {
142175 @autoreleasepool {
143- CGImageRef imageRef = SDCreateCGImageFromAVIF (decoder->image );
176+ CGImageRef originImageRef = SDCreateCGImageFromAVIF (decoder->image );
177+ if (!originImageRef) {
178+ continue ;
179+ }
180+ // TODO: optimization using vImageScale directly during transform
181+ CGImageRef imageRef = [SDImageCoderHelper CGImageCreateScaled: originImageRef size: scaledSize];
182+ CGImageRelease (originImageRef);
144183 if (!imageRef) {
145184 continue ;
146185 }
@@ -296,6 +335,7 @@ - (instancetype)initWithAnimatedImageData:(NSData *)data options:(SDImageCoderOp
296335 // TODO: Optimize the performance like WebPCoder (frame meta cache, etc)
297336 _frameCount = decoder->imageCount ;
298337 _loopCount = 0 ;
338+ _hasAnimation = decoder->imageCount > 1 ;
299339 CGFloat scale = 1 ;
300340 NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];
301341 if (scaleFactor != nil ) {
@@ -305,6 +345,22 @@ - (instancetype)initWithAnimatedImageData:(NSData *)data options:(SDImageCoderOp
305345 }
306346 }
307347 _scale = scale;
348+ CGSize thumbnailSize = CGSizeZero;
349+ NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];
350+ if (thumbnailSizeValue != nil ) {
351+ #if SD_MAC
352+ thumbnailSize = thumbnailSizeValue.sizeValue ;
353+ #else
354+ thumbnailSize = thumbnailSizeValue.CGSizeValue ;
355+ #endif
356+ }
357+ _thumbnailSize = thumbnailSize;
358+ BOOL preserveAspectRatio = YES ;
359+ NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];
360+ if (preserveAspectRatioValue != nil ) {
361+ preserveAspectRatio = preserveAspectRatioValue.boolValue ;
362+ }
363+ _preserveAspectRatio = preserveAspectRatio;
308364 _decoder = decoder;
309365 _imageData = data;
310366 SD_LOCK_INIT (_lock);
@@ -345,14 +401,25 @@ - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
345401 if (index >= _frameCount) {
346402 return nil ;
347403 }
404+ uint32_t width = 0 ;
405+ uint32_t height = 0 ;
348406 SD_LOCK (_lock);
349407 avifResult decodeResult = avifDecoderNthImage (_decoder, (uint32_t )index);
350408 if (decodeResult != AVIF_RESULT_OK) {
351409 SD_UNLOCK (_lock);
352410 return nil ;
353411 }
354- CGImageRef imageRef = SDCreateCGImageFromAVIF (_decoder->image );
412+ width = _decoder->image ->width ;
413+ height = _decoder->image ->height ;
414+ CGImageRef originImageRef = SDCreateCGImageFromAVIF (_decoder->image );
355415 SD_UNLOCK (_lock);
416+ if (!originImageRef) {
417+ return nil ;
418+ }
419+ CGSize scaledSize = [SDImageCoderHelper scaledSizeWithImageSize: CGSizeMake (width, height) scaleSize: _thumbnailSize preserveAspectRatio: _preserveAspectRatio shouldScaleUp: NO ];
420+ // TODO: optimization using vImageScale directly during transform
421+ CGImageRef imageRef = [SDImageCoderHelper CGImageCreateScaled: originImageRef size: scaledSize];
422+ CGImageRelease (originImageRef);
356423 if (!imageRef) {
357424 return nil ;
358425 }
0 commit comments