[OpenJDK 2D-Dev] Missing colour profiles
Andrew Haley
aph at redhat.com
Thu Apr 24 09:52:53 UTC 2008
Jerry Evans wrote:
> Andrew Haley wrote:
>
>> 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
>>
>>
>> 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.
>>
>>
> sRGB defines a linear section of the transfer curve for very low light levels.
> If you want to have new tests for sRGB/lRGB fidelity, you should use the
> equations in the ISO standard.
Sure, it's two curves jammed together to make something similar to Gamma 2.2,
and that's why I used the words "similar to", but 0 * 12.92 == 0,
just as 0 ^ 1/2.2 == 0.
Okay, let's use that official curve.
Here's that official IEC 61966-2-1:1999 curve on the left,
then the values LCMS returns:
0,243,178, 0,251,184,
11,243,178, 12,251,184,
20,243,178, 21,251,184,
26,243,178, 28,251,184,
32,243,178, 33,251,184,
36,243,178, 38,251,184,
40,243,178, 42,251,184,
44,243,178, 46,251,184,
47,243,178, 49,251,184,
50,243,178, 52,251,184,
and here's Java 6 again:
0,243,178, 43,251,183,
11,243,178, 47,251,183,
20,243,178, 50,251,183,
26,243,178, 53,251,183,
32,243,178, 56,251,183,
36,243,178, 59,251,183,
40,243,178, 62,251,183,
44,243,178, 64,251,183,
47,243,178, 66,251,183,
50,243,178, 69,251,183,
Whichever way you measure it, lcms is doing a better job here, and
this should not be a test failure.
Let's talk about what we should do to check the quality of the CMS.
For sRGB, linear sRGB, and so on, we can check the accuracy of the curves
against the standards, and we can make sure that the white point is
correct, and we can test a few well-known XYZ values. We can also
check that the inverse transform is reasonably accurate.
Alternatively, we could use golden images, but with the golden images
regenerated using standard values.
Andrew.
import java.awt.color.ColorSpace;
public class LrgbTest
{
static float gamma(float c)
{
final float a = 0.055f;
if (c <= 0.0031308)
return c * 12.92f;
else
return (float)Math.pow((1+a)*c, 1/2.4) - a;
}
static float Xgamma(float c)
{
return (float)Math.pow(c, 1/2.2);
}
public static void main(String [] args) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
for (int red = 0; red < 10; red++)
{
float [] p = {(float)(red), 247f, 123f};
for (int j = 0; j < p.length; j++)
System.out.print((int)(gamma(p[j]/255)*255) + ",");
System.out.print(" ");
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) + ",");
}
System.out.println();
}
}
}
More information about the 2d-dev
mailing list