16
16
static void FreeImageData (void *info, const void *data, size_t size) {
17
17
free ((void *)data);
18
18
}
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
+ }
19
81
20
82
static CGImageRef CreateImageFromBuffer (avifImage * avif, vImage_Buffer* result) {
21
83
BOOL monochrome = avif->yuvPlanes [1 ] == NULL || avif->yuvPlanes [2 ] == NULL ;
@@ -26,28 +88,27 @@ static CGImageRef CreateImageFromBuffer(avifImage * avif, vImage_Buffer* result)
26
88
CGDataProviderRef provider = CGDataProviderCreateWithData (NULL , result->data , result->rowBytes * result->height , FreeImageData);
27
89
CGBitmapInfo bitmapInfo = usesU16 ? kCGBitmapByteOrder16Host : kCGBitmapByteOrderDefault ;
28
90
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
31
93
CGColorSpaceRef colorSpace = NULL ;
94
+ BOOL shouldReleaseColorSpace = FALSE ;
32
95
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);
38
97
}else {
39
- colorSpace = CGColorSpaceCreateDeviceRGB ( );
98
+ CalcColorSpaceRGB (avif, & colorSpace, &shouldReleaseColorSpace );
40
99
}
100
+
41
101
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault ;
42
-
43
102
size_t bitsPerComponent = usesU16 ? 16 : 8 ;
44
103
size_t bitsPerPixel = components * bitsPerComponent;
45
104
size_t rowBytes = result->width * components * (usesU16 ? sizeof (uint16_t ) : sizeof (uint8_t ));
46
105
47
106
CGImageRef imageRef = CGImageCreate (result->width , result->height , bitsPerComponent, bitsPerPixel, rowBytes, colorSpace, bitmapInfo, provider, NULL , NO , renderingIntent);
48
107
49
108
// clean up
50
- CGColorSpaceRelease (colorSpace);
109
+ if (shouldReleaseColorSpace) {
110
+ CGColorSpaceRelease (colorSpace);
111
+ }
51
112
CGDataProviderRelease (provider);
52
113
53
114
return imageRef;
0 commit comments