3.1.9.1.2 Color Space Conversion
Color channel-based compression does not operate on the ARGB color space but rather a color space based on Luminosity (Y) and differentials of two color components: Orange (Co) and Green (Cg). Conversion between the ARGB and AYCoCg color spaces can be performed by using forward and inverse transformations (represented using matrix multiplication). The Alpha channel (A) is never converted in either direction.
The forward transformation to convert from ARGB to AYCoCg is as follows.
-
A = A |Y| | 1/4 1/2 1/4| |R| |Co| = | 1 0 -1 | * |G| |Cg| |-1/2 1 -1/2| |B|
The inverse transformation to convert from AYCoCg to ARGB is as follows.
-
A = A |R| |1 1/2 -1/2| |Y | |G| = |1 0 1/2| * |Co| |B| |1 -1/2 -1/2| |Cg|
Note that Microsoft RDP servers incorrectly convert 24 bpp RGB bitmaps to the YCoCg color space when color loss reduction (see the DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY (0x02) flag in [MS-RDPBCGR] section 2.2.7.1.2) is in effect. This results in an incorrect value for the Co component. To compensate for this issue, client decoders MUST swap the B and R components after applying the inverse transformation, which converts from the YCoCg color space to the RGB color space.
The allowed ranges of the individual color planes and their lengths in bits are as follows.
Color plane |
Range |
Type |
---|---|---|
Alpha (A) |
0 (transparent) – 255 (opaque) |
8 bits |
Red (R) |
0 – 255 |
8 bits |
Green (G) |
0 – 255 |
8 bits |
Blue (B) |
0 – 255 |
8 bits |
Luma (Y) |
0 – 255 |
8 bits |
Orange Chroma (Co) |
-255 – 255 |
9 bits (two's complement) |
Green Chroma (Cg) |
-255 – 255 |
9 bits (two's complement) |
When performing the color space conversion, the data types used for all calculations MUST be at least 9 bits long to accommodate the orange and green chroma channels. In the inverse transformation, after the red, green and blue values have been calculated with 9-bit precision, they MUST all be converted to 8-bit precision in order to be stored in the decoded image. This calculation MUST be performed by taking the closest value within the 0 to 255 range (this technique is referred to as "clamping between 0 and 255"). For example:
-
-14 clamped = 0 123 clamped = 123 254 clamped = 254 300 clamped = 255 421 clamped = 255