diff --git a/ChangeLog b/ChangeLog index fe66be18..007d7f9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ What's New for OpenJPEG + : added September 7, 2007 ++ [FOD] Indexes can now be generated when decoding J2K codestreams. * [Mathieu Malaterre] Upon failure, properly return error code (!=0). * [Mathieu Malaterre] CMake: Add cmake code to do testing if user has properly setup a testimages directory diff --git a/codec/convert.c b/codec/convert.c index d074909f..013bc152 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -1795,7 +1795,7 @@ opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw opj_image_t * image = NULL; unsigned short ch; - if((raw_cp->rawWidth * raw_cp->rawHeight * raw_cp->rawComp * raw_cp->rawBitDepth) == 0) + if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0) { fprintf(stderr,"\nError: invalid raw image parameters\n"); fprintf(stderr,"Please use the Format option -F:\n"); @@ -1834,7 +1834,6 @@ opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw fclose(f); return NULL; } - /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; @@ -1871,7 +1870,6 @@ opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw if (fread(&ch, 1, 1, f)) { fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n"); } - fclose(f); return image; diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index 14737424..eb559f3c 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -582,11 +582,11 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "%d\n", cstr_info->prog); fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y); fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th); - fprintf(stream, "%d\n", cstr_info->comp); - fprintf(stream, "%d\n", cstr_info->layer); - fprintf(stream, "%d\n", cstr_info->decomposition); + fprintf(stream, "%d\n", cstr_info->numcomps); + fprintf(stream, "%d\n", cstr_info->numlayers); + fprintf(stream, "%d\n", cstr_info->numdecompos); - for (resno = cstr_info->decomposition; resno >= 0; resno--) { + for (resno = cstr_info->numdecompos; resno >= 0; resno--) { fprintf(stream, "[%d,%d] ", (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 */ } @@ -598,26 +598,16 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "%d\n", cstr_info->codestream_size); fprintf(stream, "\nINFO ON TILES\n"); - fprintf(stream, "tileno start_pos end_hd end_tile" -/* UniPG>> */ - " nbparts" -/* <tw * cstr_info->th; tileno++) { - fprintf(stream, "%4d %9d %9d %9d " -/* UniPG>> */ - "%9d " -/* <tile[tileno].num_tile, + fprintf(stream, "%4d %9d %9d %9d %9d %9e %9d %9e\n", + cstr_info->tile[tileno].tileno, cstr_info->tile[tileno].start_pos, cstr_info->tile[tileno].end_header, cstr_info->tile[tileno].end_pos, -/* UniPG>> */ cstr_info->tile[tileno].num_tps, -/* <tile[tileno].distotile, cstr_info->tile[tileno].nbpix, - cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].nbpix); + cstr_info->tile[tileno].distotile, cstr_info->tile[tileno].numpix, + cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].numpix); } for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { @@ -626,24 +616,21 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { pack_nb = 0; fprintf(stream, "\nTILE %d DETAILS\n", tileno); -/* UniPG>> */ - fprintf(stream, "part_nb tileno pack_nb start_pos end_tph_pos end_pos\n"); + fprintf(stream, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n"); for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++) - fprintf(stream, "%4d %9d %9d %9d %11d %9d\n", + fprintf(stream, "%4d %9d %9d %9d %11d %9d\n", tilepartno, tileno, - cstr_info->tile[tileno].tp_num[tilepartno], - cstr_info->tile[tileno].tp_start_pos[tilepartno], - cstr_info->tile[tileno].tp_end_header[tilepartno], - cstr_info->tile[tileno].tp_end_pos[tilepartno] + cstr_info->tile[tileno].tp[tilepartno].tp_numpacks, + cstr_info->tile[tileno].tp[tilepartno].tp_start_pos, + cstr_info->tile[tileno].tp[tilepartno].tp_end_header, + cstr_info->tile[tileno].tp[tilepartno].tp_end_pos ); -/* <prog == LRCP) { /* LRCP */ - fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n"); - for (layno = 0; layno < cstr_info->layer; layno++) { - for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { - for (compno = 0; compno < cstr_info->comp; compno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; for (precno = 0; precno < prec_max; precno++) { start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; @@ -663,9 +650,9 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos disto\n"); - for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { - for (layno = 0; layno < cstr_info->layer; layno++) { - for (compno = 0; compno < cstr_info->comp; compno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; for (precno = 0; precno < prec_max; precno++) { start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; @@ -685,25 +672,25 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos disto\n"); - for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { /* I suppose components have same XRsiz, YRsiz */ int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x; int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y; int x1 = x0 + cstr_info->tile_x; int y1 = y0 + cstr_info->tile_y; - for (compno = 0; compno < cstr_info->comp; compno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; for (precno = 0; precno < prec_max; precno++) { int pcnx = cstr_info->tile[tileno].pw[resno]; - int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->decomposition - resno ); - int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->decomposition - resno ); + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; int precno_y = (int) floor( (float)precno/(float)pcnx ); for(y = y0; y < y1; y++) { if (precno_y*pcy == y ) { for (x = x0; x < x1; x++) { if (precno_x*pcx == x ) { - for (layno = 0; layno < cstr_info->layer; layno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; @@ -730,20 +717,20 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos disto\n"); - for (compno = 0; compno < cstr_info->comp; compno++) { - for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; for (precno = 0; precno < prec_max; precno++) { int pcnx = cstr_info->tile[tileno].pw[resno]; - int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->decomposition - resno ); - int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->decomposition - resno ); + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; int precno_y = (int) floor( (float)precno/(float)pcnx ); for(y = y0; y < y1; y++) { if (precno_y*pcy == y ) { for (x = x0; x < x1; x++) { if (precno_x*pcx == x ) { - for (layno = 0; layno < cstr_info->layer; layno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; @@ -765,26 +752,26 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos disto\n"); - for (compno = 0; compno < cstr_info->comp; compno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { /* I suppose components have same XRsiz, YRsiz */ int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x; int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y; int x1 = x0 + cstr_info->tile_x; int y1 = y0 + cstr_info->tile_y; - for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; for (precno = 0; precno < prec_max; precno++) { int pcnx = cstr_info->tile[tileno].pw[resno]; - int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->decomposition - resno ); - int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->decomposition - resno ); + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; int precno_y = (int) floor( (float)precno/(float)pcnx ); for(y = y0; y < y1; y++) { if (precno_y*pcy == y ) { for (x = x0; x < x1; x++) { if (precno_x*pcx == x ) { - for (layno = 0; layno < cstr_info->layer; layno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; @@ -816,7 +803,7 @@ int write_index_file(opj_codestream_info_t *cstr_info, char *index) { /* ------------------------------------------------------------------------------------ */ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, - img_fol_t *img_fol, raw_cparameters_t *raw_cp) { + img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename) { int i, j,totlen; option_t long_option[]={ {"cinema2K",REQ_ARG, NULL ,'w'}, @@ -1087,8 +1074,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, case 'x': /* creation of index file */ { char *index = optarg; - strncpy(parameters->index, index, sizeof(parameters->index)-1); - parameters->index_on = 1; + strncpy(indexfilename, index, OPJ_PATH_LEN); } break; @@ -1302,9 +1288,8 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, int hprot, pprot, sens, addr, size, range; /* we need to enable indexing */ - if (!parameters->index_on) { + if (!indexfilename) { strncpy(parameters->index, JPWL_PRIVATEINDEX_NAME, sizeof(parameters->index)-1); - parameters->index_on = 1; } /* search for different protection methods */ @@ -1731,7 +1716,8 @@ int main(int argc, char **argv) { int imageno; dircnt_t *dirptr; raw_cparameters_t raw_cp; - opj_codestream_info_t cstr_info; + opj_codestream_info_t cstr_info; /* Codestream information structure */ + char indexfilename[OPJ_PATH_LEN]; /* index file name */ /* configure the event callbacks (not required) @@ -1745,11 +1731,12 @@ int main(int argc, char **argv) { /* set encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); - /* need to initialize img_fol since parameters will be read in parse_cmdline_decoder */ + /* Initialize indexfilename and img_fol */ + *indexfilename = 0; memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ - if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp) == 1) { + if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp, indexfilename) == 1) { return 1; } @@ -1929,8 +1916,8 @@ int main(int argc, char **argv) { opj_cio_close(cio); /* Write the index to disk */ - if (parameters.index_on) { - bSuccess = write_index_file(&cstr_info, parameters.index); + if (*indexfilename) { + bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } @@ -1938,6 +1925,8 @@ int main(int argc, char **argv) { /* free remaining compression structures */ opj_destroy_compress(cinfo); + opj_destroy_cstr_info(&cstr_info); + } else { /* JP2 format output */ int codestream_length; opj_cio_t *cio = NULL; @@ -1978,8 +1967,8 @@ int main(int argc, char **argv) { opj_cio_close(cio); /* Write the index to disk */ - if (parameters.index_on) { - bSuccess = write_index_file(&cstr_info, parameters.index); + if (*indexfilename) { + bSuccess = write_index_file(&cstr_info, indexfilename); if (bSuccess) { fprintf(stderr, "Failed to output index file\n"); } @@ -1987,7 +1976,7 @@ int main(int argc, char **argv) { /* free remaining compression structures */ opj_destroy_compress(cinfo); - + opj_destroy_cstr_info(&cstr_info); } /* free image data */ diff --git a/codec/j2k_to_image.c b/codec/j2k_to_image.c index 677bf98e..182420f5 100644 --- a/codec/j2k_to_image.c +++ b/codec/j2k_to_image.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "openjpeg.h" #include "compat/getopt.h" @@ -120,6 +121,9 @@ void decode_help_display() { fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n"); fprintf(stdout," less quality layers than the specified number, all the quality layers\n"); fprintf(stdout," are decoded.\n"); + fprintf(stdout," -x \n"); + fprintf(stdout," Create an index file *.Idx (-x index_name.Idx) \n"); + fprintf(stdout,"\n"); /* UniPG>> */ #ifdef USE_JPWL fprintf(stdout," -W \n"); @@ -225,10 +229,237 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet return 0; } +/* ------------------------------------------------------------------------------------ */ + +/** +Create an index and write it to a file +@param cstr_info Codestream information +@param index Index filename +@return Returns 0 if successful, returns 1 otherwise +*/ +int write_index_file(opj_codestream_info_t *cstr_info, char *index) { + int tileno, compno, layno, resno, precno, pack_nb, x, y; + FILE *stream = NULL; + int tilepartno; + + if (!cstr_info) + return 1; + + stream = fopen(index, "w"); + if (!stream) { + fprintf(stderr, "failed to open index file [%s] for writing\n", index); + return 1; + } + + fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h); + fprintf(stream, "%d\n", cstr_info->prog); + fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y); + fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th); + fprintf(stream, "%d\n", cstr_info->numcomps); + fprintf(stream, "%d\n", cstr_info->numlayers); + fprintf(stream, "%d\n", cstr_info->numdecompos); + + for (resno = cstr_info->numdecompos; resno >= 0; resno--) { + fprintf(stream, "[%d,%d] ", + (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 */ + } + fprintf(stream, "\n"); + fprintf(stream, "%d\n", cstr_info->main_head_start); + fprintf(stream, "%d\n", cstr_info->main_head_end); + fprintf(stream, "%d\n", cstr_info->codestream_size); + + fprintf(stream, "\nINFO ON TILES\n"); + fprintf(stream, "tileno start_pos end_hd end_tile nbparts\n"); + for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { + fprintf(stream, "%4d %9d %9d %9d %9d\n", + cstr_info->tile[tileno].tileno, + cstr_info->tile[tileno].start_pos, + cstr_info->tile[tileno].end_header, + cstr_info->tile[tileno].end_pos, + cstr_info->tile[tileno].num_tps); + } + + for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { + int start_pos, end_ph_pos, end_pos; + pack_nb = 0; + + fprintf(stream, "\nTILE %d DETAILS\n", tileno); + fprintf(stream, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n"); + for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++) + fprintf(stream, "%4d %9d %9d %9d %11d %9d\n", + tilepartno, tileno, + cstr_info->tile[tileno].tp[tilepartno].tp_numpacks, + cstr_info->tile[tileno].tp[tilepartno].tp_start_pos, + cstr_info->tile[tileno].tp[tilepartno].tp_end_header, + cstr_info->tile[tileno].tp[tilepartno].tp_end_pos + ); + if (cstr_info->prog == LRCP) { /* LRCP */ + fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos\n"); + + for (layno = 0; layno < cstr_info->numlayers; layno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { + int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; + end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; + end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; + fprintf(stream, "%4d %6d %7d %5d %6d %6d %6d %6d %7d\n", + pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos); + pack_nb++; + } + } + } + } + } /* LRCP */ + else if (cstr_info->prog == RLCP) { /* RLCP */ + + fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n"); + + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + for (compno = 0; compno < cstr_info->numcomps; compno++) { + int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; + end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; + end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; + fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %7d\n", + pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos); + pack_nb++; + } + } + } + } + } /* RLCP */ + else if (cstr_info->prog == RPCL) { /* RPCL */ + + fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos\n"); + + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + /* I suppose components have same XRsiz, YRsiz */ + int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x; + int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y; + int x1 = x0 + cstr_info->tile_x; + int y1 = y0 + cstr_info->tile_y; + for (compno = 0; compno < cstr_info->numcomps; compno++) { + int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = cstr_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + for(y = y0; y < y1; y++) { + if (precno_y*pcy == y ) { + for (x = x0; x < x1; x++) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; + end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; + end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; + fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %7d\n", + pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos); + pack_nb++; + } + } + }/* x = x0..x1 */ + } + } /* y = y0..y1 */ + } /* precno */ + } /* compno */ + } /* resno */ + } /* RPCL */ + else if (cstr_info->prog == PCRL) { /* PCRL */ + /* I suppose components have same XRsiz, YRsiz */ + int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x; + int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y; + int x1 = x0 + cstr_info->tile_x; + int y1 = y0 + cstr_info->tile_y; + + fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos\n"); + + for (compno = 0; compno < cstr_info->numcomps; compno++) { + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = cstr_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + for(y = y0; y < y1; y++) { + if (precno_y*pcy == y ) { + for (x = x0; x < x1; x++) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; + end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; + end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d\n", + pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos); + pack_nb++; + } + } + }/* x = x0..x1 */ + } + } /* y = y0..y1 */ + } /* precno */ + } /* resno */ + } /* compno */ + } /* PCRL */ + else { /* CPRL */ + + fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos\n"); + + for (compno = 0; compno < cstr_info->numcomps; compno++) { + /* I suppose components have same XRsiz, YRsiz */ + int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x; + int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y; + int x1 = x0 + cstr_info->tile_x; + int y1 = y0 + cstr_info->tile_y; + + for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) { + int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = cstr_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos - resno ); + int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + for(y = y0; y < y1; y++) { + if (precno_y*pcy == y ) { + for (x = x0; x < x1; x++) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < cstr_info->numlayers; layno++) { + start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; + end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos; + end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d\n", + pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos); + pack_nb++; + } + } + }/* x = x0..x1 */ + } + } /* y = y0..y1 */ + } /* precno */ + } /* resno */ + } /* compno */ + } /* CPRL */ + } /* tileno */ + + fclose(stream); + + fprintf(stderr,"Generated index file %s\n", index); + + return 0; +} + +/* ------------------------------------------------------------------------------------ */ /* -------------------------------------------------------------------------- */ - -int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) { +int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) { /* parse the command line */ int totlen; option_t long_option[]={ @@ -236,7 +467,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i {"OutFor",REQ_ARG, NULL ,'O'}, }; - const char optlist[] = "i:o:r:l:h" + const char optlist[] = "i:o:r:l:hx:" /* UniPG>> */ #ifdef USE_JPWL @@ -361,8 +592,15 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i img_fol->set_imgdir=1; } break; + /* ----------------------------------------------------- */ + case 'x': /* Creation of index file */ + { + char *index = optarg; + strncpy(indexfilename, index, OPJ_PATH_LEN); + } + break; /* ----------------------------------------------------- */ -/* UniPG>> */ + /* UniPG>> */ #ifdef USE_JPWL case 'W': /* activate JPWL correction */ @@ -507,6 +745,8 @@ int main(int argc, char **argv) { dircnt_t *dirptr; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; + opj_codestream_info_t cstr_info; /* Codestream information structure */ + char indexfilename[OPJ_PATH_LEN]; /* index file name */ /* configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); @@ -517,14 +757,16 @@ int main(int argc, char **argv) { /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); - /* need to initialize img_fol since parameters will be read in parse_cmdline_decoder */ + /* Initialize indexfilename and img_fol */ + *indexfilename = 0; memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ - if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { + if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { return 1; } + /* Initialize reading of directory */ if(img_fol.set_imgdir==1){ num_images=get_num_images(img_fol.imgdirpath); @@ -552,9 +794,7 @@ int main(int argc, char **argv) { } /*Encoding image one by one*/ - for(imageno = 0; imageno < num_images ; imageno++) - { - + for(imageno = 0; imageno < num_images ; imageno++) { image = NULL; fprintf(stderr,"\n"); @@ -563,10 +803,8 @@ int main(int argc, char **argv) { fprintf(stderr,"skipping file...\n"); continue; } - } - /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(parameters.infile, "rb"); @@ -604,7 +842,7 @@ int main(int argc, char **argv) { cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ - image = opj_decode(dinfo, cio); + image = opj_decode(dinfo, cio, &cstr_info); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); @@ -614,6 +852,15 @@ int main(int argc, char **argv) { /* close the byte stream */ opj_cio_close(cio); + + /* Write the index to disk */ + if (*indexfilename) { + char bSuccess; + bSuccess = write_index_file(&cstr_info, indexfilename); + if (bSuccess) { + fprintf(stderr, "Failed to output index file\n"); + } + } } break; @@ -634,7 +881,7 @@ int main(int argc, char **argv) { cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ - image = opj_decode(dinfo, cio); + image = opj_decode(dinfo, cio, &cstr_info); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); @@ -645,6 +892,14 @@ int main(int argc, char **argv) { /* close the byte stream */ opj_cio_close(cio); + /* Write the index to disk */ + if (*indexfilename) { + char bSuccess; + bSuccess = write_index_file(&cstr_info, indexfilename); + if (bSuccess) { + fprintf(stderr, "Failed to output index file\n"); + } + } } break; @@ -665,7 +920,7 @@ int main(int argc, char **argv) { cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ - image = opj_decode(dinfo, cio); + image = opj_decode(dinfo, cio, &cstr_info); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); @@ -675,6 +930,15 @@ int main(int argc, char **argv) { /* close the byte stream */ opj_cio_close(cio); + + /* Write the index to disk */ + if (*indexfilename) { + char bSuccess; + bSuccess = write_index_file(&cstr_info, indexfilename); + if (bSuccess) { + fprintf(stderr, "Failed to output index file\n"); + } + } } break; @@ -749,6 +1013,8 @@ int main(int argc, char **argv) { if(dinfo) { opj_destroy_decompress(dinfo); } + /* free codestream information structure */ + opj_destroy_cstr_info(&cstr_info); /* free image data structure */ opj_image_destroy(image); diff --git a/libopenjpeg/cio.c b/libopenjpeg/cio.c index 0725b381..2ac262a1 100644 --- a/libopenjpeg/cio.c +++ b/libopenjpeg/cio.c @@ -58,9 +58,10 @@ opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer opj_free(cio); return NULL; } - cio->length = (int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */ + cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */ cio->buffer = (unsigned char *)opj_malloc(cio->length); if(!cio->buffer) { + opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n"); opj_free(cio); return NULL; } diff --git a/libopenjpeg/image.c b/libopenjpeg/image.c index 26d2074a..6698f459 100644 --- a/libopenjpeg/image.c +++ b/libopenjpeg/image.c @@ -42,6 +42,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c /* allocate memory for the per-component information */ image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); if(!image->comps) { + fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); return NULL; } @@ -59,6 +60,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c comp->sgnd = cmptparms[compno].sgnd; comp->data = (int*)opj_malloc(comp->w * comp->h * sizeof(int)); if(!comp->data) { + fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); return NULL; } diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 8580098a..727391ef 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -421,17 +421,12 @@ int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t * pi_destroy(pi, cp, tileno); } j2k->cur_totnum_tp[tileno] = cur_totnum_tp; -/* UniPG>> */ /* INDEX >> */ - if (j2k->cstr_info && j2k->cstr_info->index_on) { + if (j2k->cstr_info) { j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp; - j2k->cstr_info->tile[tileno].tp_start_pos = (int *) opj_malloc(cur_totnum_tp * sizeof(int)); - j2k->cstr_info->tile[tileno].tp_end_header = (int *) opj_malloc(cur_totnum_tp * sizeof(int)); - j2k->cstr_info->tile[tileno].tp_end_pos = (int *) opj_malloc(cur_totnum_tp * sizeof(int)); - j2k->cstr_info->tile[tileno].tp_num = (int *) opj_malloc(cur_totnum_tp * sizeof(int)); + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t)); } /* << INDEX */ -/* <state = J2K_STATE_MHSIZ; + /* Index */ + if (j2k->cstr_info) { + j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2; + j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start; + } } static void j2k_write_siz(opj_j2k_t *j2k) { @@ -574,7 +574,6 @@ static void j2k_read_siz(opj_j2k_t *j2k) { } #endif /* USE_JPWL */ - /* TODO: unused ? */ w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); @@ -663,6 +662,21 @@ static void j2k_read_siz(opj_j2k_t *j2k) { j2k->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * sizeof(unsigned char *)); j2k->tile_len = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); j2k->state = J2K_STATE_MH; + + /* Index */ + if (j2k->cstr_info) { + opj_codestream_info_t *cstr_info = j2k->cstr_info; + cstr_info->image_w = image->x1 - image->x0; + cstr_info->image_h = image->y1 - image->y0; + cstr_info->numcomps = image->numcomps; + cstr_info->tw = cp->tw; + cstr_info->th = cp->th; + cstr_info->tile_x = cp->tdx; + cstr_info->tile_y = cp->tdy; + cstr_info->tile_Ox = cp->tx0; + cstr_info->tile_Oy = cp->ty0; + cstr_info->tile = (opj_tile_info_t*) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); + } } static void j2k_write_com(opj_j2k_t *j2k) { @@ -676,7 +690,7 @@ static void j2k_write_com(opj_j2k_t *j2k) { cio_write(cio, J2K_MS_COM, 2); lenp = cio_tell(cio); cio_skip(cio, 2); - cio_write(cio, 0, 2); + cio_write(cio, 1, 2); /* General use (IS 8859-15:1999 (Latin) values) */ for (i = 0; i < strlen(comment); i++) { cio_write(cio, comment[i], 1); } @@ -740,6 +754,21 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) { tccp->prch[i] = tmp >> 4; } } + + /* INDEX >> */ + if(j2k->cstr_info && compno == 0) { + for (i = 0; i < tccp->numresolutions; i++) { + if (tccp->csty & J2K_CP_CSTY_PRT) { + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i]; + j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i]; + } + else { + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; + } + } + } + /* << INDEX */ } static void j2k_write_cod(opj_j2k_t *j2k) { @@ -789,6 +818,14 @@ static void j2k_read_cod(opj_j2k_t *j2k) { cio_seek(cio, pos); j2k_read_cox(j2k, i); } + + /* Index */ + if (j2k->cstr_info) { + opj_codestream_info_t *cstr_info = j2k->cstr_info; + cstr_info->prog = tcp->prg; + cstr_info->numlayers = tcp->numlayers; + cstr_info->numdecompos = tcp->tccps[0].numresolutions - 1; + } } static void j2k_write_coc(opj_j2k_t *j2k, int compno) { @@ -1249,7 +1286,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) { opj_cp_t *cp = j2k->cp; opj_cio_t *cio = j2k->cio; - + len = cio_read(cio, 2); tileno = cio_read(cio, 2); @@ -1278,7 +1315,6 @@ static void j2k_read_sot(opj_j2k_t *j2k) { backup_tileno++; }; #endif /* USE_JPWL */ - if (cp->tileno_size == 0) { cp->tileno[cp->tileno_size] = tileno; @@ -1326,12 +1362,30 @@ static void j2k_read_sot(opj_j2k_t *j2k) { numparts = cio_read(cio, 1); j2k->curtileno = tileno; + j2k->cur_tp_num = partno; j2k->eot = cio_getbp(cio) - 12 + totlen; j2k->state = J2K_STATE_TPH; tcp = &cp->tcps[j2k->curtileno]; + + /* Index */ + if (j2k->cstr_info) { + if (tcp->first) { + if (tileno == 0) + j2k->cstr_info->main_head_end = cio_tell(cio) - 13; + j2k->cstr_info->tile[tileno].tileno = tileno; + j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12; + j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1; + j2k->cstr_info->tile[tileno].num_tps = numparts; + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t)); + } + else + j2k->cstr_info->tile[tileno].end_pos += totlen; + j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12; + j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = + j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1; + } - if (tcp->first == 1) { - + if (tcp->first == 1) { /* Initialization PPT */ opj_tccp_t *tmp = tcp->tccps; memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t)); @@ -1367,12 +1421,14 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { /* INDEX >> */ cstr_info = j2k->cstr_info; - if (cstr_info && cstr_info->index_on) { - if (!j2k->cur_tp_num ){ + if (cstr_info) { + if (!j2k->cur_tp_num ) { cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; - }else{ - if(cstr_info->tile[j2k->curtileno].packet[cstr_info->num - 1].end_pos < cio_tell(cio)) - cstr_info->tile[j2k->curtileno].packet[cstr_info->num].start_pos = cio_tell(cio); + j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno; + } + else{ + if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio)) + cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio); } } /* << INDEX */ @@ -1382,7 +1438,7 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { tcp->rates[layno] -= tcp->rates[layno] ? (j2k->sod_start / (cp->th * cp->tw)) : 0; } if(cstr_info && (j2k->cur_tp_num == 0)) { - cstr_info->num = 0; + cstr_info->packno = 0; } l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info); @@ -1407,13 +1463,22 @@ static void j2k_read_sod(opj_j2k_t *j2k) { opj_cio_t *cio = j2k->cio; int curtileno = j2k->curtileno; + + /* Index */ + if (j2k->cstr_info) { + j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = + cio_tell(cio) + j2k->pos_correction - 1; + if (j2k->cur_tp_num == 0) + j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; + j2k->cstr_info->packno = 0; + } len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); - + if (len == cio_numbytesleft(cio) + 1) { truncate = 1; /* Case of a truncate codestream */ } - + data = (unsigned char *) opj_malloc((j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); for (i = 0; i < j2k->tile_len[curtileno]; i++) { @@ -1424,7 +1489,7 @@ static void j2k_read_sod(opj_j2k_t *j2k) { for (i = 0; i < len; i++) { data_ptr[i] = cio_read(cio, 1); } - + j2k->tile_len[curtileno] += len; opj_free(j2k->tile_data[curtileno]); j2k->tile_data[curtileno] = data; @@ -1434,10 +1499,10 @@ static void j2k_read_sod(opj_j2k_t *j2k) { } else { j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */ } + j2k->cur_tp_num++; } static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) { - opj_cp_t *cp = j2k->cp; opj_tcp_t *tcp = &cp->tcps[tileno]; opj_cio_t *cio = j2k->cio; @@ -1494,9 +1559,9 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { opj_tcd_t *tcd = tcd_create(j2k->cinfo); tcd_malloc_decode(tcd, j2k->image, j2k->cp); for (i = 0; i < j2k->cp->tileno_size; i++) { - tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i); + tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); tileno = j2k->cp->tileno[i]; - tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno); + tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); opj_free(j2k->tile_data[tileno]); j2k->tile_data[tileno] = NULL; tcd_free_decode_tile(tcd, i); @@ -1511,8 +1576,7 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { opj_free(j2k->tile_data[tileno]); j2k->tile_data[tileno] = NULL; } - } - + } j2k->state = J2K_STATE_MT; } @@ -1697,7 +1761,6 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) { opj_free(cp); } - opj_free(j2k); } @@ -1721,12 +1784,15 @@ void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { } } -opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio) { +opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { opj_image_t *image = NULL; - opj_common_ptr cinfo = j2k->cinfo; + opj_common_ptr cinfo = j2k->cinfo; j2k->cio = cio; + j2k->cstr_info = cstr_info; + if (cstr_info) + memset(cstr_info, 0, sizeof(opj_codestream_info_t)); /* create an empty image */ image = opj_image_create0(); @@ -1738,7 +1804,6 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio) { opj_dec_mstabent_t *e; int id = cio_read(cio, 2); - #ifdef USE_JPWL /* we try to honor JPWL correction power */ if (j2k->cp->correct) { @@ -1820,7 +1885,7 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio) { * Read a JPT-stream and decode file * */ -opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio) { +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { opj_image_t *image = NULL; opj_jpt_msg_header_t header; int position; @@ -1915,27 +1980,6 @@ void j2k_destroy_compress(opj_j2k_t *j2k) { int tileno; if(!j2k) return; - - if(j2k->cstr_info != NULL) { - opj_codestream_info_t *cstr_info = j2k->cstr_info; - if (cstr_info->index_on && j2k->cp) { - opj_cp_t *cp = j2k->cp; - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - opj_tile_info_t *tile_info = &cstr_info->tile[tileno]; - opj_free(tile_info->thresh); - opj_free(tile_info->packet); -/* UniPG>> */ - /* INDEX >> */ - opj_free(tile_info->tp_start_pos); - opj_free(tile_info->tp_end_header); - opj_free(tile_info->tp_end_pos); - opj_free(tile_info->tp_num); - /* << INDEX */ -/* <tile); - } - } if(j2k->cp != NULL) { opj_cp_t *cp = j2k->cp; @@ -1990,9 +2034,6 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ memcpy(cp->matrice, parameters->cp_matrice, array_size); } - /* creation of an index file ? */ - cp->index_on = parameters->index_on; - /* tiles */ cp->tdx = parameters->cp_tdx; cp->tdy = parameters->cp_tdy; @@ -2223,9 +2264,9 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre opj_tcd_t *tcd = NULL; /* TCD component */ -/* UniPG>> */ + /* UniPG>> */ int acc_pack_num = 0; -/* <cio = cio; j2k->image = image; @@ -2236,8 +2277,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre /* INDEX >> */ j2k->cstr_info = cstr_info; - if (cstr_info && cp->index_on) { - cstr_info->index_on = cp->index_on; + if (cstr_info) { cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); cstr_info->image_w = image->x1 - image->x0; cstr_info->image_h = image->y1 - image->y0; @@ -2248,24 +2288,19 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre cstr_info->tile_y = cp->tdy; /* new version parser */ cstr_info->tile_Ox = cp->tx0; /* new version parser */ cstr_info->tile_Oy = cp->ty0; /* new version parser */ - cstr_info->comp = image->numcomps; - cstr_info->layer = (&cp->tcps[0])->numlayers; - cstr_info->decomposition = (&cp->tcps[0])->tccps->numresolutions - 1; + cstr_info->numcomps = image->numcomps; + cstr_info->numlayers = (&cp->tcps[0])->numlayers; + cstr_info->numdecompos = (&cp->tcps[0])->tccps->numresolutions - 1; cstr_info->D_max = 0; /* ADD Marcela */ -/* UniPG>> */ cstr_info->main_head_start = cio_tell(cio); /* position of SOC */ -/* <index_on = 0; } /* << INDEX */ - + j2k_write_soc(j2k); j2k_write_siz(j2k); j2k_write_cod(j2k); j2k_write_qcd(j2k); - + if(cp->cinema){ for (compno = 1; compno < image->numcomps; compno++) { j2k_write_coc(j2k, compno); @@ -2281,7 +2316,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre if (cp->comment != NULL) { j2k_write_com(j2k); } - + j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k); /* TLM Marker*/ if(cp->cinema){ @@ -2295,12 +2330,12 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre /* j2k_write_sec(j2k); */ /* INDEX >> */ - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { cstr_info->main_head_end = cio_tell(cio) - 1; } /* << INDEX */ /**** Main Header ENDS here ***/ - + /* create the tile encoder */ tcd = tcd_create(j2k->cinfo); @@ -2311,7 +2346,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre opj_tcp_t *tcp = &cp->tcps[tileno]; opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); - + j2k->curtileno = tileno; j2k->cur_tp_num = 0; tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno]; @@ -2321,10 +2356,9 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre } else { tcd_init_encode(tcd, image, cp, j2k->curtileno); } - + /* INDEX >> */ - if(cstr_info && cstr_info->index_on) { - cstr_info->tile[j2k->curtileno].num_tile = j2k->curtileno; + if(cstr_info) { cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; } /* << INDEX */ @@ -2332,20 +2366,18 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre for(pino = 0; pino <= tcp->numpocs; pino++) { int tot_num_tp; tcd->cur_pino=pino; - + /*Get number of tile parts*/ tot_num_tp = j2k_get_num_tp(cp,pino,tileno); tcd->tp_pos = cp->tp_pos; for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){ j2k->tp_num = tilepartno; -/* UniPG>> */ /* INDEX >> */ - if(cstr_info && cstr_info->index_on) - cstr_info->tile[j2k->curtileno].tp_start_pos[j2k->cur_tp_num] = - cio_tell(cio) + j2k->pos_correction; + if(cstr_info) + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos = + cio_tell(cio) + j2k->pos_correction; /* << INDEX */ -/* <cur_tp_num == 0 && cp->cinema == 0){ @@ -2358,54 +2390,50 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre } } -/* UniPG>> */ /* INDEX >> */ - if(cstr_info && cstr_info->index_on) - cstr_info->tile[j2k->curtileno].tp_end_header[j2k->cur_tp_num] = - cio_tell(cio) + j2k->pos_correction + 1; + if(cstr_info) + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = + cio_tell(cio) + j2k->pos_correction + 1; /* << INDEX */ -/* <> */ + /* INDEX >> */ - if(cstr_info && cstr_info->index_on) { - cstr_info->tile[j2k->curtileno].tp_end_pos[j2k->cur_tp_num] = + if(cstr_info) { + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos = cio_tell(cio) + j2k->pos_correction - 1; - cstr_info->tile[j2k->curtileno].tp_num[j2k->cur_tp_num] = - cstr_info->num - acc_pack_num; - acc_pack_num = cstr_info->num; + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks = + cstr_info->packno - acc_pack_num; + acc_pack_num = cstr_info->packno; } /* << INDEX */ -/* <cur_tp_num ++; - } - + + j2k->cur_tp_num++; + } } - /* INDEX >> */ - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; } - /* << INDEX */ - - + + /* if (tile->PPT) { // BAD PPT !!! - FILE *PPT_file; - int i; - PPT_file=fopen("PPT","rb"); - fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256); - for (i=0;ilen_ppt;i++) { - unsigned char elmt; - fread(&elmt, 1, 1, PPT_file); - fwrite(&elmt,1,1,f); - } - fclose(PPT_file); - unlink("PPT"); + FILE *PPT_file; + int i; + PPT_file=fopen("PPT","rb"); + fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256); + for (i=0;ilen_ppt;i++) { + unsigned char elmt; + fread(&elmt, 1, 1, PPT_file); + fwrite(&elmt,1,1,f); + } + fclose(PPT_file); + unlink("PPT"); } */ - + } - + /* destroy the tile encoder */ tcd_free_encode(tcd); tcd_destroy(tcd); @@ -2414,14 +2442,14 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre j2k_write_eoc(j2k); - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction; -/* UniPG>> */ + /* UniPG>> */ /* The following adjustment is done to adjust the codestream size */ /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */ /* the first bunch of bytes is not in the codestream */ cstr_info->codestream_size -= cstr_info->main_head_start; -/* <j2k, cio); + image = j2k_decode(jp2->j2k, cio, cstr_info); if(!image) { opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); } diff --git a/libopenjpeg/jp2.h b/libopenjpeg/jp2.h index d04324bc..7e363be2 100644 --- a/libopenjpeg/jp2.h +++ b/libopenjpeg/jp2.h @@ -136,9 +136,10 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters); Decode an image from a JPEG-2000 file stream @param jp2 JP2 decompressor handle @param cio Input buffer stream +@param cstr_info Codestream information structure if required, NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise */ -opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio); +opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info); /** Creates a JP2 compression structure @param cinfo Codec context info diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c index 327154db..95653d06 100644 --- a/libopenjpeg/openjpeg.c +++ b/libopenjpeg/openjpeg.c @@ -147,15 +147,15 @@ void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *param } } -opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { +opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { if(dinfo && cio) { switch(dinfo->codec_format) { case CODEC_J2K: - return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio); + return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); case CODEC_JPT: - return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio); + return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); case CODEC_JP2: - return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio); + return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info); case CODEC_UNKNOWN: default: break; @@ -300,6 +300,18 @@ bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *im break; } } - return false; } + +void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { + if (cstr_info) { + int tileno; + for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { + opj_tile_info_t *tile_info = &cstr_info->tile[tileno]; + opj_free(tile_info->thresh); + opj_free(tile_info->packet); + opj_free(tile_info->tp); + } + opj_free(cstr_info->tile); + } +} diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index bf92199a..7021bb54 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -303,10 +303,6 @@ typedef struct opj_cparameters { char infile[OPJ_PATH_LEN]; /** output file name */ char outfile[OPJ_PATH_LEN]; - /** creation of an index file, default to 0 (false) */ - int index_on; - /** index file name */ - char index[OPJ_PATH_LEN]; /** subimage encoding: origin image offset in x direction */ int image_offset_x0; /** subimage encoding: origin image offset in y direction */ @@ -490,7 +486,7 @@ typedef struct opj_cio { /** pointer to the start of the buffer */ unsigned char *buffer; /** buffer size in bytes */ - int length; + unsigned int length; /** pointer to the start of the stream */ unsigned char *start; @@ -601,13 +597,27 @@ typedef struct opj_packet_info { } opj_packet_info_t; /** -Index structure : information regarding tiles inside image +Index structure : Information concerning tile-parts +*/ +typedef struct opj_tp_info { + /** start position of tile part */ + int tp_start_pos; + /** end position of tile part header */ + int tp_end_header; + /** end position of tile part */ + int tp_end_pos; + /** number of packets of tile part */ + int tp_numpacks; +} opj_tp_info_t; + +/** +Index structure : information regarding tiles */ typedef struct opj_tile_info { /** value of thresh for each layer by tile cfr. Marcela */ double *thresh; /** number of tile */ - int num_tile; + int tileno; /** start position */ int start_pos; /** end position of the header */ @@ -625,33 +635,23 @@ typedef struct opj_tile_info { /** information concerning packets inside tile */ opj_packet_info_t *packet; /** add fixed_quality */ - int nbpix; + int numpix; /** add fixed_quality */ double distotile; -/* UniPG>> */ - /** number of tile parts */ - int num_tps; - /** start position of tile part */ - int *tp_start_pos; - /** end position of tile part header */ - int *tp_end_header; - /** end position of tile part */ - int *tp_end_pos; - /** number of packets of tile part */ - int *tp_num; -/* << UniPG */ + /** number of tile parts */ + int num_tps; + /** information concerning tile parts */ + opj_tp_info_t *tp; } opj_tile_info_t; /** Index structure of the codestream */ typedef struct opj_codestream_info { - /** 0 = no index || 1 = index */ - int index_on; /** maximum distortion reduction on the whole image (add for Marcela) */ double D_max; /** packet number */ - int num; + int packno; /** writing the packet in the index with t2_encode_packets */ int index_write; /** image width */ @@ -673,15 +673,13 @@ typedef struct opj_codestream_info { /** number of tiles in Y */ int th; /** component numbers */ - int comp; + int numcomps; /** number of layer */ - int layer; - /** number of decomposition */ - int decomposition; -/* UniPG>> */ - /** main header position */ - int main_head_start; -/* <num % 65536) / 256; - c[5] = (cstr_info->num % 65536) % 256; + c[4] = (cstr_info->packno % 65536) / 256; + c[5] = (cstr_info->packno % 65536) % 256; c += 6; } /* */ @@ -254,8 +255,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera /* << INDEX */ // End of packet header position. Currently only represents the distance to start of packet // Will be updated later by incrementing with packet start value - if(cstr_info && cstr_info->index_write && cstr_info->index_on) { - opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->num]; + if(cstr_info && cstr_info->index_write) { + opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; info_PK->end_ph_pos = (int)(c - dest); } /* INDEX >> */ @@ -279,8 +280,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera cblk->numpasses += layer->numpasses; c += layer->len; /* << INDEX */ - if(cstr_info && cstr_info->index_write && cstr_info->index_on) { - opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->num]; + if(cstr_info && cstr_info->index_write) { + opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; info_PK->disto += layer->disto; if (cstr_info->D_max < info_PK->disto) { cstr_info->D_max = info_PK->disto; @@ -310,7 +311,8 @@ static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) { } } -static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) { +static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, + opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info) { int bandno, cblkno; unsigned char *c = src; @@ -393,6 +395,14 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t hd += 2; } } + + /* << INDEX */ + // End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value + if(pack_info) { + pack_info->end_ph_pos = (int)(c - src); + } + /* INDEX >> */ if (cp->ppm == 1) { /* PPM case */ cp->ppm_len += cp->ppm_data-hd; @@ -483,6 +493,14 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t hd += 2; } } + + /* << INDEX */ + // End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value + if(pack_info) { + pack_info->end_ph_pos = (int)(hd - src); + } + /* INDEX >> */ if (cp->ppm==1) { cp->ppm_len+=cp->ppm_data-hd; @@ -620,21 +638,21 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye c += e; } /* INDEX >> */ - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { if(cstr_info->index_write) { opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; - opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->num]; - if (!cstr_info->num) { + opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; + if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else { - info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->num - 1].end_pos + 1; + info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + e - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance // to start of packet is incremented by value of start of packet } - cstr_info->num++; + cstr_info->packno++; } /* << INDEX */ } @@ -650,11 +668,12 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye return (c - dest); } -int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info) { unsigned char *c = src; opj_pi_iterator_t *pi; int pino, e = 0; - int n = 0; + int n = 0, curtp = 0; + int tp_start_packno; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; @@ -665,11 +684,18 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj /* TODO: throw an error */ return -999; } + + tp_start_packno = 0; for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { - e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); + opj_packet_info_t *pack_info; + if (cstr_info) + pack_info = &cstr_info->tile[tileno].packet[cstr_info->packno]; + else + pack_info = NULL; + e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino], pack_info); } else { e = 0; } @@ -680,14 +706,40 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) : image->comps[pi[pino].compno].resno_decoded; n++; + + /* INDEX >> */ + if(cstr_info) { + opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; + if (!cstr_info->packno) { + info_PK->start_pos = info_TL->end_header + 1; + } else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ // New tile part + info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part + tp_start_packno = cstr_info->packno; + curtp++; + info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1; + } else { + info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; + } + info_PK->end_pos = info_PK->start_pos + e - 1; + info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance + // to start of packet is incremented by value of start of packet + cstr_info->packno++; + } + /* << INDEX */ if (e == -999) { /* ADD */ break; } else { c += e; - } + } } } + /* INDEX >> */ + if(cstr_info) { + cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in last tile-part + } + /* << INDEX */ /* don't forget to release pi */ pi_destroy(pi, cp, tileno); diff --git a/libopenjpeg/t2.h b/libopenjpeg/t2.h index ae2db635..10160899 100644 --- a/libopenjpeg/t2.h +++ b/libopenjpeg/t2.h @@ -78,7 +78,7 @@ Decode the packets of a tile from a source buffer @param tileno number that identifies the tile for which to decode the packets @param tile tile for which to decode the packets */ -int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile); +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info); /** Create a T2 handle diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 1e7ed1a7..767e7f3d 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -600,15 +600,12 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { for (j = 0; j < cp->tileno_size; j++) { opj_tcd_tile_t *tile; - tileno = cp->tileno[j]; - - tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); - + tileno = cp->tileno[j]; + tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); tile->numcomps = image->numcomps; tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); } - for (i = 0; i < image->numcomps; i++) { for (j = 0; j < cp->tileno_size; j++) { opj_tcd_tile_t *tile; @@ -650,10 +647,9 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { image->comps[i].x0 = x0; image->comps[i].y0 = y0; } - } -void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno) { +void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info) { int compno, resno, bandno, precno, cblkno; unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0; opj_tcp_t *tcp; @@ -704,7 +700,7 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, } else { pdx = 15; pdy = 15; - } + } /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; @@ -809,7 +805,6 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, } /* bandno */ } /* resno */ } /* compno */ - /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ } @@ -993,11 +988,11 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre min = DBL_MAX; max = 0; - tcd_tile->nbpix = 0; /* fixed_quality */ + tcd_tile->numpix = 0; /* fixed_quality */ for (compno = 0; compno < tcd_tile->numcomps; compno++) { opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; - tilec->nbpix = 0; + tilec->numpix = 0; for (resno = 0; resno < tilec->numresolutions; resno++) { opj_tcd_resolution_t *res = &tilec->resolutions[resno]; @@ -1035,8 +1030,8 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre } /* passno */ /* fixed_quality */ - tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); - tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); } /* cbklno */ } /* precno */ } /* bandno */ @@ -1044,13 +1039,13 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre maxSE += (((double)(1 << tcd->image->comps[compno].prec) - 1.0) * ((double)(1 << tcd->image->comps[compno].prec) -1.0)) - * ((double)(tilec->nbpix)); + * ((double)(tilec->numpix)); } /* compno */ /* index file */ - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno]; - tile_info->nbpix = tcd_tile->nbpix; + tile_info->numpix = tcd_tile->numpix; tile_info->distotile = tcd_tile->distotile; tile_info->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double)); } @@ -1133,7 +1128,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre return false; } - if(cstr_info && cstr_info->index_on) { /* Threshold for Marcela Index */ + if(cstr_info) { /* Threshold for Marcela Index */ cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh; } tcd_makelayer(tcd, layno, goodthresh, 1); @@ -1147,7 +1142,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { int compno; - int l, i, npck = 0; + int l, i, numpacks = 0; opj_tcd_tile_t *tile = NULL; opj_tcp_t *tcd_tcp = NULL; opj_cp_t *cp = NULL; @@ -1170,7 +1165,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op if(tcd->cur_tp_num == 0){ tcd->encoding_time = opj_clock(); /* time needed to encode a tile */ /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */ - if(cstr_info && cstr_info->index_on) { + if(cstr_info) { opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ for (i = 0; i < tilec_idx->numresolutions; i++) { opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; @@ -1178,12 +1173,12 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op cstr_info->tile[tileno].pw[i] = res_idx->pw; cstr_info->tile[tileno].ph[i] = res_idx->ph; - npck += res_idx->pw * res_idx->ph; + numpacks += res_idx->pw * res_idx->ph; cstr_info->tile[tileno].pdx[i] = tccp->prcw[i]; cstr_info->tile[tileno].pdy[i] = tccp->prch[i]; } - cstr_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(cstr_info->comp * cstr_info->layer * npck * sizeof(opj_packet_info_t)); + cstr_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(cstr_info->numcomps * cstr_info->numlayers * numpacks * sizeof(opj_packet_info_t)); } /* << INDEX */ @@ -1294,7 +1289,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op return l; } -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) { +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) { int l; int compno; int eof = 0; @@ -1311,11 +1306,36 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) { tile_time = opj_clock(); /* time needed to decode a tile */ opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d of %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th); + + /* INDEX >> */ + if(cstr_info) { + int i, numpacks = 0; + opj_tcp_t *tcp = &tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ + for (i = 0; i < tilec_idx->numresolutions; i++) { + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + cstr_info->tile[tileno].pw[i] = res_idx->pw; + cstr_info->tile[tileno].ph[i] = res_idx->ph; + numpacks += res_idx->pw * res_idx->ph; + if (tccp->csty & J2K_CP_CSTY_PRT) { + cstr_info->tile[tileno].pdx[i] = tccp->prcw[i]; + cstr_info->tile[tileno].pdy[i] = tccp->prch[i]; + } + else { + cstr_info->tile[tileno].pdx[i] = 15; + cstr_info->tile[tileno].pdx[i] = 15; + } + } + cstr_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(cstr_info->numcomps * cstr_info->numlayers * numpacks * sizeof(opj_packet_info_t)); + cstr_info->packno = 0; + } + /* << INDEX */ /*--------------TIER2------------------*/ t2 = t2_create(tcd->cinfo, tcd->image, tcd->cp); - l = t2_decode_packets(t2, src, len, tileno, tile); + l = t2_decode_packets(t2, src, len, tileno, tile, cstr_info); t2_destroy(t2); if (l == -999) { diff --git a/libopenjpeg/tcd.h b/libopenjpeg/tcd.h index a357b104..f7c64e4d 100644 --- a/libopenjpeg/tcd.h +++ b/libopenjpeg/tcd.h @@ -131,7 +131,7 @@ typedef struct opj_tcd_tilecomp { int numresolutions; /* number of resolutions level */ opj_tcd_resolution_t *resolutions; /* resolutions information */ int *data; /* data of the component */ - int nbpix; /* add fixed_quality */ + int numpix; /* add fixed_quality */ } opj_tcd_tilecomp_t; /** @@ -141,7 +141,7 @@ typedef struct opj_tcd_tile { int x0, y0, x1, y1; /* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */ int numcomps; /* number of components in tile */ opj_tcd_tilecomp_t *comps; /* Components information */ - int nbpix; /* add fixed_quality */ + int numpix; /* add fixed_quality */ double distotile; /* add fixed_quality */ double distolayer[100]; /* add fixed_quality */ } opj_tcd_tile_t; @@ -234,7 +234,7 @@ Initialize the tile decoder @param cp Coding parameters */ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp); -void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno); +void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info); void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final); void tcd_rateallocate_fixed(opj_tcd_t *tcd); void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); @@ -256,7 +256,7 @@ Decode a tile from a buffer into a raw image @param len Length of source buffer @param tileno Number that identifies one of the tiles to be decoded */ -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno); +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info); /** Free the memory allocated for decoding @param tcd TCD handle