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:
Diffstat (limited to 'extern/libopenjpeg/tcd.c')
-rw-r--r--extern/libopenjpeg/tcd.c119
1 files changed, 98 insertions, 21 deletions
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);
}