[poppler] poppler/PSOutputDev.cc poppler/PSOutputDev.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Fri Jan 21 11:01:26 PST 2011
poppler/PSOutputDev.cc | 207 ++++++++++++++++++++++++++++++++++++++-----------
poppler/PSOutputDev.h | 13 ++-
2 files changed, 170 insertions(+), 50 deletions(-)
New commits:
commit 0c5b1bef9f3f98001cee20061b1eaf20b965c5a9
Author: William Bader <williambader at hotmail.com>
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 <Thomas.Freitag at alfa.de>
// Copyright (C) 2009 Till Kamppeter <till.kamppeter at gmail.com>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
-// 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) 2009, 2010 Adrian Johnson <ajohnson at redneon.com>
//
@@ -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 <Thomas.Freitag at alfa.de>
// Copyright (C) 2009 Till Kamppeter <till.kamppeter at gmail.com>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
-// Copyright (C) 2009 William Bader <williambader at hotmail.com>
+// Copyright (C) 2009, 2011 William Bader <williambader at hotmail.com>
// Copyright 2010 Hib Eris <hib at hiberis.nl>
//
// 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);
More information about the poppler
mailing list