13
13
#import " avif/avif.h"
14
14
#endif
15
15
16
- static CGImageRef CreateImageRef (avifImage * avif, vImage_Buffer* result) {
16
+ static CGImageRef CreateImageFromBuffer (avifImage * avif, vImage_Buffer* result) {
17
17
BOOL monochrome = avif->yuvPlanes [1 ] == NULL || avif->yuvPlanes [2 ] == NULL ;
18
18
BOOL hasAlpha = avif->alphaPlane != NULL ;
19
19
BOOL usesU16 = avifImageUsesU16 (avif);
@@ -26,10 +26,11 @@ static CGImageRef CreateImageRef(avifImage * avif, vImage_Buffer* result) {
26
26
// Currently, there is no way to get MatrixCoefficients, TransferCharacteristics and ColourPrimaries values
27
27
// in Sequence Header OBU.
28
28
// https://github.com/AOMediaCodec/libavif/blob/7d36984b2994210b/include/avif/avif.h#L149-L236
29
- CGColorSpaceRef colorSpace = [SDImageCoderHelper colorSpaceGetDeviceRGB ] ;
29
+ CGColorSpaceRef colorSpace = NULL ;
30
30
if (monochrome){
31
- // colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
32
31
colorSpace = CGColorSpaceCreateDeviceGray ();
32
+ }else {
33
+ colorSpace = CGColorSpaceCreateDeviceRGB ();
33
34
}
34
35
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault ;
35
36
@@ -39,7 +40,9 @@ static CGImageRef CreateImageRef(avifImage * avif, vImage_Buffer* result) {
39
40
40
41
CGImageRef imageRef = CGImageCreate (result->width , result->height , bitsPerComponent, bitsPerPixel, rowBytes, colorSpace, bitmapInfo, provider, NULL , NO , renderingIntent);
41
42
43
+
42
44
// clean up
45
+ CFRelease (colorSpace);
43
46
CGDataProviderRelease (provider);
44
47
45
48
return imageRef;
@@ -134,7 +137,7 @@ static void SetupConversionInfo(avifImage * avif,
134
137
135
138
136
139
// Convert 8bit AVIF image into RGB888/ARGB8888/Mono/MonoA using vImage Acceralation Framework.
137
- static CGImageRef ConvertAvifImage8 (avifImage * avif) {
140
+ static CGImageRef CreateImage16U (avifImage * avif) {
138
141
vImage_Error err = kvImageNoError;
139
142
BOOL const monochrome = avif->yuvPlanes [1 ] == NULL || avif->yuvPlanes [2 ] == NULL ;
140
143
BOOL const hasAlpha = avif->alphaPlane != NULL ;
@@ -488,12 +491,19 @@ static CGImageRef ConvertAvifImage8(avifImage * avif) {
488
491
NSLog (@" Failed to convert ARGB to RGB: %ld " , err);
489
492
return NULL ;
490
493
}
491
- err = vImageConvert_PlanarToChunky8 ((const vImage_Buffer*[]){&monoBuffer , &alphaBuffer },
494
+ err = vImageConvert_PlanarToChunky8 ((const vImage_Buffer*[]){&alphaBuffer , &monoBuffer },
492
495
(void *[]){outBuffer.data , outBuffer.data + 1 },
493
496
2 /* channelCount */ , 2 /* destStrideBytes */ ,
494
497
outBuffer.width , outBuffer.height ,
495
498
outBuffer.rowBytes , kvImageNoFlags);
496
- CGImageRef img = CreateImageRef (avif, &outBuffer);
499
+ free (monoBuffer.data );
500
+ free (alphaBuffer.data );
501
+ if (err != kvImageNoError) {
502
+ free (outPixels);
503
+ NSLog (@" Failed to combine mono and alpha: %ld " , err);
504
+ return NULL ;
505
+ }
506
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
497
507
free (outPixels);
498
508
return img;
499
509
} else {
@@ -503,7 +513,7 @@ static CGImageRef ConvertAvifImage8(avifImage * avif) {
503
513
NSLog (@" Failed to overwrite alpha: %ld " , err);
504
514
return NULL ;
505
515
}
506
- CGImageRef img = CreateImageRef (avif, &argbBuffer);
516
+ CGImageRef img = CreateImageFromBuffer (avif, &argbBuffer);
507
517
free (outPixels);
508
518
return img;
509
519
}
@@ -534,7 +544,7 @@ static CGImageRef ConvertAvifImage8(avifImage * avif) {
534
544
NSLog (@" Failed to convert ARGB to RGB: %ld " , err);
535
545
return NULL ;
536
546
}
537
- CGImageRef img = CreateImageRef (avif, &outBuffer);
547
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
538
548
free (outPixels);
539
549
return img;
540
550
} else {
@@ -551,15 +561,15 @@ static CGImageRef ConvertAvifImage8(avifImage * avif) {
551
561
NSLog (@" Failed to convert ARGB to RGB: %ld " , err);
552
562
return NULL ;
553
563
}
554
- CGImageRef img = CreateImageRef (avif, &outBuffer);
564
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
555
565
free (outPixels);
556
566
return img;
557
567
}
558
568
}
559
569
}
560
570
561
571
// Convert 10/12bit AVIF image into RGB16U/ARGB16U/Mono16U/MonoA16U
562
- static CGImageRef ConvertAvifImage16U (avifImage * avif) {
572
+ static CGImageRef CreateImage8 (avifImage * avif) {
563
573
vImage_Error err = kvImageNoError;
564
574
BOOL const monochrome = avif->yuvPlanes [1 ] == NULL || avif->yuvPlanes [2 ] == NULL ;
565
575
BOOL const hasAlpha = avif->alphaPlane != NULL ;
@@ -962,7 +972,6 @@ static CGImageRef ConvertAvifImage16U(avifImage * avif) {
962
972
if (err != kvImageNoError) {
963
973
free (outPixels);
964
974
free (alphaBuffer.data );
965
- free (monoBuffer.data );
966
975
free (monoBuffer1.data );
967
976
free (monoBuffer2.data );
968
977
NSLog (@" Failed to split Mono16: %ld " , err);
@@ -1018,7 +1027,7 @@ static CGImageRef ConvertAvifImage16U(avifImage * avif) {
1018
1027
.height = avif->height ,
1019
1028
.rowBytes = avif->width * components * sizeof (uint16_t ),
1020
1029
};
1021
- err = vImageConvert_Planar16UtoARGB16U (&monoBuffer1 , &monoBuffer2 , &alphaBuffer1 , &alphaBuffer2 , &outBuffer, kvImageNoFlags);
1030
+ err = vImageConvert_Planar16UtoARGB16U (&alphaBuffer1 , &alphaBuffer2 , &monoBuffer1 , &monoBuffer2 , &outBuffer, kvImageNoFlags);
1022
1031
free (monoBuffer1.data );
1023
1032
free (monoBuffer2.data );
1024
1033
free (alphaBuffer1.data );
@@ -1028,12 +1037,11 @@ static CGImageRef ConvertAvifImage16U(avifImage * avif) {
1028
1037
NSLog (@" Failed to convert ARGB to MonoA: %ld " , err);
1029
1038
return NULL ;
1030
1039
}
1031
- CGImageRef img = CreateImageRef (avif, &outBuffer);
1040
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
1032
1041
free (outPixels);
1033
1042
return img;
1034
- return NULL ;
1035
1043
}else {
1036
- CGImageRef img = CreateImageRef (avif, &argbBuffer);
1044
+ CGImageRef img = CreateImageFromBuffer (avif, &argbBuffer);
1037
1045
free (outPixels);
1038
1046
return img;
1039
1047
}
@@ -1064,7 +1072,7 @@ static CGImageRef ConvertAvifImage16U(avifImage * avif) {
1064
1072
NSLog (@" Failed to convert ARGB to Mono: %ld " , err);
1065
1073
return NULL ;
1066
1074
}
1067
- CGImageRef img = CreateImageRef (avif, &outBuffer);
1075
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
1068
1076
free (outPixels);
1069
1077
return img;
1070
1078
} else {
@@ -1075,7 +1083,7 @@ static CGImageRef ConvertAvifImage16U(avifImage * avif) {
1075
1083
NSLog (@" Failed to convert ARGB to RGB: %ld " , err);
1076
1084
return NULL ;
1077
1085
}
1078
- CGImageRef img = CreateImageRef (avif, &outBuffer);
1086
+ CGImageRef img = CreateImageFromBuffer (avif, &outBuffer);
1079
1087
free (outPixels);
1080
1088
return img;
1081
1089
}
@@ -1173,9 +1181,9 @@ - (nullable CGImageRef)sd_createAVIFImageWithData:(nonnull NSData *)data CF_RETU
1173
1181
CGImageRef image = NULL ;
1174
1182
// convert planar to ARGB/RGB
1175
1183
if (avifImageUsesU16 (avif)) { // 10bit or 12bit
1176
- image = ConvertAvifImage16U (avif);
1184
+ image = CreateImage8 (avif);
1177
1185
} else { // 8bit
1178
- image = ConvertAvifImage8 (avif);
1186
+ image = CreateImage16U (avif);
1179
1187
}
1180
1188
avifDecoderDestroy (decoder);
1181
1189
return image;
0 commit comments