summaryrefslogtreecommitdiff
path: root/poppler/JPEG2000Stream.cc
diff options
context:
space:
mode:
authorThomas Freitag <Thomas.Freitag@alfa.de>2016-03-12 03:52:01 +0100
committerAlbert Astals Cid <aacid@kde.org>2016-03-12 03:52:01 +0100
commit2dcfefb43c0d4ca86a4f4b2d019882e134201b27 (patch)
treec0210f9f7c4d7cef3289c9530ca0067b4d8b76d8 /poppler/JPEG2000Stream.cc
parente58d310c1802b77a6356ec0d3d0180a2a1605b41 (diff)
handle SMaskInData = 0 for JPX encoded images
Bug #93468
Diffstat (limited to 'poppler/JPEG2000Stream.cc')
-rw-r--r--poppler/JPEG2000Stream.cc77
1 files changed, 61 insertions, 16 deletions
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index a6763e0d..7daa23d6 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -43,12 +43,13 @@ struct JPXStreamPrivate {
int ncomps;
GBool indexed;
GBool inited;
+ int smaskInData;
#ifdef USE_OPENJPEG1
opj_dinfo_t *dinfo;
- void init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format);
+ void init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format, GBool indexed);
#endif
#ifdef USE_OPENJPEG2
- void init2(OPJ_CODEC_FORMAT format, unsigned char *data, int length);
+ void init2(OPJ_CODEC_FORMAT format, unsigned char *data, int length, GBool indexed);
#endif
};
@@ -159,9 +160,21 @@ void JPXStream::getImageParams(int *bitsPerComponent, StreamColorSpaceMode *csMo
if (unlikely(priv->inited == gFalse)) { init(); }
*bitsPerComponent = 8;
- if (priv->image && priv->image->numcomps == 3)
+ int numComps = (priv->image) ? priv->image->numcomps : 1;
+ if (priv->image) {
+#ifdef USE_OPENJPEG1
+ if (priv->image->color_space == CLRSPC_SRGB && numComps == 4) { numComps = 3; }
+ else if (priv->image->color_space == CLRSPC_SYCC && numComps == 4) { numComps = 3; }
+#else
+ if (priv->image->color_space == OPJ_CLRSPC_SRGB && numComps == 4) { numComps = 3; }
+ else if (priv->image->color_space == OPJ_CLRSPC_SYCC && numComps == 4) { numComps = 3; }
+#endif
+ else if (numComps == 2) { numComps = 1; }
+ else if (numComps > 4) { numComps = 4; }
+ }
+ if (numComps == 3)
*csMode = streamCSDeviceRGB;
- else if (priv->image && priv->image->numcomps == 4)
+ else if (numComps == 4)
*csMode = streamCSDeviceCMYK;
else
*csMode = streamCSDeviceGray;
@@ -182,9 +195,10 @@ static void libopenjpeg_warning_callback(const char *msg, void * /*client_data*/
void JPXStream::init()
{
- Object oLen, cspace;
+ Object oLen, cspace, smaskInData;
if (getDict()) getDict()->lookup("Length", &oLen);
if (getDict()) getDict()->lookup("ColorSpace", &cspace);
+ if (getDict()) getDict()->lookup("SMaskInData", &smaskInData);
int bufSize = BUFFER_INITIAL_SIZE;
if (oLen.isInt()) bufSize = oLen.getInt();
@@ -198,14 +212,28 @@ void JPXStream::init()
}
cspace.free();
+ priv->smaskInData = 0;
+ if (smaskInData.isInt()) priv->smaskInData = smaskInData.getInt();
+ smaskInData.free();
+
int length = 0;
unsigned char *buf = str->toUnsignedChars(&length, bufSize);
- priv->init2(buf, length, CODEC_JP2);
+ priv->init2(buf, length, CODEC_JP2, priv->indexed);
free(buf);
if (priv->image) {
+ int numComps = (priv->image) ? priv->image->numcomps : 1;
+ int alpha = 0;
+ if (priv->image) {
+ if (priv->image->color_space == CLRSPC_SRGB && numComps == 4) { numComps = 3; alpha = 1; }
+ else if (priv->image->color_space == CLRSPC_SYCC && numComps == 4) { numComps = 3; alpha = 1; }
+ else if (numComps == 2) { numComps = 1; alpha = 1; }
+ else if (numComps > 4) { numComps = 4; alpha = 1; }
+ else { alpha = 0; }
+ }
priv->npixels = priv->image->comps[0].w * priv->image->comps[0].h;
priv->ncomps = priv->image->numcomps;
+ if (alpha == 1 && priv->smaskInData == 0) priv->ncomps--;
for (int component = 0; component < priv->ncomps; component++) {
if (priv->image->comps[component].data == NULL) {
close();
@@ -232,7 +260,7 @@ void JPXStream::init()
priv->inited = gTrue;
}
-void JPXStreamPrivate::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format)
+void JPXStreamPrivate::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format, GBool indexed)
{
opj_cio_t *cio = NULL;
@@ -240,7 +268,8 @@ void JPXStreamPrivate::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT fo
opj_dparameters_t parameters;
opj_set_default_decoder_parameters(&parameters);
#ifdef WITH_OPENJPEG_IGNORE_PCLR_CMAP_CDEF_FLAG
- parameters.flags = OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+ if (indexed)
+ parameters.flags = OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
#endif
/* Configure the event manager to receive errors and warnings */
@@ -274,10 +303,10 @@ void JPXStreamPrivate::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT fo
error:
if (format == CODEC_JP2) {
error(errSyntaxWarning, -1, "Did not succeed opening JPX Stream as JP2, trying as J2K.");
- init2(buf, bufLen, CODEC_J2K);
+ init2(buf, bufLen, CODEC_J2K, indexed);
} else if (format == CODEC_J2K) {
error(errSyntaxWarning, -1, "Did not succeed opening JPX Stream as J2K, trying as JPT.");
- init2(buf, bufLen, CODEC_JPT);
+ init2(buf, bufLen, CODEC_JPT, indexed);
} else {
error(errSyntaxError, -1, "Did not succeed opening JPX Stream.");
}
@@ -333,9 +362,10 @@ static OPJ_BOOL jpxSeek_callback(OPJ_OFF_T seek_pos, void * p_user_data)
void JPXStream::init()
{
- Object oLen, cspace;
+ Object oLen, cspace, smaskInData;
if (getDict()) getDict()->lookup("Length", &oLen);
if (getDict()) getDict()->lookup("ColorSpace", &cspace);
+ if (getDict()) getDict()->lookup("SMaskInData", &smaskInData);
int bufSize = BUFFER_INITIAL_SIZE;
if (oLen.isInt()) bufSize = oLen.getInt();
@@ -349,14 +379,28 @@ void JPXStream::init()
}
cspace.free();
+ priv->smaskInData = 0;
+ if (smaskInData.isInt()) priv->smaskInData = smaskInData.getInt();
+ smaskInData.free();
+
int length = 0;
unsigned char *buf = str->toUnsignedChars(&length, bufSize);
- priv->init2(OPJ_CODEC_JP2, buf, length);
+ priv->init2(OPJ_CODEC_JP2, buf, length, priv->indexed);
gfree(buf);
if (priv->image) {
+ int numComps = (priv->image) ? priv->image->numcomps : 1;
+ int alpha = 0;
+ if (priv->image) {
+ if (priv->image->color_space == OPJ_CLRSPC_SRGB && numComps == 4) { numComps = 3; alpha = 1; }
+ else if (priv->image->color_space == OPJ_CLRSPC_SYCC && numComps == 4) { numComps = 3; alpha = 1; }
+ else if (numComps == 2) { numComps = 1; alpha = 1; }
+ else if (numComps > 4) { numComps = 4; alpha = 1; }
+ else { alpha = 0; }
+ }
priv->npixels = priv->image->comps[0].w * priv->image->comps[0].h;
priv->ncomps = priv->image->numcomps;
+ if (alpha == 1 && priv->smaskInData == 0) priv->ncomps--;
for (int component = 0; component < priv->ncomps; component++) {
if (priv->image->comps[component].data == NULL) {
close();
@@ -384,7 +428,7 @@ void JPXStream::init()
priv->inited = gTrue;
}
-void JPXStreamPrivate::init2(OPJ_CODEC_FORMAT format, unsigned char *buf, int length)
+void JPXStreamPrivate::init2(OPJ_CODEC_FORMAT format, unsigned char *buf, int length, GBool indexed)
{
JPXData jpxData;
@@ -413,7 +457,8 @@ void JPXStreamPrivate::init2(OPJ_CODEC_FORMAT format, unsigned char *buf, int le
/* Use default decompression parameters */
opj_dparameters_t parameters;
opj_set_default_decoder_parameters(&parameters);
- parameters.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+ if (indexed)
+ parameters.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
/* Get the decoder handle of the format */
decoder = opj_create_decompress(format);
@@ -462,10 +507,10 @@ error:
opj_destroy_codec(decoder);
if (format == OPJ_CODEC_JP2) {
error(errSyntaxWarning, -1, "Did no succeed opening JPX Stream as JP2, trying as J2K.");
- init2(OPJ_CODEC_J2K, buf, length);
+ init2(OPJ_CODEC_J2K, buf, length, indexed);
} else if (format == OPJ_CODEC_J2K) {
error(errSyntaxWarning, -1, "Did no succeed opening JPX Stream as J2K, trying as JPT.");
- init2(OPJ_CODEC_JPT, buf, length);
+ init2(OPJ_CODEC_JPT, buf, length, indexed);
} else {
error(errSyntaxError, -1, "Did no succeed opening JPX Stream.");
}