From 74cb74c79b9bedeb8d7dc95547c22019cc13862f Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 1 Mar 2017 21:45:32 +1030 Subject: [PATCH] pdfimages: support 16bpc png and tiff images bug 99988 --- goo/PNGWriter.cc | 4 ++++ goo/PNGWriter.h | 3 ++- goo/TiffWriter.cc | 6 ++++++ goo/TiffWriter.h | 3 ++- poppler/GfxState.h | 4 ++++ utils/ImageOutputDev.cc | 38 +++++++++++++++++++++++++++++++++++++- utils/ImageOutputDev.h | 1 + 7 files changed, 56 insertions(+), 3 deletions(-) diff --git a/goo/PNGWriter.cc b/goo/PNGWriter.cc index c9d5199d..99be021d 100644 --- a/goo/PNGWriter.cc +++ b/goo/PNGWriter.cc @@ -117,6 +117,10 @@ bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI) bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB; break; + case RGB48: + bit_depth = 16; + color_type = PNG_COLOR_TYPE_RGB; + break; case RGBA: bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB_ALPHA; diff --git a/goo/PNGWriter.h b/goo/PNGWriter.h index 90a298e7..ddaedaf4 100644 --- a/goo/PNGWriter.h +++ b/goo/PNGWriter.h @@ -32,8 +32,9 @@ public: * RGBA - 4 bytes/pixel * GRAY - 1 byte/pixel * MONOCHROME - 8 pixels/byte + * RGB48 - 6 bytes/pixel */ - enum Format { RGB, RGBA, GRAY, MONOCHROME }; + enum Format { RGB, RGBA, GRAY, MONOCHROME, RGB48 }; PNGWriter(Format format = RGB); ~PNGWriter(); diff --git a/goo/TiffWriter.cc b/goo/TiffWriter.cc index 31600877..ef2f1691 100644 --- a/goo/TiffWriter.cc +++ b/goo/TiffWriter.cc @@ -147,6 +147,12 @@ bool TiffWriter::init(FILE *openedFile, int width, int height, int hDPI, int vDP samplesperpixel = 4; photometric = PHOTOMETRIC_SEPARATED; break; + + case RGB48: + samplesperpixel = 3; + bitspersample = 16; + photometric = PHOTOMETRIC_RGB; + break; } // Open the file diff --git a/goo/TiffWriter.h b/goo/TiffWriter.h index 52fdd53e..e347c645 100644 --- a/goo/TiffWriter.h +++ b/goo/TiffWriter.h @@ -31,8 +31,9 @@ public: * GRAY - 1 byte/pixel * MONOCHROME - 8 pixels/byte * CMYK - 4 bytes/pixel + * RGB48 - 6 bytes/pixel */ - enum Format { RGB, RGBA_PREMULTIPLIED, GRAY, MONOCHROME, CMYK }; + enum Format { RGB, RGBA_PREMULTIPLIED, GRAY, MONOCHROME, CMYK, RGB48 }; TiffWriter(Format format = RGB); ~TiffWriter(); diff --git a/poppler/GfxState.h b/poppler/GfxState.h index 38888717..e0872f7d 100644 --- a/poppler/GfxState.h +++ b/poppler/GfxState.h @@ -132,6 +132,10 @@ static inline Guchar colToByte(GfxColorComp x) { return (Guchar)(((x << 8) - x + 0x8000) >> 16); } +static inline Gushort colToShort(GfxColorComp x) { + return (Gushort)(x); +} + //------------------------------------------------------------------------ // GfxColor //------------------------------------------------------------------------ diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc index 5de51ad5..c302a677 100644 --- a/utils/ImageOutputDev.cc +++ b/utils/ImageOutputDev.cc @@ -349,7 +349,11 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const str->reset(); } - row = (unsigned char *) gmallocn(width, sizeof(unsigned int)); + int pixelSize = sizeof(unsigned int); + if (format == imgRGB48) + pixelSize = 2*sizeof(unsigned int); + + row = (unsigned char *) gmallocn(width, pixelSize); // PDF masks use 0 = draw current color, 1 = leave unchanged. // We invert this to provide the standard interpretation of alpha @@ -362,6 +366,7 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const invert_bits = 0x00; } + Gushort *rowp16; // for each line... for (int y = 0; y < height; y++) { switch (format) { @@ -384,6 +389,25 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const writer->writeRow(&row); break; + case imgRGB48: + p = imgStr->getLine(); + rowp16 = (Gushort*)row; + for (int x = 0; x < width; ++x) { + if (p) { + colorMap->getRGB(p, &rgb); + *rowp16++ = colToShort(rgb.r); + *rowp16++ = colToShort(rgb.g); + *rowp16++ = colToShort(rgb.b); + p += colorMap->getNumPixelComps(); + } else { + *rowp16++ = 0; + *rowp16++ = 0; + *rowp16++ = 0; + } + } + writer->writeRow(&row); + break; + case imgCMYK: p = imgStr->getLine(); rowp = row; @@ -532,6 +556,12 @@ void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str, colorMap->getColorSpace()->getMode() == csCalGray) { writer = new PNGWriter(PNGWriter::GRAY); format = imgGray; + } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csCalRGB || + (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3)) && + colorMap->getBits() > 8) { + writer = new PNGWriter(PNGWriter::RGB48); + format = imgRGB48; } else { writer = new PNGWriter(PNGWriter::RGB); format = imgRGB; @@ -557,6 +587,12 @@ void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str, (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 4)) { writer = new TiffWriter(TiffWriter::CMYK); format = imgCMYK; + } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csCalRGB || + (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3)) && + colorMap->getBits() > 8) { + writer = new TiffWriter(TiffWriter::RGB48); + format = imgRGB48; } else { writer = new TiffWriter(TiffWriter::RGB); format = imgRGB; diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h index a694bbc5..668bb08f 100644 --- a/utils/ImageOutputDev.h +++ b/utils/ImageOutputDev.h @@ -55,6 +55,7 @@ public: }; enum ImageFormat { imgRGB, + imgRGB48, imgGray, imgMonochrome, imgCMYK -- 2.11.0