WIP: begin to test opj_read_tile_header with V2 style

This commit is contained in:
Mickael Savinaud 2011-09-19 16:05:43 +00:00
parent d44375aece
commit 1a5c59326a
6 changed files with 278 additions and 151 deletions

View File

@ -6,6 +6,7 @@ What's New for OpenJPEG
+ : added
September 19, 2011
+ [mickael] WIP: begin to test opj_read_tile_header with V2 style
+ [mickael] WIP: create a new framework to output file information
+ [mickael] WIP: remove a piece of code copy by the merge op at the wrong place
+ [mickael] WIP: begin to clean j2k_dump and some other small things

View File

@ -195,8 +195,8 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet
}
/* -------------------------------------------------------------------------- */
/* parse the command line */
int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) {
/* parse the command line */
int totlen, c;
opj_option_t long_option[]={
{"ImgDir",REQ_ARG, NULL ,'y'},
@ -231,7 +231,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
}
break;
/* ------------------------------------------------------ */
/* ------------------------------------------------------ */
case 'o': /* output file */
{
@ -257,6 +257,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
break;
/* ----------------------------------------------------- */
case 'd': /* Input decode ROI */
{
int size_optarg = (int)strlen(optarg) + 1;
@ -264,7 +265,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
ROI_values[0] = '\0';
strncpy(ROI_values, optarg, strlen(optarg));
ROI_values[strlen(optarg)] = '\0';
printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg );
/*printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg ); */
parse_ROI_values( ROI_values, &parameters->ROI_x0, &parameters->ROI_y0, &parameters->ROI_x1, &parameters->ROI_y1);
}
break;
@ -371,8 +372,7 @@ int main(int argc, char *argv[])
opj_codec_t* dinfo = NULL; /* handle to a decompressor */
opj_stream_t *cio = NULL;
opj_codestream_info_t* cstr_info =NULL; /* Codestream information structure */
/* OPJ_INT32 l_tile_x0,l_tile_y0; */
/* OPJ_UINT32 l_tile_width,l_tile_height,l_nb_tiles_x,l_nb_tiles_y; */
opj_bool l_go_on = OPJ_TRUE;
/* FIXME configure the event callbacks (not required) */
@ -502,10 +502,40 @@ int main(int argc, char *argv[])
}
printf("Setting decoding area to %d,%d,%d,%d\n",
parameters.ROI_x0, parameters.ROI_y0, parameters.ROI_x1, parameters.ROI_x1);
opj_set_decode_area(dinfo,
parameters.ROI_x0, parameters.ROI_y0,
parameters.ROI_x1, parameters.ROI_x1);
parameters.ROI_x0, parameters.ROI_y0, parameters.ROI_x1, parameters.ROI_y1);
if (! opj_set_decode_area( dinfo,
parameters.ROI_x0, parameters.ROI_y0,
parameters.ROI_x1, parameters.ROI_y1)){
fprintf(stderr, "ERROR -> j2k_dump: failed to set the decoded area\n");
opj_stream_destroy(cio);
fclose(fsrc);
opj_destroy_codec(dinfo);
return EXIT_FAILURE;
}
while (l_go_on) {
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,
&l_data_size,
&l_current_tile_x0,
&l_current_tile_y0,
&l_current_tile_x1,
&l_current_tile_y1,
&l_nb_comps,
&l_go_on
)) {
fprintf(stderr, "ERROR -> j2k_dump: failed read the tile header\n");
opj_stream_destroy(cio);
fclose(fsrc);
opj_destroy_codec(dinfo);
return EXIT_FAILURE;
}
}
/* Dump file informations from header */
dump_file_info(fout, &file_info);

View File

