diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2017-09-19 16:52:07 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2017-09-19 17:06:19 +0200 |
| commit | 7e2b6bebff12eab8bdc17fc9af017e8c11652f4f (patch) | |
| tree | 1f1456a4b3962862d3ab581e7b1b080919c53d34 /src/lib/openjp2/tcd.c | |
| parent | ce199f42e77f972d6ee782b63492f6d861891053 (diff) | |
Add capability to decode only a subset of all components of an image.
This adds a opj_set_decoded_components(opj_codec_t *p_codec,
OPJ_UINT32 numcomps, const OPJ_UINT32* comps_indices) function,
and equivalent "opj_decompress -c compno[,compno]*" option.
When specified, neither the MCT transform nor JP2 channel transformations
will be applied.
Tests added for various combinations of whole image vs tiled-based decoding,
full or reduced resolution, use of decode area or not.
Diffstat (limited to 'src/lib/openjp2/tcd.c')
| -rw-r--r-- | src/lib/openjp2/tcd.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index fad9d23c..1dd15405 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -679,6 +679,9 @@ void opj_tcd_destroy(opj_tcd_t *tcd) opj_free(tcd->tcd_image); tcd->tcd_image = 00; } + + opj_free(tcd->used_component); + opj_free(tcd); } } @@ -1439,6 +1442,8 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 win_y0, OPJ_UINT32 win_x1, OPJ_UINT32 win_y1, + OPJ_UINT32 numcomps_to_decode, + const OPJ_UINT32 *comps_indices, OPJ_BYTE *p_src, OPJ_UINT32 p_max_length, OPJ_UINT32 p_tile_no, @@ -1457,7 +1462,27 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd, p_tcd->win_y1 = win_y1; p_tcd->whole_tile_decoding = OPJ_TRUE; + opj_free(p_tcd->used_component); + p_tcd->used_component = NULL; + + if (numcomps_to_decode) { + OPJ_BOOL* used_component = (OPJ_BOOL*) opj_calloc(sizeof(OPJ_BOOL), + p_tcd->image->numcomps); + if (used_component == NULL) { + return OPJ_FALSE; + } + for (compno = 0; compno < numcomps_to_decode; compno++) { + used_component[ comps_indices[compno] ] = OPJ_TRUE; + } + + p_tcd->used_component = used_component; + } + for (compno = 0; compno < p_tcd->image->numcomps; compno++) { + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + if (!opj_tcd_is_whole_tilecomp_decoding(p_tcd, compno)) { p_tcd->whole_tile_decoding = OPJ_FALSE; break; @@ -1475,6 +1500,10 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd, OPJ_SIZE_T res_w = (OPJ_SIZE_T)(l_res->x1 - l_res->x0); OPJ_SIZE_T res_h = (OPJ_SIZE_T)(l_res->y1 - l_res->y0); + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + /* issue 733, l_data_size == 0U, probably something wrong should be checked before getting here */ if (res_h > 0 && res_w > SIZE_MAX / res_h) { opj_event_msg(p_manager, EVT_ERROR, @@ -1506,6 +1535,11 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 resno; opj_tcd_tilecomp_t* tilec = &(p_tcd->tcd_image->tiles->comps[compno]); opj_image_comp_t* image_comp = &(p_tcd->image->comps[compno]); + + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + /* Compute the intersection of the area of interest, expressed in tile coordinates */ /* with the tile coordinates */ tilec->win_x0 = opj_uint_max( @@ -1600,6 +1634,10 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd, opj_image_data_free(tilec->data_win); tilec->data_win = NULL; + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + if (w > 0 && h > 0) { if (w > SIZE_MAX / h) { opj_event_msg(p_manager, EVT_ERROR, @@ -1916,14 +1954,17 @@ static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager) check_pterm = OPJ_TRUE; } - for (compno = 0; compno < l_tile->numcomps; ++compno) { + for (compno = 0; compno < l_tile->numcomps; + ++compno, ++l_tile_comp, ++l_tccp) { + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + opj_t1_decode_cblks(p_tcd, &ret, l_tile_comp, l_tccp, p_manager, p_manager_mutex, check_pterm); if (!ret) { break; } - ++l_tile_comp; - ++l_tccp; } opj_thread_pool_wait_completion(p_tcd->thread_pool, 0); @@ -1942,7 +1983,11 @@ static OPJ_BOOL opj_tcd_dwt_decode(opj_tcd_t *p_tcd) 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++) { + for (compno = 0; compno < l_tile->numcomps; + compno++, ++l_tile_comp, ++l_img_comp, ++l_tccp) { + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } if (l_tccp->qmfbid == 1) { if (! opj_dwt_decode(p_tcd, l_tile_comp, @@ -1956,9 +2001,6 @@ static OPJ_BOOL opj_tcd_dwt_decode(opj_tcd_t *p_tcd) } } - ++l_tile_comp; - ++l_img_comp; - ++l_tccp; } return OPJ_TRUE; @@ -1971,7 +2013,7 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager) opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps; OPJ_UINT32 l_samples, i; - if (! l_tcp->mct) { + if (l_tcp->mct == 0 || p_tcd->used_component != NULL) { return OPJ_TRUE; } @@ -2132,7 +2174,13 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) l_tccp = p_tcd->tcp->tccps; l_img_comp = p_tcd->image->comps; - for (compno = 0; compno < l_tile->numcomps; compno++) { + for (compno = 0; compno < l_tile->numcomps; + compno++, ++l_img_comp, ++l_tccp, ++l_tile_comp) { + + if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) { + continue; + } + l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded; if (!p_tcd->whole_tile_decoding) { @@ -2191,10 +2239,6 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) l_current_ptr += l_stride; } } - - ++l_img_comp; - ++l_tccp; - ++l_tile_comp; } return OPJ_TRUE; |
