From 24e189e4d8a231e7273d788b2bd77e2484cec761 Mon Sep 17 00:00:00 2001 From: Francois-Olivier Devaux Date: Wed, 14 Nov 2007 08:45:00 +0000 Subject: [PATCH] Patch by Callum Lerwick. This patch rearranges the largest memory allocations so they're allocated as late as possible, and freed as soon as possible. This cuts memory usage by about half on two large test images. --- ChangeLog | 4 +++- libopenjpeg/t1.c | 7 ++++--- libopenjpeg/t2.c | 5 ++--- libopenjpeg/tcd.c | 26 ++++++++++++-------------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85bf2951..2bde0ef4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,9 @@ What's New for OpenJPEG November 14, 2007 -! [FOD] Patch by Callum Lerwick. Instead of reinventing realloc, j2k_read_sod now just uses opj_realloc in j2k.c +! [FOD] First Patch by Callum Lerwick. Instead of reinventing realloc, j2k_read_sod now just uses opj_realloc in j2k.c + Second Patch by Callum Lerwick. This patch rearranges the largest memory allocations so they're allocated as + late as possible, and freed as soon as possible. This cuts memory usage by about half on two large test images. November 13, 2007 ! [FOD] Patch by Dzonatas and Callum Lerwick. diff --git a/libopenjpeg/t1.c b/libopenjpeg/t1.c index 83b10efd..63d42fa1 100644 --- a/libopenjpeg/t1.c +++ b/libopenjpeg/t1.c @@ -1131,10 +1131,10 @@ void t1_decode_cblks( opj_tcd_band_t* restrict band = &res->bands[bandno]; for (precno = 0; precno < res->pw * res->ph; ++precno) { - opj_tcd_precinct_t* prc = &band->precincts[precno]; + opj_tcd_precinct_t* precinct = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) { - opj_tcd_cblk_t* cblk = &prc->cblks[cblkno]; + for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) { + opj_tcd_cblk_t* cblk = &precinct->cblks[cblkno]; int* restrict datap; void* restrict tiledp; int cblk_w, cblk_h; @@ -1194,6 +1194,7 @@ void t1_decode_cblks( } } } /* cblkno */ + opj_free(precinct->cblks); } /* precno */ } /* bandno */ } /* resno */ diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c index 7fb53ef2..b10b822d 100644 --- a/libopenjpeg/t2.c +++ b/libopenjpeg/t2.c @@ -323,9 +323,8 @@ 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_tilecomp_t *tilec = &tile->comps[compno]; - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - + opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno]; + unsigned char *hd = NULL; int present; diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 533fd246..1303c5f8 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -641,7 +641,6 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { w = int_ceildivpow2(x1 - x0, image->comps[i].factor); h = int_ceildivpow2(y1 - y0, image->comps[i].factor); - image->comps[i].data = (int *) opj_malloc(w * h * sizeof(int)); image->comps[i].w = w; image->comps[i].h = h; image->comps[i].x0 = x0; @@ -671,8 +670,6 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); - /* 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)); tilec->numresolutions = tccp->numresolutions; tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t)); @@ -1352,7 +1349,10 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op t1_time = opj_clock(); /* time needed to decode a tile */ t1 = t1_create(tcd->cinfo); for (compno = 0; compno < tile->numcomps; ++compno) { - t1_decode_cblks(t1, &tile->comps[compno], &tcd->tcp->tccps[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)); + t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]); } t1_destroy(t1); t1_time = opj_clock() - t1_time; @@ -1423,6 +1423,9 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op int offset_y = int_ceildivpow2(imagec->y0, imagec->factor); int i, j; + if(!imagec->data){ + imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int)); + } if(tcd->tcp->tccps[compno].qmfbid == 1) { for(j = res->y0; j < res->y1; ++j) { for(i = res->x0; i < res->x1; ++i) { @@ -1441,16 +1444,12 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op } } } + opj_aligned_free(tilec->data); } tile_time = opj_clock() - tile_time; /* time needed to decode a tile */ opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); - for (compno = 0; compno < tile->numcomps; compno++) { - opj_aligned_free(tcd->tcd_image->tiles[tileno].comps[compno].data); - tcd->tcd_image->tiles[tileno].comps[compno].data = NULL; - } - if (eof) { return false; } @@ -1460,7 +1459,7 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op void tcd_free_decode(opj_tcd_t *tcd) { opj_tcd_image_t *tcd_image = tcd->tcd_image; - if (tcd_image->tiles != NULL) opj_free(tcd_image->tiles); + opj_free(tcd_image->tiles); } void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { @@ -1477,15 +1476,14 @@ void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { 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 != NULL) opj_free(prec->cblks); if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); if (prec->incltree != NULL) tgt_destroy(prec->incltree); } - if (band->precincts != NULL) opj_free(band->precincts); + opj_free(band->precincts); } } - if (tilec->resolutions != NULL) opj_free(tilec->resolutions); + opj_free(tilec->resolutions); } - if (tile->comps != NULL) opj_free(tile->comps); + opj_free(tile->comps); }