Indexes can now be generated when decoding J2K codestreams.

This commit is contained in:
Francois-Olivier Devaux 2007-09-07 15:01:55 +00:00
parent e7149e0c56
commit 3816e0edf4
18 changed files with 666 additions and 292 deletions

View File

@ -6,6 +6,7 @@ What's New for OpenJPEG
+ : added + : added
September 7, 2007 September 7, 2007
+ [FOD] Indexes can now be generated when decoding J2K codestreams.
* [Mathieu Malaterre] Upon failure, properly return error code (!=0). * [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 * [Mathieu Malaterre] CMake: Add cmake code to do testing if user has properly setup a testimages directory

View File

@ -1795,7 +1795,7 @@ opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw
opj_image_t * image = NULL; opj_image_t * image = NULL;
unsigned short ch; 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,"\nError: invalid raw image parameters\n");
fprintf(stderr,"Please use the Format option -F:\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); fclose(f);
return NULL; return NULL;
} }
/* set image offset and reference grid */ /* set image offset and reference grid */
image->x0 = parameters->image_offset_x0; image->x0 = parameters->image_offset_x0;
image->y0 = parameters->image_offset_y0; 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)) { if (fread(&ch, 1, 1, f)) {
fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n"); fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
} }
fclose(f); fclose(f);
return image; return image;

View File

