coloraide icon indicating copy to clipboard operation
coloraide copied to clipboard

Y'CbCr spaces?

Open facelessuser opened this issue 6 months ago • 9 comments

Look into Y'CbCr spaces. Much like RGB, this is a model that can be a target transform for a given RGB gamut: BT.601, BT.709, BT.2020, etc. It also has a number of other nuances. I guess, by default, the space has a range of Y' [0, 1], Cb [-0.5, 0.5], and Cr [-0.5, 0.5]. It seems in this form it might be called Y'PbPr. Traditionally though, this space is offset into positive values and scaled giving some headroom. For 8 bit values, this is often in the range of Y' [16, 235], Cb [16, 240], and Cr [16, 240]. This range will be larger for 10 bit precision, etc. For digital values (non-floating point) this values will be rounded to whole integers.

It is unclear if these range are the space's gamut or not. For instance, BT.601 is designed around the sRGB gamut. The actual sRGB gamut is tilted within this range Y'CbCr range, but does not fill the whole range. Many of the values near the corner of this space are out of the visible spectrum.

Now, we don't have to ensure digital resolution. Users can round the value to integers if needed. We have ways to serialize values in this way already. Scaling to ranges to 8 bit, 10 bit, etc. isn't really a problem, we can provide the spaces in whatever way makes sense for the gamut under evaluation.

Now, as far as the Y'CbCr gamut, we can:

  1. Treat them like Lab spaces and set it as unbounded with a reference range that matches the supported range, but no hard enforcement.
  2. We can set it as bounded, but then we have to make things like the ray trace gamut mapping support rectangular spaces in general, not just RGBish spaces. This isn't actually hard though and we can can adjust the ray trace bounding box to fit offset ranges and weirdly scaled spaces, we just can't rotate the prism. So this is easy enough to do.
  3. We set the Y'CbCr gamut to reference the intended gamut. So, Y'CbCr 601 would target the sRGB gamut, Y'CbCr 709 would target Rec. 709, etc.

I'm not sure the right approach, but the starting point would be to:

  1. Create a generic way to generate Y'CbCr spaces.
  2. Decide which variants of Y'CbCr we want to support: 601, 709, 2020? Then also decide whether we expose them with 8 bit range, 10 bit range. This could likely vary depending on the specific variant.
  3. It wouldn't hurt to make ray trace handle more generic prismatic spaces. It will loosen constraints on us even if we decide these current spaces will just gamut map to sRGB, Rec. 2020, etc.
  4. Lastly, figure out how we want to specify the Y'CbCr gamuts.

I actually don't think any of this is difficult, more that we just need to make decisions regarding how to present the spaces. I may be able to have a working prototype within a day or two.

facelessuser avatar Jul 09 '25 14:07 facelessuser