[poppler] poppler/GlobalParams.cc poppler/GlobalParams.h poppler/PSOutputDev.cc utils/pdftops.1 utils/pdftops.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Tue Feb 8 11:54:22 PST 2011


 poppler/GlobalParams.cc |   18 +++
 poppler/GlobalParams.h  |    5 -
 poppler/PSOutputDev.cc  |  227 ++++++++++++++++++++++++++++++++++--------------
 utils/pdftops.1         |    7 +
 utils/pdftops.cc        |    8 +
 5 files changed, 198 insertions(+), 67 deletions(-)

New commits:
commit c3470145f95791167c19a438934a923eab8a93cf
Author: William Bader <williambader at hotmail.com>
Date:   Tue Feb 8 19:54:48 2011 +0000

    Add PS level1 non standard binary output option
    
    More info at bug 34003

diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 4657c07..02db0da 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -20,7 +20,7 @@
 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk at gmail.com>
 // Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew at sil.org>
 // Copyright (C) 2009 Petr Gajdos <pgajdos at novell.com>
-// Copyright (C) 2009 William Bader <williambader at hotmail.com>
+// Copyright (C) 2009, 2011 William Bader <williambader at hotmail.com>
 // Copyright (C) 2009 Kovid Goyal <kovid at kovidgoyal.net>
 // Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
 // Copyright (C) 2010 Patrick Spendrin <ps_ml at gmx.de>
@@ -665,6 +665,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
   psPreload = gFalse;
   psOPI = gFalse;
   psASCIIHex = gFalse;
+  psBinary = gFalse;
   textEncoding = new GooString("UTF-8");
 #if defined(_WIN32)
   textEOL = eolDOS;
@@ -1380,6 +1381,15 @@ GBool GlobalParams::getPSASCIIHex() {
   return ah;
 }
 
