[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h poppler/JBIG2Stream.cc poppler/JBIG2Stream.h poppler/Stream.cc
Adrian Johnson
ajohnson at kemper.freedesktop.org
Fri Jan 23 03:55:11 PST 2015
poppler/CairoOutputDev.cc | 117 ++++++++++++++++++++++++++++++++++++++--------
poppler/CairoOutputDev.h | 3 +
poppler/JBIG2Stream.cc | 9 ++-
poppler/JBIG2Stream.h | 4 +
poppler/Stream.cc | 13 ++++-
5 files changed, 121 insertions(+), 25 deletions(-)
New commits:
commit f932315e559a7857d9c5642eb04efc0d2b717789
Author: suzuki toshiya <mpsuzuki at hiroshima-u.ac.jp>
Date: Tue Jan 20 22:05:29 2015 +1030
cairo: support embedding JBIG2 image data
http://lists.freedesktop.org/archives/poppler/2014-December/011183.html
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 4e8abcf..a770320 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 8de391a..cc29846 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 0695dc5..8e1c12f 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 0ee2518..7ffc441 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 4c00ddb..8996e29 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")) {
More information about the poppler
mailing list