diff options
-rw-r--r-- | poppler/CairoOutputDev.cc | 117 | ||||
-rw-r--r-- | poppler/CairoOutputDev.h | 3 | ||||
-rw-r--r-- | poppler/JBIG2Stream.cc | 9 | ||||
-rw-r--r-- | poppler/JBIG2Stream.h | 4 | ||||
-rw-r--r-- | poppler/Stream.cc | 13 |
5 files changed, 121 insertions, 25 deletions
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 4e8abcfd..a7703207 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -63,6 +63,7 @@ #include "CairoFontEngine.h" #include "CairoRescaleBox.h" #include "UnicodeMap.h" +#include "JBIG2Stream.h" //------------------------------------------------------------------------ // #define LOG_CAIRO @@ -2701,6 +2702,68 @@ static GBool colorMapHasIdentityDecodeMap(GfxImageColorMap *colorMap) return gTrue; } +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) +static cairo_status_t setMimeIdFromRef(cairo_surface_t *surface, + const char *mime_type, + const char *mime_id_prefix, + Ref ref) +{ + GooString *mime_id; + char *idBuffer; + cairo_status_t status; + + mime_id = new GooString; + + if (mime_id_prefix) + mime_id->append(mime_id_prefix); + + mime_id->appendf("{0:d}-{1:d}", ref.gen, ref.num); + + idBuffer = copyString(mime_id->getCString()); + status = cairo_surface_set_mime_data (surface, mime_type, + (const unsigned char *)idBuffer, + mime_id->getLength(), + gfree, idBuffer); + delete mime_id; + if (status) + gfree (idBuffer); + return status; +} +#endif + +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) +GBool CairoOutputDev::setMimeDataForJBIG2Globals(Stream *str, + cairo_surface_t *image) +{ + JBIG2Stream *jb2Str = static_cast<JBIG2Stream *>(str); + Object* globalsStr = jb2Str->getGlobalsStream(); + char *globalsBuffer; + int globalsLength; + + // nothing to do for JBIG2 stream without Globals + if (!globalsStr->isStream()) + return gTrue; + + if (setMimeIdFromRef(image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, NULL, + jb2Str->getGlobalsStreamRef())) + return gFalse; + + if (!getStreamData(globalsStr->getStream(), &globalsBuffer, &globalsLength)) + return gFalse; + + if (cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2_GLOBAL, + (const unsigned char*)globalsBuffer, + globalsLength, + gfree, (void*)globalsBuffer)) + { + gfree (globalsBuffer); + return gFalse; + } + + return gTrue; +} +#endif + void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, GfxImageColorMap *colorMap, cairo_surface_t *image) { @@ -2708,17 +2771,35 @@ void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, int len; Object obj; GfxColorSpace *colorSpace; + StreamKind strKind = str->getKind(); + const char *mime_type; - if (!printing || !(str->getKind() == strDCT || str->getKind() == strJPX)) + if (!printing) return; + switch (strKind) { + case strDCT: + mime_type = CAIRO_MIME_TYPE_JPEG; + break; + case strJPX: + mime_type = CAIRO_MIME_TYPE_JP2; + break; +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + case strJBIG2: + mime_type = CAIRO_MIME_TYPE_JBIG2; + break; +#endif + default: + return; + } + str->getDict()->lookup("ColorSpace", &obj); colorSpace = GfxColorSpace::parse(NULL, &obj, this, state); obj.free(); // colorspace in stream dict may be different from colorspace in jpx // data - if (str->getKind() == strJPX && colorSpace) + if (strKind == strJPX && colorSpace) return; // only embed mime data for gray, rgb, and cmyk colorspaces. @@ -2746,31 +2827,27 @@ void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, if (!colorMapHasIdentityDecodeMap(colorMap)) return; +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + if (strKind == strJBIG2 && !setMimeDataForJBIG2Globals(str, image)) + return; +#endif + if (getStreamData (str->getNextStream(), &strBuffer, &len)) { - cairo_status_t st; + cairo_status_t status = CAIRO_STATUS_SUCCESS; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) if (ref && ref->isRef()) { - Ref imgRef = ref->getRef(); - GooString *surfaceId = new GooString("poppler-surface-"); - surfaceId->appendf("{0:d}-{1:d}", imgRef.gen, imgRef.num); - char *idBuffer = copyString(surfaceId->getCString()); - st = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_UNIQUE_ID, - (const unsigned char *)idBuffer, - surfaceId->getLength(), - gfree, idBuffer); - if (st) - gfree(idBuffer); - delete surfaceId; + status = setMimeIdFromRef(image, CAIRO_MIME_TYPE_UNIQUE_ID, + "poppler-surface-", ref->getRef()); } #endif + if (!status) { + status = cairo_surface_set_mime_data (image, mime_type, + (const unsigned char *)strBuffer, len, + gfree, strBuffer); + } - st = cairo_surface_set_mime_data (image, - str->getKind() == strDCT ? - CAIRO_MIME_TYPE_JPEG : CAIRO_MIME_TYPE_JP2, - (const unsigned char *)strBuffer, len, - gfree, strBuffer); - if (st) + if (status) gfree (strBuffer); } } diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 8de391ae..cc298466 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -280,6 +280,9 @@ protected: GfxImageColorMap *colorMap, cairo_surface_t *image); void fillToStrokePathClip(GfxState *state); void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + GBool setMimeDataForJBIG2Globals (Stream *str, cairo_surface_t *image); +#endif GfxRGB fill_color, stroke_color; cairo_pattern_t *fill_pattern, *stroke_pattern; diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc index 0695dc5d..8e1c12f7 100644 --- a/poppler/JBIG2Stream.cc +++ b/poppler/JBIG2Stream.cc @@ -1168,7 +1168,7 @@ JBIG2CodeTable::~JBIG2CodeTable() { // JBIG2Stream //------------------------------------------------------------------------ -JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA): +JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA, Object *globalsStreamRefA): FilterStream(strA) { pageBitmap = NULL; @@ -1193,7 +1193,12 @@ JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA): huffDecoder = new JBIG2HuffmanDecoder(); mmrDecoder = new JBIG2MMRDecoder(); - globalsStreamA->copy(&globalsStream); + if (globalsStreamA->isStream()) { + globalsStreamA->copy(&globalsStream); + if (globalsStreamRefA->isRef()) + globalsStreamRef = globalsStreamRefA->getRef(); + } + segments = globalSegments = NULL; curStr = NULL; dataPtr = dataEnd = NULL; diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h index 0ee25185..7ffc441d 100644 --- a/poppler/JBIG2Stream.h +++ b/poppler/JBIG2Stream.h @@ -46,7 +46,7 @@ class JBIG2MMRDecoder; class JBIG2Stream: public FilterStream { public: - JBIG2Stream(Stream *strA, Object *globalsStreamA); + JBIG2Stream(Stream *strA, Object *globalsStreamA, Object *globalsStreamRefA); virtual ~JBIG2Stream(); virtual StreamKind getKind() { return strJBIG2; } virtual void reset(); @@ -57,6 +57,7 @@ public: virtual GooString *getPSFilter(int psLevel, const char *indent); virtual GBool isBinary(GBool last = gTrue); virtual Object *getGlobalsStream() { return &globalsStream; } + virtual Ref getGlobalsStreamRef() { return globalsStreamRef; } private: virtual GBool hasGetChars() { return true; } @@ -132,6 +133,7 @@ private: GBool readLong(int *x); Object globalsStream; + Ref globalsStreamRef; Guint pageW, pageH, curPageH; Guint pageDefPixel; JBIG2Bitmap *pageBitmap; diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 4c00ddb0..8996e296 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -59,6 +59,7 @@ #include "Lexer.h" #include "GfxState.h" #include "Stream.h" +#include "XRef.h" #include "JBIG2Stream.h" #include "Stream-CCITT.h" #include "CachedFile.h" @@ -337,10 +338,18 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params, int recursio str = new FlateStream(str, pred, columns, colors, bits); } else if (!strcmp(name, "JBIG2Decode")) { if (params->isDict()) { - params->dictLookup("JBIG2Globals", &globals, recursion); + XRef *xref = params->getDict()->getXRef(); + params->dictLookupNF("JBIG2Globals", &globals); + while (globals.isRef()) { + obj.free(); + globals.copy(&obj); + globals.free(); + obj.fetch(xref, &globals); + } } - str = new JBIG2Stream(str, &globals); + str = new JBIG2Stream(str, &globals, &obj); globals.free(); + obj.free(); } else if (!strcmp(name, "JPXDecode")) { str = new JPXStream(str); } else if (!strcmp(name, "Crypt")) { |