@@ -24,15 +24,28 @@ static void CalcWhitePoint(uint16_t const colorPrimaries, vImageWhitePoint* cons
2424 white->white_y = primaries[7 ];
2525}
2626
27+ static void CalcRGBPrimaries (uint16_t const colorPrimaries, vImageRGBPrimaries* const prim) {
28+ float primaries[8 ];
29+ avifNclxColourPrimariesGetValues (colorPrimaries, primaries);
30+ prim->red_x = primaries[0 ];
31+ prim->red_y = primaries[1 ];
32+ prim->green_x = primaries[2 ];
33+ prim->green_y = primaries[3 ];
34+ prim->blue_x = primaries[4 ];
35+ prim->blue_y = primaries[5 ];
36+ prim->white_x = primaries[6 ];
37+ prim->white_y = primaries[7 ];
38+ }
39+
2740static void CalcTransferFunction (uint16_t const transferCharacteristics, vImageTransferFunction* const tf) {
41+ // See: https://www.itu.int/rec/T-REC-H.273/en
2842 static const float alpha = 1 .099296826809442f ;
2943 static const float beta = 0 .018053968510807f ;
3044 /*
3145 // R' = c0 * pow( c1 * R + c2, gamma ) + c3, (R >= cutoff)
3246 // R' = c4 * R + c5 (R < cutoff)
3347 */
3448
35- // See: https://www.itu.int/rec/T-REC-H.273/en
3649 switch (transferCharacteristics) {
3750 case AVIF_NCLX_TRANSFER_CHARACTERISTICS_GAMMA28: // 5
3851 tf->cutoff = -INFINITY;
@@ -131,7 +144,7 @@ static void CalcTransferFunction(uint16_t const transferCharacteristics, vImageT
131144 tf->c4 = 1 .0f ;
132145 tf->c5 = 0 .0f ;
133146 break ;
134- // Can't be represented by vImageTransferFunction. Use gamma 2.2 as a default .
147+ // Can't be represented by vImageTransferFunction. Use gamma 2.2 as a fallback .
135148 case AVIF_NCLX_TRANSFER_CHARACTERISTICS_ST2084: // 16
136149 case AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT2100_HLG: // 18
137150 case AVIF_NCLX_TRANSFER_CHARACTERISTICS_LOG_100_1: // 9
@@ -152,7 +165,7 @@ static void CalcTransferFunction(uint16_t const transferCharacteristics, vImageT
152165 break ;
153166 }
154167}
155- static CGColorSpaceRef CreateMonoColorSpace (uint16_t const colorPrimaries, uint16_t const transferCharacteristics) {
168+ static CGColorSpaceRef CreateColorSpaceMono (uint16_t const colorPrimaries, uint16_t const transferCharacteristics) {
156169 if (@available (macOS 10.10 , iOS 8.0 , tvOS 8.0 , *)) {
157170 vImage_Error err;
158171 vImageWhitePoint white;
@@ -162,6 +175,30 @@ static CGColorSpaceRef CreateMonoColorSpace(uint16_t const colorPrimaries, uint1
162175 CGColorSpaceRef colorSpace = vImageCreateMonochromeColorSpaceWithWhitePointAndTransferFunction (&white, &transfer, kCGRenderingIntentDefault , kvImagePrintDiagnosticsToConsole, &err);
163176 if (err != kvImageNoError) {
164177 NSLog (@" [BUG] Failed to create monochrome color space: %ld " , err);
178+ if (colorSpace != NULL ) {
179+ CGColorSpaceRelease (colorSpace);
180+ }
181+ return NULL ;
182+ }
183+ return colorSpace;
184+ }else {
185+ return NULL ;
186+ }
187+ }
188+
189+ static CGColorSpaceRef CreateColorSpaceRGB (uint16_t const colorPrimaries, uint16_t const transferCharacteristics) {
190+ if (@available (macOS 10.10 , iOS 8.0 , tvOS 8.0 , *)) {
191+ vImage_Error err;
192+ vImageRGBPrimaries primaries;
193+ vImageTransferFunction transfer;
194+ CalcRGBPrimaries (colorPrimaries, &primaries);
195+ CalcTransferFunction (transferCharacteristics, &transfer);
196+ CGColorSpaceRef colorSpace = vImageCreateRGBColorSpaceWithPrimariesAndTransferFunction (&primaries, &transfer, kCGRenderingIntentDefault , kvImagePrintDiagnosticsToConsole, &err);
197+ if (err != kvImageNoError) {
198+ NSLog (@" [BUG] Failed to create monochrome color space: %ld " , err);
199+ if (colorSpace != NULL ) {
200+ CGColorSpaceRelease (colorSpace);
201+ }
165202 return NULL ;
166203 }
167204 return colorSpace;
@@ -210,7 +247,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
210247 static CGColorSpaceRef sRGB = NULL ;
211248 static dispatch_once_t onceToken;
212249 dispatch_once (&onceToken, ^{
213- sRGB = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
250+ sRGB = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
214251 if (sRGB == NULL ) {
215252 sRGB = defaultColorSpace;
216253 }
@@ -224,7 +261,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
224261 static CGColorSpaceRef bt709 = NULL ;
225262 static dispatch_once_t onceToken;
226263 dispatch_once (&onceToken, ^{
227- bt709 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
264+ bt709 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
228265 if (bt709 == NULL ) {
229266 bt709 = defaultColorSpace;
230267 }
@@ -239,7 +276,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
239276 static CGColorSpaceRef bt2020 = NULL ;
240277 static dispatch_once_t onceToken;
241278 dispatch_once (&onceToken, ^{
242- bt2020 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
279+ bt2020 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
243280 if (bt2020 == NULL ) {
244281 bt2020 = defaultColorSpace;
245282 }
@@ -253,7 +290,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
253290 static CGColorSpaceRef p3 = NULL ;
254291 static dispatch_once_t onceToken;
255292 dispatch_once (&onceToken, ^{
256- p3 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
293+ p3 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
257294 if (p3 == NULL ) {
258295 p3 = defaultColorSpace;
259296 }
@@ -263,7 +300,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
263300 return ;
264301 }
265302
266- *ref = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
303+ *ref = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
267304 if (*ref != NULL ) {
268305 *shouldRelease = TRUE ;
269306 } else {
@@ -474,11 +511,14 @@ static void CalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shou
474511 *shouldRelease = FALSE ;
475512 return ;
476513 }
477- // TODO(ledyba-z): We can support more color spaces
478- // using vImageCreateRGBColorSpaceWithPrimariesAndTransferFunction
479514
480- *ref = defaultColorSpace;
481- *shouldRelease = FALSE ;
515+ *ref = CreateColorSpaceRGB (colorPrimaries, transferCharacteristics);
516+ if (*ref != NULL ) {
517+ *shouldRelease = TRUE ;
518+ } else {
519+ *ref = defaultColorSpace;
520+ *shouldRelease = FALSE ;
521+ }
482522}
483523
484524static CGImageRef CreateImageFromBuffer (avifImage * avif, vImage_Buffer* result) {
0 commit comments