Colorspaces

[intro]

Gamma Correction

[to do]

E'R = f(R)

E'G = f(G)

E'B = f(B)

Construction of luminance and color-difference signals

[to do]

E'Y = CoeffR E'R + CoeffG E'G + CoeffB E'B

(E'R - E'Y) = E'R - CoeffR E'R - CoeffG E'G - CoeffB E'B

(E'B - E'Y) = E'B - CoeffR E'R - CoeffG E'G - CoeffB E'B

Re-normalized color-difference signals

The color-difference signals are scaled back to unity range [-0.5;+0.5]:

KB = 0.5 / (1 - CoeffB)

KR = 0.5 / (1 - CoeffR)

PB = KB (E'B - E'Y) = 0.5 (CoeffR / CoeffB) E'R + 0.5 (CoeffG / CoeffB) E'G + 0.5 E'B

PR = KR (E'R - E'Y) = 0.5 E'R + 0.5 (CoeffG / CoeffR) E'G + 0.5 (CoeffB / CoeffR) E'B

Quantization

[to do]

Y' = (Lum. Levels - 1) E'Y + Lum. Offset

CB = (Chrom. Levels - 1) PB + Chrom. Offset

CR = (Chrom. Levels - 1) PR + Chrom. Offset

Rounding to the nearest integer and clamping to the range [0;255] finally yields the digital color components Y'CbCr stored in YUV images.

Example2.1.ITU-R Rec. BT.601 color conversion

Forward Transformation

int ER, EG, EB;         /* gamma corrected RGB input [0;255] */
int Y1, Cb, Cr;         /* output [0;255] */

double r, g, b;         /* temporaries */
double y1, pb, pr;

int
clamp (double x)
{
	int r = x;      /* round to nearest */

	if (r < 0)         return 0;
	else if (r > 255)  return 255;
	else               return r;
}

r = ER / 255.0;
g = EG / 255.0;
b = EB / 255.0;

y1  =  0.299  * r + 0.587 * g + 0.114  * b;
pb  = -0.169  * r - 0.331 * g + 0.5    * b;
pr  =  0.5    * r - 0.419 * g - 0.081  * b;

Y1 = clamp (219 * y1 + 16);
Cb = clamp (224 * pb + 128);
Cr = clamp (224 * pr + 128);

/* or shorter */

y1 = 0.299 * ER + 0.587 * EG + 0.114 * EB;

Y1 = clamp ( (219 / 255.0)                    *       y1  + 16);
Cb = clamp (((224 / 255.0) / (2 - 2 * 0.114)) * (EB - y1) + 128);
Cr = clamp (((224 / 255.0) / (2 - 2 * 0.299)) * (ER - y1) + 128);
      

Inverse Transformation

int Y1, Cb, Cr;         /* gamma pre-corrected input [0;255] */
int ER, EG, EB;         /* output [0;255] */

double r, g, b;         /* temporaries */
double y1, pb, pr;

int
clamp (double x)
{
	int r = x;      /* round to nearest */

	if (r < 0)         return 0;
	else if (r > 255)  return 255;
	else               return r;
}

y1 = (255 / 219.0) * (Y1 - 16);
pb = (255 / 224.0) * (Cb - 128);
pr = (255 / 224.0) * (Cr - 128);

r = 1.0 * y1 + 0     * pb + 1.402 * pr;
g = 1.0 * y1 - 0.344 * pb - 0.714 * pr;
b = 1.0 * y1 + 1.772 * pb + 0     * pr;

ER = clamp (r * 255); /* [ok? one should prob. limit y1,pb,pr] */
EG = clamp (g * 255);
EB = clamp (b * 255);
      

Table2.4.enum v4l2_colorspace

IdentifierValueDescriptionChromaticities[a]White PointGamma CorrectionLuminance E'YQuantization
RedGreenBlueY'Cb, Cr
V4L2_COLORSPACE_SMPTE170M1NTSC/PAL according to [SMPTE170M], [ITUBT.601]x=0.630, y=0.340x=0.310, y=0.595x=0.155, y=0.070x=0.3127, y=0.3290, Illuminant D65E' = 4.5IforI≤0.018, 1.099I0.45-0.099for0.018<I0.299E'R +0.587E'G +0.114E'B219E'Y+16224PB,R+128
V4L2_COLORSPACE_SMPTE240M21125-Line (US) HDTV, see [SMPTE240M]x=0.630, y=0.340x=0.310, y=0.595x=0.155, y=0.070x=0.3127, y=0.3290, Illuminant D65E' = 4IforI≤0.0228, 1.1115I0.45-0.1115for0.0228<I0.212E'R +0.701E'G +0.087E'B219E'Y+16224PB,R+128
V4L2_COLORSPACE_REC7093HDTV and modern devices, see [ITUBT.709]x=0.640, y=0.330x=0.300, y=0.600x=0.150, y=0.060x=0.3127, y=0.3290, Illuminant D65E' = 4.5IforI≤0.018, 1.099I0.45-0.099for0.018<I0.2125E'R +0.7154E'G +0.0721E'B219E'Y+16224PB,R+128
V4L2_COLORSPACE_BT8784Broken Bt878 extents[b], [ITUBT.601]?????0.299E'R +0.587E'G +0.114E'B237E'Y+16224PB,R+128 (probably)
V4L2_COLORSPACE_470_SYSTEM_M5M/NTSC[c] according to [ITUBT.470], [ITUBT.601]x=0.67, y=0.33x=0.21, y=0.71x=0.14, y=0.08x=0.310, y=0.316, Illuminant C?0.299E'R +0.587E'G +0.114E'B219E'Y+16224PB,R+128
V4L2_COLORSPACE_470_SYSTEM_BG6625-line PAL and SECAM systems according to [ITUBT.470], [ITUBT.601]x=0.64, y=0.33x=0.29, y=0.60x=0.15, y=0.06x=0.313, y=0.329, Illuminant D65?0.299E'R +0.587E'G +0.114E'B219E'Y+16224PB,R+128
V4L2_COLORSPACE_JPEG7JPEG Y'CbCr, see [JFIF], [ITUBT.601]?????0.299E'R +0.587E'G +0.114E'B256E'Y+16[d]256PB,R+128
V4L2_COLORSPACE_SRGB8[?]x=0.640, y=0.330x=0.300, y=0.600x=0.150, y=0.060x=0.3127, y=0.3290, Illuminant D65E' = 4.5IforI≤0.018, 1.099I0.45-0.099for0.018<In/a

[a] The coordinates of the color primaries are given in the CIE system (1931)

[b] The ubiquitous Bt878 video capture chip quantizes E'Y to 238 levels, yielding a range of Y' = 16 … 253, unlike Rec. 601 Y' = 16 … 235. This is not a typo in the Bt878 documentation, it has been implemented in silicon. The chroma extents are unclear.

[c] No identifier exists for M/PAL which uses the chromaticities of M/NTSC, the remaining parameters are equal to B and G/PAL.

[d] Note JFIF quantizes Y'PBPR in range [0;+1] and [-0.5;+0.5] to 257 levels, however Y'CbCr signals are still clamped to [0;255].