diff --git a/CHANGES b/CHANGES index e7bd2e8c..f23c3154 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ What's New for OpenJPEG + : added September 19, 2011 ++ [mickael] WIP: begin to test opj_decode_tile_data + [mickael] WIP: update t1, t2, tcd to use same strut as in V2 + [mickael] WIP: begin to test opj_read_tile_header with V2 style + [mickael] WIP: create a new framework to output file information diff --git a/applications/codec/j2k_dump.c b/applications/codec/j2k_dump.c index 9c0a4452..be5e1d63 100644 --- a/applications/codec/j2k_dump.c +++ b/applications/codec/j2k_dump.c @@ -374,6 +374,8 @@ int main(int argc, char *argv[]) opj_codestream_info_t* cstr_info =NULL; /* Codestream information structure */ opj_bool l_go_on = OPJ_TRUE; + OPJ_UINT32 l_max_data_size = 1000; + OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000); /* FIXME configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); @@ -518,6 +520,7 @@ int main(int argc, char *argv[]) OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1; OPJ_UINT32 l_nb_comps, l_tile_index, l_data_size; + if (! opj_read_tile_header( dinfo, cio, &l_tile_index, @@ -535,6 +538,32 @@ int main(int argc, char *argv[]) opj_destroy_codec(dinfo); return EXIT_FAILURE; } + + if (l_go_on) { + + if (l_data_size > l_max_data_size) { + + l_data = (OPJ_BYTE *) realloc(l_data,l_data_size); + if (! l_data) { + opj_stream_destroy(cio); + fclose(fsrc); + opj_destroy_codec(dinfo); + return 1; + } + + l_max_data_size = l_data_size; + } + + if (! opj_decode_tile_data(dinfo,l_tile_index,l_data,l_data_size,cio)) + { + free(l_data); + opj_stream_destroy(cio); + fclose(fsrc); + opj_destroy_codec(dinfo); + return 1; + } + /** now should inspect image to know the reduction factor and then how to behave with data */ + } } /* Dump file informations from header */ diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index e705441d..328cf605 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -5715,7 +5715,7 @@ opj_bool j2k_read_tile_header( opj_j2k_v2_t * p_j2k, } /* Read into the codestream until reach the EOC or ! can_decode ??? FIXME */ - while (! p_j2k->m_specific_param.m_decoder.m_can_decode && l_current_marker != J2K_MS_EOC) { + while ( (!p_j2k->m_specific_param.m_decoder.m_can_decode) && (l_current_marker != J2K_MS_EOC) ) { /* Try to read until the Start Of Data is detected */ while (l_current_marker != J2K_MS_SOD) { @@ -5848,82 +5848,79 @@ opj_bool j2k_read_tile_header( opj_j2k_v2_t * p_j2k, *p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1; *p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1; *p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps; - p_j2k->m_specific_param.m_decoder.m_state |= 0x0080;// FIXME J2K_DEC_STATE_DATA; + + p_j2k->m_specific_param.m_decoder.m_state |= 0x0080;// FIXME J2K_DEC_STATE_DATA; return OPJ_TRUE; } -opj_bool j2k_decode_tile ( - opj_j2k_v2_t * p_j2k, - OPJ_UINT32 p_tile_index, - OPJ_BYTE * p_data, - OPJ_UINT32 p_data_size, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager - ) +opj_bool j2k_decode_tile ( opj_j2k_v2_t * p_j2k, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ) { OPJ_UINT32 l_current_marker; OPJ_BYTE l_data [2]; opj_tcp_v2_t * l_tcp; - // preconditions + /* preconditions */ assert(p_stream != 00); assert(p_j2k != 00); assert(p_manager != 00); - if - (! (p_j2k->m_specific_param.m_decoder.m_state & 0x0080/*FIXME J2K_DEC_STATE_DATA*/) || p_tile_index != p_j2k->m_current_tile_number) - { + if ( !(p_j2k->m_specific_param.m_decoder.m_state & 0x0080/*FIXME J2K_DEC_STATE_DATA*/) + || (p_tile_index != p_j2k->m_current_tile_number) ) { return OPJ_FALSE; } + l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]); - if - (! l_tcp->m_data) - { + if (! l_tcp->m_data) { j2k_tcp_destroy(&(p_j2k->m_cp.tcps[p_tile_index])); return OPJ_FALSE; } - if - (! tcd_decode_tile_v2(p_j2k->m_tcd, l_tcp->m_data, l_tcp->m_data_size, p_tile_index, p_j2k->cstr_info)) - { + + if (! tcd_decode_tile_v2( p_j2k->m_tcd, + l_tcp->m_data, + l_tcp->m_data_size, + p_tile_index, + p_j2k->cstr_info) ) { j2k_tcp_destroy(l_tcp); p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;//FIXME J2K_DEC_STATE_ERR; return OPJ_FALSE; } - if - (! tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) - { + + if (! tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) { return OPJ_FALSE; } + j2k_tcp_destroy(l_tcp); p_j2k->m_tcd->tcp = 0; p_j2k->m_specific_param.m_decoder.m_can_decode = 0; p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080));// FIXME J2K_DEC_STATE_DATA); - if - (p_j2k->m_specific_param.m_decoder.m_state != 0x0100)//FIXME J2K_DEC_STATE_EOC) - { - if - (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) - { + + if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100){ //FIXME J2K_DEC_STATE_EOC) + if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) { opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n"); return OPJ_FALSE; } + opj_read_bytes(l_data,&l_current_marker,2); - if - (l_current_marker == J2K_MS_EOC) - { + + if (l_current_marker == J2K_MS_EOC) { p_j2k->m_current_tile_number = 0; p_j2k->m_specific_param.m_decoder.m_state = 0x0100;//FIXME J2K_DEC_STATE_EOC; } - else if - (l_current_marker != J2K_MS_SOT) + else if (l_current_marker != J2K_MS_SOT) { opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short, expected SOT\n"); return OPJ_FALSE; } } + return OPJ_TRUE; } diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c index f69be8e1..c03d6602 100644 --- a/libopenjpeg/openjpeg.c +++ b/libopenjpeg/openjpeg.c @@ -794,3 +794,41 @@ opj_bool OPJ_CALLCONV opj_read_tile_header( } return OPJ_FALSE; } + +/** + * Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index the index of the tile being decoded, this should be the value set by opj_read_tile_header. + * @param p_data pointer to a memory block that will hold the decoded data. + * @param p_data_size size of p_data. p_data_size should be bigger or equal to the value set by opj_read_tile_header. + * @param p_stream the stream to decode. + * + * @return true if the data could be decoded. + */ +opj_bool OPJ_CALLCONV opj_decode_tile_data( + opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream + ) +{ + if (p_codec && p_data && p_stream) { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_stream; + + if (! l_info->is_decompressor) { + return OPJ_FALSE; + } + + return l_info->m_codec_data.m_decompression.opj_decode_tile_data( l_info->m_codec, + p_tile_index, + p_data, + p_data_size, + l_cio, + l_info->m_event_mgr); + } + return OPJ_FALSE; +} diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index 80c0f79b..4eabb399 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -1365,6 +1365,25 @@ OPJ_API opj_bool OPJ_CALLCONV opj_read_tile_header( opj_codec_t *p_codec, OPJ_UINT32 * p_nb_comps, opj_bool * p_should_go_on ); + +/** + * Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index the index of the tile being decoded, this should be the value set by opj_read_tile_header. + * @param p_data pointer to a memory block that will hold the decoded data. + * @param p_data_size size of p_data. p_data_size should be bigger or equal to the value set by opj_read_tile_header. + * @param p_stream the stream to decode. + * + * @return true if the data could be decoded. + */ +OPJ_API opj_bool OPJ_CALLCONV opj_decode_tile_data( opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream ); + #ifdef __cplusplus } #endif diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c index 017203d6..3d506ef5 100644 --- a/libopenjpeg/t2.c +++ b/libopenjpeg/t2.c @@ -903,6 +903,7 @@ opj_bool t2_decode_packets_v2( p_max_len -= l_nb_bytes_read; /* INDEX >> */ +#ifdef TODO_MSD if(p_cstr_info) { opj_tile_info_v2_t *info_TL = &p_cstr_info->tile[p_tile_no]; opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno]; @@ -920,15 +921,18 @@ opj_bool t2_decode_packets_v2( info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance ++p_cstr_info->packno; } +#endif /* << INDEX */ } ++l_current_pi; } /* INDEX >> */ +#ifdef TODO_MSD if (p_cstr_info) { p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; // Number of packets in last tile-part } +#endif /* << INDEX */ /* don't forget to release pi */ @@ -1024,7 +1028,7 @@ static opj_bool t2_decode_packet_v2( *p_data_read = l_nb_total_bytes_read; - return OPJ_FALSE; + return OPJ_TRUE; } static opj_bool t2_skip_packet(