poppler/PSOutputDev.cc |  207 ++++++++++++++++++++++++++++++++++++++-----------
 poppler/PSOutputDev.h  |   13 ++-
 2 files changed, 170 insertions(+), 50 deletions(-)

New commits:
commit 0c5b1bef9f3f98001cee20061b1eaf20b965c5a9
Author: William Bader <[email protected]>
Date:   Fri Jan 21 19:01:45 2011 +0000

    Fix rendering for some pdf with -level1sep
    
    Also some speed improvemensts. Bug #32365

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 5ebe8f9..8bc6eea 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -23,7 +23,7 @@
 // Copyright (C) 2009, 2010 Thomas Freitag <[email protected]>
 // Copyright (C) 2009 Till Kamppeter <[email protected]>
 // Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
-// Copyright (C) 2009 William Bader <[email protected]>
+// Copyright (C) 2009, 2011 William Bader <[email protected]>
 // Copyright (C) 2009 Kovid Goyal <[email protected]>
 // Copyright (C) 2009, 2010 Adrian Johnson <[email protected]>
 //
@@ -567,6 +567,7 @@ static char *prolog[] = {
   "    not { pop exit } if",
   "    (%-EOD-) eq { exit } if } loop",
   "} def",
+  "~123sn",
   "/pr { 2 index 2 index 3 2 roll putinterval 4 add } def",
   "/pdfImClip {",
   "  gsave",
@@ -2968,6 +2969,8 @@ GBool PSOutputDev::checkPageSlice(Page *page, double 
/*hDPI*/, double /*vDPI*/,
   Guchar col[4];
   double m0, m1, m2, m3, m4, m5;
   int c, w, h, x, y, comp, i;
+  char hexBuf[32*2 + 2];       // 32 values X 2 chars/value + line ending + 
null
+  Guchar digit;
 
   if (!forceRasterize) {
     scan = new PreScanOutputDev();
@@ -3074,15 +3077,20 @@ GBool PSOutputDev::checkPageSlice(Page *page, double 
/*hDPI*/, double /*vDPI*/,
     i = 0;
     for (y = 0; y < h; ++y) {
       for (x = 0; x < w; ++x) {
-       writePSFmt("{0:02x}", *p++);
-       if (++i == 32) {
-         writePSChar('\n');
+       digit = *p / 16;
+       hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+       digit = *p++ % 16;
+       hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+       if (i >= 64) {
+         hexBuf[i++] = '\n';
+         writePSBuf(hexBuf, i);
          i = 0;
        }
       }
     }
     if (i != 0) {
-      writePSChar('\n');
+      hexBuf[i++] = '\n';
+      writePSBuf(hexBuf, i);
     }
     break;
   case psLevel1Sep:
@@ -3091,21 +3099,45 @@ GBool PSOutputDev::checkPageSlice(Page *page, double 
/*hDPI*/, double /*vDPI*/,
     p = bitmap->getDataPtr();
     i = 0;
     col[0] = col[1] = col[2] = col[3] = 0;
-    for (y = 0; y < h; ++y) {
-      for (comp = 0; comp < 4; ++comp) {
-       for (x = 0; x < w; ++x) {
-         writePSFmt("{0:02x}", p[4*x + comp]);
-         col[comp] |= p[4*x + comp];
-         if (++i == 32) {
-           writePSChar('\n');
-           i = 0;
+    if (((psProcessCyan | psProcessMagenta | psProcessYellow | psProcessBlack) 
& ~processColors) != 0) {
+      for (y = 0; y < h; ++y) {
+        for (comp = 0; comp < 4; ++comp) {
+         for (x = 0; x < w; ++x) {
+           col[comp] |= p[4*x + comp];
+           digit = p[4*x + comp] / 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+           digit = p[4*x + comp] % 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+           if (i >= 64) {
+             hexBuf[i++] = '\n';
+             writePSBuf(hexBuf, i);
+             i = 0;
+           }
          }
-       }
+        }
+        p += bitmap->getRowSize();
+      }
+    } else {
+      for (y = 0; y < h; ++y) {
+        for (comp = 0; comp < 4; ++comp) {
+         for (x = 0; x < w; ++x) {
+           digit = p[4*x + comp] / 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+           digit = p[4*x + comp] % 16;
+           hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+           if (i >= 64) {
+             hexBuf[i++] = '\n';
+             writePSBuf(hexBuf, i);
+             i = 0;
+           }
+         }
+        }
+        p += bitmap->getRowSize();
       }
-      p += bitmap->getRowSize();
     }
     if (i != 0) {
-      writePSChar('\n');
+      hexBuf[i++] = '\n';
+      writePSBuf(hexBuf, i);
     }
     if (col[0]) {
       processColors |= psProcessCyan;
@@ -4417,7 +4449,8 @@ void PSOutputDev::drawImageMask(GfxState *state, Object 
*ref, Stream *str,
     switch (level) {
       case psLevel1:
       case psLevel1Sep:
-        doImageL1(ref, NULL, invert, inlineImg, str, width, height, len);
+        doImageL1(ref, NULL, invert, inlineImg, str, width, height, len,
+                  NULL, NULL, 0, 0, gFalse);
       break;
       case psLevel2:
       case psLevel2Sep:
@@ -4442,11 +4475,13 @@ void PSOutputDev::drawImage(GfxState *state, Object 
*ref, Stream *str,
                   colorMap->getBits() + 7) / 8);
   switch (level) {
   case psLevel1:
-    doImageL1(ref, colorMap, gFalse, inlineImg, str, width, height, len);
+    doImageL1(ref, colorMap, gFalse, inlineImg, str,
+            width, height, len, maskColors, NULL, 0, 0, gFalse);
     break;
   case psLevel1Sep:
     //~ handle indexed, separation, ... color spaces
-    doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len);
+    doImageL1Sep(ref, colorMap, gFalse, inlineImg, str,
+            width, height, len, maskColors, NULL, 0, 0, gFalse);
     break;
   case psLevel2:
   case psLevel2Sep:
@@ -4475,11 +4510,13 @@ void PSOutputDev::drawMaskedImage(GfxState *state, 
Object *ref, Stream *str,
                   colorMap->getBits() + 7) / 8);
   switch (level) {
   case psLevel1:
-    doImageL1(ref, colorMap, gFalse, gFalse, str, width, height, len);
+    doImageL1(ref, colorMap, gFalse, gFalse, str, width, height, len,
+             NULL, maskStr, maskWidth, maskHeight, maskInvert);    
     break;
   case psLevel1Sep:
     //~ handle indexed, separation, ... color spaces
-    doImageL1Sep(colorMap, gFalse, gFalse, str, width, height, len);
+    doImageL1Sep(ref, colorMap, gFalse, gFalse, str, width, height, len,
+             NULL, maskStr, maskWidth, maskHeight, maskInvert);    
     break;
   case psLevel2:
   case psLevel2Sep:
@@ -4497,11 +4534,20 @@ void PSOutputDev::drawMaskedImage(GfxState *state, 
Object *ref, Stream *str,
 
 void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
                            GBool invert, GBool inlineImg,
-                           Stream *str, int width, int height, int len) {
+                           Stream *str, int width, int height, int len,
+                           int *maskColors, Stream *maskStr,
+                           int maskWidth, int maskHeight, GBool maskInvert) {
   ImageStream *imgStr;
   Guchar pixBuf[gfxColorMaxComps];
   GfxGray gray;
   int col, x, y, c, i;
+  char hexBuf[32*2 + 2];       // 32 values X 2 chars/value + line ending + 
null
+  Guchar digit, grayValue;
+
+  // explicit masking
+  if (maskStr && !(maskColors && colorMap)) {
+    maskToClippingPath(maskStr, maskWidth, maskHeight, maskInvert);
+  }
 
   if ((inType3Char || preload) && !colorMap) {
     if (inlineImg) {
@@ -4574,15 +4620,21 @@ void PSOutputDev::doImageL1(Object *ref, 
GfxImageColorMap *colorMap,
        for (x = 0; x < width; ++x) {
          imgStr->getPixel(pixBuf);
          colorMap->getGray(pixBuf, &gray);
-         writePSFmt("{0:02x}", colToByte(gray));
-         if (++i == 32) {
-           writePSChar('\n');
+         grayValue = colToByte(gray);
+         digit = grayValue / 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+         digit = grayValue % 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+         if (i >= 64) {
+           hexBuf[i++] = '\n';
+           writePSBuf(hexBuf, i);
            i = 0;
          }
        }
       }
       if (i != 0) {
-       writePSChar('\n');
+       hexBuf[i++] = '\n';
+       writePSBuf(hexBuf, i);
       }
       str->close();
       delete imgStr;
@@ -4593,29 +4645,49 @@ void PSOutputDev::doImageL1(Object *ref, 
GfxImageColorMap *colorMap,
       i = 0;
       for (y = 0; y < height; ++y) {
        for (x = 0; x < width; x += 8) {
-         writePSFmt("{0:02x}", str->getChar() & 0xff);
-         if (++i == 32) {
-           writePSChar('\n');
+         grayValue = str->getChar();
+         digit = grayValue / 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+         digit = grayValue % 16;
+         hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+         if (i >= 64) {
+           hexBuf[i++] = '\n';
+           writePSBuf(hexBuf, i);
            i = 0;
          }
        }
       }
       if (i != 0) {
-       writePSChar('\n');
+       hexBuf[i++] = '\n';
+       writePSBuf(hexBuf, i);
       }
       str->close();
     }
   }
+
+  if (maskStr && !(maskColors && colorMap)) {
+    writePS("pdfImClipEnd\n");
+  }
 }
 
-void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL1Sep(Object *ref, GfxImageColorMap *colorMap,
                               GBool invert, GBool inlineImg,
-                              Stream *str, int width, int height, int len) {
+                              Stream *str, int width, int height, int len,
+                              int *maskColors, Stream *maskStr,
+                              int maskWidth, int maskHeight, GBool maskInvert) 
{
   ImageStream *imgStr;
   Guchar *lineBuf;
   Guchar pixBuf[gfxColorMaxComps];
   GfxCMYK cmyk;
   int x, y, i, comp;
+  GBool checkProcessColor;
+  char hexBuf[32*2 + 2];       // 32 values X 2 chars/value + line ending + 
null
+  Guchar digit;
+
+  // 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\n",
@@ -4631,27 +4703,46 @@ void PSOutputDev::doImageL1Sep(GfxImageColorMap 
*colorMap,
   imgStr->reset();
 
   // process the data stream
+  checkProcessColor = gTrue;
   i = 0;
   for (y = 0; y < height; ++y) {
 
     // read the line
-    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 (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));
+      }
+    } 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
     for (comp = 0; comp < 4; ++comp) {
       for (x = 0; x < width; ++x) {
-       writePSFmt("{0:02x}", lineBuf[4*x + comp]);
-       if (++i == 32) {
-         writePSChar('\n');
+       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;
        }
       }
@@ -4659,12 +4750,17 @@ void PSOutputDev::doImageL1Sep(GfxImageColorMap 
*colorMap,
   }
 
   if (i != 0) {
-    writePSChar('\n');
+    hexBuf[i++] = '\n';
+    writePSBuf(hexBuf, i);
   }
 
   str->close();
   delete imgStr;
   gfree(lineBuf);
+
+  if (maskStr && !(maskColors && colorMap)) {
+    writePS("pdfImClipEnd\n");
+  }
 }
 
 void PSOutputDev::maskToClippingPath(Stream *maskStr, int maskWidth, int 
maskHeight, GBool maskInvert) {
@@ -4804,6 +4900,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap 
*colorMap,
   GfxCMYK cmyk;
   int c;
   int col, i, j, x0, x1, y;
+  char dataBuf[4096];
   
   rectsOutLen = 0;
 
@@ -5202,8 +5299,16 @@ void PSOutputDev::doImageL2(Object *ref, 
GfxImageColorMap *colorMap,
 
     // copy the stream data
     str->reset();
+    i = 0;
     while ((c = str->getChar()) != EOF) {
-      writePSChar(c);
+      dataBuf[i++] = c;
+      if (i >= (int)sizeof(dataBuf)) {
+       writePSBuf(dataBuf, i);
+       i = 0;
+      }
+    }
+    if (i > 0) {
+      writePSBuf(dataBuf, i);
     }
     str->close();
 
@@ -6440,6 +6545,16 @@ void PSOutputDev::writePS(char *s) {
   }
 }
 
+void PSOutputDev::writePSBuf(char *s, int len) {
+  if (t3String) {
+    for (int i = 0; i < len; i++) {
+      t3String->append(s[i]);
+    }
+  } else {
+    (*outputFunc)(outputStream, s, len);
+  }
+}
+
 void PSOutputDev::writePSFmt(const char *fmt, ...) {
   va_list args;
   GooString *buf;
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 013de18..d3eddec 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -20,7 +20,7 @@
 // Copyright (C) 2009, 2010 Thomas Freitag <[email protected]>
 // Copyright (C) 2009 Till Kamppeter <[email protected]>
 // Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
-// Copyright (C) 2009 William Bader <[email protected]>
+// Copyright (C) 2009, 2011 William Bader <[email protected]>
 // Copyright 2010 Hib Eris <[email protected]>
 //
 // To see a description of the changes please see the Changelog file that
@@ -317,10 +317,14 @@ private:
   void maskToClippingPath(Stream *maskStr, int maskWidth, int maskHeight, 
GBool maskInvert);
   void doImageL1(Object *ref, GfxImageColorMap *colorMap,
                 GBool invert, GBool inlineImg,
-                Stream *str, int width, int height, int len);
-  void doImageL1Sep(GfxImageColorMap *colorMap,
+                Stream *str, int width, int height, int len,
+                int *maskColors, Stream *maskStr,
+                int maskWidth, int maskHeight, GBool maskInvert);
+  void doImageL1Sep(Object *ref, GfxImageColorMap *colorMap,
                    GBool invert, GBool inlineImg,
-                   Stream *str, int width, int height, int len);
+                   Stream *str, int width, int height, int len,
+                   int *maskColors, Stream *maskStr,
+                   int maskWidth, int maskHeight, GBool maskInvert);
   void doImageL2(Object *ref, GfxImageColorMap *colorMap,
                 GBool invert, GBool inlineImg,
                 Stream *str, int width, int height, int len,
@@ -347,6 +351,7 @@ private:
 
   void writePSChar(char c);
   void writePS(char *s);
+  void writePSBuf(char *s, int len);
   void writePSFmt(const char *fmt, ...);
   void writePSString(GooString *s);
   void writePSName(char *s);
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to