+GBool GlobalParams::getPSBinary() {
+  GBool binary;
+
+  lockGlobalParams;
+  binary = psBinary;
+  unlockGlobalParams;
+  return binary;
+}
+
 GooString *GlobalParams::getTextEncodingName() {
   GooString *s;
 
@@ -1737,6 +1747,12 @@ void GlobalParams::setPSASCIIHex(GBool hex) {
   unlockGlobalParams;
 }
 
+void GlobalParams::setPSBinary(GBool binary) {
+  lockGlobalParams;
+  psBinary = binary;
+  unlockGlobalParams;
+}
+
 void GlobalParams::setTextEncoding(char *encodingName) {
   lockGlobalParams;
   delete textEncoding;
diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
index 941a536..97db687 100644
--- a/poppler/GlobalParams.h
+++ b/poppler/GlobalParams.h
@@ -20,7 +20,7 @@
 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk at gmail.com>
 // Copyright (C) 2009 Jonathan Kew <jonathan_kew at sil.org>
 // Copyright (C) 2009 Petr Gajdos <pgajdos at novell.com>
-// Copyright (C) 2009 William Bader <williambader at hotmail.com>
+// Copyright (C) 2009, 2011 William Bader <williambader at hotmail.com>
 // Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
 //
 // To see a description of the changes please see the Changelog file that
@@ -199,6 +199,7 @@ public:
   GBool getPSPreload();
   GBool getPSOPI();
   GBool getPSASCIIHex();
+  GBool getPSBinary();
   GooString *getTextEncodingName();
   EndOfLineKind getTextEOL();
   GBool getTextPageBreaks();
@@ -244,6 +245,7 @@ public:
   void setPSPreload(GBool preload);
   void setPSOPI(GBool opi);
   void setPSASCIIHex(GBool hex);
+  void setPSBinary(GBool binary);
   void setTextEncoding(char *encodingName);
   GBool setTextEOL(char *s);
   void setTextPageBreaks(GBool pageBreaks);
@@ -325,6 +327,7 @@ private:
 				//   memory
   GBool psOPI;			// generate PostScript OPI comments?
   GBool psASCIIHex;		// use ASCIIHex instead of ASCII85?
+  GBool psBinary;		// use binary instead of hex
   GooString *textEncoding;	// encoding (unicodeMap) to use for text
 				//   output
   EndOfLineKind textEOL;	// type of EOL marker to use for text
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 7c7a29a..1c49f81 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -511,6 +511,10 @@ static char *prolog[] = {
   "  /pdfImBuf1 4 index string def",
   "  { currentfile pdfImBuf1 readhexstring pop } image",
   "} def",
+  "/pdfIm1Bin {",
+  "  /pdfImBuf1 4 index string def",
+  "  { currentfile pdfImBuf1 readstring pop } image",
+  "} def",
   "~1s",
   "/pdfIm1Sep {",
   "  /pdfImBuf1 4 index string def",
@@ -523,11 +527,26 @@ static char *prolog[] = {
   "  { currentfile pdfImBuf4 readhexstring pop }",
   "  true 4 colorimage",
   "} def",
+  "/pdfIm1SepBin {",
+  "  /pdfImBuf1 4 index string def",
+  "  /pdfImBuf2 4 index string def",
+  "  /pdfImBuf3 4 index string def",
+  "  /pdfImBuf4 4 index string def",
+  "  { currentfile pdfImBuf1 readstring pop }",
+  "  { currentfile pdfImBuf2 readstring pop }",
+  "  { currentfile pdfImBuf3 readstring pop }",
+  "  { currentfile pdfImBuf4 readstring pop }",
+  "  true 4 colorimage",
+  "} def",
   "~1ns",
   "/pdfImM1 {",
   "  fCol /pdfImBuf1 4 index 7 add 8 idiv string def",
   "  { currentfile pdfImBuf1 readhexstring pop } imagemask",
   "} def",
+  "/pdfImM1Bin {",
+  "  fCol /pdfImBuf1 4 index 7 add 8 idiv string def",
+  "  { currentfile pdfImBuf1 readstring pop } imagemask",
+  "} def",
   "/pdfImM1a {",
   "  { 2 copy get exch 1 add exch } imagemask",
   "  pop pop",
@@ -1315,6 +1334,9 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage,
     writePS("%%DocumentCustomColors: (atend)\n");
   }
   writePS("%%DocumentSuppliedResources: (atend)\n");
+  if ((level == psLevel1 || level == psLevel1Sep) && globalParams->getPSBinary()) {
+    writePS("%%DocumentData: Binary\n");
+  }
 
   switch (mode) {
   case psModePSOrigPageSizes:
@@ -2971,6 +2993,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/,
   int c, w, h, x, y, comp, i;
   char hexBuf[32*2 + 2];	// 32 values X 2 chars/value + line ending + null
   Guchar digit;
+  GBool useBinary;
 
   if (!forceRasterize) {
     scan = new PreScanOutputDev();
@@ -3071,47 +3094,76 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/,
 	     m0, m1, m2, m3, m4, m5);
   switch (level) {
   case psLevel1:
-    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1\n",
-	       w, h, w, -h, h);
+    useBinary = globalParams->getPSBinary();
+    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1{5:s}\n",
+	       w, h, w, -h, h,
+	       useBinary ? "Bin" : "");
     p = bitmap->getDataPtr();
     i = 0;
-    for (y = 0; y < h; ++y) {
-      for (x = 0; x < w; ++x) {
-	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 (useBinary) {
+      for (y = 0; y < h; ++y) {
+        for (x = 0; x < w; ++x) {
+	  hexBuf[i++] = *p++;
+	  if (i >= 64) {
+	    writePSBuf(hexBuf, i);
+	    i = 0;
+	  }
+	}
+      }
+    } else {
+      for (y = 0; y < h; ++y) {
+        for (x = 0; x < w; ++x) {
+	  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) {
-      hexBuf[i++] = '\n';
+      if (!useBinary) {
+	hexBuf[i++] = '\n';
+      }
       writePSBuf(hexBuf, i);
     }
     break;
   case psLevel1Sep:
-    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep\n",
-	       w, h, w, -h, h);
+    useBinary = globalParams->getPSBinary();
+    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep{5:s}\n",
+	       w, h, w, -h, h,
+	       useBinary ? "Bin" : "");
     p = bitmap->getDataPtr();
     i = 0;
     col[0] = col[1] = col[2] = col[3] = 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;
+	  if (useBinary) {
+	    for (x = 0; x < w; ++x) {
+	      col[comp] |= p[4*x + comp];
+	      hexBuf[i++] = p[4*x + comp];
+	      if (i >= 64) {
+	        writePSBuf(hexBuf, i);
+	        i = 0;
+	      }
+	    }
+	  } else {
+	    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;
+	      }
 	    }
 	  }
         }
@@ -3120,15 +3172,25 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/,
     } 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;
+	  if (useBinary) {
+	    for (x = 0; x < w; ++x) {
+	      hexBuf[i++] = p[4*x + comp];
+	      if (i >= 64) {
+	        writePSBuf(hexBuf, i);
+	        i = 0;
+	      }
+	    }
+	  } else {
+	    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;
+	      }
 	    }
 	  }
         }
