poppler/PSOutputDev.cc | 25 ++++++++++++++++--------- poppler/PSOutputDev.h | 4 ++++ utils/pdftops.1 | 10 +++++++++- utils/pdftops.cc | 4 ++++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index f69eb86..63109fa 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -1235,6 +1235,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, embedCIDPostScript = gTrue; embedCIDTrueType = gTrue; fontPassthrough = gFalse; + optimizeColorSpace = gFalse; preloadImagesForms = gFalse; generateOPI = gFalse; useASCIIHex = gFalse; @@ -3312,16 +3313,20 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, case psLevel1Sep: 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; + if (getOptimizeColorSpace()) { + 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(); } - p += bitmap->getRowSize(); + } else { + isGray = gFalse; } 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, @@ -3468,7 +3473,9 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, 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) { + if (!getOptimizeColorSpace()) { + isGray = gFalse; + } else if (numComps == 4) { int compCyan; isGray = gTrue; while ((compCyan = str0->getChar()) != EOF) { diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index 128ff7c..6c14cef 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -319,11 +319,13 @@ public: GBool getEmbedCIDPostScript() const { return embedCIDPostScript; } GBool getEmbedCIDTrueType() const { return embedCIDTrueType; } GBool getFontPassthrough() const { return fontPassthrough; } + GBool getOptimizeColorSpace() const { return optimizeColorSpace; } void setEmbedType1(GBool b) { embedType1 = b; } void setEmbedTrueType(GBool b) { embedTrueType = b; } void setEmbedCIDPostScript(GBool b) { embedCIDPostScript = b; } void setEmbedCIDTrueType(GBool b) { embedCIDTrueType = b; } void setFontPassthrough(GBool b) { fontPassthrough = b; } + void setOptimizeColorSpace(GBool b) { optimizeColorSpace = b; } void setPreloadImagesForms(GBool b) { preloadImagesForms = b; } void setGenerateOPI(GBool b) { generateOPI = b; } void setUseASCIIHex(GBool b) { useASCIIHex = b; } @@ -518,6 +520,8 @@ private: GBool embedCIDPostScript; // embed CID PostScript fonts? GBool embedCIDTrueType; // embed CID TrueType fonts? GBool fontPassthrough; // pass all fonts through as-is? + GBool optimizeColorSpace; // false to keep gray RGB images in their original color space + // true to optimize gray images to DeviceGray color space GBool preloadImagesForms; // preload PostScript images and forms into // memory GBool generateOPI; // generate PostScript OPI comments? diff --git a/utils/pdftops.1 b/utils/pdftops.1 index ca26bcc..cc9c2c5 100644 --- a/utils/pdftops.1 +++ b/utils/pdftops.1 @@ -128,6 +128,14 @@ substituted with the closest "Helvetica", "Times-Roman", or "Courier" font. This option passes references to non-embedded fonts through to the PostScript file. .TP +.B \-optimizecolorspace +By default, bitmap images in the PDF pass through to the output PostScript +in their original color space, which produces predictable results. +This option converts RGB and CMYK images into Gray images +if every pixel of the image has equal components. +This can fix problems when doing color separations of PDFs +that contain embedded black and white images encoded as RGB. +.TP .B \-preload preload images and forms .TP @@ -135,7 +143,7 @@ preload images and forms Set the paper size to one of "letter", "legal", "A4", or "A3". This can also be set to "match", which will set the paper size of each page to match the size specified in the PDF file. If none the \-paper, \-paperw, or \-paperh -options are spoecified the default is to match the paper size. +options are specified the default is to match the paper size. .TP .BI \-paperw " size" Set the paper width, in points. diff --git a/utils/pdftops.cc b/utils/pdftops.cc index b85d96e..dfeaa14 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -95,6 +95,7 @@ static GBool noEmbedTTFonts = gFalse; static GBool noEmbedCIDPSFonts = gFalse; static GBool noEmbedCIDTTFonts = gFalse; static GBool fontPassthrough = gFalse; +static GBool optimizeColorSpace = gFalse; static char rasterAntialiasStr[16] = ""; static GBool preload = gFalse; static char paperSize[15] = ""; @@ -157,6 +158,8 @@ static const ArgDesc argDesc[] = { "don't substitute missing fonts"}, {"-aaRaster", argString, rasterAntialiasStr, sizeof(rasterAntialiasStr), "enable anti-aliasing on rasterization: yes, no"}, + {"-optimizecolorspace", argFlag, &optimizeColorSpace,0, + "convert gray RGB images to gray color space"}, {"-preload", argFlag, &preload, 0, "preload images and forms"}, {"-paper", argString, paperSize, sizeof(paperSize), @@ -403,6 +406,7 @@ int main(int argc, char *argv[]) { psOut->setEmbedCIDTrueType(!noEmbedCIDTTFonts); psOut->setFontPassthrough(fontPassthrough); psOut->setPreloadImagesForms(preload); + psOut->setOptimizeColorSpace(optimizeColorSpace); #if OPI_SUPPORT psOut->setGenerateOPI(doOPI); #endif