2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, Professor Benoit Macq
4 * Copyright (c) 2001-2003, David Janssens
5 * Copyright (c) 2002-2003, Yannick Verschueren
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
8 * Copyright (c) 2006-2007, Parvatha Elangovan
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
38 #include "compat/getopt.h"
43 #define stricmp strcasecmp
44 #define strnicmp strncasecmp
47 /* ----------------------------------------------------------------------- */
61 /* ----------------------------------------------------------------------- */
63 typedef struct dircnt{
64 /** Buffer for holding images read from Directory*/
66 /** Pointer to the buffer*/
71 typedef struct img_folder{
72 /** The directory path of the folder containing input images*/
78 /** Enable Cod Format for output*/
83 void decode_help_display() {
84 fprintf(stdout,"HELP\n----\n\n");
85 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
88 fprintf(stdout,"List of parameters for the JPEG 2000 "
96 fprintf(stdout," -ImgDir \n");
97 fprintf(stdout," Image file Directory path \n");
98 fprintf(stdout," -OutFor \n");
99 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
100 fprintf(stdout," Need to specify only format without filename <BMP> \n");
101 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
102 fprintf(stdout," -i <compressed file>\n");
103 fprintf(stdout," REQUIRED only if an Input image directory not specified\n");
104 fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
105 fprintf(stdout," is identified based on its suffix.\n");
106 fprintf(stdout," -o <decompressed file>\n");
107 fprintf(stdout," REQUIRED\n");
108 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA files\n");
109 fprintf(stdout," Binary data is written to the file (not ascii). If a PGX\n");
110 fprintf(stdout," filename is given, there will be as many output files as there are\n");
111 fprintf(stdout," components: an indice starting from 0 will then be appended to the\n");
112 fprintf(stdout," output filename, just before the \"pgx\" extension. If a PGM filename\n");
113 fprintf(stdout," is given and there are more than one component, only the first component\n");
114 fprintf(stdout," will be written to the file.\n");
115 fprintf(stdout," -r <reduce factor>\n");
116 fprintf(stdout," Set the number of highest resolution levels to be discarded. The\n");
117 fprintf(stdout," image resolution is effectively divided by 2 to the power of the\n");
118 fprintf(stdout," number of discarded levels. The reduce factor is limited by the\n");
119 fprintf(stdout," smallest total number of decomposition levels among tiles.\n");
120 fprintf(stdout," -l <number of quality layers to decode>\n");
121 fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n");
122 fprintf(stdout," less quality layers than the specified number, all the quality layers\n");
123 fprintf(stdout," are decoded.\n");
124 fprintf(stdout," -x \n");
125 fprintf(stdout," Create an index file *.Idx (-x index_name.Idx) \n");
126 fprintf(stdout,"\n");
129 fprintf(stdout," -W <options>\n");
130 fprintf(stdout," Activates the JPWL correction capability, if the codestream complies.\n");
131 fprintf(stdout," Options can be a comma separated list of <param=val> tokens:\n");
132 fprintf(stdout," c, c=numcomps\n");
133 fprintf(stdout," numcomps is the number of expected components in the codestream\n");
134 fprintf(stdout," (search of first EPB rely upon this, default is %d)\n", JPWL_EXPECTED_COMPONENTS);
135 #endif /* USE_JPWL */
137 fprintf(stdout,"\n");
140 /* -------------------------------------------------------------------------- */
142 int get_num_images(char *imgdirpath){
144 struct dirent* content;
147 /*Reading the input images from given input directory*/
149 dir= opendir(imgdirpath);
151 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
155 while((content=readdir(dir))!=NULL){
156 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
163 int load_images(dircnt_t *dirptr, char *imgdirpath){
165 struct dirent* content;
168 /*Reading the input images from given input directory*/
170 dir= opendir(imgdirpath);
172 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
175 fprintf(stderr,"Folder opened successfully\n");
178 while((content=readdir(dir))!=NULL){
179 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
182 strcpy(dirptr->filename[i],content->d_name);
188 int get_file_format(char *filename) {
190 static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "j2k", "jp2", "jpt", "j2c" };
191 static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT };
192 char * ext = strrchr(filename, '.');
197 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
198 if(strnicmp(ext, extension[i], 3) == 0) {
207 char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
208 char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN];
209 char *temp_p, temp1[OPJ_PATH_LEN]="";
211 strcpy(image_filename,dirptr->filename[imageno]);
212 fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename);
213 parameters->decod_format = get_file_format(image_filename);
214 if (parameters->decod_format == -1)
216 sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename);
217 strncpy(parameters->infile, infilename, sizeof(infilename));
220 strcpy(temp_ofname,strtok(image_filename,"."));
221 while((temp_p = strtok(NULL,".")) != NULL){
222 strcat(temp_ofname,temp1);
223 sprintf(temp1,".%s",temp_p);
225 if(img_fol->set_out_format==1){
226 sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format);
227 strncpy(parameters->outfile, outfilename, sizeof(outfilename));
232 /* ------------------------------------------------------------------------------------ */
235 Create an index and write it to a file
236 @param cstr_info Codestream information
237 @param index Index filename
238 @return Returns 0 if successful, returns 1 otherwise
240 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {
241 int tileno, compno, layno, resno, precno, pack_nb, x, y;
248 stream = fopen(index, "w");
250 fprintf(stderr, "failed to open index file [%s] for writing\n", index);
254 fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
255 fprintf(stream, "%d\n", cstr_info->prog);
256 fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
257 fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
258 fprintf(stream, "%d\n", cstr_info->numcomps);
259 fprintf(stream, "%d\n", cstr_info->numlayers);
260 fprintf(stream, "%d\n", cstr_info->numdecompos);
262 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
263 fprintf(stream, "[%d,%d] ",
264 (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 and component 0*/
266 fprintf(stream, "\n");
267 fprintf(stream, "%d\n", cstr_info->main_head_start);
268 fprintf(stream, "%d\n", cstr_info->main_head_end);
269 fprintf(stream, "%d\n", cstr_info->codestream_size);
271 fprintf(stream, "\nINFO ON TILES\n");
272 fprintf(stream, "tileno start_pos end_hd end_tile nbparts\n");
273 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
274 fprintf(stream, "%4d %9d %9d %9d %9d\n",
275 cstr_info->tile[tileno].tileno,
276 cstr_info->tile[tileno].start_pos,
277 cstr_info->tile[tileno].end_header,
278 cstr_info->tile[tileno].end_pos,
279 cstr_info->tile[tileno].num_tps);
282 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
283 int start_pos, end_ph_pos, end_pos;
284 int max_numdecompos = 0;
287 for (compno = 0; compno < cstr_info->numcomps; compno++) {
288 if (max_numdecompos < cstr_info->numdecompos[compno])
289 max_numdecompos = cstr_info->numdecompos[compno];
292 fprintf(stream, "\nTILE %d DETAILS\n", tileno);
293 fprintf(stream, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
294 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
295 fprintf(stream, "%4d %9d %9d %9d %11d %9d\n",
297 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
298 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
299 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
300 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
302 if (cstr_info->prog == LRCP) { /* LRCP */
303 fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos\n");
305 for (layno = 0; layno < cstr_info->numlayers; layno++) {
306 for (resno = 0; resno < max_numdecompos + 1; resno++) {
307 for (compno = 0; compno < cstr_info->numcomps; compno++) {
309 if (resno > cstr_info->numdecompos[compno])
311 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
312 for (precno = 0; precno < prec_max; precno++) {
313 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
314 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
315 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
316 fprintf(stream, "%4d %6d %7d %5d %6d %6d %6d %6d %7d\n",
317 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
324 else if (cstr_info->prog == RLCP) { /* RLCP */
326 fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
328 for (resno = 0; resno < max_numdecompos + 1; resno++) {
329 for (layno = 0; layno < cstr_info->numlayers; layno++) {
330 for (compno = 0; compno < cstr_info->numcomps; compno++) {
332 if (resno > cstr_info->numdecompos[compno])
334 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
335 for (precno = 0; precno < prec_max; precno++) {
336 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
337 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
338 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
339 fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %7d\n",
340 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
347 else if (cstr_info->prog == RPCL) { /* RPCL */
349 fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos\n");
351 for (resno = 0; resno < max_numdecompos + 1; resno++) {
352 /* I suppose components have same XRsiz, YRsiz */
353 int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
354 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
355 int x1 = x0 + cstr_info->tile_x;
356 int y1 = y0 + cstr_info->tile_y;
357 for (compno = 0; compno < cstr_info->numcomps; compno++) {
359 if (resno > cstr_info->numdecompos[compno])
361 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
362 for (precno = 0; precno < prec_max; precno++) {
363 int pcnx = cstr_info->tile[tileno].pw[resno];
364 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
365 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
366 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
367 int precno_y = (int) floor( (float)precno/(float)pcnx );
368 for(y = y0; y < y1; y++) {
369 if (precno_y*pcy == y ) {
370 for (x = x0; x < x1; x++) {
371 if (precno_x*pcx == x ) {
372 for (layno = 0; layno < cstr_info->numlayers; layno++) {
373 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
374 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
375 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
376 fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %7d\n",
377 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos);
388 else if (cstr_info->prog == PCRL) { /* PCRL */
389 /* I suppose components have same XRsiz, YRsiz */
390 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
391 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
392 int x1 = x0 + cstr_info->tile_x;
393 int y1 = y0 + cstr_info->tile_y;
395 fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos\n");
397 for (compno = 0; compno < cstr_info->numcomps; compno++) {
398 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
399 int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
400 for (precno = 0; precno < prec_max; precno++) {
401 int pcnx = cstr_info->tile[tileno].pw[resno];
402 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
403 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
404 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
405 int precno_y = (int) floor( (float)precno/(float)pcnx );
406 for(y = y0; y < y1; y++) {
407 if (precno_y*pcy == y ) {
408 for (x = x0; x < x1; x++) {
409 if (precno_x*pcx == x ) {
410 for (layno = 0; layno < cstr_info->numlayers; layno++) {
411 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
412 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
413 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
414 fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d\n",
415 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos);
428 fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos\n");
430 for (compno = 0; compno < cstr_info->numcomps; compno++) {
431 /* I suppose components have same XRsiz, YRsiz */
432 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
433 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
434 int x1 = x0 + cstr_info->tile_x;
435 int y1 = y0 + cstr_info->tile_y;
437 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
438 int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
439 for (precno = 0; precno < prec_max; precno++) {
440 int pcnx = cstr_info->tile[tileno].pw[resno];
441 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
442 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
443 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
444 int precno_y = (int) floor( (float)precno/(float)pcnx );
445 for(y = y0; y < y1; y++) {
446 if (precno_y*pcy == y ) {
447 for (x = x0; x < x1; x++) {
448 if (precno_x*pcx == x ) {
449 for (layno = 0; layno < cstr_info->numlayers; layno++) {
450 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
451 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
452 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
453 fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d\n",
454 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos);
469 fprintf(stderr,"Generated index file %s\n", index);
474 /* ------------------------------------------------------------------------------------ */
476 /* -------------------------------------------------------------------------- */
477 int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) {
478 /* parse the command line */
480 option_t long_option[]={
481 {"ImgDir",REQ_ARG, NULL ,'y'},
482 {"OutFor",REQ_ARG, NULL ,'O'},
485 const char optlist[] = "i:o:r:l:hx:"
490 #endif /* USE_JPWL */
493 totlen=sizeof(long_option);
494 img_fol->set_out_format = 0;
496 int c = getopt_long(argc, argv,optlist,long_option,totlen);
500 case 'i': /* input file */
502 char *infile = optarg;
503 parameters->decod_format = get_file_format(infile);
504 switch(parameters->decod_format) {
511 "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n",
515 strncpy(parameters->infile, infile, sizeof(parameters->infile)-1);
519 /* ----------------------------------------------------- */
521 case 'o': /* output file */
523 char *outfile = optarg;
524 parameters->cod_format = get_file_format(outfile);
525 switch(parameters->cod_format) {
534 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile);
537 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
541 /* ----------------------------------------------------- */
543 case 'O': /* output format */
547 sprintf(outformat,".%s",of);
548 img_fol->set_out_format = 1;
549 parameters->cod_format = get_file_format(outformat);
550 switch(parameters->cod_format) {
552 img_fol->out_format = "pgx";
555 img_fol->out_format = "ppm";
558 img_fol->out_format = "bmp";
561 img_fol->out_format = "tif";
564 img_fol->out_format = "raw";
567 img_fol->out_format = "raw";
570 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat);
577 /* ----------------------------------------------------- */
580 case 'r': /* reduce option */
582 sscanf(optarg, "%d", ¶meters->cp_reduce);
586 /* ----------------------------------------------------- */
589 case 'l': /* layering option */
591 sscanf(optarg, "%d", ¶meters->cp_layer);
595 /* ----------------------------------------------------- */
597 case 'h': /* display an help description */
598 decode_help_display();
601 /* ------------------------------------------------------ */
603 case 'y': /* Image Directory path */
605 img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
606 strcpy(img_fol->imgdirpath,optarg);
607 img_fol->set_imgdir=1;
610 /* ----------------------------------------------------- */
611 case 'x': /* Creation of index file */
613 char *index = optarg;
614 strncpy(indexfilename, index, OPJ_PATH_LEN);
617 /* ----------------------------------------------------- */
621 case 'W': /* activate JPWL correction */
625 token = strtok(optarg, ",");
626 while(token != NULL) {
628 /* search expected number of components */
633 compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */
635 if(sscanf(token, "c=%d", &compno) == 1) {
637 if ((compno < 1) || (compno > 256)) {
638 fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);
641 parameters->jpwl_exp_comps = compno;
643 } else if (!strcmp(token, "c")) {
645 parameters->jpwl_exp_comps = compno; /* auto for default size */
648 fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);
653 /* search maximum number of tiles */
658 tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */
660 if(sscanf(token, "t=%d", &tileno) == 1) {
662 if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {
663 fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);
666 parameters->jpwl_max_tiles = tileno;
668 } else if (!strcmp(token, "t")) {
670 parameters->jpwl_max_tiles = tileno; /* auto for default size */
673 fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);
678 /* next token or bust */
679 token = strtok(NULL, ",");
681 parameters->jpwl_correct = true;
682 fprintf(stdout, "JPWL correction capability activated\n");
683 fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);
686 #endif /* USE_JPWL */
689 /* ----------------------------------------------------- */
692 fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, optarg);
697 /* check for possible errors */
698 if(img_fol->set_imgdir==1){
699 if(!(parameters->infile[0]==0)){
700 fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n");
703 if(img_fol->set_out_format == 0){
704 fprintf(stderr, "Error: When -ImgDir is used, -OutFor <FORMAT> must be used !!\n");
705 fprintf(stderr, "Only one format allowed! Valid format PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA!!\n");
708 if(!((parameters->outfile[0] == 0))){
709 fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n");
713 if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
714 fprintf(stderr, "Error: One of the options -i or -ImgDir must be specified\n");
715 fprintf(stderr, "Error: When using -i, -o must be used\n");
716 fprintf(stderr, "usage: image_to_j2k -i *.j2k/jp2/j2c -o *.pgm/ppm/pnm/pgx/bmp/tif/raw/tga(+ options)\n");
724 /* -------------------------------------------------------------------------- */
727 sample error callback expecting a FILE* client object
729 void error_callback(const char *msg, void *client_data) {
730 FILE *stream = (FILE*)client_data;
731 fprintf(stream, "[ERROR] %s", msg);
734 sample warning callback expecting a FILE* client object
736 void warning_callback(const char *msg, void *client_data) {
737 FILE *stream = (FILE*)client_data;
738 fprintf(stream, "[WARNING] %s", msg);
741 sample debug callback expecting no client object
743 void info_callback(const char *msg, void *client_data) {
745 fprintf(stdout, "[INFO] %s", msg);
748 /* -------------------------------------------------------------------------- */
750 int main(int argc, char **argv) {
751 opj_dparameters_t parameters; /* decompression parameters */
753 opj_event_mgr_t event_mgr; /* event manager */
754 opj_image_t *image = NULL;
756 unsigned char *src = NULL;
761 opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
762 opj_cio_t *cio = NULL;
763 opj_codestream_info_t cstr_info; /* Codestream information structure */
764 char indexfilename[OPJ_PATH_LEN]; /* index file name */
766 /* configure the event callbacks (not required) */
767 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
768 event_mgr.error_handler = error_callback;
769 event_mgr.warning_handler = warning_callback;
770 event_mgr.info_handler = info_callback;
772 /* set decoding parameters to default values */
773 opj_set_default_decoder_parameters(¶meters);
775 /* Initialize indexfilename and img_fol */
777 memset(&img_fol,0,sizeof(img_fol_t));
779 /* parse input and get user encoding parameters */
780 if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
784 /* Initialize reading of directory */
785 if(img_fol.set_imgdir==1){
786 num_images=get_num_images(img_fol.imgdirpath);
788 dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
790 dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); // Stores at max 10 image file names
791 dirptr->filename = (char**) malloc(num_images*sizeof(char*));
793 if(!dirptr->filename_buf){
796 for(i=0;i<num_images;i++){
797 dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN;
800 if(load_images(dirptr,img_fol.imgdirpath)==1){
804 fprintf(stdout,"Folder is empty\n");
811 /*Encoding image one by one*/
812 for(imageno = 0; imageno < num_images ; imageno++) {
814 fprintf(stderr,"\n");
816 if(img_fol.set_imgdir==1){
817 if (get_next_file(imageno, dirptr,&img_fol, ¶meters)) {
818 fprintf(stderr,"skipping file...\n");
823 /* read the input file and put it in memory */
824 /* ---------------------------------------- */
825 fsrc = fopen(parameters.infile, "rb");
827 fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
830 fseek(fsrc, 0, SEEK_END);
831 file_length = ftell(fsrc);
832 fseek(fsrc, 0, SEEK_SET);
833 src = (unsigned char *) malloc(file_length);
834 fread(src, 1, file_length, fsrc);
837 /* decode the code-stream */
838 /* ---------------------- */
840 switch(parameters.decod_format) {
843 /* JPEG-2000 codestream */
845 /* get a decoder handle */
846 dinfo = opj_create_decompress(CODEC_J2K);
848 /* catch events using our callbacks and give a local context */
849 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
851 /* setup the decoder decoding parameters using user parameters */
852 opj_setup_decoder(dinfo, ¶meters);
854 /* open a byte stream */
855 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
857 /* decode the stream and fill the image structure */
858 if (*indexfilename) // If need to extract codestream information
859 image = opj_decode_with_info(dinfo, cio, &cstr_info);
861 image = opj_decode(dinfo, cio);
863 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
864 opj_destroy_decompress(dinfo);
869 /* close the byte stream */
872 /* Write the index to disk */
873 if (*indexfilename) {
875 bSuccess = write_index_file(&cstr_info, indexfilename);
877 fprintf(stderr, "Failed to output index file\n");
885 /* JPEG 2000 compressed image data */
887 /* get a decoder handle */
888 dinfo = opj_create_decompress(CODEC_JP2);
890 /* catch events using our callbacks and give a local context */
891 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
893 /* setup the decoder decoding parameters using the current image and user parameters */
894 opj_setup_decoder(dinfo, ¶meters);
896 /* open a byte stream */
897 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
899 /* decode the stream and fill the image structure */
900 if (*indexfilename) // If need to extract codestream information
901 image = opj_decode_with_info(dinfo, cio, &cstr_info);
903 image = opj_decode(dinfo, cio);
905 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
906 opj_destroy_decompress(dinfo);
911 /* close the byte stream */
914 /* Write the index to disk */
915 if (*indexfilename) {
917 bSuccess = write_index_file(&cstr_info, indexfilename);
919 fprintf(stderr, "Failed to output index file\n");
927 /* JPEG 2000, JPIP */
929 /* get a decoder handle */
930 dinfo = opj_create_decompress(CODEC_JPT);
932 /* catch events using our callbacks and give a local context */
933 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
935 /* setup the decoder decoding parameters using user parameters */
936 opj_setup_decoder(dinfo, ¶meters);
938 /* open a byte stream */
939 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
941 /* decode the stream and fill the image structure */
942 if (*indexfilename) // If need to extract codestream information
943 image = opj_decode_with_info(dinfo, cio, &cstr_info);
945 image = opj_decode(dinfo, cio);
947 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
948 opj_destroy_decompress(dinfo);
953 /* close the byte stream */
956 /* Write the index to disk */
957 if (*indexfilename) {
959 bSuccess = write_index_file(&cstr_info, indexfilename);
961 fprintf(stderr, "Failed to output index file\n");
968 fprintf(stderr, "skipping file..\n");
972 /* free the memory containing the code-stream */
976 /* create output image */
977 /* ------------------- */
978 switch (parameters.cod_format) {
979 case PXM_DFMT: /* PNM PGM PPM */
980 if (imagetopnm(image, parameters.outfile)) {
981 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
984 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
988 case PGX_DFMT: /* PGX */
989 if(imagetopgx(image, parameters.outfile)){
990 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
993 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
997 case BMP_DFMT: /* BMP */
998 if(imagetobmp(image, parameters.outfile)){
999 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
1002 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
1006 case TIF_DFMT: /* TIFF */
1007 if(imagetotif(image, parameters.outfile)){
1008 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
1011 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
1015 case RAW_DFMT: /* RAW */
1016 if(imagetoraw(image, parameters.outfile)){
1017 fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile);
1020 fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
1024 case TGA_DFMT: /* TGA */
1025 if(imagetotga(image, parameters.outfile)){
1026 fprintf(stdout,"Error generating tga file. Outfile %s not generated\n",parameters.outfile);
1029 fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
1034 /* free remaining structures */
1036 opj_destroy_decompress(dinfo);
1038 /* free codestream information structure */
1040 opj_destroy_cstr_info(&cstr_info);
1041 /* free image data structure */
1042 opj_image_destroy(image);