diff options
Diffstat (limited to 'extern/libopenjpeg/tcd.c')
-rw-r--r-- | extern/libopenjpeg/tcd.c | 119 |
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); } |