@ -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\n", cstr_info->prog);
fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y); 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 %d\n", cstr_info->tw, cstr_info->th);
fprintf(stream, "%d\n", cstr_info->comp); fprintf(stream, "%d\n", cstr_info->numcomps);
fprintf(stream, "%d\n", cstr_info->layer); fprintf(stream, "%d\n", cstr_info->numlayers);
fprintf(stream, "%d\n", cstr_info->decomposition); 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] ", fprintf(stream, "[%d,%d] ",
(1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 */ (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, "%d\n", cstr_info->codestream_size);
fprintf(stream, "\nINFO ON TILES\n"); fprintf(stream, "\nINFO ON TILES\n");
fprintf(stream, "tileno start_pos end_hd end_tile" fprintf(stream, "tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
/* UniPG>> */
" nbparts"
/* <<UniPG */
" disto nbpix disto/nbpix\n");
for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
fprintf(stream, "%4d %9d %9d %9d " fprintf(stream, "%4d %9d %9d %9d %9d %9e %9d %9e\n",
/* UniPG>> */ cstr_info->tile[tileno].tileno,
"%9d "
/* <<UniPG */
"%9e %9d %9e\n",
cstr_info->tile[tileno].num_tile,
cstr_info->tile[tileno].start_pos, cstr_info->tile[tileno].start_pos,
cstr_info->tile[tileno].end_header, cstr_info->tile[tileno].end_header,
cstr_info->tile[tileno].end_pos, cstr_info->tile[tileno].end_pos,
/* UniPG>> */
cstr_info->tile[tileno].num_tps, cstr_info->tile[tileno].num_tps,
/* <<UniPG */ cstr_info->tile[tileno].distotile, cstr_info->tile[tileno].numpix,
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].nbpix);
} }
for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { 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; pack_nb = 0;
fprintf(stream, "\nTILE %d DETAILS\n", tileno); fprintf(stream, "\nTILE %d DETAILS\n", tileno);
/* UniPG>> */ fprintf(stream, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
fprintf(stream, "part_nb tileno pack_nb start_pos end_tph_pos end_pos\n");
for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++) 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, tilepartno, tileno,
cstr_info->tile[tileno].tp_num[tilepartno], cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
cstr_info->tile[tileno].tp_start_pos[tilepartno], cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
cstr_info->tile[tileno].tp_end_header[tilepartno], cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
cstr_info->tile[tileno].tp_end_pos[tilepartno] cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
); );
/* <<UniPG */
if (cstr_info->prog == LRCP) { /* LRCP */ if (cstr_info->prog == LRCP) { /* LRCP */
fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n"); 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 (layno = 0; layno < cstr_info->numlayers; layno++) {
for (resno = 0; resno < cstr_info->decomposition + 1; resno++) { for (resno = 0; resno < cstr_info->numdecompos + 1; resno++) {
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]; int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) { for (precno = 0; precno < prec_max; precno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; 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"); 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 (resno = 0; resno < cstr_info->numdecompos + 1; resno++) {
for (layno = 0; layno < cstr_info->layer; layno++) { for (layno = 0; layno < cstr_info->numlayers; layno++) {
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]; int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) { for (precno = 0; precno < prec_max; precno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos; 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"); 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 */ /* 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 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 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 x1 = x0 + cstr_info->tile_x;
int y1 = y0 + cstr_info->tile_y; 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]; int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) { for (precno = 0; precno < prec_max; precno++) {
int pcnx = cstr_info->tile[tileno].pw[resno]; int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[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->decomposition - 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_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
int precno_y = (int) floor( (float)precno/(float)pcnx ); int precno_y = (int) floor( (float)precno/(float)pcnx );
for(y = y0; y < y1; y++) { for(y = y0; y < y1; y++) {
if (precno_y*pcy == y ) { if (precno_y*pcy == y ) {
for (x = x0; x < x1; x++) { for (x = x0; x < x1; x++) {
if (precno_x*pcx == 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; 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_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_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"); 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 (compno = 0; compno < cstr_info->numcomps; compno++) {
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]; int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) { for (precno = 0; precno < prec_max; precno++) {
int pcnx = cstr_info->tile[tileno].pw[resno]; int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[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->decomposition - 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_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
int precno_y = (int) floor( (float)precno/(float)pcnx ); int precno_y = (int) floor( (float)precno/(float)pcnx );
for(y = y0; y < y1; y++) { for(y = y0; y < y1; y++) {
if (precno_y*pcy == y ) { if (precno_y*pcy == y ) {
for (x = x0; x < x1; x++) { for (x = x0; x < x1; x++) {
if (precno_x*pcx == 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; 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_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_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"); 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 */ /* 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 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 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 x1 = x0 + cstr_info->tile_x;
int y1 = y0 + cstr_info->tile_y; 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]; int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) { for (precno = 0; precno < prec_max; precno++) {
int pcnx = cstr_info->tile[tileno].pw[resno]; int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[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->decomposition - 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_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
int precno_y = (int) floor( (float)precno/(float)pcnx ); int precno_y = (int) floor( (float)precno/(float)pcnx );
for(y = y0; y < y1; y++) { for(y = y0; y < y1; y++) {
if (precno_y*pcy == y ) { if (precno_y*pcy == y ) {
for (x = x0; x < x1; x++) { for (x = x0; x < x1; x++) {
if (precno_x*pcx == 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; 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_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_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, 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; int i, j,totlen;
option_t long_option[]={ option_t long_option[]={
{"cinema2K",REQ_ARG, NULL ,'w'}, {"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 */ case 'x': /* creation of index file */
{ {
char *index = optarg; char *index = optarg;
strncpy(parameters->index, index, sizeof(parameters->index)-1); strncpy(indexfilename, index, OPJ_PATH_LEN);
parameters->index_on = 1;
} }
break; break;
@ -1302,9 +1288,8 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
int hprot, pprot, sens, addr, size, range; int hprot, pprot, sens, addr, size, range;
/* we need to enable indexing */ /* we need to enable indexing */
if (!parameters->index_on) { if (!indexfilename) {
strncpy(parameters->index, JPWL_PRIVATEINDEX_NAME, sizeof(parameters->index)-1); strncpy(parameters->index, JPWL_PRIVATEINDEX_NAME, sizeof(parameters->index)-1);
parameters->index_on = 1;
} }
/* search for different protection methods */ /* search for different protection methods */
@ -1731,7 +1716,8 @@ int main(int argc, char **argv) {
int imageno; int imageno;
dircnt_t *dirptr; dircnt_t *dirptr;
raw_cparameters_t raw_cp; 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) configure the event callbacks (not required)
@ -1745,11 +1731,12 @@ int main(int argc, char **argv) {
/* set encoding parameters to default values */ /* set encoding parameters to default values */
opj_set_default_encoder_parameters(&parameters); opj_set_default_encoder_parameters(&parameters);
/* 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)); memset(&img_fol,0,sizeof(img_fol_t));
/* parse input and get user encoding parameters */ /* parse input and get user encoding parameters */
if(parse_cmdline_encoder(argc, argv, &parameters,&img_fol, &raw_cp) == 1) { if(parse_cmdline_encoder(argc, argv, &parameters,&img_fol, &raw_cp, indexfilename) == 1) {
return 1; return 1;
} }
@ -1929,8 +1916,8 @@ int main(int argc, char **argv) {
opj_cio_close(cio); opj_cio_close(cio);
/* Write the index to disk */ /* Write the index to disk */
if (parameters.index_on) { if (*indexfilename) {
bSuccess = write_index_file(&cstr_info, parameters.index); bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) { if (bSuccess) {
fprintf(stderr, "Failed to output index file\n"); fprintf(stderr, "Failed to output index file\n");
} }
@ -1938,6 +1925,8 @@ int main(int argc, char **argv) {
/* free remaining compression structures */ /* free remaining compression structures */
opj_destroy_compress(cinfo); opj_destroy_compress(cinfo);
opj_destroy_cstr_info(&cstr_info);
} else { /* JP2 format output */ } else { /* JP2 format output */
int codestream_length; int codestream_length;
opj_cio_t *cio = NULL; opj_cio_t *cio = NULL;
@ -1978,8 +1967,8 @@ int main(int argc, char **argv) {
opj_cio_close(cio); opj_cio_close(cio);
/* Write the index to disk */ /* Write the index to disk */
if (parameters.index_on) { if (*indexfilename) {
bSuccess = write_index_file(&cstr_info, parameters.index); bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) { if (bSuccess) {
fprintf(stderr, "Failed to output index file\n"); fprintf(stderr, "Failed to output index file\n");
} }
@ -1987,7 +1976,7 @@ int main(int argc, char **argv) {
/* free remaining compression structures */ /* free remaining compression structures */
opj_destroy_compress(cinfo); opj_destroy_compress(cinfo);
opj_destroy_cstr_info(&cstr_info);
} }
/* free image data */ /* free image data */

View File

@ -32,6 +32,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include "openjpeg.h" #include "openjpeg.h"
#include "compat/getopt.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," 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," less quality layers than the specified number, all the quality layers\n");
fprintf(stdout," are decoded.\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>> */ /* UniPG>> */
#ifdef USE_JPWL #ifdef USE_JPWL
fprintf(stdout," -W <options>\n"); fprintf(stdout," -W <options>\n");
@ -225,10 +229,237 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet
return 0; 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, char *indexfilename) {
int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) {
/* parse the command line */ /* parse the command line */
int totlen; int totlen;
option_t long_option[]={ 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'}, {"OutFor",REQ_ARG, NULL ,'O'},
}; };
const char optlist[] = "i:o:r:l:h" const char optlist[] = "i:o:r:l:hx:"
/* UniPG>> */ /* UniPG>> */
#ifdef USE_JPWL #ifdef USE_JPWL
@ -362,6 +593,13 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
} }
break; break;
/* ----------------------------------------------------- */ /* ----------------------------------------------------- */
case 'x': /* Creation of index file */
{
char *index = optarg;
strncpy(indexfilename, index, OPJ_PATH_LEN);
}
break;
/* ----------------------------------------------------- */
/* UniPG>> */ /* UniPG>> */
#ifdef USE_JPWL #ifdef USE_JPWL
@ -507,6 +745,8 @@ int main(int argc, char **argv) {
dircnt_t *dirptr; dircnt_t *dirptr;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL; 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) */ /* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); 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 */ /* set decoding parameters to default values */
opj_set_default_decoder_parameters(&parameters); opj_set_default_decoder_parameters(&parameters);
/* 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)); memset(&img_fol,0,sizeof(img_fol_t));
/* parse input and get user encoding parameters */ /* parse input and get user encoding parameters */
if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol) == 1) { if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol, indexfilename) == 1) {
return 1; return 1;
} }
/* Initialize reading of directory */
if(img_fol.set_imgdir==1){ if(img_fol.set_imgdir==1){
num_images=get_num_images(img_fol.imgdirpath); num_images=get_num_images(img_fol.imgdirpath);
@ -552,9 +794,7 @@ int main(int argc, char **argv) {
} }
/*Encoding image one by one*/ /*Encoding image one by one*/
for(imageno = 0; imageno < num_images ; imageno++) for(imageno = 0; imageno < num_images ; imageno++) {
{
image = NULL; image = NULL;
fprintf(stderr,"\n"); fprintf(stderr,"\n");
@ -563,10 +803,8 @@ int main(int argc, char **argv) {
fprintf(stderr,"skipping file...\n"); fprintf(stderr,"skipping file...\n");
continue; continue;
} }
} }
/* read the input file and put it in memory */ /* read the input file and put it in memory */
/* ---------------------------------------- */ /* ---------------------------------------- */
fsrc = fopen(parameters.infile, "rb"); 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); cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */ /* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio); image = opj_decode(dinfo, cio, &cstr_info);
if(!image) { if(!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo); opj_destroy_decompress(dinfo);
@ -614,6 +852,15 @@ int main(int argc, char **argv) {
/* close the byte stream */ /* close the byte stream */
opj_cio_close(cio); 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; break;
@ -634,7 +881,7 @@ int main(int argc, char **argv) {
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */ /* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio); image = opj_decode(dinfo, cio, &cstr_info);
if(!image) { if(!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo); opj_destroy_decompress(dinfo);
@ -645,6 +892,14 @@ int main(int argc, char **argv) {
/* close the byte stream */ /* close the byte stream */
opj_cio_close(cio); 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; break;
@ -665,7 +920,7 @@ int main(int argc, char **argv) {
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */ /* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio); image = opj_decode(dinfo, cio, &cstr_info);
if(!image) { if(!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo); opj_destroy_decompress(dinfo);
@ -675,6 +930,15 @@ int main(int argc, char **argv) {
/* close the byte stream */ /* close the byte stream */
opj_cio_close(cio); 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; break;
@ -749,6 +1013,8 @@ int main(int argc, char **argv) {
if(dinfo) { if(dinfo) {
opj_destroy_decompress(dinfo); opj_destroy_decompress(dinfo);
} }
/* free codestream information structure */
opj_destroy_cstr_info(&cstr_info);
/* free image data structure */ /* free image data structure */
opj_image_destroy(image); opj_image_destroy(image);

View File

@ -58,9 +58,10 @@ opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer
opj_free(cio); opj_free(cio);
return NULL; 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); cio->buffer = (unsigned char *)opj_malloc(cio->length);
if(!cio->buffer) { if(!cio->buffer) {
opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n");
opj_free(cio); opj_free(cio);
return NULL; return NULL;
} }

View File

@ -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 */ /* allocate memory for the per-component information */
image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
if(!image->comps) { if(!image->comps) {
fprintf(stderr,"Unable to allocate memory for image.\n");
opj_image_destroy(image); opj_image_destroy(image);
return NULL; 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->sgnd = cmptparms[compno].sgnd;
comp->data = (int*)opj_malloc(comp->w * comp->h * sizeof(int)); comp->data = (int*)opj_malloc(comp->w * comp->h * sizeof(int));
if(!comp->data) { if(!comp->data) {
fprintf(stderr,"Unable to allocate memory for image.\n");
opj_image_destroy(image); opj_image_destroy(image);
return NULL; return NULL;
} }

View File

@ -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); pi_destroy(pi, cp, tileno);
} }
j2k->cur_totnum_tp[tileno] = cur_totnum_tp; j2k->cur_totnum_tp[tileno] = cur_totnum_tp;
/* UniPG>> */
/* INDEX >> */ /* 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].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 = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
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));
} }
/* << INDEX */ /* << INDEX */
/* <<UniPG */
} }
return totnum_tp; return totnum_tp;
} }
@ -443,6 +438,11 @@ static void j2k_write_soc(opj_j2k_t *j2k) {
static void j2k_read_soc(opj_j2k_t *j2k) { static void j2k_read_soc(opj_j2k_t *j2k) {
j2k->state = J2K_STATE_MHSIZ; j2k->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) { 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 */ #endif /* USE_JPWL */
/* TODO: unused ? */ /* TODO: unused ? */
w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); 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_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->tile_len = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
j2k->state = J2K_STATE_MH; 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) { 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); cio_write(cio, J2K_MS_COM, 2);
lenp = cio_tell(cio); lenp = cio_tell(cio);
cio_skip(cio, 2); 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++) { for (i = 0; i < strlen(comment); i++) {
cio_write(cio, comment[i], 1); 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; 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) { 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); cio_seek(cio, pos);
j2k_read_cox(j2k, i); 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) { static void j2k_write_coc(opj_j2k_t *j2k, int compno) {
@ -1279,7 +1316,6 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
}; };
#endif /* USE_JPWL */ #endif /* USE_JPWL */
if (cp->tileno_size == 0) { if (cp->tileno_size == 0) {
cp->tileno[cp->tileno_size] = tileno; cp->tileno[cp->tileno_size] = tileno;
cp->tileno_size++; cp->tileno_size++;
@ -1326,12 +1362,30 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
numparts = cio_read(cio, 1); numparts = cio_read(cio, 1);
j2k->curtileno = tileno; j2k->curtileno = tileno;
j2k->cur_tp_num = partno;
j2k->eot = cio_getbp(cio) - 12 + totlen; j2k->eot = cio_getbp(cio) - 12 + totlen;
j2k->state = J2K_STATE_TPH; j2k->state = J2K_STATE_TPH;
tcp = &cp->tcps[j2k->curtileno]; tcp = &cp->tcps[j2k->curtileno];
if (tcp->first == 1) { /* 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) {
/* Initialization PPT */ /* Initialization PPT */
opj_tccp_t *tmp = tcp->tccps; opj_tccp_t *tmp = tcp->tccps;
memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t)); 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 >> */ /* INDEX >> */
cstr_info = j2k->cstr_info; cstr_info = j2k->cstr_info;
if (cstr_info && cstr_info->index_on) { if (cstr_info) {
if (!j2k->cur_tp_num ) { if (!j2k->cur_tp_num ) {
cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
}else{ j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno;
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); 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 */ /* << 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; tcp->rates[layno] -= tcp->rates[layno] ? (j2k->sod_start / (cp->th * cp->tw)) : 0;
} }
if(cstr_info && (j2k->cur_tp_num == 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); l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info);
@ -1408,6 +1464,15 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio; opj_cio_t *cio = j2k->cio;
int curtileno = j2k->curtileno; 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); len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
if (len == cio_numbytesleft(cio) + 1) { if (len == cio_numbytesleft(cio) + 1) {
@ -1434,10 +1499,10 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
} else { } else {
j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */ j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */
} }
j2k->cur_tp_num++;
} }
static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) { static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) {
opj_cp_t *cp = j2k->cp; opj_cp_t *cp = j2k->cp;
opj_tcp_t *tcp = &cp->tcps[tileno]; opj_tcp_t *tcp = &cp->tcps[tileno];
opj_cio_t *cio = j2k->cio; 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); opj_tcd_t *tcd = tcd_create(j2k->cinfo);
tcd_malloc_decode(tcd, j2k->image, j2k->cp); tcd_malloc_decode(tcd, j2k->image, j2k->cp);
for (i = 0; i < j2k->cp->tileno_size; i++) { 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]; 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]); opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL; j2k->tile_data[tileno] = NULL;
tcd_free_decode_tile(tcd, i); tcd_free_decode_tile(tcd, i);
@ -1512,7 +1577,6 @@ static void j2k_read_eoc(opj_j2k_t *j2k) {
j2k->tile_data[tileno] = NULL; j2k->tile_data[tileno] = NULL;
} }
} }
j2k->state = J2K_STATE_MT; j2k->state = J2K_STATE_MT;
} }
@ -1697,7 +1761,6 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) {
opj_free(cp); opj_free(cp);
} }
opj_free(j2k); 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_image_t *image = NULL;
opj_common_ptr cinfo = j2k->cinfo; opj_common_ptr cinfo = j2k->cinfo;
j2k->cio = cio; j2k->cio = cio;
j2k->cstr_info = cstr_info;
if (cstr_info)
memset(cstr_info, 0, sizeof(opj_codestream_info_t));
/* create an empty image */ /* create an empty image */
image = opj_image_create0(); 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; opj_dec_mstabent_t *e;
int id = cio_read(cio, 2); int id = cio_read(cio, 2);
#ifdef USE_JPWL #ifdef USE_JPWL
/* we try to honor JPWL correction power */ /* we try to honor JPWL correction power */
if (j2k->cp->correct) { 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 * 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_image_t *image = NULL;
opj_jpt_msg_header_t header; opj_jpt_msg_header_t header;
int position; int position;
@ -1915,27 +1980,6 @@ void j2k_destroy_compress(opj_j2k_t *j2k) {
int tileno; int tileno;
if(!j2k) return; 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 */
/* <<UniPG */
}
opj_free(cstr_info->tile);
}
}
if(j2k->cp != NULL) { if(j2k->cp != NULL) {
opj_cp_t *cp = j2k->cp; 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); memcpy(cp->matrice, parameters->cp_matrice, array_size);
} }
/* creation of an index file ? */
cp->index_on = parameters->index_on;
/* tiles */ /* tiles */
cp->tdx = parameters->cp_tdx; cp->tdx = parameters->cp_tdx;
cp->tdy = parameters->cp_tdy; cp->tdy = parameters->cp_tdy;
@ -2236,8 +2277,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
/* INDEX >> */ /* INDEX >> */
j2k->cstr_info = cstr_info; j2k->cstr_info = cstr_info;
if (cstr_info && cp->index_on) { if (cstr_info) {
cstr_info->index_on = cp->index_on;
cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); 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_w = image->x1 - image->x0;
cstr_info->image_h = image->y1 - image->y0; cstr_info->image_h = image->y1 - image->y0;
@ -2248,16 +2288,11 @@ 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_y = cp->tdy; /* new version parser */
cstr_info->tile_Ox = cp->tx0; /* new version parser */ cstr_info->tile_Ox = cp->tx0; /* new version parser */
cstr_info->tile_Oy = cp->ty0; /* new version parser */ cstr_info->tile_Oy = cp->ty0; /* new version parser */
cstr_info->comp = image->numcomps; cstr_info->numcomps = image->numcomps;
cstr_info->layer = (&cp->tcps[0])->numlayers; cstr_info->numlayers = (&cp->tcps[0])->numlayers;
cstr_info->decomposition = (&cp->tcps[0])->tccps->numresolutions - 1; cstr_info->numdecompos = (&cp->tcps[0])->tccps->numresolutions - 1;
cstr_info->D_max = 0; /* ADD Marcela */ cstr_info->D_max = 0; /* ADD Marcela */
/* UniPG>> */
cstr_info->main_head_start = cio_tell(cio); /* position of SOC */ cstr_info->main_head_start = cio_tell(cio); /* position of SOC */
/* <<UniPG */
}
else if (cstr_info) {
cstr_info->index_on = 0;
} }
/* << INDEX */ /* << INDEX */
@ -2295,7 +2330,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
/* j2k_write_sec(j2k); */ /* j2k_write_sec(j2k); */
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
cstr_info->main_head_end = cio_tell(cio) - 1; cstr_info->main_head_end = cio_tell(cio) - 1;
} }
/* << INDEX */ /* << INDEX */
@ -2323,8 +2358,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
} }
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
cstr_info->tile[j2k->curtileno].num_tile = j2k->curtileno;
cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
} }
/* << INDEX */ /* << INDEX */
@ -2339,13 +2373,11 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){ for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){
j2k->tp_num = tilepartno; j2k->tp_num = tilepartno;
/* UniPG>> */
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) if(cstr_info)
cstr_info->tile[j2k->curtileno].tp_start_pos[j2k->cur_tp_num] = cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos =
cio_tell(cio) + j2k->pos_correction; cio_tell(cio) + j2k->pos_correction;
/* << INDEX */ /* << INDEX */
/* <<UniPG */
j2k_write_sot(j2k); j2k_write_sot(j2k);
if(j2k->cur_tp_num == 0 && cp->cinema == 0){ if(j2k->cur_tp_num == 0 && cp->cinema == 0){
@ -2358,34 +2390,30 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
} }
} }
/* UniPG>> */
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) if(cstr_info)
cstr_info->tile[j2k->curtileno].tp_end_header[j2k->cur_tp_num] = cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
cio_tell(cio) + j2k->pos_correction + 1; cio_tell(cio) + j2k->pos_correction + 1;
/* << INDEX */ /* << INDEX */
/* <<UniPG */
j2k_write_sod(j2k, tcd); j2k_write_sod(j2k, tcd);
/* UniPG>> */
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
cstr_info->tile[j2k->curtileno].tp_end_pos[j2k->cur_tp_num] = cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos =
cio_tell(cio) + j2k->pos_correction - 1; cio_tell(cio) + j2k->pos_correction - 1;
cstr_info->tile[j2k->curtileno].tp_num[j2k->cur_tp_num] = cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks =
cstr_info->num - acc_pack_num; cstr_info->packno - acc_pack_num;
acc_pack_num = cstr_info->num; acc_pack_num = cstr_info->packno;
} }
/* << INDEX */ /* << INDEX */
/* <<UniPG */
j2k->cur_tp_num++; j2k->cur_tp_num++;
} }
} }
/* INDEX >> */ if(cstr_info) {
if(cstr_info && cstr_info->index_on) {
cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1;
} }
/* << INDEX */
/* /*
@ -2414,7 +2442,7 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
j2k_write_eoc(j2k); j2k_write_eoc(j2k);
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction; cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction;
/* UniPG>> */ /* UniPG>> */
/* The following adjustment is done to adjust the codestream size */ /* The following adjustment is done to adjust the codestream size */

