xref: /aosp_15_r20/external/libyuv/util/yuvconstants.c (revision 4e366538070a3a6c5c163c31b791eab742e1657a)
1*4e366538SXin Li /*
2*4e366538SXin Li  *  Copyright 2021 The LibYuv Project Authors. All rights reserved.
3*4e366538SXin Li  *
4*4e366538SXin Li  *  Use of this source code is governed by a BSD-style license
5*4e366538SXin Li  *  that can be found in the LICENSE file in the root of the source
6*4e366538SXin Li  *  tree. An additional intellectual property rights grant can be found
7*4e366538SXin Li  *  in the file PATENTS. All contributing project authors may
8*4e366538SXin Li  *  be found in the AUTHORS file in the root of the source tree.
9*4e366538SXin Li  */
10*4e366538SXin Li 
11*4e366538SXin Li #include <math.h>
12*4e366538SXin Li #include <stdio.h>
13*4e366538SXin Li #include <stdlib.h>
14*4e366538SXin Li #include <string.h>
15*4e366538SXin Li 
16*4e366538SXin Li // This utility computes values needed to generate yuvconstants based on
17*4e366538SXin Li // white point values.
18*4e366538SXin Li // The yuv formulas are tuned for 8 bit YUV channels.
19*4e366538SXin Li 
20*4e366538SXin Li // See Also
21*4e366538SXin Li // https://mymusing.co/bt601-yuv-to-rgb-conversion-color/
22*4e366538SXin Li 
23*4e366538SXin Li // BT.709 full range YUV to RGB reference
24*4e366538SXin Li //  R = Y               + V * 1.5748
25*4e366538SXin Li //  G = Y - U * 0.18732 - V * 0.46812
26*4e366538SXin Li //  B = Y + U * 1.8556
27*4e366538SXin Li //  KR = 0.2126
28*4e366538SXin Li //  KB = 0.0722
29*4e366538SXin Li 
30*4e366538SXin Li // // Y contribution to R,G,B.  Scale and bias.
31*4e366538SXin Li // #define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
32*4e366538SXin Li // #define YB 32    /* 64 / 2 */
33*4e366538SXin Li //
34*4e366538SXin Li // // U and V contributions to R,G,B.
35*4e366538SXin Li // #define UB 113 /* round(1.77200 * 64) */
36*4e366538SXin Li // #define UG 22  /* round(0.34414 * 64) */
37*4e366538SXin Li // #define VG 46  /* round(0.71414 * 64) */
38*4e366538SXin Li // #define VR 90  /* round(1.40200 * 64) */
39*4e366538SXin Li //
40*4e366538SXin Li // // Bias values to round, and subtract 128 from U and V.
41*4e366538SXin Li // #define BB (-UB * 128 + YB)
42*4e366538SXin Li // #define BG (UG * 128 + VG * 128 + YB)
43*4e366538SXin Li // #define BR (-VR * 128 + YB)
44*4e366538SXin Li 
main(int argc,const char * argv[])45*4e366538SXin Li int main(int argc, const char* argv[]) {
46*4e366538SXin Li   if (argc < 3) {
47*4e366538SXin Li     printf("yuvconstants [KR] [KB]\n");
48*4e366538SXin Li     printf("  e.g. yuvconstants 0.2126 0.0722\n");
49*4e366538SXin Li     printf("  MC BT          KR           KB\n");
50*4e366538SXin Li     printf("  1  BT.709      KR = 0.2126; KB = 0.0722\n");
51*4e366538SXin Li     printf("  4  FCC         KR = 0.30;   KB = 0.11\n");
52*4e366538SXin Li     printf("  6  BT.601      KR = 0.299;  KB = 0.114\n");
53*4e366538SXin Li     printf("  7  SMPTE 240M  KR = 0.212;  KB = 0.087\n");
54*4e366538SXin Li     printf("  9  BT.2020     KR = 0.2627; KB = 0.0593\n");
55*4e366538SXin Li     return -1;
56*4e366538SXin Li   }
57*4e366538SXin Li   float kr = (float)atof(argv[1]);
58*4e366538SXin Li   float kb = (float)atof(argv[2]);
59*4e366538SXin Li   float kg = 1 - kr - kb;
60*4e366538SXin Li 
61*4e366538SXin Li   float vr = 2 * (1 - kr);
62*4e366538SXin Li   float ug = 2 * ((1 - kb) * kb / kg);
63*4e366538SXin Li   float vg = 2 * ((1 - kr) * kr / kg);
64*4e366538SXin Li   float ub = 2 * (1 - kb);
65*4e366538SXin Li 
66*4e366538SXin Li   printf("Full range\n");
67*4e366538SXin Li   printf("R = Y                + V * %5f\n", vr);
68*4e366538SXin Li   printf("G = Y - U * %6f - V * %6f\n", ug, vg);
69*4e366538SXin Li   printf("B = Y + U * %5f\n", ub);
70*4e366538SXin Li 
71*4e366538SXin Li   printf("KR = %4f; ", kr);
72*4e366538SXin Li   printf("KB = %4f\n", kb);
73*4e366538SXin Li   // printf("KG = %4f\n", kg);
74*4e366538SXin Li   // #define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
75*4e366538SXin Li   // #define YB 32    /* 64 / 2 */
76*4e366538SXin Li   //
77*4e366538SXin Li   // // U and V contributions to R,G,B.
78*4e366538SXin Li 
79*4e366538SXin Li   printf("UB %-3.0f /* round(%f * 64 = %8.4f) */\n", round(ub * 64), ub, ub * 64);
80*4e366538SXin Li   printf("UG %-3.0f /* round(%f * 64 = %8.4f) */\n", round(ug * 64), ug, ug * 64);
81*4e366538SXin Li   printf("VG %-3.0f /* round(%f * 64 = %8.4f) */\n", round(vg * 64), vg, vg * 64);
82*4e366538SXin Li   printf("VR %-3.0f /* round(%f * 64 = %8.4f) */\n", round(vr * 64), vr, vr * 64);
83*4e366538SXin Li 
84*4e366538SXin Li   vr = 255.f / 224.f * 2 * (1 - kr);
85*4e366538SXin Li   ug = 255.f / 224.f * 2 * ((1 - kb) * kb / kg);
86*4e366538SXin Li   vg = 255.f / 224.f * 2 * ((1 - kr) * kr / kg);
87*4e366538SXin Li   ub = 255.f / 224.f * 2 * (1 - kb);
88*4e366538SXin Li 
89*4e366538SXin Li   printf("\nLimited range\n");
90*4e366538SXin Li   printf("R = (Y - 16) * 1.164                + V * %5f\n", vr);
91*4e366538SXin Li   printf("G = (Y - 16) * 1.164 - U * %6f - V * %6f\n", ug, vg);
92*4e366538SXin Li   printf("B = (Y - 16) * 1.164 + U * %5f\n", ub);
93*4e366538SXin Li 
94*4e366538SXin Li   // printf("KG = %4f\n", kg);
95*4e366538SXin Li   // #define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
96*4e366538SXin Li   // #define YB 32    /* 64 / 2 */
97*4e366538SXin Li   //
98*4e366538SXin Li   // // U and V contributions to R,G,B.
99*4e366538SXin Li 
100*4e366538SXin Li   printf("UB %-3.0f /* round(%f * 64 = %8.4f) */\n", round(ub * 64), ub, ub * 64);
101*4e366538SXin Li   printf("UG %-3.0f /* round(%f * 64 = %8.4f) */\n", round(ug * 64), ug, ug * 64);
102*4e366538SXin Li   printf("VG %-3.0f /* round(%f * 64 = %8.4f) */\n", round(vg * 64), vg, vg * 64);
103*4e366538SXin Li   printf("VR %-3.0f /* round(%f * 64 = %8.4f) */\n", round(vr * 64), vr, vr * 64);
104*4e366538SXin Li 
105*4e366538SXin Li   return 0;
106*4e366538SXin Li }
107