question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Gamut mapping: clarification of chroma reduction algorithm

See original GitHub issue

Hello, I’m coming to the repo from @svgeesus’s comment regarding color clamping in the CSSWG repository. I’ve finally had the chance to look into the proposed algorithm, and I just wanted to confirm some details.

A basic bisection method for reducing the LCH chroma:

let low = 0;
let high = color.chroma;
while (high - low > ε) {
	color.chroma = (high + low) / 2;
	if (displayable(color)) {
		low = color.chroma;
	} else {
		high = color.chroma;
	}
}

color.js compares the color at each iteration with its clipped version:

while ((high - low > ε) && (error < base_error)) {
	let clipped = mappedColor.toGamut({space, method: "clip"});
	let deltaE = mappedColor.deltaE(clipped, {method: "2000"});
	error = color.deltaE(mappedColor, {method: "2000"});
	if (deltaE - 2 < ε) {
		low = mappedColor[coordName];
		// console.log(++i, "in", mappedColor.chroma, mappedColor.srgb, error);
	}
	else {
		// console.log(++i, "out", mappedColor.chroma, mappedColor.srgb, clipped.srgb, deltaE, error);
		if (Math.abs(deltaE - 2) < ε) {
			// We've found the boundary
			break;
		}
		high = mappedColor[coordName];
	}
	mappedColor[coordName] = (high + low) / 2;
}

The current implementation seems to have diverged from the description in the docs:

Instead, the default algorithm reduces chroma (by binary search) and also, at each stage, calculates the deltaE2000 between the current estimate and a channel-clipped version of that color. If the deltaE is less than 2, the clipped color is displayed.

At a first pass through the function, what I see is the definition of displayable() / inGamut() relaxed to include colors at a deltaE2000 distance smaller than 2 to an in-gamut color (which, even by itself, sounds like a great idea). What I’m not seeing, unless I’m missing something, is how the condition Math.abs(deltaE - 2) < ε) can ever be fulfilled (and the clipped color returned early) without deltaE - 2 < ε catching it first.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
svgeesuscommented, Dec 20, 2021

Note that CSS Color 4 now describes gamut mapping. Much of that is just explanation, but it is followed by the actual algorithm which is constant-lightness, constant-hue chroma reduction in OKLCH using deltaE OK as the difference metric.

1reaction
svgeesuscommented, Jun 21, 2022

I would like to prototype the CSS Color 4 gamut mapping algorithm in color.js and have it available as an option. (It should probably the default, as it is clearly better than CIE LCH chroma reduction).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Gamut Mapping: An Overview of the Problem
For a target device, a gamut mapping algorithm establishes a correspondence between the out of gamut color and the color within the gamut,...
Read more >
Gamut Mapping: Evaluation of Chroma Clipping Techniques ...
A psychophysical experiment was carried out to evaluate 5 chroma clipping techniques for gamut mapping. Three different destination gamuts were used in ...
Read more >
Gamut Mapping in Cinematography through Perceptually ...
Abstract—Gamut mapping transforms the colors of an input image to the colors of a target device so as to exploit the full potential...
Read more >
Gamut Mapping - an overview | ScienceDirect Topics
In this chapter we show how the local histogram equalisation approach presented earlier can be used to develop gamut mapping algorithms that are...
Read more >
(PDF) Evaluating gamut mapping algorithms for universal ...
... Herzog [10] proposed a method for deforming the color gamut of unit cube to fit that of a device, to represent the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found