On Sunday 17 May 2009 12:44:51 pm Albert Astals Cid wrote:
> A Diumenge, 17 de maig de 2009, Hal V. Engel va escriure:
> > Here is a patch that will apply the white point correction after a call
> > to getXYZ(). This patch can be applied to current git.
> >
> > Hal
>
> Do you have a pdf that shows what this fixes?
>
> Albert
#35 on the altona test pdf shows this for the Lab to XYZ conversion. Without
the white point correction the difference between the upper right ECI-RGB
ICCBased image and the lower left CIELAB image is apparent although it was not
a huge difference. With this fix the difference goes away. This was testing
with color management enabled. This test is NOT valid with color management
disabled.
I don't have test PDFs for the calRGB or calGray cases. The altona test PDF
does not have any CalRGB or CalGray objects. The CIE to XYZ conversions do
need a white point correction other than CalRGB. At least that is what is
shown in the PDF specification for these conversions.
After looking closer just now at the CalRGB to XYZ documentation I see that
the CalRGB to XYZ conversion does not use the white point values in the
conversion unlike CalGray to XYZ and Lab to XYZ. But the original code was
doing a white point correction but it was dividing by the white point so this
was clearly incorrect because the conversion should not do a separate white
point correction since this is handled by the matrix. I made a mistake when I
saw the incorrect WP conversion in the CalRGB code and assumed that it should
be the same as the CalGray and Lab code when in fact it should have been
removed.
Also it might be common for these objects to use the default white point of X
= Y= Z = 1.0 in which case this will not make any difference. But I am not
sure how common this is and the PDF documentation implies that D65 is the
recommended WhitePoint ([ 0.9505 1.0000 1.0890 ]) for CalRGB and CalGray.
I have attached a new version of the patch that removes all white point
corrections from the code for CalRGB.
Hal
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 1ca3289..16b697d 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -618,9 +618,10 @@ void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
double X, Y, Z;
getXYZ(color,&X,&Y,&Z);
- in[0] = clip01(X);
- in[1] = clip01(Y);
- in[2] = clip01(Z);
+ // do the white point correction
+ in[0] = clip01(X * whiteX);
+ in[1] = clip01(Y * whiteY);
+ in[2] = clip01(Z * whiteZ);
XYZ2DisplayTransform->doTransform(in,out,1);
*gray = byteToCol(out[0]);
return;
@@ -637,6 +638,10 @@ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
double r, g, b;
getXYZ(color,&X,&Y,&Z);
+ // do the white point correction
+ X *= whiteX;
+ Y *= whiteY;
+ Z *= whiteZ;
#ifdef USE_CMS
if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
Guchar out[gfxColorMaxComps];
@@ -652,9 +657,6 @@ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
return;
}
#endif
- X *= whiteX;
- Y *= whiteY;
- Z *= whiteZ;
// convert XYZ to RGB, including gamut mapping and gamma correction
r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
@@ -676,9 +678,10 @@ void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
double X, Y, Z;
getXYZ(color,&X,&Y,&Z);
- in[0] = clip01(X);
- in[1] = clip01(Y);
- in[2] = clip01(Z);
+ // do the white point correction
+ in[0] = clip01(X * whiteX);
+ in[1] = clip01(Y * whiteY);
+ in[2] = clip01(Z * whiteZ);
XYZ2DisplayTransform->doTransform(in,out,1);
cmyk->c = byteToCol(out[0]);
@@ -938,9 +941,9 @@ void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
Guchar out[gfxColorMaxComps];
double in[gfxColorMaxComps];
- in[0] = clip01(X/whiteX);
- in[1] = clip01(Y/whiteY);
- in[2] = clip01(Z/whiteZ);
+ in[0] = clip01(X);
+ in[1] = clip01(Y);
+ in[2] = clip01(Z);
XYZ2DisplayTransform->doTransform(in,out,1);
rgb->r = byteToCol(out[0]);
rgb->g = byteToCol(out[1]);
@@ -1210,6 +1213,10 @@ void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) {
double in[gfxColorMaxComps];
getXYZ(color, &in[0], &in[1], &in[2]);
+ // do the white point correction
+ in[0] *= whiteX;
+ in[1] *= whiteY;
+ in[2] *= whiteZ;
XYZ2DisplayTransform->doTransform(in,out,1);
*gray = byteToCol(out[0]);
return;
@@ -1256,6 +1263,10 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
double r, g, b;
getXYZ(color, &X, &Y, &Z);
+ // do the white point correction
+ X *= whiteX;
+ Y *= whiteY;
+ Z *= whiteZ;
#ifdef USE_CMS
if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
Guchar out[gfxColorMaxComps];
@@ -1271,9 +1282,6 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
return;
}
#endif
- X *= whiteX;
- Y *= whiteY;
- Z *= whiteZ;
// convert XYZ to RGB, including gamut mapping and gamma correction
r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
@@ -1293,6 +1301,10 @@ void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
Guchar out[gfxColorMaxComps];
getXYZ(color, &in[0], &in[1], &in[2]);
+ // do the white point correction
+ in[0] *= whiteX;
+ in[1] *= whiteY;
+ in[2] *= whiteZ;
XYZ2DisplayTransform->doTransform(in,out,1);
cmyk->c = byteToCol(out[0]);
cmyk->m = byteToCol(out[1]);
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler