video-color: Add bt601 transfer function
[platform/upstream/gstreamer.git] / gst-libs / gst / video / video-color.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Library       <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
4  * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <math.h>
29
30 #include "video-color.h"
31
32 #ifndef GST_DISABLE_GST_DEBUG
33 #define GST_CAT_DEFAULT ensure_debug_category()
34 static GstDebugCategory *
35 ensure_debug_category (void)
36 {
37   static gsize cat_gonce = 0;
38
39   if (g_once_init_enter (&cat_gonce)) {
40     gsize cat_done;
41
42     cat_done = (gsize) _gst_debug_category_new ("video-color", 0,
43         "video-color object");
44
45     g_once_init_leave (&cat_gonce, cat_done);
46   }
47
48   return (GstDebugCategory *) cat_gonce;
49 }
50 #else
51 #define ensure_debug_category() /* NOOP */
52 #endif /* GST_DISABLE_GST_DEBUG */
53
54 typedef struct
55 {
56   const gchar *name;
57   GstVideoColorimetry color;
58 } ColorimetryInfo;
59
60 #define MAKE_COLORIMETRY(n,r,m,t,p) { GST_VIDEO_COLORIMETRY_ ##n, \
61   { GST_VIDEO_COLOR_RANGE ##r, GST_VIDEO_COLOR_MATRIX_ ##m, \
62   GST_VIDEO_TRANSFER_ ##t, GST_VIDEO_COLOR_PRIMARIES_ ##p } }
63
64 #define GST_VIDEO_COLORIMETRY_NONAME  NULL
65
66 static const ColorimetryInfo colorimetry[] = {
67   MAKE_COLORIMETRY (BT601, _16_235, BT601, BT601, SMPTE170M),
68   MAKE_COLORIMETRY (BT709, _16_235, BT709, BT709, BT709),
69   MAKE_COLORIMETRY (SMPTE240M, _16_235, SMPTE240M, SMPTE240M, SMPTE240M),
70   MAKE_COLORIMETRY (SRGB, _0_255, RGB, SRGB, BT709),
71   MAKE_COLORIMETRY (BT2020, _16_235, BT2020, BT2020_12, BT2020),
72   MAKE_COLORIMETRY (BT2020_10, _16_235, BT2020, BT2020_10, BT2020),
73   MAKE_COLORIMETRY (BT2100_PQ, _16_235, BT2020, SMPTE2084, BT2020),
74   MAKE_COLORIMETRY (BT2100_HLG, _16_235, BT2020, ARIB_STD_B67, BT2020),
75   MAKE_COLORIMETRY (NONAME, _0_255, BT601, UNKNOWN, UNKNOWN),
76   MAKE_COLORIMETRY (NONAME, _UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN),       /* Keep last! */
77 };
78
79 #define DEFAULT_UNKNOWN (G_N_ELEMENTS(colorimetry)-1)
80
81 static const ColorimetryInfo *
82 gst_video_get_colorimetry (const gchar * s)
83 {
84   gint i;
85
86   for (i = 0; colorimetry[i].name; i++) {
87     if (g_str_equal (colorimetry[i].name, s))
88       return &colorimetry[i];
89   }
90   return NULL;
91 }
92
93 #define CI_IS_EQUAL(ci,i) (((ci)->range == (i)->range) && \
94                         ((ci)->matrix == (i)->matrix) && \
95                         ((ci)->transfer == (i)->transfer) && \
96                         ((ci)->primaries == (i)->primaries))
97
98 #define IS_EQUAL(ci,i) CI_IS_EQUAL(&(ci)->color, (i))
99
100 #define IS_UNKNOWN(ci) (IS_EQUAL (&colorimetry[DEFAULT_UNKNOWN], ci))
101
102 /**
103  * gst_video_colorimetry_from_string:
104  * @cinfo: a #GstVideoColorimetry
105  * @color: a colorimetry string
106  *
107  * Parse the colorimetry string and update @cinfo with the parsed
108  * values.
109  *
110  * Returns: %TRUE if @color points to valid colorimetry info.
111  */
112 gboolean
113 gst_video_colorimetry_from_string (GstVideoColorimetry * cinfo,
114     const gchar * color)
115 {
116   const ColorimetryInfo *ci;
117   gboolean res = FALSE;
118
119   if (!color) {
120     *cinfo = colorimetry[DEFAULT_UNKNOWN].color;
121     res = TRUE;
122   } else if ((ci = gst_video_get_colorimetry (color))) {
123     *cinfo = ci->color;
124     res = TRUE;
125   } else {
126     gint r, m, t, p;
127
128     if (sscanf (color, "%d:%d:%d:%d", &r, &m, &t, &p) == 4) {
129       cinfo->range = r;
130       cinfo->matrix = m;
131       cinfo->transfer = t;
132       cinfo->primaries = p;
133       res = TRUE;
134     }
135   }
136   return res;
137 }
138
139 /**
140  * gst_video_colorimetry_to_string:
141  * @cinfo: a #GstVideoColorimetry
142  *
143  * Make a string representation of @cinfo.
144  *
145  * Returns: (transfer full) (nullable): a string representation of @cinfo
146  * or %NULL if all the entries of @cinfo are unknown values.
147  */
148 gchar *
149 gst_video_colorimetry_to_string (const GstVideoColorimetry * cinfo)
150 {
151   gint i;
152
153   for (i = 0; colorimetry[i].name; i++) {
154     if (IS_EQUAL (&colorimetry[i], cinfo)) {
155       return g_strdup (colorimetry[i].name);
156     }
157   }
158   if (!IS_UNKNOWN (cinfo)) {
159     return g_strdup_printf ("%d:%d:%d:%d", cinfo->range, cinfo->matrix,
160         cinfo->transfer, cinfo->primaries);
161   }
162   return NULL;
163 }
164
165 /**
166  * gst_video_colorimetry_matches:
167  * @cinfo: a #GstVideoInfo
168  * @color: a colorimetry string
169  *
170  * Check if the colorimetry information in @info matches that of the
171  * string @color.
172  *
173  * Returns: %TRUE if @color conveys the same colorimetry info as the color
174  * information in @info.
175  */
176 gboolean
177 gst_video_colorimetry_matches (const GstVideoColorimetry * cinfo,
178     const gchar * color)
179 {
180   const ColorimetryInfo *ci;
181
182   if ((ci = gst_video_get_colorimetry (color)))
183     return IS_EQUAL (ci, cinfo);
184
185   return FALSE;
186 }
187
188 /**
189  * gst_video_color_range_offsets:
190  * @range: a #GstVideoColorRange
191  * @info: a #GstVideoFormatInfo
192  * @offset: (out caller-allocates) (array fixed-size=4): output offsets
193  * @scale: (out caller-allocates) (array fixed-size=4): output scale
194  *
195  * Compute the offset and scale values for each component of @info. For each
196  * component, (c[i] - offset[i]) / scale[i] will scale the component c[i] to the
197  * range [0.0 .. 1.0].
198  *
199  * The reverse operation (c[i] * scale[i]) + offset[i] can be used to convert
200  * the component values in range [0.0 .. 1.0] back to their representation in
201  * @info and @range.
202  */
203 void
204 gst_video_color_range_offsets (GstVideoColorRange range,
205     const GstVideoFormatInfo * info, gint offset[GST_VIDEO_MAX_COMPONENTS],
206     gint scale[GST_VIDEO_MAX_COMPONENTS])
207 {
208   gboolean yuv;
209
210   yuv = GST_VIDEO_FORMAT_INFO_IS_YUV (info);
211
212   switch (range) {
213     default:
214     case GST_VIDEO_COLOR_RANGE_0_255:
215       offset[0] = 0;
216       if (yuv) {
217         offset[1] = 1 << (info->depth[1] - 1);
218         offset[2] = 1 << (info->depth[2] - 1);
219       } else {
220         offset[1] = 0;
221         offset[2] = 0;
222       }
223       scale[0] = (1 << info->depth[0]) - 1;
224       scale[1] = (1 << info->depth[1]) - 1;
225       scale[2] = (1 << info->depth[2]) - 1;
226       break;
227     case GST_VIDEO_COLOR_RANGE_16_235:
228       offset[0] = 1 << (info->depth[0] - 4);
229       scale[0] = 219 << (info->depth[0] - 8);
230       if (yuv) {
231         offset[1] = 1 << (info->depth[1] - 1);
232         offset[2] = 1 << (info->depth[2] - 1);
233         scale[1] = 224 << (info->depth[1] - 8);
234         scale[2] = 224 << (info->depth[2] - 8);
235       } else {
236         offset[1] = 1 << (info->depth[1] - 4);
237         offset[2] = 1 << (info->depth[2] - 4);
238         scale[1] = 219 << (info->depth[1] - 8);
239         scale[2] = 219 << (info->depth[2] - 8);
240       }
241       break;
242   }
243   /* alpha channel is always full range */
244   offset[3] = 0;
245   scale[3] = (1 << info->depth[3]) - 1;
246
247   GST_DEBUG ("scale: %d %d %d %d", scale[0], scale[1], scale[2], scale[3]);
248   GST_DEBUG ("offset: %d %d %d %d", offset[0], offset[1], offset[2], offset[3]);
249 }
250
251 /**
252  * gst_video_colorimetry_is_equal:
253  * @cinfo: a #GstVideoColorimetry
254  * @other: another #GstVideoColorimetry
255  *
256  * Compare the 2 colorimetry sets for equality
257  *
258  * Returns: %TRUE if @cinfo and @other are equal.
259  *
260  * Since: 1.6
261  */
262 gboolean
263 gst_video_colorimetry_is_equal (const GstVideoColorimetry * cinfo,
264     const GstVideoColorimetry * other)
265 {
266   g_return_val_if_fail (cinfo != NULL, FALSE);
267   g_return_val_if_fail (other != NULL, FALSE);
268
269   return CI_IS_EQUAL (cinfo, other);
270 }
271
272 #define WP_C    0.31006, 0.31616
273 #define WP_D65  0.31271, 0.32902
274 #define WP_CENTRE (1/3), (1/3)
275 #define WP_WHITE 0.314, 0.351
276
277 static const GstVideoColorPrimariesInfo color_primaries[] = {
278   {GST_VIDEO_COLOR_PRIMARIES_UNKNOWN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
279   {GST_VIDEO_COLOR_PRIMARIES_BT709, WP_D65, 0.64, 0.33, 0.30, 0.60, 0.15, 0.06},
280   {GST_VIDEO_COLOR_PRIMARIES_BT470M, WP_C, 0.67, 0.33, 0.21, 0.71, 0.14, 0.08},
281   {GST_VIDEO_COLOR_PRIMARIES_BT470BG, WP_D65, 0.64, 0.33, 0.29, 0.60, 0.15,
282       0.06},
283   {GST_VIDEO_COLOR_PRIMARIES_SMPTE170M, WP_D65, 0.63, 0.34, 0.31, 0.595, 0.155,
284       0.07},
285   {GST_VIDEO_COLOR_PRIMARIES_SMPTE240M, WP_D65, 0.63, 0.34, 0.31, 0.595, 0.155,
286       0.07},
287   {GST_VIDEO_COLOR_PRIMARIES_FILM, WP_C, 0.681, 0.319, 0.243, 0.692, 0.145,
288       0.049},
289   {GST_VIDEO_COLOR_PRIMARIES_BT2020, WP_D65, 0.708, 0.292, 0.170, 0.797, 0.131,
290       0.046},
291   {GST_VIDEO_COLOR_PRIMARIES_ADOBERGB, WP_D65, 0.64, 0.33, 0.21, 0.71, 0.15,
292       0.06},
293   {GST_VIDEO_COLOR_PRIMARIES_SMPTEST428, WP_CENTRE, 1.0, 0.0, 0.0, 1.0, 0.0,
294       0.0},
295   {GST_VIDEO_COLOR_PRIMARIES_SMPTERP431, WP_WHITE, 0.68, 0.32, 0.265, 0.69,
296       0.15, 0.06},
297   {GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432, WP_D65, 0.68, 0.32, 0.265, 0.69, 0.15,
298       0.06},
299   {GST_VIDEO_COLOR_PRIMARIES_EBU3213, WP_D65, 0.63, 0.34, 0.295, 0.605, 0.155,
300       0.077},
301 };
302
303 /**
304  * gst_video_color_primaries_get_info:
305  * @primaries: a #GstVideoColorPrimaries
306  *
307  * Get information about the chromaticity coordinates of @primaries.
308  *
309  * Returns: a #GstVideoColorPrimariesInfo for @primaries.
310  *
311  * Since: 1.6
312  */
313 const GstVideoColorPrimariesInfo *
314 gst_video_color_primaries_get_info (GstVideoColorPrimaries primaries)
315 {
316   g_return_val_if_fail ((gint) primaries <
317       G_N_ELEMENTS (color_primaries), NULL);
318
319   return &color_primaries[primaries];
320 }
321
322 /**
323  * gst_video_color_matrix_get_Kr_Kb:
324  * @matrix: a #GstVideoColorMatrix
325  * @Kr: (out): result red channel coefficient
326  * @Kb: (out): result blue channel coefficient
327  *
328  * Get the coefficients used to convert between Y'PbPr and R'G'B' using @matrix.
329  *
330  * When:
331  *
332  * |[
333  *   0.0 <= [Y',R',G',B'] <= 1.0)
334  *   (-0.5 <= [Pb,Pr] <= 0.5)
335  * ]|
336  *
337  * the general conversion is given by:
338  *
339  * |[
340  *   Y' = Kr*R' + (1-Kr-Kb)*G' + Kb*B'
341  *   Pb = (B'-Y')/(2*(1-Kb))
342  *   Pr = (R'-Y')/(2*(1-Kr))
343  * ]|
344  *
345  * and the other way around:
346  *
347  * |[
348  *   R' = Y' + Cr*2*(1-Kr)
349  *   G' = Y' - Cb*2*(1-Kb)*Kb/(1-Kr-Kb) - Cr*2*(1-Kr)*Kr/(1-Kr-Kb)
350  *   B' = Y' + Cb*2*(1-Kb)
351  * ]|
352  *
353  * Returns: TRUE if @matrix was a YUV color format and @Kr and @Kb contain valid
354  *    values.
355  *
356  * Since: 1.6
357  */
358 gboolean
359 gst_video_color_matrix_get_Kr_Kb (GstVideoColorMatrix matrix, gdouble * Kr,
360     gdouble * Kb)
361 {
362   gboolean res = TRUE;
363
364   switch (matrix) {
365       /* RGB */
366     default:
367     case GST_VIDEO_COLOR_MATRIX_RGB:
368       res = FALSE;
369       break;
370       /* YUV */
371     case GST_VIDEO_COLOR_MATRIX_FCC:
372       *Kr = 0.30;
373       *Kb = 0.11;
374       break;
375     case GST_VIDEO_COLOR_MATRIX_BT709:
376       *Kr = 0.2126;
377       *Kb = 0.0722;
378       break;
379     case GST_VIDEO_COLOR_MATRIX_BT601:
380       *Kr = 0.2990;
381       *Kb = 0.1140;
382       break;
383     case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
384       *Kr = 0.212;
385       *Kb = 0.087;
386       break;
387     case GST_VIDEO_COLOR_MATRIX_BT2020:
388       *Kr = 0.2627;
389       *Kb = 0.0593;
390       break;
391   }
392   GST_DEBUG ("matrix: %d, Kr %f, Kb %f", matrix, *Kr, *Kb);
393
394   return res;
395 }
396
397 /**
398  * gst_video_color_transfer_encode:
399  * @func: a #GstVideoTransferFunction
400  * @val: a value
401  *
402  * Convert @val to its gamma encoded value.
403  *
404  * For a linear value L in the range [0..1], conversion to the non-linear
405  * (gamma encoded) L' is in general performed with a power function like:
406  *
407  * |[
408  *    L' = L ^ (1 / gamma)
409  * ]|
410  *
411  * Depending on @func, different formulas might be applied. Some formulas
412  * encode a linear segment in the lower range.
413  *
414  * Returns: the gamme encoded value of @val
415  *
416  * Since: 1.6
417  */
418 gdouble
419 gst_video_color_transfer_encode (GstVideoTransferFunction func, gdouble val)
420 {
421   gdouble res;
422
423   switch (func) {
424     case GST_VIDEO_TRANSFER_UNKNOWN:
425     case GST_VIDEO_TRANSFER_GAMMA10:
426     default:
427       res = val;
428       break;
429     case GST_VIDEO_TRANSFER_GAMMA18:
430       res = pow (val, 1.0 / 1.8);
431       break;
432     case GST_VIDEO_TRANSFER_GAMMA20:
433       res = pow (val, 1.0 / 2.0);
434       break;
435     case GST_VIDEO_TRANSFER_GAMMA22:
436       res = pow (val, 1.0 / 2.2);
437       break;
438     case GST_VIDEO_TRANSFER_BT601:
439     case GST_VIDEO_TRANSFER_BT709:
440     case GST_VIDEO_TRANSFER_BT2020_10:
441       if (val < 0.018)
442         res = 4.5 * val;
443       else
444         res = 1.099 * pow (val, 0.45) - 0.099;
445       break;
446     case GST_VIDEO_TRANSFER_SMPTE240M:
447       if (val < 0.0228)
448         res = val * 4.0;
449       else
450         res = 1.1115 * pow (val, 0.45) - 0.1115;
451       break;
452     case GST_VIDEO_TRANSFER_SRGB:
453       if (val <= 0.0031308)
454         res = 12.92 * val;
455       else
456         res = 1.055 * pow (val, 1.0 / 2.4) - 0.055;
457       break;
458     case GST_VIDEO_TRANSFER_GAMMA28:
459       res = pow (val, 1 / 2.8);
460       break;
461     case GST_VIDEO_TRANSFER_LOG100:
462       if (val < 0.01)
463         res = 0.0;
464       else
465         res = 1.0 + log10 (val) / 2.0;
466       break;
467     case GST_VIDEO_TRANSFER_LOG316:
468       if (val < 0.0031622777)
469         res = 0.0;
470       else
471         res = 1.0 + log10 (val) / 2.5;
472       break;
473     case GST_VIDEO_TRANSFER_BT2020_12:
474       if (val < 0.0181)
475         res = 4.5 * val;
476       else
477         res = 1.0993 * pow (val, 0.45) - 0.0993;
478       break;
479     case GST_VIDEO_TRANSFER_ADOBERGB:
480       res = pow (val, 1.0 / 2.19921875);
481       break;
482     case GST_VIDEO_TRANSFER_SMPTE2084:
483     {
484       gdouble c1 = 3424.0 / 4096.0;     /* c3 - c2 + 1 */
485       gdouble c2 = 32 * 2413 / 4096.0;
486       gdouble c3 = 32 * 2392 / 4096.0;
487       gdouble m = 128 * 2523 / 4096.0;
488       gdouble n = 0.25 * 2610 / 4096.0;
489       gdouble Ln = pow (val, n);
490
491       /* val equal to 1 for peak white is ordinarily intended to
492        * correspond to a reference output luminance level of 10000 cd/m^2  */
493       res = pow ((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
494       break;
495     }
496     case GST_VIDEO_TRANSFER_ARIB_STD_B67:
497     {
498       gdouble a = 0.17883277;
499       gdouble b = 0.28466892;
500       gdouble c = 0.55991073;
501
502       /* For [0, 1] normalized source as defined by HEVC specification */
503       if (val > (1.0 / 12.0))
504         res = a * log (12.0 * val - b) + c;
505       else
506         res = sqrt (3.0 * val);
507
508       break;
509     }
510   }
511   return res;
512 }
513
514 /**
515  * gst_video_color_transfer_decode:
516  * @func: a #GstVideoTransferFunction
517  * @val: a value
518  *
519  * Convert @val to its gamma decoded value. This is the inverse operation of
520  * @gst_video_color_transfer_encode().
521  *
522  * For a non-linear value L' in the range [0..1], conversion to the linear
523  * L is in general performed with a power function like:
524  *
525  * |[
526  *    L = L' ^ gamma
527  * ]|
528  *
529  * Depending on @func, different formulas might be applied. Some formulas
530  * encode a linear segment in the lower range.
531  *
532  * Returns: the gamme decoded value of @val
533  *
534  * Since: 1.6
535  */
536 gdouble
537 gst_video_color_transfer_decode (GstVideoTransferFunction func, gdouble val)
538 {
539   gdouble res;
540
541   switch (func) {
542     case GST_VIDEO_TRANSFER_UNKNOWN:
543     case GST_VIDEO_TRANSFER_GAMMA10:
544     default:
545       res = val;
546       break;
547     case GST_VIDEO_TRANSFER_GAMMA18:
548       res = pow (val, 1.8);
549       break;
550     case GST_VIDEO_TRANSFER_GAMMA20:
551       res = pow (val, 2.0);
552       break;
553     case GST_VIDEO_TRANSFER_GAMMA22:
554       res = pow (val, 2.2);
555       break;
556     case GST_VIDEO_TRANSFER_BT601:
557     case GST_VIDEO_TRANSFER_BT709:
558     case GST_VIDEO_TRANSFER_BT2020_10:
559       if (val < 0.081)
560         res = val / 4.5;
561       else
562         res = pow ((val + 0.099) / 1.099, 1.0 / 0.45);
563       break;
564     case GST_VIDEO_TRANSFER_SMPTE240M:
565       if (val < 0.0913)
566         res = val / 4.0;
567       else
568         res = pow ((val + 0.1115) / 1.1115, 1.0 / 0.45);
569       break;
570     case GST_VIDEO_TRANSFER_SRGB:
571       if (val <= 0.04045)
572         res = val / 12.92;
573       else
574         res = pow ((val + 0.055) / 1.055, 2.4);
575       break;
576     case GST_VIDEO_TRANSFER_GAMMA28:
577       res = pow (val, 2.8);
578       break;
579     case GST_VIDEO_TRANSFER_LOG100:
580       if (val == 0.0)
581         res = 0.0;
582       else
583         res = pow (10.0, 2.0 * (val - 1.0));
584       break;
585     case GST_VIDEO_TRANSFER_LOG316:
586       if (val == 0.0)
587         res = 0.0;
588       else
589         res = pow (10.0, 2.5 * (val - 1.0));
590       break;
591     case GST_VIDEO_TRANSFER_BT2020_12:
592       if (val < 0.08145)
593         res = val / 4.5;
594       else
595         res = pow ((val + 0.0993) / 1.0993, 1.0 / 0.45);
596       break;
597     case GST_VIDEO_TRANSFER_ADOBERGB:
598       res = pow (val, 2.19921875);
599       break;
600     case GST_VIDEO_TRANSFER_SMPTE2084:
601     {
602       gdouble c1 = 3424.0 / 4096.0;     /* c3 - c2 + 1 */
603       gdouble c2 = 32 * 2413 / 4096.0;
604       gdouble c3 = 32 * 2392 / 4096.0;
605       gdouble mi = 1 / (128 * 2523 / 4096.0);
606       gdouble ni = 1 / (0.25 * 2610 / 4096.0);
607       gdouble nm = pow (val, mi);
608
609       res = pow ((nm - c1) / (c2 - c3 * nm), ni);
610       break;
611     }
612     case GST_VIDEO_TRANSFER_ARIB_STD_B67:
613     {
614       gdouble a = 0.17883277;
615       gdouble b = 0.28466892;
616       gdouble c = 0.55991073;
617
618       if (val > 0.5)
619         res = (exp ((val - c) / a) + b) / 12.0;
620       else
621         res = val * val / 3.0;
622
623       break;
624     }
625   }
626   return res;
627 }
628
629 /* conversion between GStreamer color{matrix,transfer,primaries} enum
630  * and indices defined by ITU-T H.273 and ISO/IEC 230001-8 specification */
631
632 /* FIXME 2.0: Define color{matrix,transfer,primaries} with explicit numbering
633  * to be matched with specification
634  */
635
636 /**
637  * gst_video_color_matrix_to_iso:
638  * @matrix: a #GstVideoColorMatrix
639  *
640  * Converts #GstVideoColorMatrix to the "matrix coefficients"
641  * (MatrixCoefficients) value defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
642  * and "ITU-T H.273 Table 4".
643  * "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
644  *
645  * Returns: The value of ISO/IEC 23001-8 matrix coefficients.
646  *
647  * Since: 1.18
648  */
649 guint
650 gst_video_color_matrix_to_iso (GstVideoColorMatrix matrix)
651 {
652   switch (matrix) {
653     case GST_VIDEO_COLOR_MATRIX_RGB:
654       return 0;
655     case GST_VIDEO_COLOR_MATRIX_BT709:
656       return 1;
657     case GST_VIDEO_COLOR_MATRIX_FCC:
658       return 4;
659     case GST_VIDEO_COLOR_MATRIX_BT601:
660       return 6;
661     case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
662       return 7;
663     case GST_VIDEO_COLOR_MATRIX_BT2020:
664       return 9;
665     case GST_VIDEO_COLOR_MATRIX_UNKNOWN:
666     default:
667       return 2;
668   }
669 }
670
671 /**
672  * gst_video_color_transfer_to_iso:
673  * @func: a #GstVideoTransferFunction
674  *
675  * Converts #GstVideoTransferFunction to the "transfer characteristics"
676  * (TransferCharacteristics) value defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
677  * and "ITU-T H.273 Table 3".
678  * "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
679  *
680  * Returns: The value of ISO/IEC 23001-8 transfer characteristics.
681  *
682  * Since: 1.18
683  */
684 guint
685 gst_video_color_transfer_to_iso (GstVideoTransferFunction func)
686 {
687   switch (func) {
688     case GST_VIDEO_TRANSFER_BT709:
689       return 1;
690     case GST_VIDEO_TRANSFER_GAMMA22:
691       return 4;
692     case GST_VIDEO_TRANSFER_GAMMA28:
693       return 5;
694     case GST_VIDEO_TRANSFER_BT601:
695       return 6;
696     case GST_VIDEO_TRANSFER_SMPTE240M:
697       return 7;
698     case GST_VIDEO_TRANSFER_GAMMA10:
699       return 8;
700     case GST_VIDEO_TRANSFER_LOG100:
701       return 9;
702     case GST_VIDEO_TRANSFER_LOG316:
703       return 10;
704     case GST_VIDEO_TRANSFER_SRGB:
705       return 13;
706     case GST_VIDEO_TRANSFER_BT2020_10:
707       return 14;
708     case GST_VIDEO_TRANSFER_BT2020_12:
709       return 15;
710     case GST_VIDEO_TRANSFER_SMPTE2084:
711       return 16;
712     case GST_VIDEO_TRANSFER_ARIB_STD_B67:
713       return 18;
714     case GST_VIDEO_TRANSFER_GAMMA18:
715     case GST_VIDEO_TRANSFER_GAMMA20:
716     case GST_VIDEO_TRANSFER_ADOBERGB:
717     case GST_VIDEO_TRANSFER_UNKNOWN:
718     default:
719       return 2;
720   }
721 }
722
723 /**
724  * gst_video_color_primaries_to_iso:
725  * @primaries: a #GstVideoColorPrimaries
726  *
727  * Converts #GstVideoColorPrimaries to the "colour primaries" (ColourPrimaries)
728  * value defined by "ISO/IEC 23001-8 Section 7.1 Table 2"
729  * and "ITU-T H.273 Table 2".
730  * "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
731  *
732  * Returns: The value of ISO/IEC 23001-8 colour primaries.
733  *
734  * Since: 1.18
735  */
736 guint
737 gst_video_color_primaries_to_iso (GstVideoColorPrimaries primaries)
738 {
739   switch (primaries) {
740     case GST_VIDEO_COLOR_PRIMARIES_BT709:
741       return 1;
742     case GST_VIDEO_COLOR_PRIMARIES_BT470M:
743       return 4;
744     case GST_VIDEO_COLOR_PRIMARIES_BT470BG:
745       return 5;
746     case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
747       return 6;
748     case GST_VIDEO_COLOR_PRIMARIES_SMPTE240M:
749       return 7;
750     case GST_VIDEO_COLOR_PRIMARIES_FILM:
751       return 8;
752     case GST_VIDEO_COLOR_PRIMARIES_BT2020:
753       return 9;
754     case GST_VIDEO_COLOR_PRIMARIES_SMPTEST428:
755       return 10;
756     case GST_VIDEO_COLOR_PRIMARIES_SMPTERP431:
757       return 11;
758     case GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432:
759       return 12;
760     case GST_VIDEO_COLOR_PRIMARIES_EBU3213:
761       return 22;
762     case GST_VIDEO_COLOR_PRIMARIES_ADOBERGB:
763     case GST_VIDEO_COLOR_PRIMARIES_UNKNOWN:
764     default:
765       return 2;
766   }
767 }
768
769 /**
770  * gst_video_color_matrix_from_iso:
771  * @value: a ITU-T H.273 matrix coefficients value
772  *
773  * Converts the @value to the #GstVideoColorMatrix
774  * The matrix coefficients (MatrixCoefficients) value is
775  * defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
776  * and "ITU-T H.273 Table 4".
777  * "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
778  *
779  * Returns: the matched #GstVideoColorMatrix
780  *
781  * Since: 1.18
782  */
783 GstVideoColorMatrix
784 gst_video_color_matrix_from_iso (guint value)
785 {
786   switch (value) {
787     case 0:
788       return GST_VIDEO_COLOR_MATRIX_RGB;
789     case 1:
790       return GST_VIDEO_COLOR_MATRIX_BT709;
791     case 4:
792       return GST_VIDEO_COLOR_MATRIX_FCC;
793     case 5:
794     case 6:
795       return GST_VIDEO_COLOR_MATRIX_BT601;
796     case 7:
797       return GST_VIDEO_COLOR_MATRIX_SMPTE240M;
798     case 9:
799       return GST_VIDEO_COLOR_MATRIX_BT2020;
800     case 2:
801     default:
802       return GST_VIDEO_COLOR_MATRIX_UNKNOWN;
803   }
804 }
805
806 /**
807  * gst_video_color_transfer_from_iso:
808  * @value: a ITU-T H.273 transfer characteristics value
809  *
810  * Converts the @value to the #GstVideoTransferFunction
811  * The transfer characteristics (TransferCharacteristics) value is
812  * defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
813  * and "ITU-T H.273 Table 3".
814  * "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
815  *
816  * Returns: the matched #GstVideoTransferFunction
817  *
818  * Since: 1.18
819  */
820 GstVideoTransferFunction
821 gst_video_color_transfer_from_iso (guint value)
822 {
823   switch (value) {
824     case 1:
825       return GST_VIDEO_TRANSFER_BT709;
826     case 4:
827       return GST_VIDEO_TRANSFER_GAMMA22;
828     case 5:
829       return GST_VIDEO_TRANSFER_GAMMA28;
830     case 6:
831       return GST_VIDEO_TRANSFER_BT601;
832     case 7:
833       return GST_VIDEO_TRANSFER_SMPTE240M;
834     case 8:
835       return GST_VIDEO_TRANSFER_GAMMA10;
836     case 9:
837       return GST_VIDEO_TRANSFER_LOG100;
838     case 10:
839       return GST_VIDEO_TRANSFER_LOG316;
840     case 13:
841       return GST_VIDEO_TRANSFER_SRGB;
842     case 14:
843       return GST_VIDEO_TRANSFER_BT2020_10;
844     case 15:
845       return GST_VIDEO_TRANSFER_BT2020_12;
846     case 16:
847       return GST_VIDEO_TRANSFER_SMPTE2084;
848     case 18:
849       return GST_VIDEO_TRANSFER_ARIB_STD_B67;
850     case 2:
851     default:
852       return GST_VIDEO_TRANSFER_UNKNOWN;
853   }
854 }
855
856 /**
857  * gst_video_color_primaries_from_iso:
858  * @value: a ITU-T H.273 colour primaries value
859  *
860  * Converts the @value to the #GstVideoColorPrimaries
861  * The colour primaries (ColourPrimaries) value is
862  * defined by "ISO/IEC 23001-8 Section 7.1 Table 2" and "ITU-T H.273 Table 2".
863  * "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
864  *
865  * Returns: the matched #GstVideoColorPrimaries
866  *
867  * Since: 1.18
868  */
869 GstVideoColorPrimaries
870 gst_video_color_primaries_from_iso (guint value)
871 {
872   switch (value) {
873     case 1:
874       return GST_VIDEO_COLOR_PRIMARIES_BT709;
875     case 4:
876       return GST_VIDEO_COLOR_PRIMARIES_BT470M;
877     case 5:
878       return GST_VIDEO_COLOR_PRIMARIES_BT470BG;
879     case 6:
880       return GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
881     case 7:
882       return GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
883     case 8:
884       return GST_VIDEO_COLOR_PRIMARIES_FILM;
885     case 9:
886       return GST_VIDEO_COLOR_PRIMARIES_BT2020;
887     case 10:
888       return GST_VIDEO_COLOR_PRIMARIES_SMPTEST428;
889     case 11:
890       return GST_VIDEO_COLOR_PRIMARIES_SMPTERP431;
891     case 12:
892       return GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432;
893     case 22:
894       return GST_VIDEO_COLOR_PRIMARIES_EBU3213;
895     case 2:
896     default:
897       return GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
898   }
899 }