[poppler] poppler/JPEG2000Stream.cc poppler/JPEG2000Stream.h

Albert Astals Cid aacid at kemper.freedesktop.org
Sat Jul 23 10:57:01 PDT 2011


 poppler/JPEG2000Stream.cc |   37 ++++++++++++++++++++++++++++++++++++-
 poppler/JPEG2000Stream.h  |   36 +++++++++++-------------------------
 2 files changed, 47 insertions(+), 26 deletions(-)

New commits:
commit 300900afa2140141748a7571270be5d850274072
Author: Daniel Glöckner <daniel-gl at gmx.net>
Date:   Sat Jul 23 19:49:15 2011 +0200

    Fix numerical overflow in libopenjpeg JPXStream::doLookChar()
    
    It also includes a speed optimization. Bug 39361

diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index d52f088..b7a29bf 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -5,6 +5,7 @@
 // A JPX stream decoder using OpenJPEG
 //
 // Copyright 2008-2010 Albert Astals Cid <aacid at kde.org>
+// Copyright 2011 Daniel Glöckner <daniel-gl at gmx.net>
 //
 // Licensed under GPLv2 or later
 //
@@ -17,6 +18,8 @@ JPXStream::JPXStream(Stream *strA) : FilterStream(strA)
   inited = gFalse;
   image = NULL;
   dinfo = NULL;
+  npixels = 0;
+  ncomps = 0;
 }
 
 JPXStream::~JPXStream() {
@@ -26,12 +29,14 @@ JPXStream::~JPXStream() {
 
 void JPXStream::reset() {
   counter = 0;
+  ccounter = 0;
 }
 
 void JPXStream::close() {
   if (image != NULL) {
     opj_image_destroy(image);
     image = NULL;
+    npixels = 0;
   }
   if (dinfo != NULL) {
     opj_destroy_decompress(dinfo);
@@ -40,7 +45,7 @@ void JPXStream::close() {
 }
 
 int JPXStream::getPos() {
-  return counter;
+  return counter * ncomps + ccounter;
 }
 
 int JPXStream::getChars(int nChars, Guchar *buffer) {
@@ -73,7 +78,37 @@ void JPXStream::init()
   init2(buf, length, CODEC_JP2);
   free(buf);
 
+  if (image) {
+    npixels = image->comps[0].w * image->comps[0].h;
+    ncomps = image->numcomps;
+    for (int component = 0; component < ncomps; component++) {
+      if (image->comps[component].data == NULL) {
+        close();
+        break;
+      }
+      unsigned char *cdata = (unsigned char *)image->comps[component].data;
+      int adjust = 0;
+      if (image->comps[component].prec > 8)
+	adjust = image->comps[component].prec - 8;
+      int sgndcorr = 0;
+      if (image->comps[component].sgnd)
+	sgndcorr = 1 << (image->comps[0].prec - 1);
+      for (int i = 0; i < npixels; i++) {
+	int r = image->comps[component].data[i];
+	r += sgndcorr;
+	if (adjust) {
+	  r = (r >> adjust)+((r >> (adjust-1))%2);
+	  if (unlikely(r > 255))
+	    r = 255;
+        }
+	*(cdata++) = r;
+      }
+    }
+  } else
+    npixels = 0;
+
   counter = 0;
+  ccounter = 0;
   inited = gTrue;
 }
 
diff --git a/poppler/JPEG2000Stream.h b/poppler/JPEG2000Stream.h
index bda2721..bb4085a 100644
--- a/poppler/JPEG2000Stream.h
+++ b/poppler/JPEG2000Stream.h
@@ -5,6 +5,7 @@
 // A JPX stream decoder using OpenJPEG
 //
 // Copyright 2008, 2010 Albert Astals Cid <aacid at kde.org>
+// Copyright 2011 Daniel Glöckner <daniel-gl at gmx.net>
 //
 // Licensed under GPLv2 or later
 //
@@ -44,42 +45,27 @@ private:
 
   inline int doGetChar() {
     int result = doLookChar();
-    ++counter;
+    if (++ccounter == ncomps) {
+      ccounter = 0;
+      ++counter;
+    }
     return result;
   }
 
   inline int doLookChar() {
-    if (inited == gFalse) init();
-
-    if (!image) return EOF;
-
-    int w = image->comps[0].w;
-    int h = image->comps[0].h;
-
-    int y = (counter / image->numcomps) / w;
-    int x = (counter / image->numcomps) % w;
-    if (y >= h) return EOF;
-
-    int component = counter % image->numcomps;
-
-    int adjust = 0;
-    if (image->comps[component].prec > 8) {
-      adjust = image->comps[component].prec - 8;
-    }
-
-    if (unlikely(image->comps[component].data == NULL)) return EOF;
-
-    int r = image->comps[component].data[y * w + x];
-    r += (image->comps[component].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+    if (unlikely(inited == gFalse)) init();
 
-    unsigned char rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
+    if (unlikely(counter >= npixels)) return EOF;
 
-    return rc;
+    return ((unsigned char *)image->comps[ccounter].data)[counter];
   }
 
   opj_image_t *image;
   opj_dinfo_t *dinfo;
   int counter;
+  int ccounter;
+  int npixels;
+  int ncomps;
   GBool inited;
 };
 


More information about the poppler mailing list