@ -5670,19 +5670,15 @@ void j2k_cp_destroy (opj_cp_v2_t *p_cp)
* @param p_stream the stream to write data to.
* @param p_manager the user event manager.
*/
opj_bool j2k_read_tile_header (
opj_j2k_v2_t * p_j2k,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0,
OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1,
OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_go_on,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
opj_bool j2k_read_tile_header( opj_j2k_v2_t * p_j2k,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_go_on,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
OPJ_UINT32 l_current_marker = J2K_MS_SOT;
OPJ_UINT32 l_marker_size;
@ -5690,91 +5686,70 @@ opj_bool j2k_read_tile_header (
opj_tcp_v2_t * l_tcp = 00;
OPJ_UINT32 l_nb_tiles;
// preconditions
/* preconditions */
assert(p_stream != 00);
assert(p_j2k != 00);
assert(p_manager != 00);
if
(p_j2k->m_specific_param.m_decoder.m_state == 0x0100)// FIXME J2K_DEC_STATE_EOC)
{
if (p_j2k->m_specific_param.m_decoder.m_state == 0x0100){// FIXME J2K_DEC_STATE_EOC)
l_current_marker = J2K_MS_EOC;
}
else if
(p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) // FIXME J2K_DEC_STATE_TPHSOT)
{
else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT){ // FIXME J2K_DEC_STATE_TPHSOT)
return OPJ_FALSE;
}
while
(! p_j2k->m_specific_param.m_decoder.m_can_decode && l_current_marker != J2K_MS_EOC)
{
while
(l_current_marker != J2K_MS_SOD)
{
if
(opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2)
{
while (! p_j2k->m_specific_param.m_decoder.m_can_decode && l_current_marker != J2K_MS_EOC) {
while (l_current_marker != J2K_MS_SOD) {
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
}
opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
if
(p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH) // FIXME J2K_DEC_STATE_TPH)
{
if (p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH){ // FIXME J2K_DEC_STATE_TPH)
p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2);
}
l_marker_size -= 2;
l_marker_handler = j2k_get_marker_handler(l_current_marker);
// Check if the marker is known
if
(! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) )
{
/* Check if the marker is known */
if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
return OPJ_FALSE;
}
if
(l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size)
{
if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
p_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE*)
opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size);
if
(p_j2k->m_specific_param.m_decoder.m_header_data == 00)
{
opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size);
if (p_j2k->m_specific_param.m_decoder.m_header_data == 00) {
return OPJ_FALSE;
}
p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
}
if
(opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size)
{
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
}
if
(! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager))
{
if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
return OPJ_FALSE;
}
if
(p_j2k->m_specific_param.m_decoder.m_skip_data)
{
if
(opj_stream_skip(p_stream,p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length)
{
if (p_j2k->m_specific_param.m_decoder.m_skip_data) {
if (opj_stream_skip(p_stream,p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
}
l_current_marker = J2K_MS_SOD;
}
else
{
if
(opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2)
{
else {
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
}
@ -5782,23 +5757,17 @@ opj_bool j2k_read_tile_header (
}
}
if
(! p_j2k->m_specific_param.m_decoder.m_skip_data)
{
if
(! j2k_read_sod_v2(p_j2k,p_stream,p_manager))
{
if (! p_j2k->m_specific_param.m_decoder.m_skip_data) {
if (! j2k_read_sod_v2(p_j2k,p_stream,p_manager)) {
return OPJ_FALSE;
}
}
else
{
else {
p_j2k->m_specific_param.m_decoder.m_skip_data = 0;
p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; // FIXME J2K_DEC_STATE_TPHSOT;
if
(opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2)
{
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
}
@ -5806,55 +5775,47 @@ opj_bool j2k_read_tile_header (
}
}
if
(l_current_marker == J2K_MS_EOC)
{
if
(p_j2k->m_specific_param.m_decoder.m_state != 0x0100 )// FIXME J2K_DEC_STATE_EOC)
{
if (l_current_marker == J2K_MS_EOC) {
if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100 ){// FIXME J2K_DEC_STATE_EOC)
p_j2k->m_current_tile_number = 0;
p_j2k->m_specific_param.m_decoder.m_state = 0x0100;// FIXMEJ2K_DEC_STATE_EOC;
p_j2k->m_specific_param.m_decoder.m_state = 0x0100;// FIXME J2K_DEC_STATE_EOC;
}
}
if
( ! p_j2k->m_specific_param.m_decoder.m_can_decode)
{
if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
while
(
(p_j2k->m_current_tile_number < l_nb_tiles)
&& (l_tcp->m_data == 00)
)
{
while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
++p_j2k->m_current_tile_number;
++l_tcp;
}
if
(p_j2k->m_current_tile_number == l_nb_tiles)
{
if (p_j2k->m_current_tile_number == l_nb_tiles) {
*p_go_on = OPJ_FALSE;
return OPJ_TRUE;
}
}
if
(! tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number))
{
if (! tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
return OPJ_FALSE;
}
*p_tile_index = p_j2k->m_current_tile_number;
*p_go_on = OPJ_TRUE;
*p_data_size = tcd_get_decoded_tile_size(p_j2k->m_tcd);
* p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
* p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
* 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_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
*p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
*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;
return OPJ_TRUE;
}
opj_bool j2k_decode_tile (
opj_j2k_v2_t * p_j2k,
OPJ_UINT32 p_tile_index,
@ -5941,27 +5902,89 @@ opj_bool j2k_decode_tile (
*
* @return true if the area could be set.
*/
opj_bool j2k_set_decode_area(
opj_j2k_v2_t *p_j2k,
OPJ_INT32 p_start_x,
OPJ_INT32 p_start_y,
OPJ_INT32 p_end_x,
OPJ_INT32 p_end_y,
struct opj_event_mgr * p_manager
)
opj_bool j2k_set_decode_area( opj_j2k_v2_t *p_j2k,
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
struct opj_event_mgr * p_manager )
{
opj_cp_v2_t * l_cp = &(p_j2k->m_cp);
if
(p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT)// FIXME J2K_DEC_STATE_TPHSOT)
{
/* Check if we are read the main header */
if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { // FIXME J2K_DEC_STATE_TPHSOT)
opj_event_msg_v2(p_manager, EVT_ERROR, "Need to decode the main header before begin to decode the remaining codestream");
return OPJ_FALSE;
}
p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx;
p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy;
p_j2k->m_specific_param.m_decoder.m_end_tile_x = int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx);
p_j2k->m_specific_param.m_decoder.m_end_tile_y = int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy);
/* ----- */
/* Check if the positions provided by the user are correct */
/* Left */
if (p_start_x > l_cp->tw * l_cp->tdx) {
opj_event_msg_v2(p_manager, EVT_ERROR,
"Left position of the decoded area (ROI_x0=%d) is outside the tile area (nb_tw x XTsiz=%d).\n",
p_start_x, l_cp->tw * l_cp->tdx);
return OPJ_FALSE;
}
else if (p_start_x < l_cp->tx0){
opj_event_msg_v2(p_manager, EVT_WARNING,
"Left position of the decoded area (ROI_x0=%d) is outside the tile area (XTOsiz=%d).\n",
p_start_x, l_cp->tx0);
p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
}
else
p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx;
/* Up */
if (p_start_y > l_cp->th * l_cp->tdy){
opj_event_msg_v2(p_manager, EVT_ERROR,
"Up position of the decoded area (ROI_y0=%d) is outside the tile area (nb_th x YTsiz=%d).\n",
p_start_y, l_cp->th * l_cp->tdy);
return OPJ_FALSE;
}
else if (p_start_y < l_cp->ty0){
opj_event_msg_v2(p_manager, EVT_WARNING,
"Up position of the decoded area (ROI_y0=%d) is outside the tile area (YTOsiz=%d).\n",
p_start_y, l_cp->ty0);
p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
}
else
p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy;
/* Right */
if (p_end_x < l_cp->tx0) {
opj_event_msg_v2(p_manager, EVT_ERROR,
"Right position of the decoded area (ROI_x1=%d) is outside the tile area (XTOsiz=%d).\n",
p_end_x, l_cp->tx0);
return OPJ_FALSE;
}
else if (p_end_x > l_cp->tw * l_cp->tdx) {
opj_event_msg_v2(p_manager, EVT_WARNING,
"Right position of the decoded area (ROI_x1=%d) is outside the tile area (nb_tw x XTsiz=%d).\n",
p_end_x, l_cp->tw * l_cp->tdx);
p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw; // FIXME (-1) ???
}
else
p_j2k->m_specific_param.m_decoder.m_end_tile_x = int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx);
/* Bottom */
if (p_end_x < l_cp->ty0) {
opj_event_msg_v2(p_manager, EVT_ERROR,
"Right position of the decoded area (ROI_y1=%d) is outside the tile area (YTOsiz=%d).\n",
p_end_x, l_cp->ty0);
return OPJ_FALSE;
}
if (p_end_y > l_cp->th * l_cp->tdy){
opj_event_msg_v2(p_manager, EVT_WARNING,
"Bottom position of the decoded area (ROI_y1=%d) is outside the tile area (nb_th x YTsiz=%d).\n",
p_end_y, l_cp->th * l_cp->tdy);
p_j2k->m_specific_param.m_decoder.m_start_tile_y = l_cp->th; // FIXME (-1) ???
}
else
p_j2k->m_specific_param.m_decoder.m_end_tile_y = int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy);
/* ----- */
p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1;
return OPJ_TRUE;
}

View File

@ -2451,27 +2451,21 @@ void jp2_setup_header_reading (opj_jp2_v2_t *jp2)
* @param p_stream the stream to write data to.
* @param p_manager the user event manager.
*/
opj_bool jp2_read_tile_header (
opj_jp2_v2_t * p_jp2,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0,
OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1,
OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_go_on,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
opj_bool jp2_read_tile_header( opj_jp2_v2_t * p_jp2,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_go_on,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
return j2k_read_tile_header (p_jp2->j2k,
return j2k_read_tile_header(p_jp2->j2k,
p_tile_index,
p_data_size,
p_tile_x0,
p_tile_y0,
p_tile_x1,
p_tile_y1,
p_tile_x0, p_tile_y0,
p_tile_x1, p_tile_y1,
p_nb_comps,
p_go_on,
p_stream,
@ -2558,16 +2552,12 @@ void jp2_destroy(opj_jp2_v2_t *jp2)
*
* @return true if the area could be set.
*/
opj_bool jp2_set_decode_area(
opj_jp2_v2_t *p_jp2,
OPJ_INT32 p_start_x,
OPJ_INT32 p_start_y,
OPJ_INT32 p_end_x,
OPJ_INT32 p_end_y,
struct opj_event_mgr * p_manager
)
opj_bool jp2_set_decode_area( opj_jp2_v2_t *p_jp2,
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
struct opj_event_mgr * p_manager )
{
return j2k_set_decode_area(p_jp2->j2k,p_start_x,p_start_y,p_end_x,p_end_y,p_manager);
return j2k_set_decode_area(p_jp2->j2k, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
}
/* ----------------------------------------------------------------------- */

View File

@ -736,8 +736,61 @@ opj_bool OPJ_CALLCONV opj_set_decode_area( opj_codec_t *p_codec,
p_start_y,
p_end_x,
p_end_y,
&(l_info->m_event_mgr));
l_info->m_event_mgr);
}
return OPJ_FALSE;
}
/**
* Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded.
* 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 pointer to a value that will hold the index of the tile being decoded, in case of success.
* @param p_data_size pointer to a value that will hold the maximum size of the decoded data, in case of success. In case
* of truncated codestreams, the actual number of bytes decoded may be lower. The computation of the size is the same
* as depicted in opj_write_tile.
* @param p_tile_x0 pointer to a value that will hold the x0 pos of the tile (in the image).
* @param p_tile_y0 pointer to a value that will hold the y0 pos of the tile (in the image).
* @param p_tile_x1 pointer to a value that will hold the x1 pos of the tile (in the image).
* @param p_tile_y1 pointer to a value that will hold the y1 pos of the tile (in the image).
* @param p_nb_comps pointer to a value that will hold the number of components in the tile.
* @param p_should_go_on pointer to a boolean that will hold the fact that the decoding should go on. In case the
* codestream is over at the time of the call, the value will be set to false. The user should then stop
* the decoding.
* @param p_stream the stream to decode.
* @return true if the tile header could be decoded. In case the decoding should end, the returned value is still true.
* returning false may be the result of a shortage of memory or an internal error.
*/
opj_bool OPJ_CALLCONV opj_read_tile_header(
opj_codec_t *p_codec,
opj_stream_t * p_stream,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_should_go_on)
{
if (p_codec && p_stream && p_data_size && p_tile_index) {
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_read_tile_header(
l_info->m_codec,
p_tile_index,
p_data_size,
p_tile_x0, p_tile_y0,
p_tile_x1, p_tile_y1,
p_nb_comps,
p_should_go_on,
l_cio,
l_info->m_event_mgr);
}
return OPJ_FALSE;
}

View File

@ -1335,6 +1335,36 @@ OPJ_API opj_bool OPJ_CALLCONV opj_set_decode_area( opj_codec_t *p_codec,
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
OPJ_INT32 p_end_x, OPJ_INT32 p_end_y );
/**
* Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded.
* 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 pointer to a value that will hold the index of the tile being decoded, in case of success.
* @param p_data_size pointer to a value that will hold the maximum size of the decoded data, in case of success. In case
* of truncated codestreams, the actual number of bytes decoded may be lower. The computation of the size is the same
* as depicted in opj_write_tile.
* @param p_tile_x0 pointer to a value that will hold the x0 pos of the tile (in the image).
* @param p_tile_y0 pointer to a value that will hold the y0 pos of the tile (in the image).
* @param p_tile_x1 pointer to a value that will hold the x1 pos of the tile (in the image).
* @param p_tile_y1 pointer to a value that will hold the y1 pos of the tile (in the image).
* @param p_nb_comps pointer to a value that will hold the number of components in the tile.
* @param p_should_go_on pointer to a boolean that will hold the fact that the decoding should go on. In case the
* codestream is over at the time of the call, the value will be set to false. The user should then stop
* the decoding.
* @param p_stream the stream to decode.
* @return true if the tile header could be decoded. In case the decoding should end, the returned value is still true.
* returning false may be the result of a shortage of memory or an internal error.
*/
OPJ_API opj_bool OPJ_CALLCONV opj_read_tile_header( opj_codec_t *p_codec,
opj_stream_t * p_stream,
OPJ_UINT32 * p_tile_index,
OPJ_UINT32 * p_data_size,
OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
OPJ_UINT32 * p_nb_comps,
opj_bool * p_should_go_on );
#ifdef __cplusplus
}
#endif