X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fopenjp2%2Ftcd.c;h=53cdcf64d7f87ef2ba2ca14137be9875b81fe8dc;hb=8e6c371e66d9c579048fd336cc3365869486080a;hp=a6921464843f9b6d276958399fbbd29498fd652a;hpb=820fcfe8bb101a2862c076b02c9b6b636ce39d2f;p=openjpeg.git diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index a6921464..53cdcf64 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -180,12 +180,14 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd, OPJ_BYTE * p_dest_data, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_max_dest_size, - opj_codestream_info_t *p_cstr_info); + opj_codestream_info_t *p_cstr_info, + opj_event_mgr_t *p_manager); static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd, OPJ_BYTE * p_dest_data, OPJ_UINT32 p_max_dest_size, - opj_codestream_info_t *p_cstr_info); + opj_codestream_info_t *p_cstr_info, + opj_event_mgr_t *p_manager); /* ----------------------------------------------------------------------- */ @@ -431,7 +433,8 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd, OPJ_BYTE *dest, OPJ_UINT32 * p_data_written, OPJ_UINT32 len, - opj_codestream_info_t *cstr_info) + opj_codestream_info_t *cstr_info, + opj_event_mgr_t *p_manager) { OPJ_UINT32 compno, resno, bandno, precno, cblkno, layno; OPJ_UINT32 passno; @@ -563,7 +566,7 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd, if (OPJ_IS_CINEMA(cp->rsiz)) { if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino, - THRESH_CALC)) { + THRESH_CALC, p_manager)) { lo = thresh; continue; @@ -593,7 +596,7 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd, } else { if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino, - THRESH_CALC)) { + THRESH_CALC, p_manager)) { /* TODO: what to do with l ??? seek / tell ??? */ /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */ lo = thresh; @@ -674,7 +677,7 @@ 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_aligned_malloc(l_tilec->data_size_needed); + l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed); if (! l_tilec->data) { return OPJ_FALSE; } @@ -683,8 +686,8 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec) l_tilec->ownsData = OPJ_TRUE; } else if (l_tilec->data_size_needed > l_tilec->data_size) { /* We don't need to keep old data */ - opj_aligned_free(l_tilec->data); - l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed); + opj_image_data_free(l_tilec->data); + l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed); if (! l_tilec->data) { l_tilec->data_size = 0; l_tilec->data_size_needed = 0; @@ -965,8 +968,10 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, numbps = (OPJ_INT32)(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; + /* Mb value of Equation E-2 in "E.1 Inverse quantization + * procedure" of the standard */ l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - - 1; /* WHY -1 ? */ + 1; if (!l_band->precincts && (l_nb_precincts > 0U)) { l_band->precincts = (opj_tcd_precinct_t *) opj_malloc(/*3 * */ @@ -1182,8 +1187,12 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t * { OPJ_UINT32 l_data_size; - l_data_size = (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * - (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32)); + /* +1 is needed for https://github.com/uclouvain/openjpeg/issues/835 */ + /* and actually +2 required for https://github.com/uclouvain/openjpeg/issues/982 */ + /* TODO: is there a theoretical upper-bound for the compressed code */ + /* block size ? */ + l_data_size = 2 + (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * + (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32)); if (l_data_size > p_code_block->data_size) { if (p_code_block->data) { @@ -1207,20 +1216,19 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t * return OPJ_TRUE; } + +void opj_tcd_reinit_segment(opj_tcd_seg_t* seg) +{ + memset(seg, 0, sizeof(opj_tcd_seg_t)); +} + /** * Allocates memory for a decoding code block. */ static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t * p_code_block) { - if (! p_code_block->data) { - - p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_COMMON_DEFAULT_CBLK_DATA_SIZE); - if (! p_code_block->data) { - return OPJ_FALSE; - } - p_code_block->data_max_size = OPJ_COMMON_DEFAULT_CBLK_DATA_SIZE; - /*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/ + if (! p_code_block->segs) { p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS, sizeof(opj_tcd_seg_t)); @@ -1233,16 +1241,20 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t * /*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/ } else { /* sanitize */ - OPJ_BYTE* l_data = p_code_block->data; - OPJ_UINT32 l_data_max_size = p_code_block->data_max_size; opj_tcd_seg_t * l_segs = p_code_block->segs; OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_segs; + opj_tcd_seg_data_chunk_t* l_chunks = p_code_block->chunks; + OPJ_UINT32 l_numchunksalloc = p_code_block->numchunksalloc; + OPJ_UINT32 i; memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t)); - p_code_block->data = l_data; - p_code_block->data_max_size = l_data_max_size; p_code_block->segs = l_segs; p_code_block->m_current_max_segs = l_current_max_segs; + for (i = 0; i < l_current_max_segs; ++i) { + opj_tcd_reinit_segment(&l_segs[i]); + } + p_code_block->chunks = l_chunks; + p_code_block->numchunksalloc = l_numchunksalloc; } return OPJ_TRUE; @@ -1256,6 +1268,7 @@ OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd) opj_tcd_tilecomp_t * l_tile_comp = 00; opj_tcd_resolution_t * l_res = 00; OPJ_UINT32 l_size_comp, l_remaining; + OPJ_UINT32 l_temp; l_tile_comp = p_tcd->tcd_image->tiles->comps; l_img_comp = p_tcd->image->comps; @@ -1273,8 +1286,17 @@ OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd) } l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1; - l_data_size += l_size_comp * (OPJ_UINT32)((l_res->x1 - l_res->x0) * - (l_res->y1 - l_res->y0)); + l_temp = (OPJ_UINT32)((l_res->x1 - l_res->x0) * (l_res->y1 - + l_res->y0)); /* x1*y1 can't overflow */ + if (l_size_comp && UINT_MAX / l_size_comp < l_temp) { + return UINT_MAX; + } + l_temp *= l_size_comp; + + if (l_temp > UINT_MAX - l_data_size) { + return UINT_MAX; + } + l_data_size += l_temp; ++l_img_comp; ++l_tile_comp; } @@ -1287,7 +1309,8 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd, OPJ_BYTE *p_dest, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_max_length, - opj_codestream_info_t *p_cstr_info) + opj_codestream_info_t *p_cstr_info, + opj_event_mgr_t *p_manager) { if (p_tcd->cur_tp_num == 0) { @@ -1349,7 +1372,8 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd, /* FIXME _ProfStop(PGROUP_T1); */ /* FIXME _ProfStart(PGROUP_RATE); */ - if (! opj_tcd_rate_allocate_encode(p_tcd, p_dest, p_max_length, p_cstr_info)) { + if (! opj_tcd_rate_allocate_encode(p_tcd, p_dest, p_max_length, + p_cstr_info, p_manager)) { return OPJ_FALSE; } /* FIXME _ProfStop(PGROUP_RATE); */ @@ -1364,7 +1388,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd, /* FIXME _ProfStart(PGROUP_T2); */ if (! opj_tcd_t2_encode(p_tcd, p_dest, p_data_written, p_max_length, - p_cstr_info)) { + p_cstr_info, p_manager)) { return OPJ_FALSE; } /* FIXME _ProfStop(PGROUP_T2); */ @@ -1469,7 +1493,7 @@ OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd, OPJ_UINT32 l_stride, l_width, l_height; l_data_size = opj_tcd_get_decoded_tile_size(p_tcd); - if (l_data_size > p_dest_length) { + if (l_data_size == UINT_MAX || l_data_size > p_dest_length) { return OPJ_FALSE; } @@ -1634,7 +1658,7 @@ static void opj_tcd_free_tile(opj_tcd_t *p_tcd) } if (l_tile_comp->ownsData && l_tile_comp->data) { - opj_aligned_free(l_tile_comp->data); + opj_image_data_free(l_tile_comp->data); l_tile_comp->data = 00; l_tile_comp->ownsData = 0; l_tile_comp->data_size = 0; @@ -1872,7 +1896,7 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) l_max = (1 << (l_img_comp->prec - 1)) - 1; } else { l_min = 0; - l_max = (1 << l_img_comp->prec) - 1; + l_max = (OPJ_INT32)((1U << l_img_comp->prec) - 1); } l_current_ptr = l_tile_comp->data; @@ -1890,8 +1914,15 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) 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 = opj_int_clamp((OPJ_INT32)opj_lrintf(l_value) + - l_tccp->m_dc_level_shift, l_min, l_max); ; + OPJ_INT32 l_value_int = (OPJ_INT32)opj_lrintf(l_value); + if (l_value > INT_MAX || + (l_value_int > 0 && l_tccp->m_dc_level_shift > 0 && + l_value_int > INT_MAX - l_tccp->m_dc_level_shift)) { + *l_current_ptr = l_max; + } else { + *l_current_ptr = opj_int_clamp( + l_value_int + l_tccp->m_dc_level_shift, l_min, l_max); + } ++l_current_ptr; } l_current_ptr += l_stride; @@ -1928,16 +1959,16 @@ static void opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct) 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; } + if (l_code_block->chunks) { + opj_free(l_code_block->chunks); + l_code_block->chunks = 00; + } + ++l_code_block; } @@ -2173,7 +2204,8 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd, OPJ_BYTE * p_dest_data, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_max_dest_size, - opj_codestream_info_t *p_cstr_info) + opj_codestream_info_t *p_cstr_info, + opj_event_mgr_t *p_manager) { opj_t2_t * l_t2; @@ -2194,7 +2226,8 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd, p_tcd->tp_num, p_tcd->tp_pos, p_tcd->cur_pino, - FINAL_PASS)) { + FINAL_PASS, + p_manager)) { opj_t2_destroy(l_t2); return OPJ_FALSE; } @@ -2209,7 +2242,8 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd, static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd, OPJ_BYTE * p_dest_data, OPJ_UINT32 p_max_dest_size, - opj_codestream_info_t *p_cstr_info) + opj_codestream_info_t *p_cstr_info, + opj_event_mgr_t *p_manager) { opj_cp_t * l_cp = p_tcd->cp; OPJ_UINT32 l_nb_written = 0; @@ -2223,7 +2257,7 @@ static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd, /* fixed_quality */ /* Normal Rate/distortion allocation */ if (! opj_tcd_rateallocate(p_tcd, p_dest_data, &l_nb_written, p_max_dest_size, - p_cstr_info)) { + p_cstr_info, p_manager)) { return OPJ_FALSE; } } else {