poppler/PSOutputDev.cc |  181 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 132 insertions(+), 49 deletions(-)

New commits:
commit 8d46550c4ff3d4a1923cfc4c42e3fd4d154a7624
Author: William Bader <[email protected]>
Date:   Fri Nov 29 01:55:29 2019 -0500

    Improve pdftops -optimizecolorspace by implementing the CMYK to K 
conversion in more places.
    This fixes the conversion of the PDF in poppler/poppler#833

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index a7c86f8f..511a6ebb 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -23,7 +23,7 @@
 // Copyright (C) 2009-2013 Thomas Freitag <[email protected]>
 // Copyright (C) 2009 Till Kamppeter <[email protected]>
 // Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
-// Copyright (C) 2009, 2011, 2012, 2014-2017 William Bader 
<[email protected]>
+// Copyright (C) 2009, 2011, 2012, 2014-2017, 2019 William Bader 
<[email protected]>
 // Copyright (C) 2009 Kovid Goyal <[email protected]>
 // Copyright (C) 2009-2011, 2013-2015, 2017 Adrian Johnson 
<[email protected]>
 // Copyright (C) 2012, 2014 Fabio D'Urso <[email protected]>
@@ -4105,6 +4105,16 @@ void PSOutputDev::updateFillColor(GfxState *state) {
       m = colToDbl(cmyk.m);
       y = colToDbl(cmyk.y);
       k = colToDbl(cmyk.k);
+      if (getOptimizeColorSpace()) {
+       double g;
+       g = 0.299*c + 0.587*m + 0.114*y;
+       if ((fabs(m - c) < 0.01 && fabs(m - y) < 0.01) ||
+           (fabs(m - c) < 0.2 && fabs(m - y) < 0.2 && k + g > 1.5)) {
+         c = m = y = 0.0;
+         k += g;
+         if (k > 1.0) k = 1.0;
+       }
+      }
       writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} k\n", c, m, y, k);
       addProcessColor(c, m, y, k);
     }
@@ -4162,6 +4172,16 @@ void PSOutputDev::updateStrokeColor(GfxState *state) {
       m = colToDbl(cmyk.m);
       y = colToDbl(cmyk.y);
       k = colToDbl(cmyk.k);
+      if (getOptimizeColorSpace()) {
+       double g;
+       g = 0.299*c + 0.587*m + 0.114*y;
+       if ((fabs(m - c) < 0.01 && fabs(m - y) < 0.01) ||
+           (fabs(m - c) < 0.2 && fabs(m - y) < 0.2 && k + g > 1.5)) {
+         c = m = y = 0.0;
+         k += g;
+         if (k > 1.0) k = 1.0;
+       }
+      }
       writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} K\n", c, m, y, k);
       addProcessColor(c, m, y, k);
     }
@@ -5479,79 +5499,142 @@ void PSOutputDev::doImageL1Sep(Object *ref, 
GfxImageColorMap *colorMap,
   bool checkProcessColor;
   char hexBuf[32*2 + 2];       // 32 values X 2 chars/value + line ending + 
null
   unsigned char digit;
+  bool isGray;
 
   // explicit masking
   if (maskStr && !(maskColors && colorMap)) {
     maskToClippingPath(maskStr, maskWidth, maskHeight, maskInvert);
   }
 
-  // width, height, matrix, bits per component
-  writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep{5:s}\n",
-            width, height,
-            width, -height, height,
-            useBinary ? "Bin" : "");
-
   // allocate a line buffer
   lineBuf = (unsigned char *)gmallocn(width, 4);
 
+  // scan for all gray
+  if (getOptimizeColorSpace()) {
+    ImageStream *imgCheckStr;
+    imgCheckStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+                          colorMap->getBits());
+    imgCheckStr->reset();
+    isGray = true;
+    for (y = 0; y < height; ++y) {
+      for (x = 0; x < width; ++x) {
+       imgCheckStr->getPixel(pixBuf);
+       colorMap->getCMYK(pixBuf, &cmyk);
+       if (colToByte(cmyk.c) != colToByte(cmyk.m) || colToByte(cmyk.c) != 
colToByte(cmyk.y)) {
+         isGray = false;
+         y = height; // end outer loop
+         break;
+       }
+      }
+    }
+    imgCheckStr->close();
+    delete imgCheckStr;
+  } else {
+    isGray = false;
+  }
+
   // set up to process the data stream
   imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
                           colorMap->getBits());
   imgStr->reset();
 
+  // width, height, matrix, bits per component
+  writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1{5:s}{6:s}\n",
+            width, height,
+            width, -height, height,
+            isGray ? "" : "Sep",
+            useBinary ? "Bin" : "");
+
   // process the data stream
   checkProcessColor = true;
   i = 0;
