--- poppler-git-25feb12-wb/poppler/GfxState.cc- 2012-02-25 05:23:41.880148390 +0100 +++ poppler-git-25feb12-wb/poppler/GfxState.cc 2012-02-25 05:36:53.497955456 +0100 @@ -4836,6 +4836,7 @@ // initialize for (k = 0; k < gfxColorMaxComps; ++k) { + lookup[k] = NULL; lookup2[k] = NULL; } byte_lookup = NULL; @@ -5024,6 +5025,7 @@ delete colorSpace; for (i = 0; i < gfxColorMaxComps; ++i) { + gfree(lookup[i]); gfree(lookup2[i]); } gfree(byte_lookup); --- poppler-git-25feb12-wb/poppler/PSOutputDev.cc- 2012-02-25 05:23:41.889148424 +0100 +++ poppler-git-25feb12-wb/poppler/PSOutputDev.cc 2012-02-25 05:36:53.504955475 +0100 @@ -23,7 +23,7 @@ // Copyright (C) 2009-2012 Thomas Freitag // Copyright (C) 2009 Till Kamppeter // Copyright (C) 2009 Carlos Garcia Campos -// Copyright (C) 2009, 2011 William Bader +// Copyright (C) 2009, 2011-2012 William Bader // Copyright (C) 2009 Kovid Goyal // Copyright (C) 2009-2011 Adrian Johnson // @@ -1249,7 +1249,6 @@ fontIDSize = 64; fontIDLen = 0; fontIDs = (Ref *)gmallocn(fontIDSize, sizeof(Ref)); - fontIDs = (Ref *)gmallocn(fontIDSize, sizeof(Ref)); for (i = 0; i < 14; ++i) { fontNames->add(new GooString(psBase14SubstFonts[i].psName), 1); } @@ -3070,6 +3069,10 @@ int c, w, h, x, y, comp, i; int numComps; #endif + char hexBuf[32*2 + 2]; // 32 values X 2 chars/value + line ending + null + Guchar digit; + GBool useBinary; + GBool isGray; if (globalParams->getPSAlwaysRasterize()) { rasterize = gTrue; @@ -3104,19 +3107,23 @@ delete state; // set up the SplashOutputDev - if (mono) { + if (mono || level == psLevel1) { + numComps = 1; paperColor[0] = 0xff; splashOut = new SplashOutputDev(splashModeMono8, 1, gFalse, paperColor, gFalse, globalParams->getAntialiasPrinting()); #if SPLASH_CMYK - } else if (level == psLevel1Sep || globalParams->getOverprintPreview()) { + } else if (level == psLevel1Sep || level == psLevel2Sep || + level == psLevel3Sep || globalParams->getOverprintPreview()) { + numComps = 4; paperColor[0] = paperColor[1] = paperColor[2] = paperColor[3] = 0; splashOut = new SplashOutputDev(splashModeCMYK8, 1, gFalse, paperColor, gFalse, globalParams->getAntialiasPrinting()); #endif } else { + numComps = 3; paperColor[0] = paperColor[1] = paperColor[2] = 0xff; splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor, gFalse, @@ -3167,115 +3174,297 @@ 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() + (h - 1) * bitmap->getRowSize(); i = 0; - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - writePSFmt("{0:02x}", *p++); - if (++i == 32) { - writePSChar('\n'); - 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) { - writePSChar('\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(); + p = bitmap->getDataPtr(); + // Check for an all gray image + isGray = gTrue; + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + if (p[4*x] != p[4*x + 1] || p[4*x] != p[4*x + 2]) { + isGray = gFalse; + y = h; + break; + } + } + p += bitmap->getRowSize(); + } + writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1{5:s}{6:s}\n", + w, h, w, -h, h, + isGray ? "" : "Sep", + useBinary ? "Bin" : ""); p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize(); 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 (isGray) { + int g; + if ((psProcessBlack & processColors) == 0) { + // Check if the image uses black + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + if (p[4*x] > 0 || p[4*x + 3] > 0) { + col[3] = 1; + y = h; + break; + } } + p -= bitmap->getRowSize(); } - } - p -= bitmap->getRowSize(); + p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize(); + } + for (y = 0; y < h; ++y) { + if (useBinary) { + // Binary gray image + for (x = 0; x < w; ++x) { + g = p[4*x] + p[4*x + 3]; + g = 255 - g; + if (g < 0) g = 0; + hexBuf[i++] = (Guchar) g; + if (i >= 64) { + writePSBuf(hexBuf, i); + i = 0; + } + } + } else { + // Hex gray image + for (x = 0; x < w; ++x) { + g = p[4*x] + p[4*x + 3]; + g = 255 - g; + if (g < 0) g = 0; + 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) { + hexBuf[i++] = '\n'; + writePSBuf(hexBuf, i); + i = 0; + } + } + } + p -= bitmap->getRowSize(); + } + } else if (((psProcessCyan | psProcessMagenta | psProcessYellow | psProcessBlack) & ~processColors) != 0) { + // Color image, need to check color flags for each dot + for (y = 0; y < h; ++y) { + for (comp = 0; comp < 4; ++comp) { + if (useBinary) { + // Binary color image + 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 { + // Gray color image + 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 { + // Color image, do not need to check color flags + for (y = 0; y < h; ++y) { + for (comp = 0; comp < 4; ++comp) { + if (useBinary) { + // Binary color image + for (x = 0; x < w; ++x) { + hexBuf[i++] = p[4*x + comp]; + if (i >= 64) { + writePSBuf(hexBuf, i); + i = 0; + } + } + } else { + // Hex color image + 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(); + } } if (i != 0) { - writePSChar('\n'); + if (!useBinary) { + hexBuf[i++] = '\n'; + } + writePSBuf(hexBuf, i); } if (col[0]) { - processColors |= psProcessCyan; + processColors |= psProcessCyan; } if (col[1]) { - processColors |= psProcessMagenta; + processColors |= psProcessMagenta; } if (col[2]) { - processColors |= psProcessYellow; + processColors |= psProcessYellow; } if (col[3]) { - processColors |= psProcessBlack; + processColors |= psProcessBlack; } break; case psLevel2: case psLevel2Sep: case psLevel3: case psLevel3Sep: - if (mono) { - writePS("/DeviceGray setcolorspace\n"); -#if SPLASH_CMYK - } else if (globalParams->getOverprintPreview()) { - writePS("/DeviceCMYK setcolorspace\n"); -#endif + obj.initNull(); + p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize(); + str0 = new MemStream((char *)p, 0, w * h * numComps, &obj); + // Check for a color image that uses only gray + if (numComps == 4) { + int compCyan; + isGray = gTrue; + while ((compCyan = str0->getChar()) != EOF) { + if (str0->getChar() != compCyan || + str0->getChar() != compCyan) { + isGray = gFalse; + break; + } + str0->getChar(); + } + } else if (numComps == 3) { + int compRed; + isGray = gTrue; + while ((compRed = str0->getChar()) != EOF) { + if (str0->getChar() != compRed || + str0->getChar() != compRed) { + isGray = gFalse; + break; + } + } } else { + isGray = gFalse; + } + str0->reset(); + if (isGray && numComps == 4) { + str = new RunLengthEncoder(new CMYKGrayEncoder(str0)); + numComps = 1; + } else if (isGray && numComps == 3) { + str = new RunLengthEncoder(new RGBGrayEncoder(str0)); + numComps = 1; + } else { + str = new RunLengthEncoder(str0); + } + if (numComps == 1) { + writePS("/DeviceGray setcolorspace\n"); + } else if (numComps == 3) { writePS("/DeviceRGB setcolorspace\n"); + } else { + writePS("/DeviceCMYK setcolorspace\n"); } writePS("<<\n /ImageType 1\n"); writePSFmt(" /Width {0:d}\n", bitmap->getWidth()); writePSFmt(" /Height {0:d}\n", bitmap->getHeight()); writePSFmt(" /ImageMatrix [{0:d} 0 0 {1:d} 0 {2:d}]\n", w, -h, h); writePS(" /BitsPerComponent 8\n"); - if (mono) { - writePS(" /Decode [0 1]\n"); - numComps = 1; -#if SPLASH_CMYK - } else if (globalParams->getOverprintPreview()) { - writePS(" /Decode [0 1 0 1 0 1 0 1]\n"); - numComps = 4; -#endif - } else { + if (numComps == 1) { + writePS(" /Decode [1 0]\n"); + } else if (numComps == 3) { writePS(" /Decode [0 1 0 1 0 1]\n"); - numComps = 3; + } else { + writePS(" /Decode [0 1 0 1 0 1 0 1]\n"); } writePS(" /DataSource currentfile\n"); - if (globalParams->getPSASCIIHex()) { + useBinary = globalParams->getPSBinary(); + if (useBinary) { + /* nothing to do */; + } else if (globalParams->getPSASCIIHex()) { writePS(" /ASCIIHexDecode filter\n"); } else { writePS(" /ASCII85Decode filter\n"); } writePS(" /RunLengthDecode filter\n"); writePS(">>\n"); - writePS("image\n"); - obj.initNull(); - p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize(); - str0 = new MemStream((char *)p, 0, w * h * numComps, &obj); - str = new RunLengthEncoder(str0); - if (globalParams->getPSASCIIHex()) { + if (useBinary) { + /* nothing to do */; + } else if (globalParams->getPSASCIIHex()) { str = new ASCIIHexEncoder(str); } else { str = new ASCII85Encoder(str); } str->reset(); + if (useBinary) { + // Count the bytes to write a document comment + int len = 0; + while (str->getChar() != EOF) { + len++; + } + str->reset(); + writePSFmt("%%BeginData: {0:d} Binary Bytes\n", len+6+1); + } + writePS("image\n"); while ((c = str->getChar()) != EOF) { writePSChar(c); } + writePSChar('\n'); + if (useBinary) { + writePS("%%EndData\n"); + } str->close(); delete str; delete str0; - writePSChar('\n'); - processColors |= mono ? psProcessBlack : psProcessCMYK; + processColors |= (numComps == 1) ? psProcessBlack : psProcessCMYK; break; } writePS("grestore\n"); --- poppler-git-25feb12-wb/poppler/Stream.cc- 2012-02-25 05:23:41.894148440 +0100 +++ poppler-git-25feb12-wb/poppler/Stream.cc 2012-02-25 05:36:53.507955485 +0100 @@ -5160,27 +5160,27 @@ } //------------------------------------------------------------------------ -// CMKYGrayEncoder +// CMYKGrayEncoder //------------------------------------------------------------------------ -CMKYGrayEncoder::CMKYGrayEncoder(Stream *strA): +CMYKGrayEncoder::CMYKGrayEncoder(Stream *strA): FilterStream(strA) { bufPtr = bufEnd = buf; eof = gFalse; } -CMKYGrayEncoder::~CMKYGrayEncoder() { +CMYKGrayEncoder::~CMYKGrayEncoder() { if (str->isEncoder()) delete str; } -void CMKYGrayEncoder::reset() { +void CMYKGrayEncoder::reset() { str->reset(); bufPtr = bufEnd = buf; eof = gFalse; } -GBool CMKYGrayEncoder::fillBuf() { +GBool CMYKGrayEncoder::fillBuf() { int c0, c1, c2, c3; int i; @@ -5201,3 +5201,46 @@ *bufEnd++ = (char) i; return gTrue; } + +//------------------------------------------------------------------------ +// RGBGrayEncoder +//------------------------------------------------------------------------ + +RGBGrayEncoder::RGBGrayEncoder(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = buf; + eof = gFalse; +} + +RGBGrayEncoder::~RGBGrayEncoder() { + if (str->isEncoder()) + delete str; +} + +void RGBGrayEncoder::reset() { + str->reset(); + bufPtr = bufEnd = buf; + eof = gFalse; +} + +GBool RGBGrayEncoder::fillBuf() { + int c0, c1, c2; + int i; + + if (eof) { + return gFalse; + } + c0 = str->getChar(); + c1 = str->getChar(); + c2 = str->getChar(); + if (c2 == EOF) { + eof = gTrue; + return gFalse; + } + i = 255 - (3 * c0 + 6 * c1 + c2) / 10; + if (i < 0) i = 0; + bufPtr = bufEnd = buf; + *bufEnd++ = (char) i; + return gTrue; +} + --- poppler-git-25feb12-wb/poppler/Stream.h- 2012-02-25 05:23:41.894148440 +0100 +++ poppler-git-25feb12-wb/poppler/Stream.h 2012-02-25 05:36:53.508955489 +0100 @@ -1179,14 +1179,43 @@ }; //------------------------------------------------------------------------ -// CMKYGrayEncoder +// CMYKGrayEncoder //------------------------------------------------------------------------ -class CMKYGrayEncoder: public FilterStream { +class CMYKGrayEncoder: public FilterStream { public: - CMKYGrayEncoder(Stream *strA); - virtual ~CMKYGrayEncoder(); + CMYKGrayEncoder(Stream *strA); + virtual ~CMYKGrayEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL; } + virtual GBool isBinary(GBool /*last = gTrue*/) { return gFalse; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[2]; + char *bufPtr; + char *bufEnd; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// RGBGrayEncoder +//------------------------------------------------------------------------ + +class RGBGrayEncoder: public FilterStream { +public: + + RGBGrayEncoder(Stream *strA); + virtual ~RGBGrayEncoder(); virtual StreamKind getKind() { return strWeird; } virtual void reset(); virtual int getChar() --- poppler-git-25feb12-wb/splash/Splash.cc- 2012-02-25 05:23:41.910148498 +0100 +++ poppler-git-25feb12-wb/splash/Splash.cc 2012-02-25 05:36:53.512955503 +0100 @@ -1293,8 +1293,39 @@ if (noClip) { pipeSetXY(pipe, x0, y); - for (x = x0; x <= x1; ++x) { - (this->*pipe->run)(pipe); + if (bitmap->mode == splashModeRGB8 && !pipe->pattern && + pipe->noTransparency && !state->blendFunc && !state->softMask && !pipe->usesShape) { + for (x = x0; x <= x1; ++x) { + // pipeRun(pipe); + *pipe->destColorPtr++ = pipe->cSrc[0]; + *pipe->destColorPtr++ = pipe->cSrc[1]; + *pipe->destColorPtr++ = pipe->cSrc[2]; + if (pipe->destAlphaPtr) { + *pipe->destAlphaPtr++ = 255; + } + ++pipe->x; + } + } else +#if SPLASH_CMYK + if (bitmap->mode == splashModeCMYK8 && !pipe->pattern && + pipe->noTransparency && !state->blendFunc && !state->softMask && !pipe->usesShape) { + for (x = x0; x <= x1; ++x) { + // pipeRun(pipe); + *pipe->destColorPtr++ = pipe->cSrc[0]; + *pipe->destColorPtr++ = pipe->cSrc[1]; + *pipe->destColorPtr++ = pipe->cSrc[2]; + *pipe->destColorPtr++ = pipe->cSrc[3]; + if (pipe->destAlphaPtr) { + *pipe->destAlphaPtr++ = 255; + } + ++pipe->x; + } + } else +#endif + { + for (x = x0; x <= x1; ++x) { + pipeRun(pipe); + } } updateModX(x0); updateModX(x1);