[OpenJDK 2D-Dev] Missing colour profiles

Andrew Haley aph at redhat.com
Wed Apr 23 16:52:12 UTC 2008

Phil Race wrote:
> Andrew,
> I think we just need to verify how well these work.
> How did you verify them?
> Did you run any of the tests in test/sun/java2d/cmm ?

There are some failures, but I don't believe that's entirely
due to any problem in lcms and/or my profiles.

For example, consider a straightforward conversion from
sRGB to linear RGB.  As far as I'm aware, linear RGB is
supposed to be identical to sRGB, but with a linear gamma

So, here's a worked example that failed the CMM tests.

sRGB data is (a function similar to) raising to the power 2,2,
so to go from linear RGB to sRGB is 
  Math.pow(x/255, 1/2.2) * 255


sRGB = { 0, 247, 123 }
lRGB(in theory) = { 0,251,183 }

which is very close to what lcms + my profile returns:


The "gold" image in the test suite corresponds with what Kodak returns,
which is


Now, where has that red value of 43 come from?  The green and the
blue values are the same.  What seems to be happening is that
the first few values of Kodak's transformation have high errors.

Here are a few examples, varying red from 0 to 9, with the 
"theoretical" value first and then what Kodak's CMM calculates:

0,251,183,    43,251,183,
20,251,183,    47,251,183,
28,251,183,    50,251,183,
33,251,183,    53,251,183,
38,251,183,    56,251,183,
42,251,183,    59,251,183,
46,251,183,    62,251,183,
49,251,183,    64,251,183,
52,251,183,    66,251,183,
55,251,183,    69,251,183,

Note that the green and blue results always agree, but there is a large
error in the red.

lcms's results are closer, but still with a significant error:

0,251,183,    0,251,184,
20,251,183,    12,251,184,
28,251,183,    21,251,184,
33,251,183,    28,251,184,
38,251,183,    33,251,184,
42,251,183,    38,251,184,
46,251,183,    42,251,184,
49,251,183,    46,251,184,
52,251,183,    49,251,184,
55,251,183,    52,251,184,

Ok, here's what I think is going wrong:

When light levels are very low the transfer function is very nonlinear, so
errors will be high.  That's true of both lcms and Kodak, but in my opinion
lcms is doing a better job in this case.

In summary: The approach of assuming that Kodak's CMM returns correct
values in all cases is flawed.  The "golden" images are good examples
of converted images, but they are not correct in every minute detail.
We need to talk about a better approach to tetsing the CMM; one
that does not require us to be bug-compatible with Kodak, which
in any case would be impossible.


import java.awt.color.ColorSpace;

public class LrgbTest {
    public static void main(String [] args) {
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
        float [] p = {0f, 247f, 123f};

	for (int j = 0; j < p.length; j++) 
	  System.out.print((int)(Math.pow(p[j]/255, 1/2.2)*255) + ",");

	for (int i = 0; i < p.length; i++)
	  p[i] /= 255;
	float [] r = cs.toRGB(p);
	for (int j = 0; j < r.length; j++) {
	  System.out.print((int)(r[j]*255) + ",");

More information about the 2d-dev mailing list