@@ -3136,7 +3198,9 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/,
       }
     }
     if (i != 0) {
-      hexBuf[i++] = '\n';
+      if (!useBinary) {
+        hexBuf[i++] = '\n';
+      }
       writePSBuf(hexBuf, i);
     }
     if (col[0]) {
@@ -4543,6 +4607,7 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
   int col, x, y, c, i;
   char hexBuf[32*2 + 2];	// 32 values X 2 chars/value + line ending + null
   Guchar digit, grayValue;
+  const GBool useBinary = globalParams->getPSBinary();
 
   // explicit masking
   if (maskStr && !(maskColors && colorMap)) {
@@ -4593,13 +4658,15 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
 	       width, height, invert ? "true" : "false",
 	       width, -height, height);
   } else if (colorMap) {
-    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1\n",
+    writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1{5:s}\n",
 	       width, height,
-	       width, -height, height);
+	       width, -height, height,
+	       useBinary ? "Bin" : "");
   } else {
-    writePSFmt("{0:d} {1:d} {2:s} [{3:d} 0 0 {4:d} 0 {5:d}] pdfImM1\n",
+    writePSFmt("{0:d} {1:d} {2:s} [{3:d} 0 0 {4:d} 0 {5:d}] pdfImM1{6:s}\n",
 	       width, height, invert ? "true" : "false",
-	       width, -height, height);
+	       width, -height, height,
+	       useBinary ? "Bin" : "");
   }
 
   // image data
@@ -4621,19 +4688,27 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
 	  imgStr->getPixel(pixBuf);
 	  colorMap->getGray(pixBuf, &gray);
 	  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 (useBinary) {
+	    hexBuf[i++] = grayValue;
+	  } else {
+	    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';
+	    if (!useBinary) {
+	      hexBuf[i++] = '\n';
+	    }
 	    writePSBuf(hexBuf, i);
 	    i = 0;
 	  }
 	}
       }
       if (i != 0) {
-	hexBuf[i++] = '\n';
+	if (!useBinary) {
+	  hexBuf[i++] = '\n';
+	}
 	writePSBuf(hexBuf, i);
       }
       str->close();
@@ -4646,19 +4721,27 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
       for (y = 0; y < height; ++y) {
 	for (x = 0; x < width; x += 8) {
 	  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 (useBinary) {
+	    hexBuf[i++] = grayValue;
+	  } else {
+	    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';
+	    if (!useBinary) {
+	      hexBuf[i++] = '\n';
+	    }
 	    writePSBuf(hexBuf, i);
 	    i = 0;
 	  }
 	}
       }
       if (i != 0) {
-	hexBuf[i++] = '\n';
+	if (!useBinary) {
+	  hexBuf[i++] = '\n';
+	}
 	writePSBuf(hexBuf, i);
       }
       str->close();
