poppler/JPEG2000Stream.cc | 37 ++++++++++++++++++++++++++++++++++++- poppler/JPEG2000Stream.h | 36 +++++++++++------------------------- 2 files changed, 47 insertions(+), 26 deletions(-)
New commits: commit 300900afa2140141748a7571270be5d850274072 Author: Daniel Glöckner <[email protected]> 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 <[email protected]> +// Copyright 2011 Daniel Glöckner <[email protected]> // // 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 <[email protected]> +// Copyright 2011 Daniel Glöckner <[email protected]> // // 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; };
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
