Skip to content

Commit 127b0b4

Browse files
committed
use advanded decoding to avoid unnecessary copy.
1 parent f4d244f commit 127b0b4

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -260,20 +260,20 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
260260
}
261261

262262
vImage_Buffer tmpY1 = {
263-
.data = calloc(avif->width/2 * avif->height, sizeof(uint8_t)),
264-
.width = avif->width/2,
265-
.height = avif->height,
266-
.rowBytes = avif->width/2,
263+
.data = calloc(origY.width/2 * origY.height, sizeof(uint8_t)),
264+
.width = origY.width/2,
265+
.height = origY.height,
266+
.rowBytes = origY.width/2 * sizeof(uint8_t),
267267
};
268268
if(!tmpY1.data) {
269269
free(argbPixels);
270270
return;
271271
}
272272
vImage_Buffer tmpY2 = {
273-
.data = calloc(avif->width/2 * avif->height, sizeof(uint8_t)),
274-
.width = avif->width/2,
275-
.height = avif->height,
276-
.rowBytes = avif->width/2,
273+
.data = calloc(origY.width/2 * origY.height, sizeof(uint8_t)),
274+
.width = origY.width/2,
275+
.height = origY.height,
276+
.rowBytes = origY.width/2 * sizeof(uint8_t),
277277
};
278278
if(!tmpY2.data) {
279279
free(argbPixels);
@@ -283,8 +283,8 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
283283
err= vImageConvert_ChunkyToPlanar8((const void*[]){origY.data, origY.data+1},
284284
(const vImage_Buffer*[]){&tmpY1, &tmpY2},
285285
2 /* channelCount */,2 /* src srcStrideBytes */,
286-
avif->width/2, avif->height,
287-
avif->width, kvImageNoFlags);
286+
origY.width/2, origY.height,
287+
origY.rowBytes, kvImageNoFlags);
288288
if(err != kvImageNoError) {
289289
NSLog(@"Failed to separate Y channel: %ld", err);
290290
free(argbPixels);
@@ -296,14 +296,15 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
296296
.data = calloc(avif->width * avif->height * 2, sizeof(uint8_t)),
297297
.width = avif->width/2,
298298
.height = avif->height,
299-
.rowBytes = avif->width * 2,
299+
.rowBytes = avif->width / 2 * 4 * sizeof(uint8_t),
300300
};
301301
if(!tmpBuffer.data) {
302302
free(argbPixels);
303303
free(tmpY1.data);
304304
free(tmpY2.data);
305305
return;
306306
}
307+
307308
err = vImageConvert_Planar8toARGB8888(&tmpY1, &origCb, &tmpY2, &origCr,
308309
&tmpBuffer, kvImageNoFlags);
309310
if(err != kvImageNoError) {
@@ -398,6 +399,7 @@ static void ConvertAvifImagePlanar16ToRGB16U(avifImage * avif, uint8_t * outPixe
398399
.width = avif->width,
399400
.height = avif->height,
400401
};
402+
401403

402404
vImage_Buffer origCb = {
403405
.data = avif->yuvPlanes[AVIF_CHAN_U],
@@ -695,15 +697,21 @@ - (nullable CGImageRef)sd_createAVIFImageWithData:(nonnull NSData *)data CF_RETU
695697
.data = (uint8_t *)data.bytes,
696698
.size = data.length
697699
};
698-
avifImage * avif = avifImageCreateEmpty();
699-
avifDecoder *decoder = avifDecoderCreate();
700-
avifResult result = avifDecoderRead(decoder, avif, &rawData);
701-
if (result != AVIF_RESULT_OK) {
700+
avifDecoder * decoder = avifDecoderCreate();
701+
avifResult decodeResult = avifDecoderParse(decoder, &rawData);
702+
if (decodeResult != AVIF_RESULT_OK) {
703+
NSLog(@"Failed to decode image: %s", avifResultToString(decodeResult));
702704
avifDecoderDestroy(decoder);
703-
avifImageDestroy(avif);
704705
return nil;
705706
}
706-
707+
avifResult nextImageResult = avifDecoderNextImage(decoder);
708+
if (nextImageResult != AVIF_RESULT_OK || nextImageResult == AVIF_RESULT_NO_IMAGES_REMAINING) {
709+
NSLog(@"Failed to decode image: %s", avifResultToString(nextImageResult));
710+
avifDecoderDestroy(decoder);
711+
return nil;
712+
}
713+
avifImage * avif = decoder->image;
714+
707715
int width = avif->width;
708716
int height = avif->height;
709717
BOOL hasAlpha = avif->alphaPlane != NULL;
@@ -716,7 +724,6 @@ - (nullable CGImageRef)sd_createAVIFImageWithData:(nonnull NSData *)data CF_RETU
716724
uint8_t * dest = calloc(width * components * height, usesU16 ? sizeof(uint16_t) : sizeof(uint8_t));
717725
if (!dest) {
718726
avifDecoderDestroy(decoder);
719-
avifImageDestroy(avif);
720727
return nil;
721728
}
722729
// convert planar to ARGB/RGB
@@ -736,7 +743,6 @@ - (nullable CGImageRef)sd_createAVIFImageWithData:(nonnull NSData *)data CF_RETU
736743
// clean up
737744
CGDataProviderRelease(provider);
738745
avifDecoderDestroy(decoder);
739-
avifImageDestroy(avif);
740746

741747
return imageRef;
742748
}

0 commit comments

Comments
 (0)