diff options
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc | 208 |
1 files changed, 197 insertions, 11 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc index 3f6b1a1d49f..2e9b1390db9 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc @@ -16,7 +16,9 @@ #include <stdlib.h> #include <stddef.h> #include <ctype.h> +#include <math.h> #include "gmem.h" +#include "gmempp.h" #include "config.h" #include "Error.h" #include "GfxState.h" @@ -24,11 +26,15 @@ #include "Stream.h" #include "ImageOutputDev.h" -ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA) { +ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA, + GBool dumpRawA, GBool listA) { fileRoot = copyString(fileRootA); - fileName = (char *)gmalloc((int)strlen(fileRoot) + 20); + fileName = (char *)gmalloc((int)strlen(fileRoot) + 30); dumpJPEG = dumpJPEGA; + dumpRaw = dumpRawA; + list = listA; imgNum = 0; + curPageNum = 0; ok = gTrue; } @@ -37,9 +43,14 @@ ImageOutputDev::~ImageOutputDev() { gfree(fileRoot); } +void ImageOutputDev::startPage(int pageNum, GfxState *state) { + curPageNum = pageNum; +} + void ImageOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef, - int paintType, Dict *resDict, + int paintType, int tilingType, + Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) { @@ -53,8 +64,32 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, char buf[4096]; int size, n, i; + // dump raw file + if (dumpRaw && !inlineImg) { + + // open the image file + sprintf(fileName, "%s-%04d.%s", + fileRoot, imgNum, getRawFileExtension(str)); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(errIO, -1, "Couldn't open image file '{0:s}'", fileName); + return; + } + + // initialize stream + str = getRawStream(str); + str->reset(); + + // copy the stream + while ((n = str->getBlock(buf, sizeof(buf))) > 0) { + fwrite(buf, 1, n, f); + } + + str->close(); + fclose(f); + // dump JPEG file - if (dumpJPEG && str->getKind() == strDCT && !inlineImg) { + } else if (dumpJPEG && str->getKind() == strDCT && !inlineImg) { // open the image file sprintf(fileName, "%s-%04d.jpg", fileRoot, imgNum); @@ -107,6 +142,10 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, str->close(); fclose(f); } + + if (list) { + writeImageInfo(width, height, state, NULL); + } } void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, @@ -114,19 +153,51 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, GfxImageColorMap *colorMap, int *maskColors, GBool inlineImg, GBool interpolate) { + GfxColorSpaceMode csMode; FILE *f; ImageStream *imgStr; Guchar *p; GfxRGB rgb; + GfxGray gray; int x, y; char buf[4096]; - int size, n, i; + int size, n, i, j; + + csMode = colorMap->getColorSpace()->getMode(); + if (csMode == csIndexed) { + csMode = ((GfxIndexedColorSpace *)colorMap->getColorSpace()) + ->getBase()->getMode(); + } + + // dump raw file + if (dumpRaw && !inlineImg) { + + // open the image file + sprintf(fileName, "%s-%04d.%s", + fileRoot, imgNum, getRawFileExtension(str)); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(errIO, -1, "Couldn't open image file '{0:s}'", fileName); + return; + } + + // initialize stream + str = getRawStream(str); + str->reset(); + + // copy the stream + while ((n = str->getBlock(buf, sizeof(buf))) > 0) { + fwrite(buf, 1, n, f); + } + + str->close(); + fclose(f); // dump JPEG file - if (dumpJPEG && str->getKind() == strDCT && - (colorMap->getNumPixelComps() == 1 || - colorMap->getNumPixelComps() == 3) && - !inlineImg) { + } else if (dumpJPEG && str->getKind() == strDCT && + (colorMap->getNumPixelComps() == 1 || + colorMap->getNumPixelComps() == 3) && + !inlineImg) { // open the image file sprintf(fileName, "%s-%04d.jpg", fileRoot, imgNum); @@ -170,6 +241,9 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, while (size > 0) { i = size < (int)sizeof(buf) ? size : (int)sizeof(buf); n = str->getBlock(buf, i); + for (j = 0; j < n; ++j) { + buf[j] ^= 0xff; + } fwrite(buf, 1, n, f); if (n < i) { break; @@ -180,6 +254,48 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, str->close(); fclose(f); + // dump PGM file + } else if (colorMap->getNumPixelComps() == 1 && + (csMode == csDeviceGray || csMode == csCalGray)) { + + // open the image file and write the PGM header + sprintf(fileName, "%s-%04d.pgm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(errIO, -1, "Couldn't open image file '{0:s}'", fileName); + return; + } + fprintf(f, "P5\n"); + fprintf(f, "%d %d\n", width, height); + fprintf(f, "255\n"); + + // initialize stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // for each line... + for (y = 0; y < height; ++y) { + + // write the line + if ((p = imgStr->getLine())) { + for (x = 0; x < width; ++x) { + colorMap->getGray(p, &gray, state->getRenderingIntent()); + fputc(colToByte(gray), f); + ++p; + } + } else { + for (x = 0; x < width; ++x) { + fputc(0, f); + } + } + } + + imgStr->close(); + delete imgStr; + + fclose(f); + // dump PPM file } else { @@ -205,7 +321,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, // write the line if ((p = imgStr->getLine())) { for (x = 0; x < width; ++x) { - colorMap->getRGB(p, &rgb); + colorMap->getRGB(p, &rgb, state->getRenderingIntent()); fputc(colToByte(rgb.r), f); fputc(colToByte(rgb.g), f); fputc(colToByte(rgb.b), f); @@ -225,6 +341,10 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, fclose(f); } + + if (list) { + writeImageInfo(width, height, state, colorMap); + } } void ImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, @@ -246,9 +366,75 @@ void ImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap, - GBool interpolate) { + double *matte, GBool interpolate) { drawImage(state, ref, str, width, height, colorMap, NULL, gFalse, interpolate); drawImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap, NULL, gFalse, interpolate); } + +Stream *ImageOutputDev::getRawStream(Stream *str) { + switch (str->getKind()) { + case strLZW: + case strRunLength: + case strCCITTFax: + case strDCT: + case strFlate: + case strJBIG2: + case strJPX: + return ((FilterStream *)str)->getNextStream(); + default: + return str; + } +} + +const char *ImageOutputDev::getRawFileExtension(Stream *str) { + switch (str->getKind()) { + case strLZW: return "lzw"; + case strRunLength: return "rle"; + case strCCITTFax: return "fax"; + case strDCT: return "jpg"; + case strFlate: return "flate"; + case strJBIG2: return "jb2"; + case strJPX: return "jpx"; + default: return "unknown"; + } +} + +void ImageOutputDev::writeImageInfo(int width, int height, GfxState *state, + GfxImageColorMap *colorMap) { + const char *mode; + double hdpi, vdpi, x0, y0, x1, y1; + int bpc; + + // this works for 0/90/180/270-degree rotations, along with + // horizontal/vertical flips + state->transformDelta(1, 0, &x0, &y0); + state->transformDelta(0, 1, &x1, &y1); + x0 = fabs(x0); + y0 = fabs(y0); + x1 = fabs(x1); + y1 = fabs(y1); + if (x0 > y0) { + hdpi = (72 * width) / x0; + vdpi = (72 * height) / y1; + } else { + hdpi = (72 * height) / x1; + vdpi = (72 * width) / y0; + } + + if (colorMap) { + mode = GfxColorSpace::getColorSpaceModeName( + colorMap->getColorSpace()->getMode()); + bpc = colorMap->getBits(); + } else { + mode = NULL; + bpc = 1; + } + + printf("%s: page=%d width=%d height=%d hdpi=%.2f vdpi=%.2f %s%s bpc=%d\n", + fileName, curPageNum, width, height, hdpi, vdpi, + mode ? "colorspace=" : "mask", + mode ? mode : "", + bpc); +} |