@@ -24,15 +24,28 @@ static void CalcWhitePoint(uint16_t const colorPrimaries, vImageWhitePoint* cons
24
24
white->white_y = primaries[7 ];
25
25
}
26
26
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
+
27
40
static void CalcTransferFunction (uint16_t const transferCharacteristics, vImageTransferFunction* const tf) {
41
+ // See: https://www.itu.int/rec/T-REC-H.273/en
28
42
static const float alpha = 1 .099296826809442f ;
29
43
static const float beta = 0 .018053968510807f ;
30
44
/*
31
45
// R' = c0 * pow( c1 * R + c2, gamma ) + c3, (R >= cutoff)
32
46
// R' = c4 * R + c5 (R < cutoff)
33
47
*/
34
48
35
- // See: https://www.itu.int/rec/T-REC-H.273/en
36
49
switch (transferCharacteristics) {
37
50
case AVIF_NCLX_TRANSFER_CHARACTERISTICS_GAMMA28: // 5
38
51
tf->cutoff = -INFINITY;
@@ -131,7 +144,7 @@ static void CalcTransferFunction(uint16_t const transferCharacteristics, vImageT
131
144
tf->c4 = 1 .0f ;
132
145
tf->c5 = 0 .0f ;
133
146
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 .
135
148
case AVIF_NCLX_TRANSFER_CHARACTERISTICS_ST2084: // 16
136
149
case AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT2100_HLG: // 18
137
150
case AVIF_NCLX_TRANSFER_CHARACTERISTICS_LOG_100_1: // 9
@@ -152,7 +165,7 @@ static void CalcTransferFunction(uint16_t const transferCharacteristics, vImageT
152
165
break ;
153
166
}
154
167
}
155
- static CGColorSpaceRef CreateMonoColorSpace (uint16_t const colorPrimaries, uint16_t const transferCharacteristics) {
168
+ static CGColorSpaceRef CreateColorSpaceMono (uint16_t const colorPrimaries, uint16_t const transferCharacteristics) {
156
169
if (@available (macOS 10.10 , iOS 8.0 , tvOS 8.0 , *)) {
157
170
vImage_Error err;
158
171
vImageWhitePoint white;
@@ -162,6 +175,30 @@ static CGColorSpaceRef CreateMonoColorSpace(uint16_t const colorPrimaries, uint1
162
175
CGColorSpaceRef colorSpace = vImageCreateMonochromeColorSpaceWithWhitePointAndTransferFunction (&white, &transfer, kCGRenderingIntentDefault , kvImagePrintDiagnosticsToConsole, &err);
163
176
if (err != kvImageNoError) {
164
177
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
+ }
165
202
return NULL ;
166
203
}
167
204
return colorSpace;
@@ -210,7 +247,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
210
247
static CGColorSpaceRef sRGB = NULL ;
211
248
static dispatch_once_t onceToken;
212
249
dispatch_once (&onceToken, ^{
213
- sRGB = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
250
+ sRGB = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
214
251
if (sRGB == NULL ) {
215
252
sRGB = defaultColorSpace;
216
253
}
@@ -224,7 +261,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
224
261
static CGColorSpaceRef bt709 = NULL ;
225
262
static dispatch_once_t onceToken;
226
263
dispatch_once (&onceToken, ^{
227
- bt709 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
264
+ bt709 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
228
265
if (bt709 == NULL ) {
229
266
bt709 = defaultColorSpace;
230
267
}
@@ -239,7 +276,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
239
276
static CGColorSpaceRef bt2020 = NULL ;
240
277
static dispatch_once_t onceToken;
241
278
dispatch_once (&onceToken, ^{
242
- bt2020 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
279
+ bt2020 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
243
280
if (bt2020 == NULL ) {
244
281
bt2020 = defaultColorSpace;
245
282
}
@@ -253,7 +290,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
253
290
static CGColorSpaceRef p3 = NULL ;
254
291
static dispatch_once_t onceToken;
255
292
dispatch_once (&onceToken, ^{
256
- p3 = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
293
+ p3 = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
257
294
if (p3 == NULL ) {
258
295
p3 = defaultColorSpace;
259
296
}
@@ -263,7 +300,7 @@ static void CalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* sho
263
300
return ;
264
301
}
265
302
266
- *ref = CreateMonoColorSpace (colorPrimaries, transferCharacteristics);
303
+ *ref = CreateColorSpaceMono (colorPrimaries, transferCharacteristics);
267
304
if (*ref != NULL ) {
268
305
*shouldRelease = TRUE ;
269
306
} else {
@@ -474,11 +511,14 @@ static void CalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shou
474
511
*shouldRelease = FALSE ;
475
512
return ;
476
513
}
477
- // TODO(ledyba-z): We can support more color spaces
478
- // using vImageCreateRGBColorSpaceWithPrimariesAndTransferFunction
479
514
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
+ }
482
522
}
483
523
484
524
static CGImageRef CreateImageFromBuffer (avifImage * avif, vImage_Buffer* result) {
0 commit comments