(lcms) Precision problem converting to/from RGB - XYZ
(lcms) Precision problem converting to/from RGB - XYZ
- Subject: (lcms) Precision problem converting to/from RGB - XYZ
- From: Mark <email@hidden>
- Date: Fri, 19 Sep 2008 15:16:53 +0200
(Tried posting this twice to the lcms list but looks like the list is
down).
Hi all,
debugging my app I found a weird precision problem transforming
between RGB and XYZ.
The test app (attached below) converts 16 bit sRGB values {65535,
65535, 65535} to double XYZ and back to 16 bit sRGB.
The resulting sRGB values are {64117, 65100, 65131} and seem quite
wrong.
Doing the conversion using doubles seems equally wrong.
Interestingly doing the same from sRGB to Lab, back to sRGB gives only
a very small error, which I guess is normal.
The result is {65535, 65534, 65533}.
Any ideas?
Here's the output from the sample program and below the program itself.
double sRGB -> XYZ -> sRGB
R 1.000000 G 1.000000 B 1.000000
X 0.964172 Y 1.000000 Z 0.824860
R 0.978363 G 0.993362 B 0.993835
double Lab -> XYZ -> Lab
L 100.000000 a 0.000000 b 0.000000
X 0.964172 Y 0.999969 Z 0.824829
L 100.000000 a -0.058594 b 0.023438
double sRGB -> Lab -> sRGB
R 1.000000 G 1.000000 B 1.000000
L 100.000000 a 0.000000 b 0.000000
R 1.000000 G 0.999985 B 0.999969
16bit sRGB -> XYZ -> sRGB
R 65535 G 65535 B 65535
X 0.964172 Y 1.000000 Z 0.824860
R 64117 G 65100 B 65131
16bit sRGB -> Lab -> sRGB
R 65535 G 65535 B 65535
L 100.000000 a 0.000000 b 0.000000
R 65535 G 65534 B 65533
void tranformsTest(void)
{
cmsHPROFILE pxyz = cmsCreateXYZProfile();
cmsHPROFILE plab = cmsCreateLabProfile(cmsD50_xyY());
cmsHPROFILE psrgb = cmsCreate_sRGBProfile();
cmsHTRANSFORM xyz2srgb = cmsCreateTransform(pxyz, TYPE_XYZ_DBL,
psrgb, TYPE_RGB_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM srgb2xyz = cmsCreateTransform(psrgb, TYPE_RGB_DBL,
pxyz, TYPE_XYZ_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM xyz2srgb_16 = cmsCreateTransform(pxyz, TYPE_XYZ_DBL,
psrgb, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM srgb2xyz_16 = cmsCreateTransform(psrgb, TYPE_RGB_16,
pxyz, TYPE_XYZ_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM xyz2lab = cmsCreateTransform(pxyz, TYPE_XYZ_DBL, plab,
TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM lab2xyz = cmsCreateTransform(plab, TYPE_Lab_DBL, pxyz,
TYPE_XYZ_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM srgb2lab = cmsCreateTransform(psrgb, TYPE_RGB_DBL,
plab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM lab2srgb = cmsCreateTransform(plab, TYPE_Lab_DBL,
psrgb, TYPE_RGB_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM srgb2lab_16 = cmsCreateTransform(psrgb, TYPE_RGB_16,
plab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);
cmsHTRANSFORM lab2srgb_16 = cmsCreateTransform(plab, TYPE_Lab_DBL,
psrgb, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, 0);
printf("double sRGB -> XYZ -> sRGB\n");
double v1[3] = {1.0, 1.0, 1.0};
printRGB(v1);
cmsCIEXYZ v2;
cmsDoTransform(srgb2xyz, v1, &v2, 1);
printXYZ(v2);
double v3[3];
cmsDoTransform(xyz2srgb, &v2, v3, 1);
printRGB(v3);
printf("\ndouble Lab -> XYZ -> Lab\n");
cmsCIELab v4 = {.L = 100.0, .a = 0.0, .b = 0.0};
printLAB(v4);
cmsCIEXYZ v5;
cmsDoTransform(lab2xyz, &v4, &v5, 1);
printXYZ(v5);
cmsCIELab v6;
cmsDoTransform(xyz2lab, &v5, &v6, 1);
printLAB(v6);
printf("\ndouble sRGB -> Lab -> sRGB\n");
double v7[3] = {1.0, 1.0, 1.0};
printRGB(v7);
cmsCIELab v8;
cmsDoTransform(srgb2lab, v7, &v8, 1);
printLAB(v8);
double v9[3];
cmsDoTransform(lab2srgb, &v8, v9, 1);
printRGB(v9);
printf("\n16bit sRGB -> XYZ -> sRGB\n");
unsigned short v10[3] = {65535, 65535, 65535};
printRGB16(v10);
cmsCIEXYZ v11;
cmsDoTransform(srgb2xyz_16, v10, &v11, 1);
printXYZ(v11);
unsigned short v12[3];
cmsDoTransform(xyz2srgb_16, &v11, v12, 1);
printRGB16(v12);
printf("\n16bit sRGB -> Lab -> sRGB\n");
unsigned short v13[3] = {65535, 65535, 65535};
printRGB16(v13);
cmsCIELab v14;
cmsDoTransform(srgb2lab_16, v13, &v14, 1);
printLAB(v14);
unsigned short v15[3];
cmsDoTransform(lab2srgb_16, &v14, v15, 1);
printRGB16(v15);
}
void printLAB(cmsCIELab v)
{
printf("L %f a %f b %f\n",v.L, v.a, v.b);
}
void printXYZ(cmsCIEXYZ v)
{
printf("X %f Y %f Z %f\n",v.X, v.Y, v.Z);
}
void printRGB(double v[3])
{
printf("R %f G %f B %f\n",v[0], v[1], v[2]);
}
void printRGB8(unsigned char v[3])
{
printf("R %u G %u B %u\n",v[0], v[1], v[2]);
}
void printRGB16(unsigned short v[3])
{
printf("R %u G %u B %u\n",v[0], v[1], v[2]);
}
Best regards
Mark
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Colorsync-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden