Video for Linux Two API Specification: Revision 0.24
Prev | Chapter 2. Image Formats | Next

# 2.2. 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.

Example 2-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);

Table 2-2. enum v4l2_colorspace

Identifier | Value | Description | Chromaticities[a] | White Point | Gamma Correction | Luminance E'Y | Quantization
--- | --- | --- | --- | --- | --- | --- | ---
Red | Green | Blue | Y' | Cb, Cr
`V4L2_COLORSPACE_SMPTE170M` | 1 | NTSC/PAL according to SMPTE 170M, ITU BT.601 | x = 0.630, y = 0.340 | x = 0.310, y = 0.595 | x = 0.155, y = 0.070 | x = 0.3127, y = 0.3290, Illuminant D65 | E' = 4.5 I for I ≤0.018, 1.099 I0.45 - 0.099 for 0.018 < I | 0.299 E'R + 0.587 E'G + 0.114 E'B | 219 E'Y + 16 | 224 PB,R + 128
`V4L2_COLORSPACE_SMPTE240M` | 2 | 1125-Line (US) HDTV, see SMPTE 240M | x = 0.630, y = 0.340 | x = 0.310, y = 0.595 | x = 0.155, y = 0.070 | x = 0.3127, y = 0.3290, Illuminant D65 | E' = 4 I for I ≤0.0228, 1.1115 I0.45 - 0.1115 for 0.0228 < I | 0.212 E'R + 0.701 E'G + 0.087 E'B | 219 E'Y + 16 | 224 PB,R + 128
`V4L2_COLORSPACE_REC709` | 3 | HDTV and modern devices, see ITU BT.709 | x = 0.640, y = 0.330 | x = 0.300, y = 0.600 | x = 0.150, y = 0.060 | x = 0.3127, y = 0.3290, Illuminant D65 | E' = 4.5 I for I ≤0.018, 1.099 I0.45 - 0.099 for 0.018 < I | 0.2125 E'R + 0.7154 E'G + 0.0721 E'B | 219 E'Y + 16 | 224 PB,R + 128
`V4L2_COLORSPACE_BT878` | 4 | Broken Bt878 extents[b], ITU BT.601 | ? | ? | ? | ? | ? | 0.299 E'R + 0.587 E'G + 0.114 E'B | 237 E'Y + 16 | 224 PB,R + 128 (probably)
`V4L2_COLORSPACE_470_SYSTEM_M` | 5 | M/NTSC[c] according to ITU BT.470, ITU BT.601 | x = 0.67, y = 0.33 | x = 0.21, y = 0.71 | x = 0.14, y = 0.08 | x = 0.310, y = 0.316, Illuminant C | ? | 0.299 E'R + 0.587 E'G + 0.114 E'B | 219 E'Y + 16 | 224 PB,R + 128
`V4L2_COLORSPACE_470_SYSTEM_BG` | 6 | 625-line PAL and SECAM systems according to ITU BT.470, ITU BT.601 | x = 0.64, y = 0.33 | x = 0.29, y = 0.60 | x = 0.15, y = 0.06 | x = 0.313, y = 0.329, Illuminant D65 | ? | 0.299 E'R + 0.587 E'G + 0.114 E'B | 219 E'Y + 16 | 224 PB,R + 128
`V4L2_COLORSPACE_JPEG` | 7 | JPEG Y'CbCr, see JFIF, ITU BT.601 | ? | ? | ? | ? | ? | 0.299 E'R + 0.587 E'G + 0.114 E'B | 256 E'Y + 16[d] | 256 PB,R + 128
`V4L2_COLORSPACE_SRGB` | 8 | [?] | x = 0.640, y = 0.330 | x = 0.300, y = 0.600 | x = 0.150, y = 0.060 | x = 0.3127, y = 0.3290, Illuminant D65 | E' = 4.5 I for I ≤0.018, 1.099 I0.45 - 0.099 for 0.018 < I | n/a

Notes:
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].

Prev | Home | Next
Image Formats | Up | Indexed Format