[1.5] Apply private patch from Alex Macfarlane Smith
This gets rids of a lot memory leaks when used on device with low memory
This commit is contained in:
parent
835bf5357f
commit
6c5a066b20
|
@ -558,7 +558,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
|
||||
|
@ -1737,6 +1747,14 @@ 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];
|
||||
opj_free(j2k->tile_data[tileno]);
|
||||
j2k->tile_data[tileno] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
opj_free(j2k->tile_data);
|
||||
}
|
||||
if(j2k->default_tcp != NULL) {
|
||||
|
@ -1877,7 +1895,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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -64,7 +64,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 +296,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 +324,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,
|
||||
|
@ -462,12 +472,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 +498,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 +739,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) ?
|
||||
|
|
|
@ -615,7 +615,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
|
||||
|
@ -1377,10 +1377,23 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
|
|||
|
||||
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");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
|
||||
}
|
||||
t1_destroy(t1);
|
||||
|
@ -1460,6 +1473,11 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
|
|||
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) {
|
||||
|
@ -1493,32 +1511,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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue