diff options
| author | Mickael Savinaud <savmickael@users.noreply.github.com> | 2011-09-19 13:04:04 +0000 |
|---|---|---|
| committer | Mickael Savinaud <savmickael@users.noreply.github.com> | 2011-09-19 13:04:04 +0000 |
| commit | b551844cc2412981bcf7c26c897c07c0e6bc6a8e (patch) | |
| tree | 1326e5824e0eeb5daf8ea7b49c8a14094a655b99 /libopenjpeg/tcd.c | |
| parent | 93f3e2b007e79fc6e06621e10750b8980f2078bb (diff) | |
Work In Progress: insert elements from V2 framework into the trunk
Diffstat (limited to 'libopenjpeg/tcd.c')
| -rw-r--r-- | libopenjpeg/tcd.c | 1178 |
1 files changed, 1178 insertions, 0 deletions
diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 9c7bcc0d..5a0f0f4d 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -90,7 +90,43 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { } fprintf(fd, "}\n"); } +/** +* Allocates memory for a decoding code block. +*/ +static opj_bool tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block); + +/** +Free the memory allocated for encoding +@param tcd TCD handle +*/ +static void tcd_free_tile(opj_tcd_v2_t *tcd); + + +opj_bool tcd_t2_decode ( + opj_tcd_v2_t *p_tcd, + OPJ_BYTE * p_src_data, + OPJ_UINT32 * p_data_read, + OPJ_UINT32 p_max_src_size, + opj_codestream_info_t *p_cstr_info + ); +opj_bool tcd_t1_decode ( + opj_tcd_v2_t *p_tcd + ); + +opj_bool tcd_dwt_decode ( + opj_tcd_v2_t *p_tcd + ); + +opj_bool tcd_mct_decode ( + opj_tcd_v2_t *p_tcd + ); + +opj_bool tcd_dc_level_shift_decode ( + opj_tcd_v2_t *p_tcd + ); + +void tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct); /* ----------------------------------------------------------------------- */ /** @@ -111,6 +147,33 @@ opj_tcd_t* tcd_create(opj_common_ptr cinfo) { } /** +Create a new TCD handle +*/ +opj_tcd_v2_t* tcd_create_v2(opj_bool p_is_decoder) +{ + opj_tcd_v2_t *l_tcd = 00; + + /* create the tcd structure */ + l_tcd = (opj_tcd_v2_t*) opj_malloc(sizeof(opj_tcd_v2_t)); + if + (!l_tcd) + { + return 00; + } + memset(l_tcd,0,sizeof(opj_tcd_v2_t)); + l_tcd->m_is_decoder = p_is_decoder ? 1 : 0; + l_tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t)); + if + (!l_tcd->tcd_image) + { + opj_free(l_tcd); + return 00; + } + memset(l_tcd->tcd_image,0,sizeof(opj_tcd_image_t)); + return l_tcd; +} + +/** Destroy a previously created TCD handle */ void tcd_destroy(opj_tcd_t *tcd) { @@ -1520,4 +1583,1119 @@ void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { } +opj_bool tcd_init_v2( + opj_tcd_v2_t *p_tcd, + opj_image_t * p_image, + opj_cp_v2_t * p_cp + ) +{ + OPJ_UINT32 l_tile_comp_size; + + p_tcd->image = p_image; + p_tcd->cp = p_cp; + p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t)); + + if + (! p_tcd->tcd_image->tiles) + { + return OPJ_FALSE; + } + memset(p_tcd->tcd_image->tiles,0, sizeof(opj_tcd_tile_t)); + + l_tile_comp_size = p_image->numcomps * sizeof(opj_tcd_tilecomp_t); + p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_malloc(l_tile_comp_size); + if + (! p_tcd->tcd_image->tiles->comps ) + { + return OPJ_FALSE; + } + memset( p_tcd->tcd_image->tiles->comps , 0 , l_tile_comp_size); + p_tcd->tcd_image->tiles->numcomps = p_image->numcomps; + p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos; + return OPJ_TRUE; +} + +/** +Destroy a previously created TCD handle +*/ +void tcd_destroy_v2(opj_tcd_v2_t *tcd) { + if + (tcd) + { + tcd_free_tile(tcd); + if + (tcd->tcd_image) + { + opj_free(tcd->tcd_image); + tcd->tcd_image = 00; + } + opj_free(tcd); + } +} + +/* ----------------------------------------------------------------------- */ +/** + * Initialize the tile coder and may reuse some meory. + * @param p_tcd TCD handle. + * @param p_image raw image. + * @param p_cp coding parameters. + * @param p_tile_no current tile index to encode. + * + * @return true if the encoding values could be set (false otherwise). +*/ +#define MACRO_TCD_ALLOCATE(FUNCTION,TYPE,FRACTION,ELEMENT,FUNCTION_ELEMENT) \ +opj_bool FUNCTION \ + ( \ + opj_tcd_v2_t *p_tcd, \ + OPJ_UINT32 p_tile_no \ + ) \ +{ \ + OPJ_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00; \ + OPJ_UINT32 compno, resno, bandno, precno, cblkno; \ + opj_tcp_v2_t * l_tcp = 00; \ + opj_cp_v2_t * l_cp = 00; \ + opj_tcd_tile_t * l_tile = 00; \ + opj_tccp_t *l_tccp = 00; \ + opj_tcd_tilecomp_t *l_tilec = 00; \ + opj_image_comp_t * l_image_comp = 00; \ + opj_tcd_resolution_t *l_res = 00; \ + opj_tcd_band_t *l_band = 00; \ + opj_stepsize_t * l_step_size = 00; \ + opj_tcd_precinct_t *l_current_precinct = 00; \ + TYPE* l_code_block = 00; \ + opj_image_t * l_image = 00; \ + OPJ_UINT32 p,q; \ + OPJ_UINT32 l_level_no; \ + OPJ_UINT32 l_pdx, l_pdy; \ + OPJ_UINT32 l_gain; \ + OPJ_INT32 l_x0b, l_y0b; \ + /* extent of precincts , top left, bottom right**/ \ + OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end; \ + /* number of precinct for a resolution */ \ + OPJ_UINT32 l_nb_precincts; \ + /* room needed to store l_nb_precinct precinct for a resolution */ \ + OPJ_UINT32 l_nb_precinct_size; \ + /* number of code blocks for a precinct*/ \ + OPJ_UINT32 l_nb_code_blocks; \ + /* room needed to store l_nb_code_blocks code blocks for a precinct*/ \ + OPJ_UINT32 l_nb_code_blocks_size; \ + /* size of data for a tile */ \ + OPJ_UINT32 l_data_size; \ + l_cp = p_tcd->cp; \ + l_tcp = &(l_cp->tcps[p_tile_no]); \ + l_tile = p_tcd->tcd_image->tiles; \ + l_tccp = l_tcp->tccps; \ + l_tilec = l_tile->comps; \ + l_image = p_tcd->image; \ + l_image_comp = p_tcd->image->comps; \ + \ + p = p_tile_no % l_cp->tw; /* tile coordinates */ \ + q = p_tile_no / l_cp->tw; \ + \ + /* 4 borders of the tile rescale on the image if necessary */ \ + l_tile->x0 = int_max(l_cp->tx0 + p * l_cp->tdx, l_image->x0); \ + l_tile->y0 = int_max(l_cp->ty0 + q * l_cp->tdy, l_image->y0); \ + l_tile->x1 = int_min(l_cp->tx0 + (p + 1) * l_cp->tdx, l_image->x1); \ + l_tile->y1 = int_min(l_cp->ty0 + (q + 1) * l_cp->tdy, l_image->y1); \ + /*tile->numcomps = image->numcomps; */ \ + for \ + (compno = 0; compno < l_tile->numcomps; ++compno) \ + { \ + /* border of each l_tile component (global) */ \ + l_tilec->x0 = int_ceildiv(l_tile->x0, l_image_comp->dx); \ + l_tilec->y0 = int_ceildiv(l_tile->y0, l_image_comp->dy); \ + l_tilec->x1 = int_ceildiv(l_tile->x1, l_image_comp->dx); \ + l_tilec->y1 = int_ceildiv(l_tile->y1, l_image_comp->dy); \ + \ + l_data_size = (l_tilec->x1 - l_tilec->x0) \ + * (l_tilec->y1 - l_tilec->y0) * sizeof(OPJ_UINT32 ); \ + l_tilec->numresolutions = l_tccp->numresolutions; \ + if \ + (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce)\ + { \ + l_tilec->minimum_num_resolutions = 1; \ + } \ + else \ + { \ + l_tilec->minimum_num_resolutions = l_tccp->numresolutions - l_cp->m_specific_param.m_dec.m_reduce;\ + } \ + if \ + (l_tilec->data == 00) \ + { \ + l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_data_size); \ + if \ + (! l_tilec->data ) \ + { \ + return OPJ_FALSE; \ + } \ + l_tilec->data_size = l_data_size; \ + } \ + else if \ + (l_data_size > l_tilec->data_size) \ + { \ + l_tilec->data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_data_size);\ + if \ + (! l_tilec->data) \ + { \ + return OPJ_FALSE; \ + } \ + l_tilec->data_size = l_data_size; \ + } \ + l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t);\ + if \ + (l_tilec->resolutions == 00) \ + { \ + l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);\ + if \ + (! l_tilec->resolutions ) \ + { \ + return OPJ_FALSE; \ + } \ + l_tilec->resolutions_size = l_data_size; \ + memset(l_tilec->resolutions,0,l_data_size); \ + } \ + else if \ + (l_data_size > l_tilec->resolutions_size) \ + { \ + l_tilec->resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size);\ + if \ + (! l_tilec->resolutions) \ + { \ + return OPJ_FALSE; \ + } \ + memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);\ + l_tilec->resolutions_size = l_data_size; \ + } \ + l_level_no = l_tilec->numresolutions - 1; \ + l_res = l_tilec->resolutions; \ + l_step_size = l_tccp->stepsizes; \ + if \ + (l_tccp->qmfbid == 0) \ + { \ + l_gain_ptr = &dwt_getgain_real; \ + } \ + else \ + { \ + l_gain_ptr = &dwt_getgain; \ + } \ + for \ + (resno = 0; resno < l_tilec->numresolutions; ++resno) \ + { \ + OPJ_INT32 tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; \ + OPJ_UINT32 cbgwidthexpn, cbgheightexpn; \ + OPJ_UINT32 cblkwidthexpn, cblkheightexpn; \ + /* border for each resolution level (global) */ \ + l_res->x0 = int_ceildivpow2(l_tilec->x0, l_level_no); \ + l_res->y0 = int_ceildivpow2(l_tilec->y0, l_level_no); \ + l_res->x1 = int_ceildivpow2(l_tilec->x1, l_level_no); \ + l_res->y1 = int_ceildivpow2(l_tilec->y1, l_level_no); \ + /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */\ + l_pdx = l_tccp->prcw[resno]; \ + l_pdy = l_tccp->prch[resno]; \ + /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ \ + l_tl_prc_x_start = int_floordivpow2(l_res->x0, l_pdx) << l_pdx; \ + l_tl_prc_y_start = int_floordivpow2(l_res->y0, l_pdy) << l_pdy; \ + l_br_prc_x_end = int_ceildivpow2(l_res->x1, l_pdx) << l_pdx; \ + l_br_prc_y_end = int_ceildivpow2(l_res->y1, l_pdy) << l_pdy; \ + \ + l_res->pw = (l_res->x0 == l_res->x1) ? 0 : ((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);\ + l_res->ph = (l_res->y0 == l_res->y1) ? 0 : ((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);\ + l_nb_precincts = l_res->pw * l_res->ph; \ + l_nb_precinct_size = l_nb_precincts * sizeof(opj_tcd_precinct_t);\ + if \ + (resno == 0) \ + { \ + tlcbgxstart = l_tl_prc_x_start; \ + tlcbgystart = l_tl_prc_y_start; \ + brcbgxend = l_br_prc_x_end; \ + brcbgyend = l_br_prc_y_end; \ + cbgwidthexpn = l_pdx; \ + cbgheightexpn = l_pdy; \ + l_res->numbands = 1; \ + } \ + else \ + { \ + tlcbgxstart = int_ceildivpow2(l_tl_prc_x_start, 1); \ + tlcbgystart = int_ceildivpow2(l_tl_prc_y_start, 1); \ + brcbgxend = int_ceildivpow2(l_br_prc_x_end, 1); \ + brcbgyend = int_ceildivpow2(l_br_prc_y_end, 1); \ + cbgwidthexpn = l_pdx - 1; \ + cbgheightexpn = l_pdy - 1; \ + l_res->numbands = 3; \ + } \ + \ + cblkwidthexpn = uint_min(l_tccp->cblkw, cbgwidthexpn); \ + cblkheightexpn = uint_min(l_tccp->cblkh, cbgheightexpn); \ + l_band = l_res->bands; \ + for \ + (bandno = 0; bandno < l_res->numbands; ++bandno) \ + { \ + OPJ_INT32 numbps; \ + if \ + (resno == 0) \ + { \ + l_band->bandno = 0 ; \ + l_band->x0 = int_ceildivpow2(l_tilec->x0, l_level_no); \ + l_band->y0 = int_ceildivpow2(l_tilec->y0, l_level_no); \ + l_band->x1 = int_ceildivpow2(l_tilec->x1, l_level_no); \ + l_band->y1 = int_ceildivpow2(l_tilec->y1, l_level_no); \ + } \ + else \ + { \ + l_band->bandno = bandno + 1; \ + /* x0b = 1 if bandno = 1 or 3 */ \ + l_x0b = l_band->bandno&1; \ + /* y0b = 1 if bandno = 2 or 3 */ \ + l_y0b = (l_band->bandno)>>1; \ + /* l_band border (global) */ \ + l_band->x0 = int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, l_level_no + 1);\ + l_band->y0 = int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, l_level_no + 1);\ + l_band->x1 = int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, l_level_no + 1);\ + l_band->y1 = int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, l_level_no + 1);\ + } \ + /** avoid an if with storing function pointer */ \ + l_gain = (*l_gain_ptr) (l_band->bandno); \ + numbps = l_image_comp->prec + l_gain; \ + l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * FRACTION;\ + l_band->numbps = l_step_size->expn + l_tccp->numgbits - 1; /* WHY -1 ? */\ + if \ + (! l_band->precincts) \ + { \ + l_band->precincts = (opj_tcd_precinct_t *) opj_malloc(/*3 * */ l_nb_precinct_size);\ + if \ + (! l_band->precincts) \ + { \ + return OPJ_FALSE; \ + } \ + memset(l_band->precincts,0,l_nb_precinct_size); \ + l_band->precincts_data_size = l_nb_precinct_size; \ + } \ + else if \ + (l_band->precincts_data_size < l_nb_precinct_size) \ + { \ + l_band->precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);\ + if \ + (! l_band->precincts) \ + { \ + return OPJ_FALSE; \ + } \ + memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size);\ + l_band->precincts_data_size = l_nb_precinct_size; \ + } \ + l_current_precinct = l_band->precincts; \ + for \ + (precno = 0; precno < l_nb_precincts; ++precno) \ + { \ + OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; \ + OPJ_INT32 cbgxstart = tlcbgxstart + (precno % l_res->pw) * (1 << cbgwidthexpn);\ + OPJ_INT32 cbgystart = tlcbgystart + (precno / l_res->pw) * (1 << cbgheightexpn);\ + OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn); \ + OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn); \ + /* precinct size (global) */ \ + l_current_precinct->x0 = int_max(cbgxstart, l_band->x0);\ + l_current_precinct->y0 = int_max(cbgystart, l_band->y0);\ + l_current_precinct->x1 = int_min(cbgxend, l_band->x1); \ + l_current_precinct->y1 = int_min(cbgyend, l_band->y1); \ + tlcblkxstart = int_floordivpow2(l_current_precinct->x0, cblkwidthexpn) << cblkwidthexpn;\ + tlcblkystart = int_floordivpow2(l_current_precinct->y0, cblkheightexpn) << cblkheightexpn;\ + brcblkxend = int_ceildivpow2(l_current_precinct->x1, cblkwidthexpn) << cblkwidthexpn;\ + brcblkyend = int_ceildivpow2(l_current_precinct->y1, cblkheightexpn) << cblkheightexpn;\ + l_current_precinct->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\ + l_current_precinct->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;\ + l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;\ + l_nb_code_blocks_size = l_nb_code_blocks * sizeof(TYPE);\ + if \ + (! l_current_precinct->cblks.ELEMENT) \ + { \ + l_current_precinct->cblks.ELEMENT = (TYPE*) opj_malloc(l_nb_code_blocks_size);\ + if \ + (! l_current_precinct->cblks.ELEMENT ) \ + { \ + return OPJ_FALSE; \ + } \ + memset(l_current_precinct->cblks.ELEMENT,0,l_nb_code_blocks_size);\ + l_current_precinct->block_size = l_nb_code_blocks_size;\ + } \ + else if \ + (l_nb_code_blocks_size > l_current_precinct->block_size)\ + { \ + l_current_precinct->cblks.ELEMENT = (TYPE*) \ + opj_realloc(l_current_precinct->cblks.ELEMENT, l_nb_code_blocks_size);\ + if \ + (! l_current_precinct->cblks.ELEMENT ) \ + { \ + return OPJ_FALSE; \ + } \ + memset(((OPJ_BYTE *) l_current_precinct->cblks.ELEMENT) + l_current_precinct->block_size\ + ,0 \ + ,l_nb_code_blocks_size - l_current_precinct->block_size);\ + l_current_precinct->block_size = l_nb_code_blocks_size;\ + } \ + if \ + (! l_current_precinct->incltree) \ + { \ + l_current_precinct->incltree = tgt_create(l_current_precinct->cw,\ + l_current_precinct->ch);\ + } \ + else \ + { \ + l_current_precinct->incltree = tgt_init(l_current_precinct->incltree,\ + l_current_precinct->cw, \ + l_current_precinct->ch);\ + } \ + if \ + (! l_current_precinct->incltree) \ + { \ + return OPJ_FALSE; \ + } \ + if \ + (! l_current_precinct->imsbtree) \ + { \ + l_current_precinct->imsbtree = tgt_create( \ + l_current_precinct->cw,\ + l_current_precinct->ch);\ + } \ + else \ + { \ + l_current_precinct->imsbtree = tgt_init( \ + l_current_precinct->imsbtree,\ + l_current_precinct->cw,\ + l_current_precinct->ch);\ + } \ + if \ + (! l_current_precinct->imsbtree) \ + { \ + return OPJ_FALSE; \ + } \ + l_code_block = l_current_precinct->cblks.ELEMENT; \ + for \ + (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) \ + { \ + OPJ_INT32 cblkxstart = tlcblkxstart + (cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn);\ + OPJ_INT32 cblkystart = tlcblkystart + (cblkno / l_current_precinct->cw) * (1 << cblkheightexpn);\ + OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn); \ + OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn); \ + /* code-block size (global) */ \ + l_code_block->x0 = int_max(cblkxstart, l_current_precinct->x0);\ + l_code_block->y0 = int_max(cblkystart, l_current_precinct->y0);\ + l_code_block->x1 = int_min(cblkxend, l_current_precinct->x1);\ + l_code_block->y1 = int_min(cblkyend, l_current_precinct->y1);\ + if \ + (! FUNCTION_ELEMENT(l_code_block)) \ + { \ + return OPJ_FALSE; \ + } \ + ++l_code_block; \ + } \ + ++l_current_precinct; \ + } /* precno */ \ + ++l_band; \ + ++l_step_size; \ + } /* bandno */ \ + ++l_res; \ + --l_level_no; \ + } /* resno */ \ + ++l_tccp; \ + ++l_tilec; \ + ++l_image_comp; \ + } /* compno */ \ + return OPJ_TRUE; \ +} \ + +// V2 ENCODE MACRO_TCD_ALLOCATE(tcd_init_encode_tile,opj_tcd_cblk_enc_t,1.f,enc,tcd_code_block_enc_allocate) +MACRO_TCD_ALLOCATE(tcd_init_decode_tile,opj_tcd_cblk_dec_t,0.5f,dec,tcd_code_block_dec_allocate) + +#undef MACRO_TCD_ALLOCATE + + +OPJ_UINT32 tcd_get_decoded_tile_size ( + opj_tcd_v2_t *p_tcd + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_data_size = 0; + opj_image_comp_t * l_img_comp = 00; + opj_tcd_tilecomp_t * l_tile_comp = 00; + opj_tcd_resolution_t * l_res = 00; + OPJ_UINT32 l_size_comp, l_remaining; + + l_tile_comp = p_tcd->tcd_image->tiles->comps; + l_img_comp = p_tcd->image->comps; + for + (i=0;i<p_tcd->image->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; + } + if + (l_size_comp == 3) + { + l_size_comp = 4; + } + l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1; + l_data_size += l_size_comp * (l_res->x1 - l_res->x0) * (l_res->y1 - l_res->y0); + ++l_img_comp; + ++l_tile_comp; + } + return l_data_size; +} + + +opj_bool tcd_decode_tile_v2( + opj_tcd_v2_t *p_tcd, + OPJ_BYTE *p_src, + OPJ_UINT32 p_max_length, + OPJ_UINT32 p_tile_no, + opj_codestream_info_t *p_cstr_info) +{ + OPJ_UINT32 l_data_read; + p_tcd->tcd_tileno = p_tile_no; + p_tcd->tcp = &(p_tcd->cp->tcps[p_tile_no]); + + /* INDEX >> */ + if(p_cstr_info) { + OPJ_UINT32 resno, compno, numprec = 0; + for (compno = 0; compno < (OPJ_UINT32) p_cstr_info->numcomps; compno++) { + opj_tcp_v2_t *tcp = &p_tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_tcd_tilecomp_t *tilec_idx = &p_tcd->tcd_image->tiles->comps[compno]; + for (resno = 0; resno < tilec_idx->numresolutions; resno++) { + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno]; + p_cstr_info->tile[p_tile_no].pw[resno] = res_idx->pw; + p_cstr_info->tile[p_tile_no].ph[resno] = res_idx->ph; + numprec += res_idx->pw * res_idx->ph; + p_cstr_info->tile[p_tile_no].pdx[resno] = tccp->prcw[resno]; + p_cstr_info->tile[p_tile_no].pdy[resno] = tccp->prch[resno]; + } + } + p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t *) opj_malloc(p_cstr_info->numlayers * numprec * sizeof(opj_packet_info_t)); + p_cstr_info->packno = 0; + } + /* << INDEX */ + + /*--------------TIER2------------------*/ + // FIXME _ProfStart(PGROUP_T2); + l_data_read = 0; + if + (! tcd_t2_decode(p_tcd,p_src,&l_data_read,p_max_length,p_cstr_info)) + { + return OPJ_FALSE; + } + // FIXME _ProfStop(PGROUP_T2); + + /*------------------TIER1-----------------*/ + + // FIXME _ProfStart(PGROUP_T1); + if + (! tcd_t1_decode(p_tcd)) + { + return OPJ_FALSE; + } + // FIXME _ProfStop(PGROUP_T1); + + /*----------------DWT---------------------*/ + + // FIXME _ProfStart(PGROUP_DWT); + if + (! tcd_dwt_decode(p_tcd)) + { + return OPJ_FALSE; + } + // FIXME _ProfStop(PGROUP_DWT); + + /*----------------MCT-------------------*/ + // FIXME _ProfStart(PGROUP_MCT); + if + (! tcd_mct_decode(p_tcd)) + { + return OPJ_FALSE; + } + // FIXME _ProfStop(PGROUP_MCT); + + // FIXME _ProfStart(PGROUP_DC_SHIFT); + if + (! tcd_dc_level_shift_decode(p_tcd)) + { + return OPJ_FALSE; + } + // FIXME _ProfStop(PGROUP_DC_SHIFT); + + + /*---------------TILE-------------------*/ + return OPJ_TRUE; +} + +opj_bool tcd_update_tile_data ( + opj_tcd_v2_t *p_tcd, + OPJ_BYTE * p_dest, + OPJ_UINT32 p_dest_length + ) +{ + OPJ_UINT32 i,j,k,l_data_size = 0; + opj_image_comp_t * l_img_comp = 00; + opj_tcd_tilecomp_t * l_tilec = 00; + opj_tcd_resolution_t * l_res; + OPJ_UINT32 l_size_comp, l_remaining; + OPJ_UINT32 l_stride, l_width,l_height; + + l_data_size = tcd_get_decoded_tile_size(p_tcd); + if + (l_data_size > p_dest_length) + { + return OPJ_FALSE; + } + + l_tilec = p_tcd->tcd_image->tiles->comps; + l_img_comp = p_tcd->image->comps; + for + (i=0;i<p_tcd->image->numcomps;++i) + { + l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/ + l_remaining = l_img_comp->prec & 7; /* (%8) */ + l_res = l_tilec->resolutions + l_img_comp->resno_decoded; + l_width = (l_res->x1 - l_res->x0); + l_height = (l_res->y1 - l_res->y0); + l_stride = (l_tilec->x1 - l_tilec->x0) - l_width; + if + (l_remaining) + { + ++l_size_comp; + } + if + (l_size_comp == 3) + { + l_size_comp = 4; + } + switch + (l_size_comp) + { + case 1: + { + OPJ_CHAR * l_dest_ptr = (OPJ_CHAR *) p_dest; + const OPJ_INT32 * l_src_ptr = l_tilec->data; + if + (l_img_comp->sgnd) + { + for + (j=0;j<l_height;++j) + { + for + (k=0;k<l_width;++k) + { + *(l_dest_ptr++) = (OPJ_CHAR) (*(l_src_ptr++)); + } + l_src_ptr += l_stride; + } + } + else + { + for + (j=0;j<l_height;++j) + { + for + (k=0;k<l_width;++k) + { + *(l_dest_ptr++) = (OPJ_BYTE) ((*(l_src_ptr++))&0xff); + } + l_src_ptr += l_stride; + } + } + p_dest = (OPJ_BYTE *)l_dest_ptr; + + } + break; + case 2: + { + const OPJ_INT32 * l_src_ptr = l_tilec->data; + OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_dest; + if + (l_img_comp->sgnd) + { + for + (j=0;j<l_height;++j) + { + for + (k=0;k<l_width;++k) + { + *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++)); + } + l_src_ptr += l_stride; + } + } + else + { + for + (j=0;j<l_height;++j) + { + for + (k=0;k<l_width;++k) + { + *(l_dest_ptr++) = (OPJ_UINT16) ((*(l_src_ptr++))&0xffff); + } + l_src_ptr += l_stride; + } + } + p_dest = (OPJ_BYTE*) l_dest_ptr; + } + break; + case 4: + { + OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_dest; + OPJ_INT32 * l_src_ptr = l_tilec->data; + for + (j=0;j<l_height;++j) + { + for + (k=0;k<l_width;++k) + { + *(l_dest_ptr++) = (*(l_src_ptr++)); + } + l_src_ptr += l_stride; + } + p_dest = (OPJ_BYTE*) l_dest_ptr; + } + break; + } + ++l_img_comp; + ++l_tilec; + } + return OPJ_TRUE; +} + + + + +void tcd_free_tile(opj_tcd_v2_t *p_tcd) +{ + OPJ_UINT32 compno, resno, bandno, precno; + opj_tcd_tile_t *l_tile = 00; + opj_tcd_tilecomp_t *l_tile_comp = 00; + opj_tcd_resolution_t *l_res = 00; + opj_tcd_band_t *l_band = 00; + opj_tcd_precinct_t *l_precinct = 00; + OPJ_UINT32 l_nb_resolutions, l_nb_precincts; + void (* l_tcd_code_block_deallocate) (opj_tcd_precinct_t *) = 00; + + if + (! p_tcd) + { + return; + } + if + (! p_tcd->tcd_image) + { + return; + } + if + (p_tcd->m_is_decoder) + { + l_tcd_code_block_deallocate = tcd_code_block_dec_deallocate; + } + else + { + // FIXME l_tcd_code_block_deallocate = tcd_code_block_enc_deallocate; + } + + + l_tile = p_tcd->tcd_image->tiles; + if + (! l_tile) + { + return; + } + l_tile_comp = l_tile->comps; + + for + (compno = 0; compno < l_tile->numcomps; ++compno) + { + l_res = l_tile_comp->resolutions; + if + (l_res) + { + l_nb_resolutions = l_tile_comp->resolutions_size / sizeof(opj_tcd_resolution_t); + for + (resno = 0; resno < l_nb_resolutions; ++resno) + { + l_band = l_res->bands; + for + (bandno = 0; bandno < 3; ++bandno) + { + l_precinct = l_band->precincts; + if + (l_precinct) + { + l_nb_precincts = l_band->precincts_data_size / sizeof(opj_tcd_precinct_t); + for + (precno = 0; precno < l_nb_precincts; ++precno) + { + tgt_destroy(l_precinct->incltree); + l_precinct->incltree = 00; + tgt_destroy(l_precinct->imsbtree); + l_precinct->imsbtree = 00; + (*l_tcd_code_block_deallocate) (l_precinct); + ++l_precinct; + } + opj_free(l_band->precincts); + l_band->precincts = 00; + } + ++l_band; + } /* for (resno */ + ++l_res; + } + opj_free(l_tile_comp->resolutions); + l_tile_comp->resolutions = 00; + } + if + (l_tile_comp->data) + { + opj_aligned_free(l_tile_comp->data); + l_tile_comp->data = 00; + } + ++l_tile_comp; + } + opj_free(l_tile->comps); + l_tile->comps = 00; + opj_free(p_tcd->tcd_image->tiles); + p_tcd->tcd_image->tiles = 00; +} + + +/** + * Allocates memory for a decoding code block. + */ +opj_bool tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block) +{ + OPJ_UINT32 l_seg_size; + + if + (! p_code_block->data) + { + p_code_block->data = (OPJ_BYTE*) opj_malloc(8192); + if + (! p_code_block->data) + { + return OPJ_FALSE; + } + l_seg_size = J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t); + p_code_block->segs = (opj_tcd_seg_t *) opj_malloc(l_seg_size); + if + (! p_code_block->segs) + { + return OPJ_FALSE; + } + memset(p_code_block->segs,0,l_seg_size); + p_code_block->m_current_max_segs = J2K_DEFAULT_NB_SEGS; + } + // TODO + //p_code_block->numsegs = 0; + return OPJ_TRUE; +} + +opj_bool tcd_t2_decode ( + opj_tcd_v2_t *p_tcd, + OPJ_BYTE * p_src_data, + OPJ_UINT32 * p_data_read, + OPJ_UINT32 p_max_src_size, + opj_codestream_info_t *p_cstr_info + ) +{ + opj_t2_v2_t * l_t2; + + l_t2 = t2_create_v2(p_tcd->image, p_tcd->cp); + if + (l_t2 == 00) + { + return OPJ_FALSE; + } + + if + (! t2_decode_packets_v2( + l_t2, + p_tcd->tcd_tileno, + p_tcd->tcd_image->tiles, + p_src_data, + p_data_read, + p_max_src_size, + p_cstr_info)) + { + t2_destroy_v2(l_t2); + return OPJ_FALSE; + } + t2_destroy_v2(l_t2); + + /*---------------CLEAN-------------------*/ + return OPJ_TRUE; +} + +opj_bool tcd_t1_decode ( + opj_tcd_v2_t *p_tcd + ) +{ + OPJ_UINT32 compno; + opj_t1_t * l_t1; + opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles; + opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps; + opj_tccp_t * l_tccp = p_tcd->tcp->tccps; + + + l_t1 = t1_create_v2(); + if + (l_t1 == 00) + { + return OPJ_FALSE; + } + for + (compno = 0; compno < l_tile->numcomps; ++compno) + { + /* The +3 is headroom required by the vectorized DWT */ + t1_decode_cblks(l_t1, l_tile_comp, l_tccp); + ++l_tile_comp; + ++l_tccp; + } + t1_destroy_v2(l_t1); + return OPJ_TRUE; +} + + +opj_bool tcd_dwt_decode ( + opj_tcd_v2_t *p_tcd + ) +{ + OPJ_UINT32 compno; + opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles; + opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps; + opj_tccp_t * l_tccp = p_tcd->tcp->tccps; + opj_image_comp_t * l_img_comp = p_tcd->image->comps; + + for + (compno = 0; compno < l_tile->numcomps; compno++) + { + /* + 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) + { + return false; + } + } + numres2decode = tcd->image->comps[compno].resno_decoded + 1; + if(numres2decode > 0){ + */ + if + (l_tccp->qmfbid == 1) + { + if + (! dwt_decode(l_tile_comp, l_img_comp->resno_decoded+1)) + { + return OPJ_FALSE; + } + } + else + { + if + (! dwt_decode_real(l_tile_comp, l_img_comp->resno_decoded+1)) + { + return OPJ_FALSE; + } + } + ++l_tile_comp; + ++l_img_comp; + ++l_tccp; + } + return OPJ_TRUE; +} +opj_bool tcd_mct_decode ( + opj_tcd_v2_t *p_tcd + ) +{ + opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles; + opj_tcp_v2_t * l_tcp = p_tcd->tcp; + opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps; + OPJ_UINT32 l_samples,i; + + if + (! l_tcp->mct) + { + return OPJ_TRUE; + } + l_samples = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0); + if + (l_tcp->mct == 2) + { + OPJ_BYTE ** l_data; + if + (! l_tcp->m_mct_decoding_matrix) + { + return OPJ_TRUE; + } + l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*)); + if + (! l_data) + { + return OPJ_FALSE; + } + for + (i=0;i<l_tile->numcomps;++i) + { + l_data[i] = (OPJ_BYTE*) l_tile_comp->data; + ++l_tile_comp; + } + if + (! mct_decode_custom( // MCT data + (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix, + // size of components + l_samples, + // components + l_data, + // nb of components (i.e. size of pData) + l_tile->numcomps, + // tells if the data is signed + p_tcd->image->comps->sgnd)) + { + opj_free(l_data); + return OPJ_FALSE; + } + opj_free(l_data); + } + else + { + if + (l_tcp->tccps->qmfbid == 1) + { + mct_decode( + l_tile->comps[0].data, + l_tile->comps[1].data, + l_tile->comps[2].data, + l_samples); + } + else + { + mct_decode_real( + (float*)l_tile->comps[0].data, + (float*)l_tile->comps[1].data, + (float*)l_tile->comps[2].data, + l_samples); + } + } + return OPJ_TRUE; +} + + +opj_bool tcd_dc_level_shift_decode ( + opj_tcd_v2_t *p_tcd + ) +{ + OPJ_UINT32 compno; + opj_tcd_tilecomp_t * l_tile_comp = 00; + opj_tccp_t * l_tccp = 00; + opj_image_comp_t * l_img_comp = 00; + opj_tcd_resolution_t* l_res = 00; + opj_tcp_v2_t * l_tcp = 00; + opj_tcd_tile_t * l_tile; + OPJ_UINT32 l_width,l_height,i,j; + OPJ_INT32 * l_current_ptr; + OPJ_INT32 l_min, l_max; + OPJ_UINT32 l_stride; + + l_tile = p_tcd->tcd_image->tiles; + l_tile_comp = l_tile->comps; + l_tcp = p_tcd->tcp; + l_tccp = p_tcd->tcp->tccps; + l_img_comp = p_tcd->image->comps; + + for + (compno = 0; compno < l_tile->numcomps; compno++) + { + l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded; + l_width = (l_res->x1 - l_res->x0); + l_height = (l_res->y1 - l_res->y0); + l_stride = (l_tile_comp->x1 - l_tile_comp->x0) - l_width; + if + (l_img_comp->sgnd) + { + l_min = -(1 << (l_img_comp->prec - 1)); + l_max = (1 << (l_img_comp->prec - 1)) - 1; + } + else + { + l_min = 0; + l_max = (1 << l_img_comp->prec) - 1; + } + l_current_ptr = l_tile_comp->data; + if + (l_tccp->qmfbid == 1) + { + for + (j=0;j<l_height;++j) + { + for + (i = 0; i < l_width; ++i) + { + *l_current_ptr = int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min, l_max); + ++l_current_ptr; + } + l_current_ptr += l_stride; + } + } + else + { + for + (j=0;j<l_height;++j) + { + for + (i = 0; i < l_width; ++i) + { + OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr); + *l_current_ptr = int_clamp(lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ; + ++l_current_ptr; + } + l_current_ptr += l_stride; + } + } + ++l_img_comp; + ++l_tccp; + ++l_tile_comp; + } + return OPJ_TRUE; +} + + +/** + * Deallocates the encoding data of the given precinct. + */ +void tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct) +{ + OPJ_UINT32 cblkno , l_nb_code_blocks; + + opj_tcd_cblk_dec_t * l_code_block = p_precinct->cblks.dec; + if + (l_code_block) + { + l_nb_code_blocks = p_precinct->block_size / sizeof(opj_tcd_cblk_dec_t); + for + (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) + { + if + (l_code_block->data) + { + opj_free(l_code_block->data); + l_code_block->data = 00; + } + if + (l_code_block->segs) + { + opj_free(l_code_block->segs ); + l_code_block->segs = 00; + } + ++l_code_block; + } + opj_free(p_precinct->cblks.dec); + p_precinct->cblks.dec = 00; + } +} |
