mirror of
https://github.com/uclouvain/openjpeg.git
synced 2026-02-01 16:47:14 +00:00
Use TLM markers to optimize opj_get_decoded_tile()
This commit is contained in:
parent
5005a350a7
commit
954c6e3cb9
@ -2484,6 +2484,11 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
|
||||
++l_current_tile_param;
|
||||
}
|
||||
|
||||
/*Allocate and initialize some elements of codestrem index*/
|
||||
if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MH;
|
||||
opj_image_comp_header_update(l_image, l_cp);
|
||||
|
||||
@ -3657,21 +3662,29 @@ static OPJ_BOOL opj_j2k_read_tlm(opj_j2k_t *p_j2k,
|
||||
opj_event_mgr_t * p_manager
|
||||
)
|
||||
{
|
||||
OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, l_tot_num_tp_remaining, l_quotient,
|
||||
l_Ptlm_size;
|
||||
OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP,
|
||||
l_Ptlm_size, l_entry_size, l_num_tileparts;
|
||||
OPJ_UINT32 i;
|
||||
opj_j2k_tlm_tile_part_info_t* l_tile_part_infos;
|
||||
opj_j2k_tlm_info_t* l_tlm;
|
||||
|
||||
/* preconditions */
|
||||
assert(p_header_data != 00);
|
||||
assert(p_j2k != 00);
|
||||
assert(p_manager != 00);
|
||||
|
||||
OPJ_UNUSED(p_j2k);
|
||||
l_tlm = &(p_j2k->m_specific_param.m_decoder.m_tlm);
|
||||
|
||||
if (p_header_size < 2) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker.\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
p_header_size -= 2;
|
||||
|
||||
if (l_tlm->m_is_invalid) {
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
opj_read_bytes(p_header_data, &l_Ztlm,
|
||||
1); /* Ztlm */
|
||||
++p_header_data;
|
||||
@ -3680,27 +3693,83 @@ static OPJ_BOOL opj_j2k_read_tlm(opj_j2k_t *p_j2k,
|
||||
++p_header_data;
|
||||
|
||||
l_ST = ((l_Stlm >> 4) & 0x3);
|
||||
if (l_ST == 3) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"opj_j2k_read_tlm(): ST = 3 is invalid.\n");
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
l_SP = (l_Stlm >> 6) & 0x1;
|
||||
|
||||
l_Ptlm_size = (l_SP + 1) * 2;
|
||||
l_quotient = l_Ptlm_size + l_ST;
|
||||
l_entry_size = l_Ptlm_size + l_ST;
|
||||
|
||||
l_tot_num_tp_remaining = p_header_size % l_quotient;
|
||||
|
||||
if (l_tot_num_tp_remaining != 0) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
|
||||
return OPJ_FALSE;
|
||||
if ((p_header_size % l_entry_size) != 0) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"opj_j2k_read_tlm(): TLM marker not of expected size.\n");
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
/* FIXME Do not care of this at the moment since only local variables are set here */
|
||||
/*
|
||||
for
|
||||
(i = 0; i < l_tot_num_tp; ++i)
|
||||
{
|
||||
opj_read_bytes(p_header_data,&l_Ttlm_i,l_ST); // Ttlm_i
|
||||
|
||||
l_num_tileparts = p_header_size / l_entry_size;
|
||||
if (l_num_tileparts == 0) {
|
||||
/* not totally sure if this is valid... */
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
/* Highly unlikely, unless there are gazillions of TLM markers */
|
||||
if (l_tlm->m_entries_count > UINT32_MAX - l_num_tileparts ||
|
||||
l_tlm->m_entries_count + l_num_tileparts > UINT32_MAX / sizeof(
|
||||
opj_j2k_tlm_tile_part_info_t)) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"opj_j2k_read_tlm(): too many TLM markers.\n");
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
l_tile_part_infos = (opj_j2k_tlm_tile_part_info_t*)opj_realloc(
|
||||
l_tlm->m_tile_part_infos,
|
||||
(l_tlm->m_entries_count + l_num_tileparts) * sizeof(
|
||||
opj_j2k_tlm_tile_part_info_t));
|
||||
if (!l_tile_part_infos) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"opj_j2k_read_tlm(): cannot allocate m_tile_part_infos.\n");
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
l_tlm->m_tile_part_infos = l_tile_part_infos;
|
||||
|
||||
for (i = 0; i < l_num_tileparts; ++ i) {
|
||||
OPJ_UINT32 l_tile_index;
|
||||
OPJ_UINT32 l_length;
|
||||
|
||||
/* Read Ttlm_i */
|
||||
if (l_ST == 0) {
|
||||
l_tile_index = l_tlm->m_entries_count;
|
||||
} else {
|
||||
opj_read_bytes(p_header_data, &l_tile_index, l_ST);
|
||||
p_header_data += l_ST;
|
||||
opj_read_bytes(p_header_data,&l_Ptlm_i,l_Ptlm_size); // Ptlm_i
|
||||
p_header_data += l_Ptlm_size;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (l_tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"opj_j2k_read_tlm(): invalid tile number %d\n",
|
||||
l_tile_index);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
/* Read Ptlm_i */
|
||||
opj_read_bytes(p_header_data, &l_length, l_Ptlm_size);
|
||||
p_header_data += l_Ptlm_size;
|
||||
|
||||
l_tile_part_infos[l_tlm->m_entries_count].m_tile_index =
|
||||
(OPJ_UINT16)l_tile_index;
|
||||
l_tile_part_infos[l_tlm->m_entries_count].m_length = l_length;
|
||||
++l_tlm->m_entries_count;
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
@ -4583,14 +4652,26 @@ static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k,
|
||||
}
|
||||
|
||||
/* Index */
|
||||
if (p_j2k->cstr_index) {
|
||||
{
|
||||
assert(p_j2k->cstr_index->tile_index != 00);
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno =
|
||||
p_j2k->m_current_tile_number;
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno =
|
||||
l_current_part;
|
||||
|
||||
if (l_num_parts != 0) {
|
||||
if (!p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid &&
|
||||
l_num_parts >
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps) {
|
||||
opj_event_msg(p_manager, EVT_WARNING,
|
||||
"SOT marker for tile %u declares more tile-parts than found in TLM marker.",
|
||||
p_j2k->m_current_tile_number);
|
||||
p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid = OPJ_TRUE;
|
||||
}
|
||||
|
||||
if (!p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid) {
|
||||
/* do nothing */
|
||||
} else if (l_num_parts != 0) {
|
||||
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps =
|
||||
l_num_parts;
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps =
|
||||
@ -4661,33 +4742,6 @@ static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k,
|
||||
|
||||
}
|
||||
|
||||
/* FIXME move this onto a separate method to call before reading any SOT, remove part about main_end header, use a index struct inside p_j2k */
|
||||
/* if (p_j2k->cstr_info) {
|
||||
if (l_tcp->first) {
|
||||
if (tileno == 0) {
|
||||
p_j2k->cstr_info->main_head_end = p_stream_tell(p_stream) - 13;
|
||||
}
|
||||
|
||||
p_j2k->cstr_info->tile[tileno].tileno = tileno;
|
||||
p_j2k->cstr_info->tile[tileno].start_pos = p_stream_tell(p_stream) - 12;
|
||||
p_j2k->cstr_info->tile[tileno].end_pos = p_j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
|
||||
p_j2k->cstr_info->tile[tileno].num_tps = numparts;
|
||||
|
||||
if (numparts) {
|
||||
p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
|
||||
}
|
||||
else {
|
||||
p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
|
||||
}
|
||||
}
|
||||
else {
|
||||
p_j2k->cstr_info->tile[tileno].end_pos += totlen;
|
||||
}
|
||||
|
||||
p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = p_stream_tell(p_stream) - 12;
|
||||
p_j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
|
||||
p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
|
||||
}*/
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
@ -5023,7 +5077,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
|
||||
|
||||
/* Index */
|
||||
l_cstr_index = p_j2k->cstr_index;
|
||||
if (l_cstr_index) {
|
||||
{
|
||||
OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2;
|
||||
|
||||
OPJ_UINT32 l_current_tile_part =
|
||||
@ -8472,13 +8526,6 @@ OPJ_BOOL opj_j2k_read_header(opj_stream_private_t *p_stream,
|
||||
/* Copy codestream image information to the output image */
|
||||
opj_copy_image_header(p_j2k->m_private_image, *p_image);
|
||||
|
||||
/*Allocate and initialize some elements of codestrem index*/
|
||||
if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)) {
|
||||
opj_image_destroy(*p_image);
|
||||
*p_image = NULL;
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
@ -8830,6 +8877,87 @@ static OPJ_BOOL opj_j2k_decoding_validation(opj_j2k_t *p_j2k,
|
||||
return l_is_valid;
|
||||
}
|
||||
|
||||
/** Fill p_j2k->cstr_index->tp_index[].start_pos/end_pos fields from TLM marker segments */
|
||||
static void opj_j2k_build_tp_index_from_tlm(opj_j2k_t* p_j2k,
|
||||
opj_event_mgr_t * p_manager)
|
||||
{
|
||||
opj_j2k_tlm_info_t* l_tlm;
|
||||
OPJ_UINT32 i;
|
||||
OPJ_OFF_T l_cur_offset;
|
||||
|
||||
assert(p_j2k->cstr_index->main_head_end > 0);
|
||||
assert(p_j2k->cstr_index->nb_of_tiles > 0);
|
||||
assert(p_j2k->cstr_index->tile_index != NULL);
|
||||
|
||||
l_tlm = &(p_j2k->m_specific_param.m_decoder.m_tlm);
|
||||
|
||||
if (l_tlm->m_entries_count == 0) {
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (l_tlm->m_is_invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initial pass to count the number of tile-parts per tile */
|
||||
for (i = 0; i < l_tlm->m_entries_count; ++i) {
|
||||
OPJ_UINT32 l_tile_index_no = l_tlm->m_tile_part_infos[i].m_tile_index;
|
||||
assert(l_tile_index_no < p_j2k->cstr_index->nb_of_tiles);
|
||||
p_j2k->cstr_index->tile_index[l_tile_index_no].tileno = l_tile_index_no;
|
||||
++p_j2k->cstr_index->tile_index[l_tile_index_no].current_nb_tps;
|
||||
}
|
||||
|
||||
/* Now check that all tiles have at least one tile-part */
|
||||
for (i = 0; i < p_j2k->cstr_index->nb_of_tiles; ++i) {
|
||||
if (p_j2k->cstr_index->tile_index[i].current_nb_tps == 0) {
|
||||
opj_event_msg(p_manager, EVT_ERROR,
|
||||
"opj_j2k_build_tp_index_from_tlm(): tile %d has no "
|
||||
"registered tile-part in TLM marker segments.\n", i);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Final pass to fill p_j2k->cstr_index */
|
||||
l_cur_offset = p_j2k->cstr_index->main_head_end;
|
||||
for (i = 0; i < l_tlm->m_entries_count; ++i) {
|
||||
OPJ_UINT32 l_tile_index_no = l_tlm->m_tile_part_infos[i].m_tile_index;
|
||||
opj_tile_index_t* l_tile_index = &
|
||||
(p_j2k->cstr_index->tile_index[l_tile_index_no]);
|
||||
if (!l_tile_index->tp_index) {
|
||||
l_tile_index->tp_index = (opj_tp_index_t *) opj_calloc(
|
||||
l_tile_index->current_nb_tps, sizeof(opj_tp_index_t));
|
||||
if (! l_tile_index->tp_index) {
|
||||
opj_event_msg(p_manager, EVT_ERROR,
|
||||
"opj_j2k_build_tp_index_from_tlm(): tile index allocation failed\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
assert(l_tile_index->nb_tps < l_tile_index->current_nb_tps);
|
||||
l_tile_index->tp_index[l_tile_index->nb_tps].start_pos = l_cur_offset;
|
||||
/* We don't know how to set the tp_index[].end_header field, but this is not really needed */
|
||||
/* If there would be no markers between SOT and SOD, that would be : */
|
||||
/* l_tile_index->tp_index[l_tile_index->nb_tps].end_header = l_cur_offset + 12; */
|
||||
l_tile_index->tp_index[l_tile_index->nb_tps].end_pos = l_cur_offset +
|
||||
l_tlm->m_tile_part_infos[i].m_length;
|
||||
++l_tile_index->nb_tps;
|
||||
|
||||
l_cur_offset += l_tlm->m_tile_part_infos[i].m_length;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
l_tlm->m_is_invalid = OPJ_TRUE;
|
||||
for (i = 0; i < l_tlm->m_entries_count; ++i) {
|
||||
OPJ_UINT32 l_tile_index = l_tlm->m_tile_part_infos[i].m_tile_index;
|
||||
p_j2k->cstr_index->tile_index[l_tile_index].current_nb_tps = 0;
|
||||
opj_free(p_j2k->cstr_index->tile_index[l_tile_index].tp_index);
|
||||
p_j2k->cstr_index->tile_index[l_tile_index].tp_index = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static OPJ_BOOL opj_j2k_read_header_procedure(opj_j2k_t *p_j2k,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager)
|
||||
@ -9009,6 +9137,9 @@ static OPJ_BOOL opj_j2k_read_header_procedure(opj_j2k_t *p_j2k,
|
||||
/* Position of the last element if the main header */
|
||||
p_j2k->cstr_index->main_head_end = (OPJ_UINT32) opj_stream_tell(p_stream) - 2;
|
||||
|
||||
/* Build tile-part index from TLM information */
|
||||
opj_j2k_build_tp_index_from_tlm(p_j2k, p_manager);
|
||||
|
||||
/* Next step: read a tile-part header */
|
||||
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
|
||||
|
||||
@ -9232,6 +9363,9 @@ void opj_j2k_destroy(opj_j2k_t *p_j2k)
|
||||
p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode = 00;
|
||||
p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode = 0;
|
||||
|
||||
opj_free(p_j2k->m_specific_param.m_decoder.m_tlm.m_tile_part_infos);
|
||||
p_j2k->m_specific_param.m_decoder.m_tlm.m_tile_part_infos = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
|
||||
@ -9730,6 +9864,60 @@ OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
|
||||
if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* Check if we can use the TLM index to access the next tile-part */
|
||||
if (!p_j2k->m_specific_param.m_decoder.m_can_decode &&
|
||||
p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0 &&
|
||||
p_j2k->m_current_tile_number == (OPJ_UINT32)
|
||||
p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec &&
|
||||
!p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid &&
|
||||
opj_stream_has_seek(p_stream)) {
|
||||
l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
|
||||
if (l_tcp->m_nb_tile_parts ==
|
||||
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps &&
|
||||
(OPJ_UINT32)l_tcp->m_current_tile_part_number + 1 < l_tcp->m_nb_tile_parts) {
|
||||
const OPJ_OFF_T next_tp_sot_pos = p_j2k->cstr_index->tile_index[
|
||||
p_j2k->m_current_tile_number].tp_index[l_tcp->m_current_tile_part_number +
|
||||
1].start_pos;
|
||||
|
||||
if (next_tp_sot_pos != opj_stream_tell(p_stream)) {
|
||||
#if 0
|
||||
opj_event_msg(p_manager, EVT_INFO,
|
||||
"opj_j2k_read_tile_header(tile=%u): seek to tile part %u at %" PRId64 "\n",
|
||||
p_j2k->m_current_tile_number,
|
||||
l_tcp->m_current_tile_part_number + 1,
|
||||
next_tp_sot_pos);
|
||||
#endif
|
||||
|
||||
if (!(opj_stream_read_seek(p_stream,
|
||||
next_tp_sot_pos,
|
||||
p_manager))) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to read 2 bytes (the marker ID) from stream and copy them into the buffer */
|
||||
if (opj_stream_read_data(p_stream,
|
||||
p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* Read 2 bytes from the buffer as the marker ID */
|
||||
opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,
|
||||
&l_current_marker,
|
||||
2);
|
||||
|
||||
if (l_current_marker != J2K_MS_SOT) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Did not get expected SOT marker\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_j2k->m_specific_param.m_decoder.m_can_decode &&
|
||||
!p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked) {
|
||||
/* Issue 254 */
|
||||
@ -11313,6 +11501,17 @@ static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
|
||||
OPJ_UINT32 l_acc_nb_of_tile_part = 0;
|
||||
for (it_tile = 0; it_tile < cstr_index->nb_of_tiles ; it_tile++) {
|
||||
l_acc_nb_of_tile_part += cstr_index->tile_index[it_tile].nb_tps;
|
||||
|
||||
/* To avoid regenerating expected opj_dump results from the test */
|
||||
/* suite when there is a TLM marker present */
|
||||
if (cstr_index->tile_index[it_tile].nb_tps &&
|
||||
cstr_index->tile_index[it_tile].tp_index &&
|
||||
cstr_index->tile_index[it_tile].tp_index[0].start_pos > 0 &&
|
||||
cstr_index->tile_index[it_tile].tp_index[0].end_header == 0 &&
|
||||
getenv("OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM") != NULL) {
|
||||
l_acc_nb_of_tile_part = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (l_acc_nb_of_tile_part) {
|
||||
@ -11830,12 +12029,6 @@ static OPJ_BOOL opj_j2k_decode_one_tile(opj_j2k_t *p_j2k,
|
||||
OPJ_UINT32 l_nb_tiles;
|
||||
OPJ_UINT32 i;
|
||||
|
||||
/*Allocate and initialize some elements of codestrem index if not already done*/
|
||||
if (!p_j2k->cstr_index->tile_index) {
|
||||
if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
/* Move into the codestream to the first SOT used to decode the desired tile */
|
||||
l_tile_no_to_dec = (OPJ_UINT32)
|
||||
p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec;
|
||||
@ -11850,12 +12043,38 @@ static OPJ_BOOL opj_j2k_decode_one_tile(opj_j2k_t *p_j2k,
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
} else {
|
||||
OPJ_OFF_T sot_pos =
|
||||
p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos;
|
||||
OPJ_UINT32 l_marker;
|
||||
|
||||
#if 0
|
||||
opj_event_msg(p_manager, EVT_INFO,
|
||||
"opj_j2k_decode_one_tile(%u): seek to %" PRId64 "\n",
|
||||
l_tile_no_to_dec,
|
||||
sot_pos);
|
||||
#endif
|
||||
if (!(opj_stream_read_seek(p_stream,
|
||||
p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos + 2,
|
||||
sot_pos,
|
||||
p_manager))) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* Try to read 2 bytes (the marker ID) from stream and copy them into the buffer */
|
||||
if (opj_stream_read_data(p_stream,
|
||||
p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* Read 2 bytes from the buffer as the marker ID */
|
||||
opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, &l_marker,
|
||||
2);
|
||||
|
||||
if (l_marker != J2K_MS_SOT) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Did not get expected SOT marker\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
/* Special case if we have previously read the EOC marker (if the previous tile getted is the last ) */
|
||||
if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC) {
|
||||
|
||||
@ -466,6 +466,24 @@ typedef struct opj_cp {
|
||||
/* <<UniPG */
|
||||
} opj_cp_t;
|
||||
|
||||
/** Entry of a TLM marker segment */
|
||||
typedef struct opj_j2k_tlm_tile_part_info {
|
||||
/** Tile index of the tile part. Ttlmi field */
|
||||
OPJ_UINT16 m_tile_index;
|
||||
/** Length in bytes, from the beginning of the SOT marker to the end of
|
||||
* the bit stream data for that tile-part. Ptlmi field */
|
||||
OPJ_UINT32 m_length;
|
||||
} opj_j2k_tlm_tile_part_info_t;
|
||||
|
||||
/** Information got from the concatenation of TLM marker semgnets. */
|
||||
typedef struct opj_j2k_tlm_info {
|
||||
/** Number of entries in m_tile_part_infos. */
|
||||
OPJ_UINT32 m_entries_count;
|
||||
/** Array of m_entries_count values. */
|
||||
opj_j2k_tlm_tile_part_info_t* m_tile_part_infos;
|
||||
|
||||
OPJ_BOOL m_is_invalid;
|
||||
} opj_j2k_tlm_info_t;
|
||||
|
||||
typedef struct opj_j2k_dec {
|
||||
/** locate in which part of the codestream the decoder is (main header, tile header, end) */
|
||||
@ -499,6 +517,8 @@ typedef struct opj_j2k_dec {
|
||||
OPJ_UINT32 m_numcomps_to_decode;
|
||||
OPJ_UINT32 *m_comps_indices_to_decode;
|
||||
|
||||
opj_j2k_tlm_info_t m_tlm;
|
||||
|
||||
/** to tell that a tile can be decoded. */
|
||||
OPJ_BITFIELD m_can_decode : 1;
|
||||
OPJ_BITFIELD m_discard_tiles : 1;
|
||||
|
||||
@ -637,6 +637,9 @@ foreach(numFileP0 RANGE 1 16)
|
||||
-o ${TEMP}/${filenameInput}.txt
|
||||
)
|
||||
|
||||
set_tests_properties(NR-${filenameInput}-dump
|
||||
PROPERTIES ENVIRONMENT OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM=YES)
|
||||
|
||||
add_test(NAME NR-${filenameInput}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_v2_${filenameRefSub}.txt
|
||||
@ -666,6 +669,9 @@ foreach(numFileP1 RANGE 1 7)
|
||||
-o ${TEMP}/${filenameInput}.txt
|
||||
)
|
||||
|
||||
set_tests_properties(NR-${filenameInput}-dump
|
||||
PROPERTIES ENVIRONMENT OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM=YES)
|
||||
|
||||
add_test(NAME NR-${filenameInput}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_v2_${filenameInputSub}.txt
|
||||
@ -695,6 +701,9 @@ foreach(numFileJP2 RANGE 1 9)
|
||||
-o ${TEMP}/${filenameInput}.txt
|
||||
)
|
||||
|
||||
set_tests_properties(NR-${filenameInput}-dump
|
||||
PROPERTIES ENVIRONMENT OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM=YES)
|
||||
|
||||
add_test(NAME NR-${filenameInput}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_v2_${filenameInputSub}.txt
|
||||
|
||||
@ -113,7 +113,10 @@ foreach(INPUT_FILENAME ${OPJ_DATA_NR_LIST})
|
||||
-o ${TEMP}/${INPUT_FILENAME_NAME}.txt
|
||||
-v
|
||||
)
|
||||
|
||||
|
||||
set_tests_properties(NR-${INPUT_FILENAME_NAME}-dump
|
||||
PROPERTIES ENVIRONMENT OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM=YES)
|
||||
|
||||
if(bad_jpeg2000)
|
||||
set_tests_properties(NR-${INPUT_FILENAME_NAME}-dump
|
||||
PROPERTIES WILL_FAIL TRUE)
|
||||
@ -336,6 +339,10 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
-i ${OUTPUT_FILENAME}
|
||||
-o ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt
|
||||
)
|
||||
|
||||
set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
PROPERTIES ENVIRONMENT OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM=YES)
|
||||
|
||||
set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user