-  for (y = 0; y < height; ++y) {
 
-    // read the line
-    if (checkProcessColor) {
-      checkProcessColor = (((psProcessCyan | psProcessMagenta | 
psProcessYellow | psProcessBlack) & ~processColors) != 0);
-    }
-    if (checkProcessColor) {
-      for (x = 0; x < width; ++x) {
-        imgStr->getPixel(pixBuf);
-        colorMap->getCMYK(pixBuf, &cmyk);
-        lineBuf[4*x+0] = colToByte(cmyk.c);
-        lineBuf[4*x+1] = colToByte(cmyk.m);
-        lineBuf[4*x+2] = colToByte(cmyk.y);
-        lineBuf[4*x+3] = colToByte(cmyk.k);
-        addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
-                       colToDbl(cmyk.y), colToDbl(cmyk.k));
+  if (isGray) {
+    int g;
+    for (y = 0; y < height; ++y) {
+
+      // read the line
+      if (checkProcessColor) {
+       checkProcessColor = ((psProcessBlack & processColors) == 0);
       }
-    } else {
       for (x = 0; x < width; ++x) {
-        imgStr->getPixel(pixBuf);
-        colorMap->getCMYK(pixBuf, &cmyk);
-        lineBuf[4*x+0] = colToByte(cmyk.c);
-        lineBuf[4*x+1] = colToByte(cmyk.m);
-        lineBuf[4*x+2] = colToByte(cmyk.y);
-        lineBuf[4*x+3] = colToByte(cmyk.k);
+       imgStr->getPixel(pixBuf);
+       colorMap->getCMYK(pixBuf, &cmyk);
+       g = colToByte(cmyk.c) + colToByte(cmyk.k);
+       if (checkProcessColor && g > 0) {
+         processColors |= psProcessBlack;
+       }
+       g = 255 - g;
+       if (g < 0) g = 0;
+       if (useBinary) {
+         hexBuf[i++] = g;
+       } else {
+         digit = g / 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
+         digit = g % 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
+       }
+       if (i >= 64) {
+         if (!useBinary) {
+           hexBuf[i++] = '\n';
+         }
+         writePSBuf(hexBuf, i);
+         i = 0;
+       }
       }
     }
+  } else {
+    for (y = 0; y < height; ++y) {
 
-    // write one line of each color component
-    if (useBinary) {
-      for (comp = 0; comp < 4; ++comp) {
-        for (x = 0; x < width; ++x) {
-         hexBuf[i++] = lineBuf[4*x + comp];
-         if (i >= 64) {
-           writePSBuf(hexBuf, i);
-           i = 0;
-         }
-       }
+      // read the line
+      if (checkProcessColor) {
+        checkProcessColor = (((psProcessCyan | psProcessMagenta | 
psProcessYellow | psProcessBlack) & ~processColors) != 0);
       }
-    } else {
-      for (comp = 0; comp < 4; ++comp) {
+      if (checkProcessColor) {
         for (x = 0; x < width; ++x) {
-         digit = lineBuf[4*x + comp] / 16;
-         hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
-         digit = lineBuf[4*x + comp] % 16;
-         hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
-         if (i >= 64) {
-           hexBuf[i++] = '\n';
-           writePSBuf(hexBuf, i);
-           i = 0;
+          imgStr->getPixel(pixBuf);
+          colorMap->getCMYK(pixBuf, &cmyk);
+          lineBuf[4*x+0] = colToByte(cmyk.c);
+          lineBuf[4*x+1] = colToByte(cmyk.m);
+          lineBuf[4*x+2] = colToByte(cmyk.y);
+          lineBuf[4*x+3] = colToByte(cmyk.k);
+          addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
+                         colToDbl(cmyk.y), colToDbl(cmyk.k));
+        }
+      } else {
+        for (x = 0; x < width; ++x) {
+          imgStr->getPixel(pixBuf);
+          colorMap->getCMYK(pixBuf, &cmyk);
+          lineBuf[4*x+0] = colToByte(cmyk.c);
+          lineBuf[4*x+1] = colToByte(cmyk.m);
+          lineBuf[4*x+2] = colToByte(cmyk.y);
+          lineBuf[4*x+3] = colToByte(cmyk.k);
+        }
+      }
+
+      // write one line of each color component
+      if (useBinary) {
+        for (comp = 0; comp < 4; ++comp) {
+          for (x = 0; x < width; ++x) {
+           hexBuf[i++] = lineBuf[4*x + comp];
+           if (i >= 64) {
+             writePSBuf(hexBuf, i);
+             i = 0;
+           }
+         }
+        }
+      } else {
+        for (comp = 0; comp < 4; ++comp) {
+          for (x = 0; x < width; ++x) {
+           digit = lineBuf[4*x + comp] / 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
+           digit = lineBuf[4*x + comp] % 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a'-10: '0');
+           if (i >= 64) {
+             hexBuf[i++] = '\n';
+             writePSBuf(hexBuf, i);
+             i = 0;
+           }
          }
        }
       }
_______________________________________________
poppler mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to