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

Reply via email to