Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-04-20 11:36:58 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-04-20 11:36:58 +0300
commit75c9fe428fa8ed1dec093de6a7b2dc6ca042f6d6 (patch)
tree7c7c2ea8da401497a63fa7f66cdbe6756b039958
parent81a477f4dc999918ba66413a286f5a0b1c0c4e79 (diff)
Update bundled openjpeg from 1.5.0 to 1.5.2
Solves following issues: - Quite reasonable amount of paranoid warnings were solved by an upstream - Upstream seems to have all fixes needed for FreeBSD and OSX already - Brings all fixes and such from upstream
-rw-r--r--extern/libopenjpeg/bio.c8
-rw-r--r--extern/libopenjpeg/cidx_manager.c2
-rw-r--r--extern/libopenjpeg/cio.c12
-rw-r--r--extern/libopenjpeg/cio.h9
-rw-r--r--extern/libopenjpeg/event.c9
-rw-r--r--extern/libopenjpeg/image.c3
-rw-r--r--extern/libopenjpeg/j2k.c207
-rw-r--r--extern/libopenjpeg/jp2.c265
-rw-r--r--extern/libopenjpeg/openjpeg.h4
-rw-r--r--extern/libopenjpeg/opj_config.h3
-rw-r--r--extern/libopenjpeg/opj_includes.h11
-rw-r--r--extern/libopenjpeg/opj_malloc.h4
-rw-r--r--extern/libopenjpeg/patches/fbsd.patch13
-rw-r--r--extern/libopenjpeg/patches/osx.patch17
-rw-r--r--extern/libopenjpeg/t1.c1
-rw-r--r--extern/libopenjpeg/t2.c52
-rw-r--r--extern/libopenjpeg/tcd.c119
17 files changed, 559 insertions, 180 deletions
diff --git a/extern/libopenjpeg/bio.c b/extern/libopenjpeg/bio.c
index 4c02f464d8d..f04f3e503fb 100644
--- a/extern/libopenjpeg/bio.c
+++ b/extern/libopenjpeg/bio.c
@@ -42,7 +42,7 @@ Write a bit
@param bio BIO handle
@param b Bit to write (0 or 1)
*/
-static void bio_putbit(opj_bio_t *bio, int b);
+static void bio_putbit(opj_bio_t *bio, unsigned int b);
/**
Read a bit
@param bio BIO handle
@@ -78,7 +78,7 @@ static int bio_byteout(opj_bio_t *bio) {
if (bio->bp >= bio->end) {
return 1;
}
- *bio->bp++ = bio->buf >> 8;
+ *bio->bp++ = (unsigned char)(bio->buf >> 8);
return 0;
}
@@ -92,7 +92,7 @@ static int bio_bytein(opj_bio_t *bio) {
return 0;
}
-static void bio_putbit(opj_bio_t *bio, int b) {
+static void bio_putbit(opj_bio_t *bio, unsigned int b) {
if (bio->ct == 0) {
bio_byteout(bio);
}
@@ -126,7 +126,7 @@ void bio_destroy(opj_bio_t *bio) {
}
int bio_numbytes(opj_bio_t *bio) {
- return (bio->bp - bio->start);
+ return (int)(bio->bp - bio->start);
}
void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) {
diff --git a/extern/libopenjpeg/cidx_manager.c b/extern/libopenjpeg/cidx_manager.c
index 6131b938ea6..f3b251ffa09 100644
--- a/extern/libopenjpeg/cidx_manager.c
+++ b/extern/libopenjpeg/cidx_manager.c
@@ -29,8 +29,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <stdio.h>
-#include <stdlib.h>
#include "opj_includes.h"
diff --git a/extern/libopenjpeg/cio.c b/extern/libopenjpeg/cio.c
index b8a7ecf8a87..97cccea6dee 100644
--- a/extern/libopenjpeg/cio.c
+++ b/extern/libopenjpeg/cio.c
@@ -30,6 +30,7 @@
*/
#include "opj_includes.h"
+#include <assert.h>
/* ----------------------------------------------------------------------- */
@@ -106,6 +107,7 @@ int OPJ_CALLCONV cio_tell(opj_cio_t *cio) {
* pos : position, in number of bytes, from the beginning of the stream
*/
void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
+ assert((cio->start + pos) <= cio->end);
cio->bp = cio->start + pos;
}
@@ -113,6 +115,7 @@ void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
* Number of bytes left before the end of the stream.
*/
int cio_numbytesleft(opj_cio_t *cio) {
+ assert((cio->end - cio->bp) >= 0);
return cio->end - cio->bp;
}
@@ -139,6 +142,7 @@ opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
* Read a byte.
*/
unsigned char cio_bytein(opj_cio_t *cio) {
+ assert(cio->bp >= cio->start);
if (cio->bp >= cio->end) {
opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end);
return 0;
@@ -152,7 +156,7 @@ unsigned char cio_bytein(opj_cio_t *cio) {
* v : value to write
* n : number of bytes to write
*/
-unsigned int cio_write(opj_cio_t *cio, unsigned long long int v, int n) {
+unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) {
int i;
for (i = n - 1; i >= 0; i--) {
if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )
@@ -173,7 +177,7 @@ unsigned int cio_read(opj_cio_t *cio, int n) {
unsigned int v;
v = 0;
for (i = n - 1; i >= 0; i--) {
- v += cio_bytein(cio) << (i << 3);
+ v += (unsigned int)cio_bytein(cio) << (i << 3);
}
return v;
}
@@ -184,6 +188,10 @@ unsigned int cio_read(opj_cio_t *cio, int n) {
* n : number of bytes to skip
*/
void cio_skip(opj_cio_t *cio, int n) {
+ assert((cio->bp + n) >= cio->bp);
+ if (((cio->bp + n) < cio->start) || ((cio->bp + n) > cio->end)) {
+ assert(0);
+ }
cio->bp += n;
}
diff --git a/extern/libopenjpeg/cio.h b/extern/libopenjpeg/cio.h
index ce1a13ecb3a..e62743141ca 100644
--- a/extern/libopenjpeg/cio.h
+++ b/extern/libopenjpeg/cio.h
@@ -31,6 +31,13 @@
#ifndef __CIO_H
#define __CIO_H
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define int64 __int64
+#else
+#define int64 long long
+#endif
+
/**
@file cio.h
@brief Implementation of a byte input-output process (CIO)
@@ -63,7 +70,7 @@ Write some bytes
@param n Number of bytes to write
@return Returns the number of bytes written or 0 if an error occured
*/
-unsigned int cio_write(opj_cio_t *cio, unsigned long long int v, int n);
+unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n);
/**
Read some bytes
@param cio CIO handle
diff --git a/extern/libopenjpeg/event.c b/extern/libopenjpeg/event.c
index 0dc22f12549..38db33a9432 100644
--- a/extern/libopenjpeg/event.c
+++ b/extern/libopenjpeg/event.c
@@ -103,18 +103,17 @@ opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ..
va_list arg;
int str_length/*, i, j*/; /* UniPG */
char message[MSG_SIZE];
- memset(message, 0, MSG_SIZE);
/* initialize the optional parameter list */
va_start(arg, fmt);
- /* check the length of the format string */
- str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt);
/* parse the format string and put the result in 'message' */
- vsprintf(message, fmt, arg); /* UniPG */
+ str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */
/* deinitialize the optional parameter list */
va_end(arg);
/* output the message to the user program */
- msg_handler(message, cinfo->client_data);
+ if( str_length > -1 && str_length < MSG_SIZE )
+ msg_handler(message, cinfo->client_data);
+ else return OPJ_FALSE;
}
return OPJ_TRUE;
diff --git a/extern/libopenjpeg/image.c b/extern/libopenjpeg/image.c
index 7c1e7f7faa2..579fd73d718 100644
--- a/extern/libopenjpeg/image.c
+++ b/extern/libopenjpeg/image.c
@@ -40,7 +40,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c
image->color_space = clrspc;
image->numcomps = numcmpts;
/* allocate memory for the per-component information */
- image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
+ image->comps = (opj_image_comp_t*)opj_calloc(1,image->numcomps * sizeof(opj_image_comp_t));
if(!image->comps) {
fprintf(stderr,"Unable to allocate memory for image.\n");
opj_image_destroy(image);
@@ -86,3 +86,4 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
opj_free(image);
}
}
+
diff --git a/extern/libopenjpeg/j2k.c b/extern/libopenjpeg/j2k.c
index d34c75faa7b..93e5c9eb80a 100644
--- a/extern/libopenjpeg/j2k.c
+++ b/extern/libopenjpeg/j2k.c
@@ -32,6 +32,7 @@
*/
#include "opj_includes.h"
+#include <assert.h>
/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
/*@{*/
@@ -404,6 +405,7 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
static void j2k_read_siz(opj_j2k_t *j2k) {
int len, i;
+ int n_comps;
opj_cio_t *cio = j2k->cio;
opj_image_t *image = j2k->image;
@@ -422,12 +424,33 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
- "%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
+ "invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
image->x0,image->x1,image->y0,image->y1);
return;
}
+ n_comps = (len - 36 - 2 ) / 3;
+ assert( (len - 36 - 2 ) % 3 == 0 );
image->numcomps = cio_read(cio, 2); /* Csiz */
+ assert( n_comps == image->numcomps );
+ (void)n_comps;
+
+ /* testcase 4035.pdf.SIGSEGV.d8b.3375 */
+ if (image->x0 > image->x1 || image->y0 > image->y1) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", image->x1 - image->x0, image->y1 - image->y0);
+ return;
+ }
+ /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
+ if (!(cp->tdx * cp->tdy)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy);
+ return;
+ }
+
+ /* testcase 1610.pdf.SIGSEGV.59c.681 */
+ if (((int64)image->x1) * ((int64)image->y1) != (image->x1 * image->y1)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", image->x1, image->y1);
+ return;
+ }
#ifdef USE_JPWL
if (j2k->cp->correct) {
@@ -466,11 +489,19 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
/* update components number in the jpwl_exp_comps filed */
cp->exp_comps = image->numcomps;
}
+#else
+ (void)len;
#endif /* USE_JPWL */
+ /* prevent division by zero */
+ if (!(cp->tdx * cp->tdy)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy);
+ return;
+ }
+
image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
for (i = 0; i < image->numcomps; i++) {
- int tmp, w, h;
+ int tmp;
tmp = cio_read(cio, 1); /* Ssiz_i */
image->comps[i].prec = (tmp & 0x7f) + 1;
image->comps[i].sgnd = tmp >> 7;
@@ -506,9 +537,11 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
}
#endif /* USE_JPWL */
- /* TODO: unused ? */
- w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
- h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
+ /* prevent division by zero */
+ if (!(image->comps[i].dx * image->comps[i].dy)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid component size (dx: %d, dy: %d)\n", image->comps[i].dx, image->comps[i].dy);
+ return;
+ }
image->comps[i].resno_decoded = 0; /* number of resolution decoded */
image->comps[i].factor = cp->reduce; /* reducing factor per component */
@@ -517,6 +550,15 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
+ /* gdal_fuzzer_check_number_of_tiles.jp2 */
+ if (cp->tw == 0 || cp->th == 0 || cp->tw > 65535 / cp->th) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n",
+ cp->tw, cp->th);
+ return;
+ }
+
+
#ifdef USE_JPWL
if (j2k->cp->correct) {
/* if JPWL is on, we check whether TX errors have damaged
@@ -558,7 +600,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
#endif /* USE_JPWL */
cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
+ if (cp->tcps == NULL)
+ {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
+ return;
+ }
cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
+ if (cp->tileno == NULL)
+ {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
+ return;
+ }
cp->tileno_size = 0;
#ifdef USE_JPWL
@@ -684,6 +736,12 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
j2k->state |= J2K_STATE_ERR;
}
+ if( tccp->numresolutions > J2K_MAXRLVLS ) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
+ compno, tccp->numresolutions, J2K_MAXRLVLS);
+ j2k->state |= J2K_STATE_ERR;
+ tccp->numresolutions = J2K_MAXRLVLS;
+ }
tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */
tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */
@@ -753,6 +811,7 @@ static void j2k_read_cod(opj_j2k_t *j2k) {
opj_image_t *image = j2k->image;
len = cio_read(cio, 2); /* Lcod */
+ (void)len;
tcp->csty = cio_read(cio, 1); /* Scod */
tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */
tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */
@@ -806,7 +865,14 @@ static void j2k_read_coc(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
len = cio_read(cio, 2); /* Lcoc */
+ (void)len;
compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */
+ if (compno >= image->numcomps) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "bad component number in COC (%d out of a maximum of %d)\n",
+ compno, image->numcomps);
+ return;
+ }
tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */
j2k_read_cox(j2k, compno);
}
@@ -877,6 +943,8 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
opj_event_msg(j2k->cinfo, EVT_WARNING ,
"bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
"- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
+ /* edf_c2_1013627.jp2 */
+ numbands = 1;
}
#endif /* USE_JPWL */
@@ -988,9 +1056,16 @@ static void j2k_read_qcc(opj_j2k_t *j2k) {
/* keep your private count of tiles */
backup_compno++;
- };
+ }
#endif /* USE_JPWL */
+ if ((compno < 0) || (compno >= numcomp)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "bad component number in QCC (%d out of a maximum of %d)\n",
+ compno, j2k->image->numcomps);
+ return;
+ }
+
j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
}
@@ -1036,6 +1111,15 @@ static void j2k_read_poc(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Lpoc */
numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
+ if( numpchgs >= 32 )
+ {
+ /* edf_c2_1103421.jp2 */
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "bad number of POCS (%d out of a maximum of %d)\n",
+ numpchgs, 32);
+ numpchgs = 0;
+ }
+
for (i = old_poc; i < numpchgs + old_poc; i++) {
opj_poc_t *poc;
poc = &tcp->pocs[i];
@@ -1058,9 +1142,12 @@ static void j2k_read_crg(opj_j2k_t *j2k) {
int numcomps = j2k->image->numcomps;
len = cio_read(cio, 2); /* Lcrg */
+ (void)len;
for (i = 0; i < numcomps; i++) {
Xcrg_i = cio_read(cio, 2); /* Xcrg_i */
+ (void)Xcrg_i;
Ycrg_i = cio_read(cio, 2); /* Ycrg_i */
+ (void)Ycrg_i;
}
}
@@ -1072,13 +1159,16 @@ static void j2k_read_tlm(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Ltlm */
Ztlm = cio_read(cio, 1); /* Ztlm */
+ (void)Ztlm;
Stlm = cio_read(cio, 1); /* Stlm */
ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
SP = (Stlm >> 6) & 0x01;
tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
for (i = 0; i < tile_tlm; i++) {
Ttlm_i = cio_read(cio, ST); /* Ttlm_i */
+ (void)Ttlm_i;
Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */
+ (void)Ptlm_i;
}
}
@@ -1089,6 +1179,7 @@ static void j2k_read_plm(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Lplm */
Zplm = cio_read(cio, 1); /* Zplm */
+ (void)Zplm;
len -= 3;
while (len > 0) {
Nplm = cio_read(cio, 4); /* Nplm */
@@ -1114,6 +1205,7 @@ static void j2k_read_plt(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Lplt */
Zplt = cio_read(cio, 1); /* Zplt */
+ (void)Zplt;
for (i = len - 3; i > 0; i--) {
add = cio_read(cio, 1);
packet_len = (packet_len << 7) + add; /* Iplt_i */
@@ -1261,6 +1353,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
len = cio_read(cio, 2);
+ (void)len;
tileno = cio_read(cio, 2);
#ifdef USE_JPWL
@@ -1269,7 +1362,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
static int backup_tileno = 0;
/* tileno is negative or larger than the number of tiles!!! */
- if ((tileno < 0) || (tileno > (cp->tw * cp->th))) {
+ if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"JPWL: bad tile number (%d out of a maximum of %d)\n",
tileno, (cp->tw * cp->th));
@@ -1286,8 +1379,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
/* keep your private count of tiles */
backup_tileno++;
- };
+ }
+ else
#endif /* USE_JPWL */
+ {
+ /* tileno is negative or larger than the number of tiles!!! */
+ if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "JPWL: bad tile number (%d out of a maximum of %d)\n",
+ tileno, (cp->tw * cp->th));
+ return;
+ }
+ }
if (cp->tileno_size == 0) {
cp->tileno[cp->tileno_size] = tileno;
@@ -1325,8 +1428,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
totlen);
}
- };
+ }
+ else
#endif /* USE_JPWL */
+ {
+ /* totlen is negative or larger than the bytes left!!! */
+ if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
+ totlen, cio_numbytesleft(cio) + 8);
+ return;
+ }
+ }
if (!totlen)
totlen = cio_numbytesleft(cio) + 8;
@@ -1478,7 +1591,13 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
}
data = j2k->tile_data[curtileno];
+ data_ptr = data; /* store in case of failure */
data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
+ if( data == NULL ) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not reallocated\n" );
+ opj_free( data_ptr );
+ return;
+ }
data_ptr = data + j2k->tile_len[curtileno];
for (i = 0; i < len; i++) {
@@ -1518,8 +1637,10 @@ static void j2k_read_rgn(opj_j2k_t *j2k) {
int numcomps = j2k->image->numcomps;
len = cio_read(cio, 2); /* Lrgn */
+ (void)len;
compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */
roisty = cio_read(cio, 1); /* Srgn */
+ (void)roisty;
#ifdef USE_JPWL
if (j2k->cp->correct) {
@@ -1536,6 +1657,13 @@ static void j2k_read_rgn(opj_j2k_t *j2k) {
};
#endif /* USE_JPWL */
+ if (compno >= numcomps) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "bad component number in RGN (%d out of a maximum of %d)\n",
+ compno, j2k->image->numcomps);
+ return;
+ }
+
tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */
}
@@ -1554,7 +1682,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) {
static void j2k_read_eoc(opj_j2k_t *j2k) {
int i, tileno;
- opj_bool success;
+ opj_bool success = OPJ_FALSE;
/* if packets should be decoded */
if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
@@ -1562,11 +1690,17 @@ static void j2k_read_eoc(opj_j2k_t *j2k) {
tcd_malloc_decode(tcd, j2k->image, j2k->cp);
for (i = 0; i < j2k->cp->tileno_size; i++) {
tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
- tileno = j2k->cp->tileno[i];
- success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
- opj_free(j2k->tile_data[tileno]);
- j2k->tile_data[tileno] = NULL;
- tcd_free_decode_tile(tcd, i);
+ if (j2k->cp->tileno[i] != -1)
+ {
+ tileno = j2k->cp->tileno[i];
+ success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
+ assert( tileno != -1 );
+ opj_free(j2k->tile_data[tileno]);
+ j2k->tile_data[tileno] = NULL;
+ tcd_free_decode_tile(tcd, i);
+ }
+ else
+ success = OPJ_FALSE;
if (success == OPJ_FALSE) {
j2k->state |= J2K_STATE_ERR;
break;
@@ -1737,6 +1871,17 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) {
opj_free(j2k->tile_len);
}
if(j2k->tile_data != NULL) {
+ if(j2k->cp != NULL) {
+ for (i = 0; i < j2k->cp->tileno_size; i++) {
+ int tileno = j2k->cp->tileno[i];
+ if( tileno != -1 )
+ {
+ opj_free(j2k->tile_data[tileno]);
+ j2k->tile_data[tileno] = NULL;
+ }
+ }
+ }
+
opj_free(j2k->tile_data);
}
if(j2k->default_tcp != NULL) {
@@ -1856,9 +2001,15 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
#endif /* USE_JPWL */
if (id >> 8 != 0xff) {
- opj_image_destroy(image);
- opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
- return 0;
+ if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */
+ {
+ opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
+ opj_image_destroy(image);
+ return 0;
+ }
+ opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
+ j2k->state = J2K_STATE_NEOC;
+ break;
}
e = j2k_dec_mstab_lookup(id);
/* Check if the marker is known*/
@@ -1877,7 +2028,10 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
(*e->handler)(j2k);
}
if (j2k->state & J2K_STATE_ERR)
+ {
+ opj_image_destroy(image);
return NULL;
+ }
if (j2k->state == J2K_STATE_MT) {
break;
@@ -1888,6 +2042,11 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
}
if (j2k->state == J2K_STATE_NEOC) {
j2k_read_eoc(j2k);
+ /* Check one last time for errors during decoding before returning */
+ if (j2k->state & J2K_STATE_ERR) {
+ opj_image_destroy(image);
+ return NULL;
+ }
}
if (j2k->state != J2K_STATE_MT) {
@@ -1949,9 +2108,15 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
id = cio_read(cio, 2);
if (id >> 8 != 0xff) {
- opj_image_destroy(image);
- opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
- return 0;
+ if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */
+ {
+ opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
+ opj_image_destroy(image);
+ return 0;
+ }
+ opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
+ j2k->state = J2K_STATE_NEOC;
+ break;
}
e = j2k_dec_mstab_lookup(id);
if (!(j2k->state & e->states)) {
diff --git a/extern/libopenjpeg/jp2.c b/extern/libopenjpeg/jp2.c
index 5ae114c33b9..d3322603c8b 100644
--- a/extern/libopenjpeg/jp2.c
+++ b/extern/libopenjpeg/jp2.c
@@ -30,6 +30,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opj_includes.h"
+#include <assert.h>
/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
/*@{*/
@@ -172,6 +173,9 @@ static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_bo
}
else if (box->length == 0) {
box->length = cio_numbytesleft(cio) + 8;
+ } else if (box->length < 0) {
+ opj_event_msg(cinfo, EVT_ERROR, "Integer overflow in box->length\n");
+ return OPJ_FALSE; /* TODO: actually check jp2_read_boxhdr's return value */
}
return OPJ_TRUE;
@@ -206,7 +210,10 @@ static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
+ if(jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
+ return OPJ_FALSE;
+ }
if (JP2_IHDR != box.type) {
opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n");
return OPJ_FALSE;
@@ -279,7 +286,10 @@ static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
+ return OPJ_FALSE;
+ }
if (JP2_BPCC != box.type) {
opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n");
return OPJ_FALSE;
@@ -469,7 +479,7 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
for(i = 0; i < nr_channels; ++i)
{
/* Cji */
- *entries++ = cio_read(cio, channel_size[i]>>3);
+ *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
}
}
@@ -512,10 +522,8 @@ static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
{
opj_jp2_cdef_info_t *info;
- int color_space;
unsigned short i, n, cn, typ, asoc, acn;
- color_space = image->color_space;
info = color->jp2_cdef->info;
n = color->jp2_cdef->n;
@@ -525,6 +533,7 @@ static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
if((asoc = info[i].asoc) == 0) continue;
cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
+ (void)typ;
if(cn != acn)
{
@@ -639,90 +648,173 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color)
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
- do
- {
- if (JP2_JP2H != box.type)
- {
- if (box.type == JP2_JP2C)
- {
- opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
- return OPJ_FALSE;
- }
- cio_skip(cio, box.length - 8);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ do {
+ if (JP2_JP2H != box.type)
+ {
+ if (box.type == JP2_JP2C)
+ {
+ opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
+ return OPJ_FALSE;
+ }
+ if (box.length <= 8) return OPJ_FALSE;
+ cio_skip(cio, box.length - 8);
- if(cio->bp >= cio->end) return OPJ_FALSE;
+ if(cio->bp >= cio->end) return OPJ_FALSE;
- jp2_read_boxhdr(cinfo, cio, &box);
- }
- } while(JP2_JP2H != box.type);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ }
+ } while(JP2_JP2H != box.type);
if (!jp2_read_ihdr(jp2, cio))
return OPJ_FALSE;
jp2h_end = box.init_pos + box.length;
- if (jp2->bpc == 255)
- {
- if (!jp2_read_bpcc(jp2, cio))
- return OPJ_FALSE;
- }
- jp2_read_boxhdr(cinfo, cio, &box);
+ if (jp2->bpc == 255)
+ {
+ if (!jp2_read_bpcc(jp2, cio))
+ return OPJ_FALSE;
+ }
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
- while(cio_tell(cio) < jp2h_end)
- {
- if(box.type == JP2_COLR)
- {
- if( !jp2_read_colr(jp2, cio, &box, color))
- {
- cio_seek(cio, box.init_pos + 8);
- cio_skip(cio, box.length - 8);
- }
- jp2_read_boxhdr(cinfo, cio, &box);
- continue;
- }
+ while(cio_tell(cio) < jp2h_end)
+ {
+ if(box.type == JP2_COLR)
+ {
+ if( !jp2_read_colr(jp2, cio, &box, color))
+ {
+ if (box.length <= 8) return OPJ_FALSE;
+ cio_seek(cio, box.init_pos + 8);
+ cio_skip(cio, box.length - 8);
+ }
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ continue;
+ }
if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef)
- {
- if( !jp2_read_cdef(jp2, cio, &box, color))
- {
- cio_seek(cio, box.init_pos + 8);
- cio_skip(cio, box.length - 8);
- }
- jp2_read_boxhdr(cinfo, cio, &box);
- continue;
- }
+ {
+ if( !jp2_read_cdef(jp2, cio, &box, color))
+ {
+ if (box.length <= 8) return OPJ_FALSE;
+ cio_seek(cio, box.init_pos + 8);
+ cio_skip(cio, box.length - 8);
+ }
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ continue;
+ }
if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef)
- {
- if( !jp2_read_pclr(jp2, cio, &box, color))
- {
- cio_seek(cio, box.init_pos + 8);
- cio_skip(cio, box.length - 8);
- }
- jp2_read_boxhdr(cinfo, cio, &box);
- continue;
- }
+ {
+ if( !jp2_read_pclr(jp2, cio, &box, color))
+ {
+ if (box.length <= 8) return OPJ_FALSE;
+ cio_seek(cio, box.init_pos + 8);
+ cio_skip(cio, box.length - 8);
+ }
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ continue;
+ }
if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef)
- {
- if( !jp2_read_cmap(jp2, cio, &box, color))
- {
+ {
+ if( !jp2_read_cmap(jp2, cio, &box, color))
+ {
+ if (box.length <= 8) return OPJ_FALSE;
+ cio_seek(cio, box.init_pos + 8);
+ cio_skip(cio, box.length - 8);
+ }
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
+ continue;
+ }
+ if (box.length <= 8) return OPJ_FALSE;
cio_seek(cio, box.init_pos + 8);
cio_skip(cio, box.length - 8);
- }
- jp2_read_boxhdr(cinfo, cio, &box);
- continue;
- }
- cio_seek(cio, box.init_pos + 8);
- cio_skip(cio, box.length - 8);
- jp2_read_boxhdr(cinfo, cio, &box);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
- }/* while(cio_tell(cio) < box_end) */
+ }/* while(cio_tell(cio) < box_end) */
- cio_seek(cio, jp2h_end);
+ cio_seek(cio, jp2h_end);
-/* Part 1, I.5.3.3 : 'must contain at least one' */
- return (color->jp2_has_colr == 1);
+ /* Part 1, I.5.3.3 : 'must contain at least one' */
+ return (color->jp2_has_colr == 1);
}/* jp2_read_jp2h() */
+static opj_bool opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_common_ptr cinfo)
+{
+ int i;
+
+ /* testcase 4149.pdf.SIGSEGV.cf7.3501 */
+ if (color->jp2_cdef) {
+ opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
+ int n = color->jp2_cdef->n;
+
+ for (i = 0; i < n; i++) {
+ if (info[i].cn >= image->numcomps) {
+ opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
+ return OPJ_FALSE;
+ }
+ if (info[i].asoc > 0 && (info[i].asoc - 1) >= image->numcomps) {
+ opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
+ return OPJ_FALSE;
+ }
+ }
+ }
+
+ /* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and
+ 66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */
+ if (color->jp2_pclr && color->jp2_pclr->cmap) {
+ int nr_channels = color->jp2_pclr->nr_channels;
+ opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap;
+ opj_bool *pcol_usage, is_sane = OPJ_TRUE;
+
+ /* verify that all original components match an existing one */
+ for (i = 0; i < nr_channels; i++) {
+ if (cmap[i].cmp >= image->numcomps) {
+ opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps);
+ is_sane = OPJ_FALSE;
+ }
+ }
+
+ pcol_usage = opj_calloc(nr_channels, sizeof(opj_bool));
+ if (!pcol_usage) {
+ opj_event_msg(cinfo, EVT_ERROR, "Unexpected OOM.\n");
+ return OPJ_FALSE;
+ }
+ /* verify that no component is targeted more than once */
+ for (i = 0; i < nr_channels; i++) {
+ int pcol = cmap[i].pcol;
+ assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
+ if (pcol >= nr_channels) {
+ opj_event_msg(cinfo, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
+ is_sane = OPJ_FALSE;
+ }
+ else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
+ opj_event_msg(cinfo, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
+ is_sane = OPJ_FALSE;
+ }
+ else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
+ /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
+ * the value of this field shall be 0. */
+ opj_event_msg(cinfo, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol);
+ is_sane = OPJ_FALSE;
+ }
+ else
+ pcol_usage[pcol] = OPJ_TRUE;
+ }
+ /* verify that all components are targeted at least once */
+ for (i = 0; i < nr_channels; i++) {
+ if (!pcol_usage[i] && cmap[i].mtyp != 0) {
+ opj_event_msg(cinfo, EVT_ERROR, "Component %d doesn't have a mapping.\n", i);
+ is_sane = OPJ_FALSE;
+ }
+ }
+ opj_free(pcol_usage);
+ if (!is_sane) {
+ return OPJ_FALSE;
+ }
+ }
+
+ return OPJ_TRUE;
+}
+
opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
opj_codestream_info_t *cstr_info)
{
@@ -756,6 +848,10 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
}
if (!jp2->ignore_pclr_cmap_cdef){
+ if (!opj_jp2_check_color(image, &color, cinfo)) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to decode PCRL box\n");
+ return NULL;
+ }
/* Set Image Color Space */
if (jp2->enumcs == 16)
@@ -839,8 +935,10 @@ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
-
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
+ return OPJ_FALSE;
+ }
if (JP2_FTYP != box.type) {
opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n");
return OPJ_FALSE;
@@ -849,6 +947,14 @@ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
jp2->brand = cio_read(cio, 4); /* BR */
jp2->minversion = cio_read(cio, 4); /* MinV */
jp2->numcl = (box.length - 16) / 4;
+
+ /* edf_c2_1673169.jp2 */
+ if (cio_numbytesleft(cio) < ((int)jp2->numcl * 4)) {
+ opj_event_msg(cinfo, EVT_ERROR, "Not enough bytes in FTYP Box "
+ "(expected %d, but only %d left)\n",
+ ((int)jp2->numcl * 4), cio_numbytesleft(cio));
+ return OPJ_FALSE;
+ }
jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
for (i = 0; i < (int)jp2->numcl; i++) {
@@ -897,15 +1003,20 @@ static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
+ return OPJ_FALSE;
+ }
do {
if(JP2_JP2C != box.type) {
+ if (box.length <= 8) return OPJ_FALSE;
cio_skip(cio, box.length - 8);
- jp2_read_boxhdr(cinfo, cio, &box);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
}
} while(JP2_JP2C != box.type);
*j2k_codestream_offset = cio_tell(cio);
+ if (box.length <= 8) return OPJ_FALSE;
*j2k_codestream_length = box.length - 8;
return OPJ_TRUE;
@@ -930,7 +1041,10 @@ static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
opj_common_ptr cinfo = jp2->cinfo;
- jp2_read_boxhdr(cinfo, cio, &box);
+ if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
+ opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
+ return OPJ_FALSE;
+ }
if (JP2_JP != box.type) {
opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n");
return OPJ_FALSE;
@@ -1070,6 +1184,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) {
opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
if(jp2) {
+ memset(jp2, 0, sizeof(opj_jp2_t));
jp2->cinfo = cinfo;
/* create the J2K codec */
jp2->j2k = j2k_create_compress(cinfo);
diff --git a/extern/libopenjpeg/openjpeg.h b/extern/libopenjpeg/openjpeg.h
index 53e9fac0438..59147c8b3d1 100644
--- a/extern/libopenjpeg/openjpeg.h
+++ b/extern/libopenjpeg/openjpeg.h
@@ -135,6 +135,10 @@ typedef enum COLOR_SPACE {
CLRSPC_SYCC = 3 /**< YUV */
} OPJ_COLOR_SPACE;
+#define ENUMCS_SRGB 16
+#define ENUMCS_GRAY 17
+#define ENUMCS_SYCC 18
+
/**
Supported codec
*/
diff --git a/extern/libopenjpeg/opj_config.h b/extern/libopenjpeg/opj_config.h
index 82e12be03a9..5d0a877b840 100644
--- a/extern/libopenjpeg/opj_config.h
+++ b/extern/libopenjpeg/opj_config.h
@@ -3,7 +3,7 @@
* the endian check is a blender define */
/* create config.h for CMake */
-#define PACKAGE_VERSION "1.5.0"
+#define PACKAGE_VERSION "1.5.2"
#define HAVE_INTTYPES_H
#define HAVE_MEMORY_H
@@ -23,6 +23,7 @@
/* #undef HAVE_LIBLCMS2 */
/* #undef HAVE_LCMS1_H */
/* #undef HAVE_LCMS2_H */
+/* #undef USE_SYSTEM_GETOPT */
/* Byte order. */
/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or
diff --git a/extern/libopenjpeg/opj_includes.h b/extern/libopenjpeg/opj_includes.h
index 2b5866a9990..e9194fd9886 100644
--- a/extern/libopenjpeg/opj_includes.h
+++ b/extern/libopenjpeg/opj_includes.h
@@ -89,18 +89,17 @@ Most compilers implement their own version of this keyword ...
/* MSVC and Borland C do not have lrintf */
#if defined(_MSC_VER) || defined(__BORLANDC__)
static INLINE long lrintf(float f){
-#ifdef _M_X64
- return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
-#else
- int i;
+#ifdef _M_IX86
+ long int i;
_asm{
fld f
fistp i
};
-
return i;
-#endif
+#else
+ return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
+#endif /* _M_IX86 */
}
#endif
diff --git a/extern/libopenjpeg/opj_malloc.h b/extern/libopenjpeg/opj_malloc.h
index 87493f497c7..aef2ee3b8c9 100644
--- a/extern/libopenjpeg/opj_malloc.h
+++ b/extern/libopenjpeg/opj_malloc.h
@@ -83,8 +83,10 @@ Allocate memory aligned to a 16 byte boundry
#else /* Not _WIN32 */
#if defined(__sun)
#define HAVE_MEMALIGN
+ #elif defined(__FreeBSD__)
+ #define HAVE_POSIX_MEMALIGN
/* Linux x86_64 and OSX always align allocations to 16 bytes */
- #elif !defined(__amd64__) && !defined(__APPLE__)
+ #elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
#define HAVE_MEMALIGN
#include <malloc.h>
#endif
diff --git a/extern/libopenjpeg/patches/fbsd.patch b/extern/libopenjpeg/patches/fbsd.patch
deleted file mode 100644
index 90e77600941..00000000000
--- a/extern/libopenjpeg/patches/fbsd.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: extern/libopenjpeg/opj_malloc.h
-===================================================================
---- extern/libopenjpeg/opj_malloc.h (revision 27736)
-+++ extern/libopenjpeg/opj_malloc.h (working copy)
-@@ -76,7 +76,7 @@
- #if defined(__sun)
- #define HAVE_MEMALIGN
- #elif defined(__GNUC__)
-- #ifndef __APPLE__
-+ #if !defined(__APPLE__) && !defined(__FreeBSD__)
- #define HAVE_MEMALIGN
- #include <malloc.h>
- #endif
diff --git a/extern/libopenjpeg/patches/osx.patch b/extern/libopenjpeg/patches/osx.patch
deleted file mode 100644
index c518978eed6..00000000000
--- a/extern/libopenjpeg/patches/osx.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Index: opj_malloc.h
-===================================================================
---- opj_malloc.h (revision 15089)
-+++ opj_malloc.h (working copy)
-@@ -76,8 +76,10 @@
- #if defined(__sun)
- #define HAVE_MEMALIGN
- #elif defined(__GNUC__)
-- #define HAVE_MEMALIGN
-- #include <malloc.h>
-+ #ifndef __APPLE__
-+ #define HAVE_MEMALIGN
-+ #include <malloc.h>
-+ #endif
- /* Linux x86_64 and OSX always align allocations to 16 bytes */
- #elif !defined(__amd64__) && !defined(__APPLE__)
- /* FIXME: Yes, this is a big assumption */
diff --git a/extern/libopenjpeg/t1.c b/extern/libopenjpeg/t1.c
index 477720412aa..ed9cdc3fea6 100644
--- a/extern/libopenjpeg/t1.c
+++ b/extern/libopenjpeg/t1.c
@@ -1577,6 +1577,7 @@ void t1_decode_cblks(
opj_free(cblk->segs);
} /* cblkno */
opj_free(precinct->cblks.dec);
+ precinct->cblks.dec = NULL;
} /* precno */
} /* bandno */
} /* resno */
diff --git a/extern/libopenjpeg/t2.c b/extern/libopenjpeg/t2.c
index 232a5437329..2585c3d56a6 100644
--- a/extern/libopenjpeg/t2.c
+++ b/extern/libopenjpeg/t2.c
@@ -30,6 +30,7 @@
*/
#include "opj_includes.h"
+#include <assert.h>
/** @defgroup T2 T2 - Implementation of a tier-2 coding */
/*@{*/
@@ -64,7 +65,7 @@ static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterato
@param cblksty
@param first
*/
-static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
+static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
/**
Decode a packet of a tile from a source buffer
@param t2 T2 handle
@@ -296,9 +297,17 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
return (c - dest);
}
-static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
+static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
opj_tcd_seg_t* seg;
- cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
+ opj_tcd_seg_t* segs;
+ segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
+
+ if (segs == NULL)
+ {
+ return OPJ_FALSE;
+ }
+ cblk->segs = segs;
+
seg = &cblk->segs[index];
seg->data = NULL;
seg->dataindex = 0;
@@ -316,6 +325,8 @@ static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int fi
} else {
seg->maxpasses = 109;
}
+
+ return OPJ_TRUE;
}
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
@@ -330,13 +341,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
int precno = pi->precno; /* precinct value */
int layno = pi->layno; /* quality layer value */
- opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
-
unsigned char *hd = NULL;
int present;
opj_bio_t *bio = NULL; /* BIO component */
-
+
+ opj_tcd_resolution_t* res;
+ assert(&tile->comps[compno] != NULL);
+ res = &tile->comps[compno].resolutions[resno];
+
if (layno == 0) {
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];
@@ -462,12 +475,22 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
cblk->numlenbits += increment;
segno = 0;
if (!cblk->numsegs) {
- t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1);
+ if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1))
+ {
+ opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
+ bio_destroy(bio);
+ return -999;
+ }
} else {
segno = cblk->numsegs - 1;
if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) {
++segno;
- t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
+ if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
+ {
+ opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
+ bio_destroy(bio);
+ return -999;
+ }
}
}
n = cblk->numnewpasses;
@@ -478,7 +501,12 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
n -= cblk->segs[segno].numnewpasses;
if (n > 0) {
++segno;
- t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
+ if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
+ {
+ opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
+ bio_destroy(bio);
+ return -999;
+ }
}
} while (n > 0);
}
@@ -714,7 +742,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
} else {
e = 0;
}
- if(e == -999) return -999;
+ if(e == -999)
+ {
+ pi_destroy(pi, cp, tileno);
+ return -999;
+ }
/* progression in resolution */
image->comps[pi[pino].compno].resno_decoded =
(e > 0) ?
diff --git a/extern/libopenjpeg/tcd.c b/extern/libopenjpeg/tcd.c
index 18cdbc786bc..62904eb2c65 100644
--- a/extern/libopenjpeg/tcd.c
+++ b/extern/libopenjpeg/tcd.c
@@ -30,7 +30,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#define _ISOC99_SOURCE /* lrintf is C99 */
#include "opj_includes.h"
+#include <assert.h>
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
int tileno, compno, resno, bandno, precno;/*, cblkno;*/
@@ -249,7 +251,9 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
cbgwidthexpn = pdx - 1;
cbgheightexpn = pdy - 1;
}
-
+ (void)brcbgyend;
+ (void)brcbgxend;
+
cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
@@ -333,8 +337,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
cblk->y0 = int_max(cblkystart, prc->y0);
cblk->x1 = int_min(cblkxend, prc->x1);
cblk->y1 = int_min(cblkyend, prc->y1);
- cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
+ cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
+ cblk->data[0] = 0;
+ cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -509,6 +515,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
cbgwidthexpn = pdx - 1;
cbgheightexpn = pdy - 1;
}
+ (void)brcbgyend;
+ (void)brcbgxend;
cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
@@ -594,6 +602,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
cblk->y1 = int_min(cblkyend, prc->y1);
cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
+ cblk->data[0] = 0;
+ cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -614,7 +624,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
tcd->image = image;
tcd->tcd_image->tw = cp->tw;
tcd->tcd_image->th = cp->th;
- tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t));
+ tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t));
/*
Allocate place to store the decoded data = final image
@@ -690,6 +700,12 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
opj_tccp_t *tccp = &tcp->tccps[compno];
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ if (tccp->numresolutions <= 0)
+ {
+ cp->tileno[tileno] = -1;
+ return;
+ }
+
/* border of each tile component (global) */
tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
@@ -749,6 +765,8 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
cbgwidthexpn = pdx - 1;
cbgheightexpn = pdy - 1;
}
+ (void)brcbgyend;
+ (void)brcbgxend;
cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
@@ -1370,16 +1388,31 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
if (l == -999) {
eof = 1;
opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n");
+ return OPJ_FALSE;
}
/*------------------TIER1-----------------*/
t1_time = opj_clock(); /* time needed to decode a tile */
t1 = t1_create(tcd->cinfo);
+ if (t1 == NULL)
+ {
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
+ t1_destroy(t1);
+ return OPJ_FALSE;
+ }
+
for (compno = 0; compno < tile->numcomps; ++compno) {
opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
/* The +3 is headroom required by the vectorized DWT */
tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int));
+ if (tilec->data == NULL)
+ {
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
+ t1_destroy(t1);
+ return OPJ_FALSE;
+ }
+
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
}
t1_destroy(t1);
@@ -1394,13 +1427,15 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
int numres2decode;
if (tcd->cp->reduce != 0) {
- tcd->image->comps[compno].resno_decoded =
- tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
- if (tcd->image->comps[compno].resno_decoded < 0) {
+ if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number "
" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
return OPJ_FALSE;
}
+ else {
+ tcd->image->comps[compno].resno_decoded =
+ tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
+ }
}
numres2decode = tcd->image->comps[compno].resno_decoded + 1;
@@ -1421,6 +1456,13 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0);
if (tile->numcomps >= 3 ){
+ /* testcase 1336.pdf.asan.47.376 */
+ if ((tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) < n ||
+ ( tile->comps[1].x1 - tile->comps[1].x0) * (tile->comps[1].y1 - tile->comps[1].y0) < n ||
+ ( tile->comps[2].x1 - tile->comps[2].x0) * (tile->comps[2].y1 - tile->comps[2].y0) < n) {
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Tiles don't all have the same dimension. Skip the MCT step.\n");
+ return OPJ_FALSE;
+ }
if (tcd->tcp->tccps[0].qmfbid == 1) {
mct_decode(
tile->comps[0].data,
@@ -1452,18 +1494,33 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
int tw = tilec->x1 - tilec->x0;
int w = imagec->w;
+ int i, j;
int offset_x = int_ceildivpow2(imagec->x0, imagec->factor);
int offset_y = int_ceildivpow2(imagec->y0, imagec->factor);
+ /* NR-DEC-2977.pdf.asan.67.2198.jp2-52-decode */
+ if( res->x0 - offset_x < 0 || res->x1 - offset_x < 0
+ || res->y0 - offset_y < 0 || res->y1 - offset_y < 0 )
+ {
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Impossible offsets %d / %d\n", offset_x, offset_y);
+ return OPJ_FALSE;
+ }
+ assert( 0 <= res->x0 - offset_x && 0 <= res->x1 - offset_x );
+ assert( 0 <= res->y0 - offset_y && 0 <= res->y1 - offset_y );
- int i, j;
if(!imagec->data){
imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int));
}
+ if (!imagec->data)
+ {
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
+ return OPJ_FALSE;
+ }
if(tcd->tcp->tccps[compno].qmfbid == 1) {
for(j = res->y0; j < res->y1; ++j) {
for(i = res->x0; i < res->x1; ++i) {
int v = tilec->data[i - res->x0 + (j - res->y0) * tw];
v += adjust;
+ /*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
}
}
@@ -1473,6 +1530,7 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw];
int v = lrintf(tmp);
v += adjust;
+ /*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
}
}
@@ -1492,32 +1550,51 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
void tcd_free_decode(opj_tcd_t *tcd) {
opj_tcd_image_t *tcd_image = tcd->tcd_image;
+ int i = 0;
+ for (i = 0; i < tcd_image->tw * tcd_image->th; i++)
+ {
+ tcd_free_decode_tile(tcd, i);
+ }
+
opj_free(tcd_image->tiles);
}
void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) {
- int compno,resno,bandno,precno;
+ int compno,resno,bandno,precno,cblkno;
opj_tcd_image_t *tcd_image = tcd->tcd_image;
opj_tcd_tile_t *tile = &tcd_image->tiles[tileno];
- for (compno = 0; compno < tile->numcomps; compno++) {
- opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
- for (resno = 0; resno < tilec->numresolutions; resno++) {
- opj_tcd_resolution_t *res = &tilec->resolutions[resno];
- for (bandno = 0; bandno < res->numbands; bandno++) {
- opj_tcd_band_t *band = &res->bands[bandno];
- for (precno = 0; precno < res->ph * res->pw; precno++) {
- opj_tcd_precinct_t *prec = &band->precincts[precno];
- if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
- if (prec->incltree != NULL) tgt_destroy(prec->incltree);
+ if (tile->comps != NULL) {
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ for (resno = 0; resno < tilec->numresolutions; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->ph * res->pw; precno++) {
+ opj_tcd_precinct_t *prec = &band->precincts[precno];
+ if (prec->cblks.dec != NULL) {
+ for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) {
+ opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno];
+ opj_free(cblk->data);
+ opj_free(cblk->segs);
+ }
+ opj_free(prec->cblks.dec);
+ }
+ if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
+ if (prec->incltree != NULL) tgt_destroy(prec->incltree);
+
+
+ }
+ opj_free(band->precincts);
}
- opj_free(band->precincts);
}
+ opj_free(tilec->resolutions);
}
- opj_free(tilec->resolutions);
+ opj_free(tile->comps);
+ tile->comps = NULL;
}
- opj_free(tile->comps);
}