View File

@ -227,8 +227,6 @@ typedef struct opj_cp {
int layer; int layer;
/** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */ /** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */
OPJ_LIMIT_DECODING limit_decoding; OPJ_LIMIT_DECODING limit_decoding;
/** 0 = no index || 1 = index */
int index_on;
/** XTOsiz */ /** XTOsiz */
int tx0; int tx0;
/** YTOsiz */ /** YTOsiz */
@ -394,16 +392,18 @@ void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
Decode an image from a JPEG-2000 codestream Decode an image from a JPEG-2000 codestream
@param j2k J2K decompressor handle @param j2k J2K decompressor handle
@param cio Input buffer stream @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 @return Returns a decoded image if successful, returns NULL otherwise
*/ */
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);
/** /**
Decode an image form a JPT-stream (JPEG 2000, JPIP) Decode an image form a JPT-stream (JPEG 2000, JPIP)
@param j2k J2K decompressor handle @param j2k J2K decompressor handle
@param cio Input buffer stream @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 @return Returns a decoded image if successful, returns NULL otherwise
*/ */
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);
/** /**
Creates a J2K compression structure Creates a J2K compression structure
@param cinfo Codec context info @param cinfo Codec context info

View File

@ -541,7 +541,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
/* further JP2 initializations go here */ /* further JP2 initializations go here */
} }
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) {
opj_common_ptr cinfo; opj_common_ptr cinfo;
opj_image_t *image = NULL; opj_image_t *image = NULL;
@ -558,7 +558,7 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio) {
} }
/* J2K decoding */ /* J2K decoding */
image = j2k_decode(jp2->j2k, cio); image = j2k_decode(jp2->j2k, cio, cstr_info);
if(!image) { if(!image) {
opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
} }

