From 3a13817da1fff5244267bbc7dee178ac665de4e0 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Fri, 21 Apr 2017 19:23:07 +0930 Subject: [PATCH] pdfimages: don't fail listing if inline image data contains 'EI' Normally when listing images we don't read the image data. But for inline images we should read the image data to advance the stream position to the end of the image data. If we don't advance the stream position and the image data happens to contain 'EI', Gfx will resume reading the content stream from the middle of the image data. Bug 100737 --- utils/ImageOutputDev.cc | 61 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc index 00b5a679..069d8210 100644 --- a/utils/ImageOutputDev.cc +++ b/utils/ImageOutputDev.cc @@ -288,6 +288,26 @@ void ImageOutputDev::listImage(GfxState *state, Object *ref, Stream *str, printf(" - \n"); ++imgNum; + + if (inlineImg) { + // For inline images we need to advance the stream position to the end of the image + // as Gfx needs to continue reading content after the image data. + ImageFormat format; + if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) { + format = imgMonochrome; + } else if (colorMap->getColorSpace()->getMode() == csDeviceGray || + colorMap->getColorSpace()->getMode() == csCalGray) { + format = imgGray; + } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csCalRGB || + (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3)) && + colorMap->getBits() > 8) { + format = imgRGB48; + } else { + format = imgRGB; + } + writeImageFile(NULL, format, "", str, width, height, colorMap); + } } void ImageOutputDev::writeRawImage(Stream *str, const char *ext) { @@ -327,16 +347,18 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const Guchar zero = 0; int invert_bits; - setFilename(ext); - ++imgNum; - if (!(f = fopen(fileName, "wb"))) { - error(errIO, -1, "Couldn't open image file '{0:s}'", fileName); - return; - } + if (writer) { + setFilename(ext); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(errIO, -1, "Couldn't open image file '{0:s}'", fileName); + return; + } - if (!writer->init(f, width, height, 72, 72)) { - error(errIO, -1, "Error writing '{0:s}'", fileName); - return; + if (!writer->init(f, width, height, 72, 72)) { + error(errIO, -1, "Error writing '{0:s}'", fileName); + return; + } } if (format != imgMonochrome) { @@ -385,7 +407,8 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const *rowp++ = 0; } } - writer->writeRow(&row); + if (writer) + writer->writeRow(&row); break; case imgRGB48: { @@ -404,7 +427,8 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const *rowp16++ = 0; } } - writer->writeRow(&row); + if (writer) + writer->writeRow(&row); break; } @@ -426,7 +450,8 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const *rowp++ = 0; } } - writer->writeRow(&row); + if (writer) + writer->writeRow(&row); break; case imgGray: @@ -441,14 +466,16 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const *rowp++ = 0; } } - writer->writeRow(&row); + if (writer) + writer->writeRow(&row); break; case imgMonochrome: int size = (width + 7)/8; for (int x = 0; x < size; x++) row[x] = str->getChar() ^ invert_bits; - writer->writeRow(&row); + if (writer) + writer->writeRow(&row); break; } } @@ -459,8 +486,10 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const delete imgStr; } str->close(); - writer->close(); - fclose(f); + if (writer) { + writer->close(); + fclose(f); + } } void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str, -- 2.11.0