[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