View File

@ -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 Decode an image from a JPEG-2000 file stream
@param jp2 JP2 decompressor handle @param jp2 JP2 decompressor handle
@param cio Input buffer stream @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 @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 Creates a JP2 compression structure
@param cinfo Codec context info @param cinfo Codec context info

View File

@ -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) { if(dinfo && cio) {
switch(dinfo->codec_format) { switch(dinfo->codec_format) {
case CODEC_J2K: 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: 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: 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: case CODEC_UNKNOWN:
default: default:
break; break;
@ -300,6 +300,18 @@ bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *im
break; break;
} }
} }
return false; 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);
}
}

View File

@ -303,10 +303,6 @@ typedef struct opj_cparameters {
char infile[OPJ_PATH_LEN]; char infile[OPJ_PATH_LEN];
/** output file name */ /** output file name */
char outfile[OPJ_PATH_LEN]; 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 */ /** subimage encoding: origin image offset in x direction */
int image_offset_x0; int image_offset_x0;
/** subimage encoding: origin image offset in y direction */ /** subimage encoding: origin image offset in y direction */
@ -490,7 +486,7 @@ typedef struct opj_cio {
/** pointer to the start of the buffer */ /** pointer to the start of the buffer */
unsigned char *buffer; unsigned char *buffer;
/** buffer size in bytes */ /** buffer size in bytes */
int length; unsigned int length;
/** pointer to the start of the stream */ /** pointer to the start of the stream */
unsigned char *start; unsigned char *start;
@ -601,13 +597,27 @@ typedef struct opj_packet_info {
} opj_packet_info_t; } 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 { typedef struct opj_tile_info {
/** value of thresh for each layer by tile cfr. Marcela */ /** value of thresh for each layer by tile cfr. Marcela */
double *thresh; double *thresh;
/** number of tile */ /** number of tile */
int num_tile; int tileno;
/** start position */ /** start position */
int start_pos; int start_pos;
/** end position of the header */ /** end position of the header */
@ -625,33 +635,23 @@ typedef struct opj_tile_info {
/** information concerning packets inside tile */ /** information concerning packets inside tile */
opj_packet_info_t *packet; opj_packet_info_t *packet;
/** add fixed_quality */ /** add fixed_quality */
int nbpix; int numpix;
/** add fixed_quality */ /** add fixed_quality */
double distotile; double distotile;
/* UniPG>> */
/** number of tile parts */ /** number of tile parts */
int num_tps; int num_tps;
/** start position of tile part */ /** information concerning tile parts */
int *tp_start_pos; opj_tp_info_t *tp;
/** 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 */
} opj_tile_info_t; } opj_tile_info_t;
/** /**
Index structure of the codestream Index structure of the codestream
*/ */
typedef struct opj_codestream_info { typedef struct opj_codestream_info {
/** 0 = no index || 1 = index */
int index_on;
/** maximum distortion reduction on the whole image (add for Marcela) */ /** maximum distortion reduction on the whole image (add for Marcela) */
double D_max; double D_max;
/** packet number */ /** packet number */
int num; int packno;
/** writing the packet in the index with t2_encode_packets */ /** writing the packet in the index with t2_encode_packets */
int index_write; int index_write;
/** image width */ /** image width */
@ -673,15 +673,13 @@ typedef struct opj_codestream_info {
/** number of tiles in Y */ /** number of tiles in Y */
int th; int th;
/** component numbers */ /** component numbers */
int comp; int numcomps;
/** number of layer */ /** number of layer */
int layer; int numlayers;
/** number of decomposition */ /** number of decomposition of first component */
int decomposition; int numdecompos;
/* UniPG>> */
/** main header position */ /** main header position */
int main_head_start; int main_head_start;
/* <<UniPG */
/** main header position */ /** main header position */
int main_head_end; int main_head_end;
/** codestream's size */ /** codestream's size */
@ -802,9 +800,10 @@ OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_
Decode an image from a JPEG-2000 codestream Decode an image from a JPEG-2000 codestream
@param dinfo decompressor handle @param dinfo decompressor handle
@param cio Input buffer stream @param cio Input buffer stream
@param cstr_info Codestream information structure if needed afterwards, NULL otherwise
@return Returns a decoded image if successful, returns NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise
*/ */
OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
/** /**
Creates a J2K/JP2 compression structure Creates a J2K/JP2 compression structure
@param format Coder to select @param format Coder to select
@ -850,10 +849,15 @@ Encode an image into a JPEG-2000 codestream
@param cinfo compressor handle @param cinfo compressor handle
@param cio Output buffer stream @param cio Output buffer stream
@param image Image to encode @param image Image to encode
@param cstr_info Codestream information structure if required, NULL otherwise @param cstr_info Codestream information structure if needed afterwards, NULL otherwise
@return Returns true if successful, returns false otherwise @return Returns true if successful, returns false otherwise
*/ */
OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/**
Destroy Codestream information after compression or decompression
@param cstr_info Codestream information structure
*/
OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -994,7 +994,7 @@ static void t1_decode_cblk(
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
opj_t1_t* t1_create(opj_common_ptr cinfo) { opj_t1_t* t1_create(opj_common_ptr cinfo) {
opj_t1_t *t1 = (opj_t1_t*) malloc(sizeof(opj_t1_t)); opj_t1_t *t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t));
if(!t1) if(!t1)
return NULL; return NULL;

View File

@ -74,7 +74,8 @@ Decode a packet of a tile from a source buffer
@param pi Packet identity @param pi Packet identity
@return @return
*/ */
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);
/*@}*/ /*@}*/
@ -146,8 +147,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
c[1] = 145; c[1] = 145;
c[2] = 0; c[2] = 0;
c[3] = 4; c[3] = 4;
c[4] = (cstr_info->num % 65536) / 256; c[4] = (cstr_info->packno % 65536) / 256;
c[5] = (cstr_info->num % 65536) % 256; c[5] = (cstr_info->packno % 65536) % 256;
c += 6; c += 6;
} }
/* </SOP> */ /* </SOP> */
@ -254,8 +255,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
/* << INDEX */ /* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet // End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value // Will be updated later by incrementing with packet start value
if(cstr_info && cstr_info->index_write && cstr_info->index_on) { if(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->num]; opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->end_ph_pos = (int)(c - dest); info_PK->end_ph_pos = (int)(c - dest);
} }
/* INDEX >> */ /* 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; cblk->numpasses += layer->numpasses;
c += layer->len; c += layer->len;
/* << INDEX */ /* << INDEX */
if(cstr_info && cstr_info->index_write && cstr_info->index_on) { if(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->num]; opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->disto += layer->disto; info_PK->disto += layer->disto;
if (cstr_info->D_max < info_PK->disto) { if (cstr_info->D_max < info_PK->disto) {
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; int bandno, cblkno;
unsigned char *c = src; unsigned char *c = src;
@ -394,6 +396,14 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
} }
} }
/* << 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 */ if (cp->ppm == 1) { /* PPM case */
cp->ppm_len += cp->ppm_data-hd; cp->ppm_len += cp->ppm_data-hd;
cp->ppm_data = hd; cp->ppm_data = hd;
@ -484,6 +494,14 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
} }
} }
/* << 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) { if (cp->ppm==1) {
cp->ppm_len+=cp->ppm_data-hd; cp->ppm_len+=cp->ppm_data-hd;
cp->ppm_data = hd; 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; c += e;
} }
/* INDEX >> */ /* INDEX >> */
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
if(cstr_info->index_write) { if(cstr_info->index_write) {
opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; opj_tile_info_t *info_TL = &cstr_info->tile[tileno];
opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->num]; opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
if (!cstr_info->num) { if (!cstr_info->packno) {
info_PK->start_pos = info_TL->end_header + 1; info_PK->start_pos = info_TL->end_header + 1;
} else { } 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_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 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 // to start of packet is incremented by value of start of packet
} }
cstr_info->num++; cstr_info->packno++;
} }
/* << INDEX */ /* << 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); 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; unsigned char *c = src;
opj_pi_iterator_t *pi; opj_pi_iterator_t *pi;
int pino, e = 0; int pino, e = 0;
int n = 0; int n = 0, curtp = 0;
int tp_start_packno;
opj_image_t *image = t2->image; opj_image_t *image = t2->image;
opj_cp_t *cp = t2->cp; opj_cp_t *cp = t2->cp;
@ -666,10 +685,17 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
return -999; return -999;
} }
tp_start_packno = 0;
for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
while (pi_next(&pi[pino])) { while (pi_next(&pi[pino])) {
if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { 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 { } else {
e = 0; e = 0;
} }
@ -681,6 +707,27 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
: image->comps[pi[pino].compno].resno_decoded; : image->comps[pi[pino].compno].resno_decoded;
n++; 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 */ if (e == -999) { /* ADD */
break; break;
} else { } else {
@ -688,6 +735,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
} }
} }
} }
/* 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 */ /* don't forget to release pi */
pi_destroy(pi, cp, tileno); pi_destroy(pi, cp, tileno);

