gamutClipAdaptiveL0LCusp function

RGB gamutClipAdaptiveL0LCusp(
  1. RGB rgb, {
  2. double alpha = 0.05,
})

Implementation

RGB gamutClipAdaptiveL0LCusp(RGB rgb, {double alpha = 0.05}) {
  if (rgb.r < 1 && rgb.g < 1 && rgb.b < 1 && rgb.r > 0 && rgb.g > 0 && rgb.b > 0) {
    return rgb;
  }

  OkLab lab = linearRgbToOkLab(rgb);

  double L = lab.L;
  double eps = 0.00001;
  double C = math.max(eps, math.sqrt(lab.a * lab.a + lab.b * lab.b));
  double a_ = lab.a / C;
  double b_ = lab.b / C;

  // The cusp is computed here and in find_gamut_intersection, an optimized solution would only compute it once.
  LC cusp = findCusp(a_, b_);

  double Ld = L - cusp.L;
  double k = 2 * (Ld > 0 ? 1 - cusp.L : cusp.L);

  double e1 = 0.5 * k + Ld.abs() + alpha * C / k;
  double L0 = cusp.L + 0.5 * (sgn(Ld) * (e1 - math.sqrt(e1 * e1 - 2 * k * Ld.abs())));

  double t = findGamutIntersection(a_, b_, L, C, L0, cusp);
  double lClipped = L0 * (1 - t) + t * L;
  double cClipped = t * C;

  return okLabToLinearRgb(OkLab(lClipped, cClipped * a_, cClipped * b_));
}