[poppler] poppler/JPEG2000Stream.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Sat Mar 12 02:52:33 UTC 2016


 poppler/JPEG2000Stream.cc |   77 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 61 insertions(+), 16 deletions(-)

New commits:
commit 2dcfefb43c0d4ca86a4f4b2d019882e134201b27
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Sat Mar 12 03:52:01 2016 +0100

    handle SMaskInData = 0 for JPX encoded images
    
    Bug #93468

diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index a6763e0..7daa23d 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.");
   }


More information about the poppler mailing list