View File

@ -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 tileno number that identifies the tile for which to decode the packets
@param tile 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 Create a T2 handle

View File

@ -601,14 +601,11 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
opj_tcd_tile_t *tile; opj_tcd_tile_t *tile;
tileno = cp->tileno[j]; tileno = cp->tileno[j];
tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]);
tile->numcomps = image->numcomps; tile->numcomps = image->numcomps;
tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t));
} }
for (i = 0; i < image->numcomps; i++) { for (i = 0; i < image->numcomps; i++) {
for (j = 0; j < cp->tileno_size; j++) { for (j = 0; j < cp->tileno_size; j++) {
opj_tcd_tile_t *tile; 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].x0 = x0;
image->comps[i].y0 = y0; 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; int compno, resno, bandno, precno, cblkno;
unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0; unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
opj_tcp_t *tcp; opj_tcp_t *tcp;
@ -809,7 +805,6 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
} /* bandno */ } /* bandno */
} /* resno */ } /* resno */
} /* compno */ } /* compno */
/* tcd_dump(stdout, tcd, &tcd->tcd_image); */ /* 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; min = DBL_MAX;
max = 0; max = 0;
tcd_tile->nbpix = 0; /* fixed_quality */ tcd_tile->numpix = 0; /* fixed_quality */
for (compno = 0; compno < tcd_tile->numcomps; compno++) { for (compno = 0; compno < tcd_tile->numcomps; compno++) {
opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
tilec->nbpix = 0; tilec->numpix = 0;
for (resno = 0; resno < tilec->numresolutions; resno++) { for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_t *res = &tilec->resolutions[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 */ } /* passno */
/* fixed_quality */ /* fixed_quality */
tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
} /* cbklno */ } /* cbklno */
} /* precno */ } /* precno */
} /* bandno */ } /* 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) maxSE += (((double)(1 << tcd->image->comps[compno].prec) - 1.0)
* ((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 */ } /* compno */
/* index file */ /* index file */
if(cstr_info && cstr_info->index_on) { if(cstr_info) {
opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno]; 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->distotile = tcd_tile->distotile;
tile_info->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double)); 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; 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; cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
} }
tcd_makelayer(tcd, layno, goodthresh, 1); 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 tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
int compno; int compno;
int l, i, npck = 0; int l, i, numpacks = 0;
opj_tcd_tile_t *tile = NULL; opj_tcd_tile_t *tile = NULL;
opj_tcp_t *tcd_tcp = NULL; opj_tcp_t *tcd_tcp = NULL;
opj_cp_t *cp = 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){ if(tcd->cur_tp_num == 0){
tcd->encoding_time = opj_clock(); /* time needed to encode a tile */ tcd->encoding_time = opj_clock(); /* time needed to encode a tile */
/* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */ /* 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 */ opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */
for (i = 0; i < tilec_idx->numresolutions; i++) { for (i = 0; i < tilec_idx->numresolutions; i++) {
opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[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].pw[i] = res_idx->pw;
cstr_info->tile[tileno].ph[i] = res_idx->ph; 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].pdx[i] = tccp->prcw[i];
cstr_info->tile[tileno].pdy[i] = tccp->prch[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 */ /* << INDEX */
@ -1294,7 +1289,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
return l; 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 l;
int compno; int compno;
int eof = 0; int eof = 0;
@ -1312,10 +1307,35 @@ 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 */ 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); 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------------------*/ /*--------------TIER2------------------*/
t2 = t2_create(tcd->cinfo, tcd->image, tcd->cp); 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); t2_destroy(t2);
if (l == -999) { if (l == -999) {

View File

@ -131,7 +131,7 @@ typedef struct opj_tcd_tilecomp {
int numresolutions; /* number of resolutions level */ int numresolutions; /* number of resolutions level */
opj_tcd_resolution_t *resolutions; /* resolutions information */ opj_tcd_resolution_t *resolutions; /* resolutions information */
int *data; /* data of the component */ int *data; /* data of the component */
int nbpix; /* add fixed_quality */ int numpix; /* add fixed_quality */
} opj_tcd_tilecomp_t; } 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 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 */ int numcomps; /* number of components in tile */
opj_tcd_tilecomp_t *comps; /* Components information */ opj_tcd_tilecomp_t *comps; /* Components information */
int nbpix; /* add fixed_quality */ int numpix; /* add fixed_quality */
double distotile; /* add fixed_quality */ double distotile; /* add fixed_quality */
double distolayer[100]; /* add fixed_quality */ double distolayer[100]; /* add fixed_quality */
} opj_tcd_tile_t; } opj_tcd_tile_t;
@ -234,7 +234,7 @@ Initialize the tile decoder
@param cp Coding parameters @param cp Coding parameters
*/ */
void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp); 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_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
void tcd_rateallocate_fixed(opj_tcd_t *tcd); void tcd_rateallocate_fixed(opj_tcd_t *tcd);
void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); 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 len Length of source buffer
@param tileno Number that identifies one of the tiles to be decoded @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 Free the memory allocated for decoding
@param tcd TCD handle @param tcd TCD handle