# `Color.Gamut`

Gamut checking and gamut mapping.

* `in_gamut?/2` — returns whether a color fits inside the given RGB
  working space.

* `to_gamut/3` — brings an out-of-gamut color into the working
  space. Two methods are provided:

  * `:clip` — clamp linear RGB to `[0, 1]`. Fast and deterministic
    but can visibly distort saturated colors.

  * `:oklch` (default) — the CSS Color 4 gamut-mapping algorithm.
    Converts to Oklch, then binary-searches for the highest chroma
    that still fits inside the destination gamut, preserving
    lightness and hue. This is what browsers do when rendering a
    `color(display-p3 …)` value on an sRGB display.

### Examples

    iex> Color.Gamut.in_gamut?(%Color.SRGB{r: 0.5, g: 0.5, b: 0.5}, :SRGB)
    true

    iex> Color.Gamut.in_gamut?(%Color.SRGB{r: 1.2, g: 0.5, b: -0.1}, :SRGB)
    false

# `in_gamut?`

```elixir
@spec in_gamut?(Color.input(), Color.Types.working_space()) :: boolean()
```

Returns `true` if the color lies inside the given RGB working space
gamut (each linear channel in `[0, 1]` up to a small epsilon).

### Arguments

* `color` is anything accepted by `Color.new/1`.

* `working_space` is an atom naming an RGB working space (for
  example `:SRGB`, `:P3_D65`, `:Rec2020`). Defaults to `:SRGB`.

### Returns

* A boolean.

# `to_gamut`

```elixir
@spec to_gamut(Color.input(), Color.Types.working_space(), keyword()) ::
  {:ok, struct()} | {:error, Exception.t()}
```

Brings a color inside the given RGB working space gamut.

### Arguments

* `color` is anything accepted by `Color.new/1`.

* `working_space` is an atom naming an RGB working space. Defaults
  to `:SRGB`.

* `options` is a keyword list.

### Options

* `:method` is `:oklch` (default) or `:clip`.

### Returns

* `{:ok, %Color.SRGB{}}` — for `:SRGB`. For other working spaces the
  result is the appropriate companded RGB struct (`%Color.AdobeRGB{}`
  for `:Adobe`, a linear `%Color.RGB{}` otherwise).

### Examples

    iex> {:ok, mapped} = Color.Gamut.to_gamut(%Color.Oklch{l: 0.9, c: 0.3, h: 30.0}, :SRGB)
    iex> Color.Gamut.in_gamut?(mapped, :SRGB)
    true

---

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