@@ -4683,6 +4766,7 @@ void PSOutputDev::doImageL1Sep(Object *ref, GfxImageColorMap *colorMap,
   GBool checkProcessColor;
   char hexBuf[32*2 + 2];	// 32 values X 2 chars/value + line ending + null
   Guchar digit;
+  const GBool useBinary = globalParams->getPSBinary();
 
   // explicit masking
   if (maskStr && !(maskColors && colorMap)) {
@@ -4690,9 +4774,10 @@ void PSOutputDev::doImageL1Sep(Object *ref, GfxImageColorMap *colorMap,
   }
 
   // width, height, matrix, bits per component
-  writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep\n",
+  writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep{5:s}\n",
 	     width, height,
-	     width, -height, height);
+	     width, -height, height,
+	     useBinary ? "Bin" : "");
 
   // allocate a line buffer
   lineBuf = (Guchar *)gmallocn(width, 4);
@@ -4734,23 +4819,37 @@ void PSOutputDev::doImageL1Sep(Object *ref, GfxImageColorMap *colorMap,
     }
 
     // write one line of each color component
-    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;
+    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;
+	  }
 	}
       }
     }
   }
 
   if (i != 0) {
-    hexBuf[i++] = '\n';
+    if (!useBinary) {
+      hexBuf[i++] = '\n';
+    }
     writePSBuf(hexBuf, i);
   }
 
diff --git a/utils/pdftops.1 b/utils/pdftops.1
index 6c4ef61..c57dbb4 100644
--- a/utils/pdftops.1
+++ b/utils/pdftops.1
@@ -95,6 +95,13 @@ Generate OPI comments for all images and forms which have OPI
 information.  (This option is only available if pdftops was compiled
 with OPI support.)
 .TP
+.B \-binary
+Write binary data in Level 1 PostScript.  By default, pdftops writes
+hex-encoded data in Level 1 PostScript.  Binary data is non-standard
+in Level 1 PostScript but reduces the file size and can be useful
+when Level 1 PostScript is required only for its restricted use
+of PostScript operators.
+.TP
 .B \-noembt1
 By default, any Type 1 fonts which are embedded in the PDF file are
 copied into the PostScript file.  This option causes pdftops to
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index 1ef2342..01fa60d 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -19,7 +19,7 @@
 // Copyright (C) 2007-2008, 2010 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2009 Till Kamppeter <till.kamppeter at gmail.com>
 // Copyright (C) 2009 Sanjoy Mahajan <sanjoy at mit.edu>
-// Copyright (C) 2009 William Bader <williambader at hotmail.com>
+// Copyright (C) 2009, 2011 William Bader <williambader at hotmail.com>
 // Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
 //
 // To see a description of the changes please see the Changelog file that
@@ -85,6 +85,7 @@ static GBool doForm = gFalse;
 #if OPI_SUPPORT
 static GBool doOPI = gFalse;
 #endif
+static GBool psBinary = gFalse;
 static GBool noEmbedT1Fonts = gFalse;
 static GBool noEmbedTTFonts = gFalse;
 static GBool noEmbedCIDPSFonts = gFalse;
@@ -132,6 +133,8 @@ static const ArgDesc argDesc[] = {
   {"-opi",        argFlag,     &doOPI,          0,
    "generate OPI comments"},
 #endif
+  {"-binary",     argFlag,     &psBinary,       0,
+   "write binary data in Level 1 PostScript"},
   {"-noembt1",    argFlag,     &noEmbedT1Fonts, 0,
    "don't embed Type 1 fonts"},
   {"-noembtt",    argFlag,     &noEmbedTTFonts, 0,
@@ -289,6 +292,9 @@ int main(int argc, char *argv[]) {
     globalParams->setPSOPI(doOPI);
   }
 #endif
+  if (psBinary) {
+    globalParams->setPSBinary(psBinary);
+  }
   if (quiet) {
     globalParams->setErrQuiet(quiet);
   }


More information about the poppler mailing list