From c3629e37a206ec8a60da6c00dbc04bf4a28b2868 Mon Sep 17 00:00:00 2001 From: Antonin Descampe Date: Mon, 3 Nov 2014 14:51:41 +0000 Subject: [PATCH] [trunk] significantly reduces memory for single tile RGB encoding (fixes issue 375) --- src/lib/openjp2/j2k.c | 186 +++++++++++++++++++++++++++++------------- src/lib/openjp2/t1.c | 62 ++++++++------ src/lib/openjp2/t1.h | 6 +- src/lib/openjp2/tcd.c | 67 +++++++++------ src/lib/openjp2/tcd.h | 25 ++++-- 5 files changed, 229 insertions(+), 117 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 46f50eeb..daa63a0e 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -338,6 +338,18 @@ static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image); +static void opj_get_tile_dimensions(opj_image_t * l_image, + opj_tcd_tilecomp_t * l_tilec, + opj_image_comp_t * l_img_comp, + OPJ_UINT32* l_size_comp, + OPJ_UINT32* l_width, + OPJ_UINT32* l_height, + OPJ_UINT32* l_offset_x, + OPJ_UINT32* l_offset_y, + OPJ_UINT32* l_image_width, + OPJ_UINT32* l_stride, + OPJ_UINT32* l_tile_offset); + static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data); static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k, @@ -9756,50 +9768,82 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { - OPJ_UINT32 i; + OPJ_UINT32 i, j; OPJ_UINT32 l_nb_tiles; - OPJ_UINT32 l_max_tile_size, l_current_tile_size; - OPJ_BYTE * l_current_data; + OPJ_UINT32 l_max_tile_size = 0, l_current_tile_size; + OPJ_BYTE * l_current_data = 00; + opj_tcd_t* p_tcd = 00; /* preconditions */ assert(p_j2k != 00); assert(p_stream != 00); assert(p_manager != 00); - - l_current_data = (OPJ_BYTE*)opj_malloc(1000); - if (! l_current_data) { - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); - return OPJ_FALSE; - } - l_max_tile_size = 1000; + + p_tcd = p_j2k->m_tcd; l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; for (i=0;im_tcd); - if (l_current_tile_size > l_max_tile_size) { - OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size); - if (! l_new_current_data) { - opj_free(l_current_data); - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); - return OPJ_FALSE; + /* if we only have one tile, then simply set tile component data equal to image component data */ + /* otherwise, allocate the data */ + for (j=0;jm_tcd->image->numcomps;++j) { + opj_tcd_tilecomp_t* l_tilec = p_tcd->tcd_image->tiles->comps + j; + if (l_nb_tiles == 1) { + opj_image_comp_t * l_img_comp = p_tcd->image->comps + j; + l_tilec->data = l_img_comp->data; + l_tilec->ownsData = OPJ_FALSE; + } else { + if(! opj_alloc_tile_component_data(l_tilec)) { + opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." ); + if (l_current_data) { + opj_free(l_current_data); + } + return OPJ_FALSE; + } + opj_alloc_tile_component_data(l_tilec); } - l_current_data = l_new_current_data; - l_max_tile_size = l_current_tile_size; } + l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd); + if (l_nb_tiles > 1) { + if (l_current_tile_size > l_max_tile_size) { + OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size); + if (! l_new_current_data) { + if (l_current_data) { + opj_free(l_current_data); + } + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); + return OPJ_FALSE; + } + l_current_data = l_new_current_data; + l_max_tile_size = l_current_tile_size; + } - opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data); + /* copy image data (32 bit) to l_current_data as contiguous, all-component, zero offset buffer */ + /* 32 bit components @ 8 bit precision get converted to 8 bit */ + /* 32 bit components @ 16 bit precision get converted to 16 bit */ + opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data); + + /* now copy this data into the tile component */ + if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,l_current_data,l_current_tile_size)) { + opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); + return OPJ_FALSE; + } + } if (! opj_j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) { return OPJ_FALSE; } } - opj_free(l_current_data); + if (l_current_data) { + opj_free(l_current_data); + } return OPJ_TRUE; } @@ -9891,37 +9935,61 @@ OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, return OPJ_TRUE; } +void opj_get_tile_dimensions(opj_image_t * l_image, + opj_tcd_tilecomp_t * l_tilec, + opj_image_comp_t * l_img_comp, + OPJ_UINT32* l_size_comp, + OPJ_UINT32* l_width, + OPJ_UINT32* l_height, + OPJ_UINT32* l_offset_x, + OPJ_UINT32* l_offset_y, + OPJ_UINT32* l_image_width, + OPJ_UINT32* l_stride, + OPJ_UINT32* l_tile_offset) { + OPJ_UINT32 l_remaining; + *l_size_comp = l_img_comp->prec >> 3; /* (/8) */ + l_remaining = l_img_comp->prec & 7; /* (%8) */ + if (l_remaining) { + *l_size_comp += 1; + } + + if (*l_size_comp == 3) { + *l_size_comp = 4; + } + + *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); + *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); + *l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + *l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); + *l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + *l_stride = *l_image_width - *l_width; + *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; +} + void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) { OPJ_UINT32 i,j,k = 0; - OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width; - opj_image_comp_t * l_img_comp = 00; - opj_tcd_tilecomp_t * l_tilec = 00; - opj_image_t * l_image = 00; - OPJ_UINT32 l_size_comp, l_remaining; - OPJ_INT32 * l_src_ptr; - l_tilec = p_tcd->tcd_image->tiles->comps; - l_image = p_tcd->image; - l_img_comp = l_image->comps; for (i=0;iimage->numcomps;++i) { - l_size_comp = l_img_comp->prec >> 3; /* (/8) */ - l_remaining = l_img_comp->prec & 7; /* (%8) */ - if (l_remaining) { - ++l_size_comp; - } + opj_image_t * l_image = p_tcd->image; + OPJ_INT32 * l_src_ptr; + opj_tcd_tilecomp_t * l_tilec = p_tcd->tcd_image->tiles->comps + i; + opj_image_comp_t * l_img_comp = l_image->comps + i; + OPJ_UINT32 l_size_comp,l_width,l_height,l_offset_x,l_offset_y, l_image_width,l_stride,l_tile_offset; - if (l_size_comp == 3) { - l_size_comp = 4; - } + opj_get_tile_dimensions(l_image, + l_tilec, + l_img_comp, + &l_size_comp, + &l_width, + &l_height, + &l_offset_x, + &l_offset_y, + &l_image_width, + &l_stride, + &l_tile_offset); - l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); - l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); - l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); - l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); - l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); - l_stride = l_image_width - l_width; - l_src_ptr = l_img_comp->data + ((OPJ_UINT32)l_tilec->x0 - l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - l_offset_y) * l_image_width; + l_src_ptr = l_img_comp->data + l_tile_offset; switch (l_size_comp) { case 1: @@ -9988,9 +10056,6 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) } break; } - - ++l_img_comp; - ++l_tilec; } } @@ -10010,16 +10075,11 @@ OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); l_tcd = p_j2k->m_tcd; - + l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size; l_available_data = l_tile_size; l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data; - if (! opj_tcd_copy_tile_data(l_tcd,p_data,p_data_size)) { - opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); - return OPJ_FALSE; - } - l_nb_bytes_written = 0; if (! opj_j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) { return OPJ_FALSE; @@ -10490,6 +10550,22 @@ OPJ_BOOL opj_j2k_write_tile (opj_j2k_t * p_j2k, return OPJ_FALSE; } else { + OPJ_UINT32 j; + /* Allocate data */ + for (j=0;jm_tcd->image->numcomps;++j) { + opj_tcd_tilecomp_t* l_tilec = p_j2k->m_tcd->tcd_image->tiles->comps + j; + + if(! opj_alloc_tile_component_data(l_tilec)) { + opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." ); + return OPJ_FALSE; + } + } + + /* now copy data into the the tile component */ + if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,p_data,p_data_size)) { + opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); + return OPJ_FALSE; + } if (! opj_j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) { opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index); return OPJ_FALSE; diff --git a/src/lib/openjp2/t1.c b/src/lib/openjp2/t1.c index 56468963..11b72a33 100644 --- a/src/lib/openjp2/t1.c +++ b/src/lib/openjp2/t1.c @@ -496,7 +496,7 @@ void opj_t1_enc_sigpass(opj_t1_t *t1, opj_t1_enc_sigpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], orient, bpno, one, @@ -718,7 +718,7 @@ void opj_t1_enc_refpass( opj_t1_enc_refpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], bpno, one, nmsedec, @@ -970,7 +970,7 @@ void opj_t1_enc_clnpass( } if (agg) { for (runlen = 0; runlen < 4; ++runlen) { - if (opj_int_abs(t1->data[((k + runlen)*t1->w) + i]) & one) + if (opj_int_abs(t1->data[((k + runlen)*t1->data_stride) + i]) & one) break; } opj_mqc_setcurctx(mqc, T1_CTXNO_AGG); @@ -989,7 +989,7 @@ void opj_t1_enc_clnpass( opj_t1_enc_clnpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], orient, bpno, one, @@ -1166,17 +1166,19 @@ OPJ_BOOL opj_t1_allocate_buffers( OPJ_UINT32 datasize=w * h; OPJ_UINT32 flagssize; - if(datasize > t1->datasize){ - opj_aligned_free(t1->data); - t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32)); - if(!t1->data){ - /* FIXME event manager error callback */ - return OPJ_FALSE; + /* encoder uses tile buffer, so no need to allocate */ + if (!t1->encoder) { + if(datasize > t1->datasize){ + opj_aligned_free(t1->data); + t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32)); + if(!t1->data){ + /* FIXME event manager error callback */ + return OPJ_FALSE; + } + t1->datasize=datasize; } - t1->datasize=datasize; + memset(t1->data,0,datasize * sizeof(OPJ_INT32)); } - memset(t1->data,0,datasize * sizeof(OPJ_INT32)); - t1->flags_stride=w+2; flagssize=t1->flags_stride * (h+2); @@ -1205,7 +1207,7 @@ OPJ_BOOL opj_t1_allocate_buffers( * and initializes the look-up tables of the Tier-1 coder/decoder * @return a new T1 handle if successful, returns NULL otherwise */ -opj_t1_t* opj_t1_create() +opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder) { opj_t1_t *l_t1 = 00; @@ -1226,6 +1228,7 @@ opj_t1_t* opj_t1_create() opj_t1_destroy(l_t1); return 00; } + l_t1->encoder = isEncoder; return l_t1; } @@ -1248,7 +1251,8 @@ void opj_t1_destroy(opj_t1_t *p_t1) opj_raw_destroy(p_t1->raw); p_t1->raw = 00; - if (p_t1->data) { + /* encoder uses tile buffer, so no need to free */ + if (!p_t1->encoder && p_t1->data) { opj_aligned_free(p_t1->data); p_t1->data = 00; } @@ -1482,11 +1486,10 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) { opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; - OPJ_INT32 * restrict datap; OPJ_INT32* restrict tiledp; OPJ_UINT32 cblk_w; OPJ_UINT32 cblk_h; - OPJ_UINT32 i, j; + OPJ_UINT32 i, j, tileIndex=0, tileLineAdvance; OPJ_INT32 x = cblk->x0 - band->x0; OPJ_INT32 y = cblk->y0 - band->y0; @@ -1507,27 +1510,32 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, return OPJ_FALSE; } - datap=t1->data; cblk_w = t1->w; cblk_h = t1->h; + tileLineAdvance = tile_w - cblk_w; tiledp=&tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x]; + t1->data = tiledp; + t1->data_stride = tile_w; if (tccp->qmfbid == 1) { for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { - OPJ_INT32 tmp = tiledp[(j * tile_w) + i]; - datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS; + tiledp[tileIndex] <<= T1_NMSEDEC_FRACBITS; + tileIndex++; } + tileIndex += tileLineAdvance; } } else { /* if (tccp->qmfbid == 0) */ for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { - OPJ_INT32 tmp = tiledp[(j * tile_w) + i]; - datap[(j * cblk_w) + i] = + OPJ_INT32 tmp = tiledp[tileIndex]; + tiledp[tileIndex] = opj_int_fix_mul( tmp, bandconst) >> (11 - T1_NMSEDEC_FRACBITS); + tileIndex++; } + tileIndex += tileLineAdvance; } } @@ -1574,14 +1582,16 @@ void opj_t1_encode_cblk(opj_t1_t *t1, OPJ_UINT32 passtype; OPJ_INT32 nmsedec = 0; OPJ_INT32 max; - OPJ_UINT32 i; + OPJ_UINT32 i, j; OPJ_BYTE type = T1_TYPE_MQ; OPJ_FLOAT64 tempwmsedec; max = 0; - for (i = 0; i < t1->w * t1->h; ++i) { - OPJ_INT32 tmp = abs(t1->data[i]); - max = opj_int_max(max, tmp); + for (i = 0; i < t1->w; ++i) { + for (j = 0; j < t1->h; ++j) { + OPJ_INT32 tmp = abs(t1->data[i + j*t1->data_stride]); + max = opj_int_max(max, tmp); + } } cblk->numbps = max ? (OPJ_UINT32)((opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS) : 0; diff --git a/src/lib/openjp2/t1.h b/src/lib/openjp2/t1.h index e5be70ed..e1d41ed5 100644 --- a/src/lib/openjp2/t1.h +++ b/src/lib/openjp2/t1.h @@ -103,13 +103,15 @@ typedef struct opj_t1 { /** RAW component */ opj_raw_t *raw; - OPJ_INT32 *data; + OPJ_INT32 *data; opj_flag_t *flags; OPJ_UINT32 w; OPJ_UINT32 h; OPJ_UINT32 datasize; OPJ_UINT32 flagssize; OPJ_UINT32 flags_stride; + OPJ_UINT32 data_stride; + OPJ_BOOL encoder; } opj_t1_t; #define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)] @@ -147,7 +149,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, * and initializes the look-up tables of the Tier-1 coder/decoder * @return a new T1 handle if successful, returns NULL otherwise */ -opj_t1_t* opj_t1_create(void); +opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder); /** * Destroys a previously created T1 handle diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index 1720b8ef..e368d4ce 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -611,6 +611,37 @@ void opj_tcd_destroy(opj_tcd_t *tcd) { } } +OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec) +{ + if ((l_tilec->data == 00) || ((l_tilec->data_size_needed > l_tilec->data_size) && (l_tilec->ownsData == OPJ_FALSE))) { + l_tilec->data = (OPJ_INT32 *) opj_malloc(l_tilec->data_size_needed); + if (! l_tilec->data ) { + return OPJ_FALSE; + } + /*fprintf(stderr, "tAllocate data of tilec (int): %d x OPJ_UINT32n",l_data_size);*/ + l_tilec->data_size = l_tilec->data_size_needed; + l_tilec->ownsData = OPJ_TRUE; + } + else if (l_tilec->data_size_needed > l_tilec->data_size) { + OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_tilec->data_size_needed); + /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile datan"); */ + /* fprintf(stderr, "Not enough memory to handle tile data"); */ + if (! new_data) { + opj_free(l_tilec->data); + l_tilec->data = NULL; + l_tilec->data_size = 0; + l_tilec->data_size_needed = 0; + l_tilec->ownsData = OPJ_FALSE; + return OPJ_FALSE; + } + l_tilec->data = new_data; + /*fprintf(stderr, "tReallocate data of tilec (int): from %d to %d x OPJ_UINT32n", l_tilec->data_size, l_data_size);*/ + l_tilec->data_size = l_tilec->data_size_needed; + l_tilec->ownsData = OPJ_TRUE; + } + return OPJ_TRUE; +} + /* ----------------------------------------------------------------------- */ #define OPJ_MACRO_TCD_ALLOCATE(FUNCTION,TYPE,FRACTION,ELEMENT,FUNCTION_ELEMENT) \ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ @@ -695,29 +726,10 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ - l_cp->m_specific_param.m_dec.m_reduce; \ } \ \ - if (l_tilec->data == 00) { \ - l_tilec->data = (OPJ_INT32 *) opj_malloc(l_data_size); \ - if (! l_tilec->data ) { \ - return OPJ_FALSE; \ - } \ - /*fprintf(stderr, "\tAllocate data of tilec (int): %d x OPJ_UINT32\n",l_data_size);*/ \ - \ - l_tilec->data_size = l_data_size; \ - } \ - else if (l_data_size > l_tilec->data_size) { \ - OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_data_size); \ - /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile data\n"); */ \ - fprintf(stderr, "Not enough memory to handle tile data\n"); \ - if (! new_data) { \ - opj_free(l_tilec->data); \ - l_tilec->data = NULL; \ - l_tilec->data_size = 0; \ - return OPJ_FALSE; \ - } \ - l_tilec->data = new_data; \ - /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->data_size, l_data_size);*/ \ - l_tilec->data_size = l_data_size; \ - } \ + l_tilec->data_size_needed = l_data_size; \ + if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) { \ + return OPJ_FALSE; \ + } \ \ l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); \ \ @@ -1457,9 +1469,12 @@ void opj_tcd_free_tile(opj_tcd_t *p_tcd) l_tile_comp->resolutions = 00; } - if (l_tile_comp->data) { + if (l_tile_comp->ownsData && l_tile_comp->data) { opj_free(l_tile_comp->data); l_tile_comp->data = 00; + l_tile_comp->ownsData = 0; + l_tile_comp->data_size = 0; + l_tile_comp->data_size_needed = 0; } ++l_tile_comp; } @@ -1512,7 +1527,7 @@ OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd ) opj_tccp_t * l_tccp = p_tcd->tcp->tccps; - l_t1 = opj_t1_create(); + l_t1 = opj_t1_create(OPJ_FALSE); if (l_t1 == 00) { return OPJ_FALSE; } @@ -1947,7 +1962,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd ) const OPJ_FLOAT64 * l_mct_norms; opj_tcp_t * l_tcp = p_tcd->tcp; - l_t1 = opj_t1_create(); + l_t1 = opj_t1_create(OPJ_TRUE); if (l_t1 == 00) { return OPJ_FALSE; } diff --git a/src/lib/openjp2/tcd.h b/src/lib/openjp2/tcd.h index 360923b1..bcd5135b 100644 --- a/src/lib/openjp2/tcd.h +++ b/src/lib/openjp2/tcd.h @@ -155,14 +155,16 @@ FIXME DOC */ typedef struct opj_tcd_tilecomp { - OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ - OPJ_UINT32 numresolutions; /* number of resolutions level */ - OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/ - opj_tcd_resolution_t *resolutions; /* resolutions information */ - OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */ - OPJ_INT32 *data; /* data of the component */ - OPJ_UINT32 data_size; /* size of the data of the component */ - OPJ_INT32 numpix; /* add fixed_quality */ + OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + OPJ_UINT32 numresolutions; /* number of resolutions level */ + OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/ + opj_tcd_resolution_t *resolutions; /* resolutions information */ + OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */ + OPJ_INT32 *data; /* data of the component */ + OPJ_BOOL ownsData; /* if true, then need to free after usage, otherwise do not free */ + OPJ_UINT32 data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */ + OPJ_UINT32 data_size; /* size of the data of the component */ + OPJ_INT32 numpix; /* add fixed_quality */ } opj_tcd_tilecomp_t; @@ -346,6 +348,13 @@ OPJ_BOOL opj_tcd_copy_tile_data (opj_tcd_t *p_tcd, OPJ_BYTE * p_src, OPJ_UINT32 p_src_length ); +/** + * Allocates tile component data + * + * + */ +OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec); + /* ----------------------------------------------------------------------- */ /*@}*/