1616static void FreeImageData (void *info, const void *data, size_t size) {
1717 free ((void *)data);
1818}
19+ static void CalcColorSpaceMono (avifImage * avif, CGColorSpaceRef* ref, BOOL * shouldRelease) {
20+ static CGColorSpaceRef defaultColorSpace;
21+ {
22+ static dispatch_once_t onceToken;
23+ dispatch_once (&onceToken, ^{
24+ defaultColorSpace = CGColorSpaceCreateDeviceGray ();
25+ });
26+ }
27+ default_color_space:
28+ *ref = defaultColorSpace;
29+ *shouldRelease = FALSE ;
30+ }
31+ static void CalcColorSpaceRGB (avifImage * avif, CGColorSpaceRef* ref, BOOL * shouldRelease) {
32+ static CGColorSpaceRef defaultColorSpace;
33+ static CGColorSpaceRef bt709;
34+ static CGColorSpaceRef bt2020;
35+ {
36+ static dispatch_once_t onceToken;
37+ dispatch_once (&onceToken, ^{
38+ if (@available (iOS 9.0 , tvOS 9.0 , *)) {
39+ defaultColorSpace = CGColorSpaceCreateWithName (kCGColorSpaceSRGB );
40+ } else {
41+ defaultColorSpace = CGColorSpaceCreateDeviceRGB ();
42+ }
43+ if (@available (macOS 10.11 , *)) {
44+ bt709 = CGColorSpaceCreateWithName (kCGColorSpaceITUR_709 );
45+ } else {
46+ bt709 = defaultColorSpace;
47+ }
48+ if (@available (macOS 10.11 , *)) {
49+ bt2020 = CGColorSpaceCreateWithName (kCGColorSpaceITUR_2020 );
50+ } else {
51+ bt2020 = defaultColorSpace;
52+ }
53+ });
54+ }
55+
56+ if ((avif->profileFormat == AVIF_PROFILE_FORMAT_ICC) && avif->icc .data && avif->icc .size ) {
57+ if (@available (macOS 10.12 , *)) {
58+ *ref = CGColorSpaceCreateWithICCData (avif->icc .data );
59+ *shouldRelease = TRUE ;
60+ return ;
61+ }
62+ }
63+ uint16_t colorPrimaries = avif->nclx .colourPrimaries ;
64+ uint16_t transferCharacteristics = avif->nclx .transferCharacteristics ;
65+ if (colorPrimaries == AVIF_NCLX_COLOUR_PRIMARIES_UNKNOWN && transferCharacteristics == AVIF_NCLX_TRANSFER_CHARACTERISTICS_UNKNOWN) {
66+ goto default_color_space;
67+ }
68+ if (colorPrimaries == AVIF_NCLX_COLOUR_PRIMARIES_BT709 && transferCharacteristics == AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT709) {
69+ *ref = bt709;
70+ *shouldRelease = FALSE ;
71+ }
72+ if (colorPrimaries == AVIF_NCLX_COLOUR_PRIMARIES_BT2020 && (transferCharacteristics == AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT2020_10BIT || transferCharacteristics == AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT2020_12BIT)) {
73+ *ref = bt2020;
74+ *shouldRelease = FALSE ;
75+ }
76+
77+ default_color_space:
78+ *ref = defaultColorSpace;
79+ *shouldRelease = FALSE ;
80+ }
1981
2082static CGImageRef CreateImageFromBuffer (avifImage * avif, vImage_Buffer* result) {
2183 BOOL monochrome = avif->yuvPlanes [1 ] == NULL || avif->yuvPlanes [2 ] == NULL ;
@@ -26,28 +88,27 @@ static CGImageRef CreateImageFromBuffer(avifImage * avif, vImage_Buffer* result)
2688 CGDataProviderRef provider = CGDataProviderCreateWithData (NULL , result->data , result->rowBytes * result->height , FreeImageData);
2789 CGBitmapInfo bitmapInfo = usesU16 ? kCGBitmapByteOrder16Host : kCGBitmapByteOrderDefault ;
2890 bitmapInfo |= hasAlpha ? kCGImageAlphaFirst : kCGImageAlphaNone ;
29- // FIXME: (ledyba-z): Set appropriate color space.
30- // use avif->nclx.colourPrimaries and avif->nclx.transferCharacteristics to detect appropriate color space.
91+
92+ // Calc color space
3193 CGColorSpaceRef colorSpace = NULL ;
94+ BOOL shouldReleaseColorSpace = FALSE ;
3295 if (monochrome){
33- vImage_Error err;
34- vImageWhitePoint whitePoint ;
35- vImageTransferFunction transferFunction;
36- CGColorRenderingIntent intent;
37- colorSpace = vImageCreateMonochromeColorSpaceWithWhitePointAndTransferFunction (&whitePoint, &transferFunction, intent, kvImageNoFlags, &err);
96+ CalcColorSpaceMono (avif, &colorSpace, &shouldReleaseColorSpace);
3897 }else {
39- colorSpace = CGColorSpaceCreateDeviceRGB ( );
98+ CalcColorSpaceRGB (avif, & colorSpace, &shouldReleaseColorSpace );
4099 }
100+
41101 CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault ;
42-
43102 size_t bitsPerComponent = usesU16 ? 16 : 8 ;
44103 size_t bitsPerPixel = components * bitsPerComponent;
45104 size_t rowBytes = result->width * components * (usesU16 ? sizeof (uint16_t ) : sizeof (uint8_t ));
46105
47106 CGImageRef imageRef = CGImageCreate (result->width , result->height , bitsPerComponent, bitsPerPixel, rowBytes, colorSpace, bitmapInfo, provider, NULL , NO , renderingIntent);
48107
49108 // clean up
50- CGColorSpaceRelease (colorSpace);
109+ if (shouldReleaseColorSpace) {
110+ CGColorSpaceRelease (colorSpace);
111+ }
51112 CGDataProviderRelease (provider);
52113
53114 return imageRef;
0 commit comments