--- poppler-0.17.1-cmyk/poppler/PSOutputDev.cc- 2011-03-21 17:52:18.000000000 -0300 +++ poppler-0.17.1-cmyk/poppler/PSOutputDev.cc 2011-05-30 00:08:23.076715896 -0300 @@ -2986,6 +2986,7 @@ GfxState *state; SplashBitmap *bitmap; Stream *str0, *str; + Stream *str1 = NULL; Object obj; Guchar *p; Guchar col[4]; @@ -2995,6 +2996,8 @@ char hexBuf[32*2 + 2]; // 32 values X 2 chars/value + line ending + null Guchar digit; GBool useBinary; + GBool isGray; + int compCyan; if (!forceRasterize) { scan = new PreScanOutputDev(xref); @@ -3016,13 +3019,13 @@ splashOut = new SplashOutputDev(splashModeMono8, 1, gFalse, paperColor, gTrue, gFalse); #if SPLASH_CMYK - } else if (level == psLevel1Sep) { + } else if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { paperColor[0] = paperColor[1] = paperColor[2] = paperColor[3] = 0; splashOut = new SplashOutputDev(splashModeCMYK8, 1, gFalse, paperColor, gTrue, gFalse); #else - } else if (level == psLevel1Sep) { - error(-1, "pdftops was built without CMYK support, level1sep needs it to work in this file"); + } else if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { + error(-1, "pdftops was built without CMYK support, levelnsep needs it to work in this file"); return gFalse; #endif } else { @@ -3221,10 +3224,82 @@ processColors |= psProcessBlack; } break; - case psLevel2: case psLevel2Sep: - case psLevel3: case psLevel3Sep: + obj.initNull(); + str0 = new MemStream((char *)bitmap->getDataPtr(), 0, w * h * 4, &obj); + isGray = gTrue; + while ((compCyan = str0->getChar()) != EOF) { + if (str0->getChar() != compCyan || + str0->getChar() != compCyan) { + isGray = gFalse; + break; + } + str0->getChar(); + } + str0->reset(); + if (isGray) { + writePS("/DeviceGray setcolorspace\n"); + str1 = new CMKYGrayEncoder(str0); + str = new RunLengthEncoder(str1); + } else { + processColors |= psProcessCMYK; + writePS("/DeviceCMYK setcolorspace\n"); + str = new RunLengthEncoder(str0); + } + 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 (isGray) { + writePS(" /Decode [1 0]\n"); + } else { + writePS(" /Decode [0 1 0 1 0 1 0 1]\n"); + } + writePS(" /DataSource currentfile\n"); + 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"); + if (useBinary) { + /* nothing to do */; + } else if (globalParams->getPSASCIIHex()) { + str = new ASCIIHexEncoder(str); + } else { + str = new ASCII85Encoder(str); + } + str->reset(); + if (useBinary) { + 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); + } + if (useBinary) { + writePS("\n%%EndData\n"); + } else if (isGray) { + writePSChar('\n'); + } + str->close(); + delete str; + // delete str1; // deleted by str0 + delete str0; + break; + case psLevel2: + case psLevel3: writePS("/DeviceRGB setcolorspace\n"); writePS("<<\n /ImageType 1\n"); writePSFmt(" /Width {0:d}\n", bitmap->getWidth()); --- poppler-0.17.1-cmyk/poppler/Stream.cc- 2010-11-08 17:45:24.000000000 -0300 +++ poppler-0.17.1-cmyk/poppler/Stream.cc 2011-05-30 00:08:23.079715832 -0300 @@ -4923,3 +4923,46 @@ bufPtr = buf; return gTrue; } + +//------------------------------------------------------------------------ +// CMKYGrayEncoder +//------------------------------------------------------------------------ + +CMKYGrayEncoder::CMKYGrayEncoder(Stream *strA): + FilterStream(strA) { + bufPtr = bufEnd = buf; + eof = gFalse; +} + +CMKYGrayEncoder::~CMKYGrayEncoder() { + if (str->isEncoder()) + delete str; +} + +void CMKYGrayEncoder::reset() { + str->reset(); + bufPtr = bufEnd = buf; + eof = gFalse; +} + +GBool CMKYGrayEncoder::fillBuf() { + int c0, c1, c2, c3; + int i; + + if (eof) { + return gFalse; + } + c0 = str->getChar(); + c1 = str->getChar(); + c2 = str->getChar(); + c3 = str->getChar(); + if (c3 == EOF) { + eof = gTrue; + return gFalse; + } + i = (3 * c0 + 6 * c1 + c2) / 10 + c3; + if (i > 255) i = 255; + bufPtr = bufEnd = buf; + *bufEnd++ = (char) i; + return gTrue; +} --- poppler-0.17.1-cmyk/poppler/Stream.h- 2010-11-10 20:08:18.000000000 -0300 +++ poppler-0.17.1-cmyk/poppler/Stream.h 2011-05-30 00:08:23.079715832 -0300 @@ -1141,4 +1141,33 @@ GBool fillBuf(); }; +//------------------------------------------------------------------------ +// CMKYGrayEncoder +//------------------------------------------------------------------------ + +class CMKYGrayEncoder: public FilterStream { +public: + + CMKYGrayEncoder(Stream *strA); + virtual ~CMKYGrayEncoder(); + 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*/, 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(); +}; + #endif