# `Color.YCbCr`

YCbCr digital-video color space with BT.601, BT.709 and BT.2020
variants.

YCbCr operates on **gamma-encoded** RGB (the corresponding
working-space companded values), not linear RGB. The `:variant`
field selects the luma coefficients and the matching RGB working
space / transfer function:

* `:bt601` — SDTV (ITU-R BT.601). Uses sRGB primaries for the
  underlying RGB.

* `:bt709` — HDTV (ITU-R BT.709). Uses sRGB primaries (which match
  BT.709 primaries) with the BT.709 transfer function.

* `:bt2020` — UHDTV (ITU-R BT.2020). Uses BT.2020 primaries and
  transfer function. **Non-constant luminance** variant.

Channels are normalised full-range floats:

* `y ∈ [0, 1]` — luma.

* `cb, cr ∈ [-0.5, 0.5]` — chroma differences.

If you need the 8-bit TV-range (`Y ∈ [16, 235]`, `Cb/Cr ∈ [16, 240]`)
values, scale on the outside.

# `t`

```elixir
@type t() :: %Color.YCbCr{
  alpha: Color.Types.alpha(),
  cb: float() | nil,
  cr: float() | nil,
  variant: :bt601 | :bt709 | :bt2020,
  y: float() | nil
}
```

Digital video YCbCr. `y` is luma; `cb` and `cr` are the
blue-difference and red-difference chroma channels. The `:variant`
field selects the matrix coefficients (`:bt601`, `:bt709`,
`:bt2020`).

# `from_rgb`

Converts a gamma-encoded RGB triple to YCbCr.

### Arguments

* `rgb` is a `{r, g, b}` tuple of unit floats in the variant's
  working space.

* `variant` is `:bt601`, `:bt709` (default) or `:bt2020`.

### Returns

* A `Color.YCbCr` struct.

# `from_xyz`

Converts a CIE `XYZ` color to YCbCr using the given variant.

### Arguments

* `xyz` is a `Color.XYZ` struct (D65/2°).

* `variant` is `:bt601`, `:bt709` (default) or `:bt2020`.

### Returns

* A `Color.YCbCr` struct.

# `to_rgb`

Converts a YCbCr color to its corresponding gamma-encoded RGB triple.

The result is a `{r, g, b}` tuple in the working space selected by
the variant (sRGB for BT.601/BT.709, BT.2020 for :bt2020).

### Arguments

* `ycbcr` is a `Color.YCbCr` struct.

### Returns

* A `{r, g, b}` tuple of unit floats.

### Examples

    iex> Color.YCbCr.to_rgb(%Color.YCbCr{y: 1.0, cb: 0.0, cr: 0.0})
    {1.0, 1.0, 1.0}

# `to_xyz`

Converts a YCbCr color to CIE `XYZ`.

For BT.601 and BT.709 the underlying RGB is treated as sRGB. For
BT.2020 it is linearised with the BT.2020 transfer function and
converted via the BT.2020 working space.

### Arguments

* `ycbcr` is a `Color.YCbCr` struct.

### Returns

* A `Color.XYZ` struct tagged D65/2°.

### Examples

    iex> {:ok, xyz} = Color.YCbCr.to_xyz(%Color.YCbCr{y: 1.0, cb: 0.0, cr: 0.0, variant: :bt709})
    iex> {Float.round(xyz.x, 4), Float.round(xyz.y, 4), Float.round(xyz.z, 4)}
    {0.9505, 1.0, 1.0888}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
