Provide safer string copy than strncpy
[openjpeg.git] / src / bin / jp2 / opj_decompress.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses 
3  * BSD License, included below. This software may be subject to other third 
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2001-2003, David Janssens
10  * Copyright (c) 2002-2003, Yannick Verschueren
11  * Copyright (c) 2003-2007, Francois-Olivier Devaux 
12  * Copyright (c) 2003-2014, Antonin Descampe
13  * Copyright (c) 2005, Herve Drolon, FreeImage Team
14  * Copyright (c) 2006-2007, Parvatha Elangovan
15  * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR 
16  * Copyright (c) 2012, CS Systemes d'Information, France
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 #include "opj_apps_config.h"
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <math.h>
46
47 #ifdef _WIN32
48 #include "windirent.h"
49 #else
50 #include <dirent.h>
51 #endif /* _WIN32 */
52
53 #ifdef _WIN32
54 #include <windows.h>
55 #define strcasecmp _stricmp
56 #define strncasecmp _strnicmp
57 #else
58 #include <strings.h>
59 #include <sys/time.h>
60 #include <sys/resource.h>
61 #include <sys/times.h>
62 #endif /* _WIN32 */
63
64 #include "openjpeg.h"
65 #include "opj_getopt.h"
66 #include "convert.h"
67 #include "index.h"
68
69 #ifdef OPJ_HAVE_LIBLCMS2
70 #include <lcms2.h>
71 #endif
72 #ifdef OPJ_HAVE_LIBLCMS1
73 #include <lcms.h>
74 #endif
75 #include "color.h"
76
77 #include "format_defs.h"
78 #include "opj_string.h"
79
80 typedef struct dircnt{
81         /** Buffer for holding images read from Directory*/
82         char *filename_buf;
83         /** Pointer to the buffer*/
84         char **filename;
85 }dircnt_t;
86
87
88 typedef struct img_folder{
89         /** The directory path of the folder containing input images*/
90         char *imgdirpath;
91         /** Output format*/
92         const char *out_format;
93         /** Enable option*/
94         char set_imgdir;
95         /** Enable Cod Format for output*/
96         char set_out_format;
97
98 }img_fol_t;
99
100 typedef enum opj_prec_mode
101 {
102         OPJ_PREC_MODE_CLIP,
103         OPJ_PREC_MODE_SCALE
104 } opj_precision_mode;
105
106 typedef struct opj_prec
107 {
108         OPJ_UINT32         prec;
109         opj_precision_mode mode;
110 }opj_precision;
111
112 typedef struct opj_decompress_params
113 {
114         /** core library parameters */
115         opj_dparameters_t core;
116         
117         /** input file name */
118         char infile[OPJ_PATH_LEN];
119         /** output file name */
120         char outfile[OPJ_PATH_LEN];
121         /** input file format 0: J2K, 1: JP2, 2: JPT */
122         int decod_format;
123         /** output file format 0: PGX, 1: PxM, 2: BMP */
124         int cod_format;
125         /** index file name */
126         char indexfilename[OPJ_PATH_LEN];
127         
128         /** Decoding area left boundary */
129         OPJ_UINT32 DA_x0;
130         /** Decoding area right boundary */
131         OPJ_UINT32 DA_x1;
132         /** Decoding area up boundary */
133         OPJ_UINT32 DA_y0;
134         /** Decoding area bottom boundary */
135         OPJ_UINT32 DA_y1;
136         /** Verbose mode */
137         OPJ_BOOL m_verbose;
138         
139         /** tile number ot the decoded tile*/
140         OPJ_UINT32 tile_index;
141         /** Nb of tile to decode */
142         OPJ_UINT32 nb_tile_to_decode;
143         
144         opj_precision* precision;
145         OPJ_UINT32     nb_precision;
146         
147         /* force output colorspace to RGB */
148         int force_rgb;
149         /* upsample components according to their dx/dy values */
150         int upsample;
151         /* split output components to different files */
152         int split_pnm;
153 }opj_decompress_parameters;
154
155 /* -------------------------------------------------------------------------- */
156 /* Declarations                                                               */
157 int get_num_images(char *imgdirpath);
158 int load_images(dircnt_t *dirptr, char *imgdirpath);
159 int get_file_format(const char *filename);
160 char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters);
161 static int infile_format(const char *fname);
162
163 int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol);
164 int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1);
165
166 static opj_image_t* convert_gray_to_rgb(opj_image_t* original);
167
168 /* -------------------------------------------------------------------------- */
169 static void decode_help_display(void) {
170         fprintf(stdout,"\nThis is the opj_decompress utility from the OpenJPEG project.\n"
171                        "It decompresses JPEG 2000 codestreams to various image formats.\n"
172                        "It has been compiled against openjp2 library v%s.\n\n",opj_version());
173
174         fprintf(stdout,"Parameters:\n"
175                        "-----------\n"
176                        "\n"
177                        "  -ImgDir <directory> \n"
178                        "        Image file Directory path \n"
179                        "  -OutFor <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|RAW|RAWL|TGA>\n"
180                        "    REQUIRED only if -ImgDir is used\n"
181                        "        Output format for decompressed images.\n");
182         fprintf(stdout,"  -i <compressed file>\n"
183                        "    REQUIRED only if an Input image directory is not specified\n"
184                        "    Currently accepts J2K-files, JP2-files and JPT-files. The file type\n"
185                        "    is identified based on its suffix.\n");
186         fprintf(stdout,"  -o <decompressed file>\n"
187                        "    REQUIRED\n"
188                        "    Currently accepts formats specified above (see OutFor option)\n"
189                        "    Binary data is written to the file (not ascii). If a PGX\n"
190                        "    filename is given, there will be as many output files as there are\n"
191                        "    components: an indice starting from 0 will then be appended to the\n"
192                        "    output filename, just before the \"pgx\" extension. If a PGM filename\n"
193                        "    is given and there are more than one component, only the first component\n"
194                        "    will be written to the file.\n");
195         fprintf(stdout,"  -r <reduce factor>\n"
196                        "    Set the number of highest resolution levels to be discarded. The\n"
197                        "    image resolution is effectively divided by 2 to the power of the\n"
198                        "    number of discarded levels. The reduce factor is limited by the\n"
199                        "    smallest total number of decomposition levels among tiles.\n"
200                        "  -l <number of quality layers to decode>\n"
201                        "    Set the maximum number of quality layers to decode. If there are\n"
202                        "    less quality layers than the specified number, all the quality layers\n"
203                        "    are decoded.\n");
204         fprintf(stdout,"  -x  \n"
205                        "    Create an index file *.Idx (-x index_name.Idx) \n"
206                        "  -d <x0,y0,x1,y1>\n"
207                        "    OPTIONAL\n"
208                        "    Decoding area\n"
209                        "    By default all the image is decoded.\n"
210                        "  -t <tile_number>\n"
211                        "    OPTIONAL\n"
212                        "    Set the tile number of the decoded tile. Follow the JPEG2000 convention from left-up to bottom-up\n"
213                        "    By default all tiles are decoded.\n");
214         fprintf(stdout,"  -p <comp 0 precision>[C|S][,<comp 1 precision>[C|S][,...]]\n"
215                        "    OPTIONAL\n"
216                        "    Force the precision (bit depth) of components.\n");
217         fprintf(stdout,"    There shall be at least 1 value. Theres no limit on the number of values (comma separated, last values ignored if too much values).\n"
218                        "    If there are less values than components, the last value is used for remaining components.\n"
219                        "    If 'C' is specified (default), values are clipped.\n"
220                        "    If 'S' is specified, values are scaled.\n"
221                        "    A 0 value can be specified (meaning original bit depth).\n");
222         fprintf(stdout,"  -force-rgb\n"
223                        "    Force output image colorspace to RGB\n"
224                        "  -upsample\n"
225                        "    Downsampled components will be upsampled to image size\n"
226                        "  -split-pnm\n"
227                        "    Split output components to different files when writing to PNM\n"
228                        "\n");
229 /* UniPG>> */
230 #ifdef USE_JPWL
231         fprintf(stdout,"  -W <options>\n"
232                        "    Activates the JPWL correction capability, if the codestream complies.\n"
233                        "    Options can be a comma separated list of <param=val> tokens:\n"
234                        "    c, c=numcomps\n"
235                        "       numcomps is the number of expected components in the codestream\n"
236                        "       (search of first EPB rely upon this, default is %d)\n", JPWL_EXPECTED_COMPONENTS);
237 #endif /* USE_JPWL */
238 /* <<UniPG */
239         fprintf(stdout,"\n");
240 }
241
242 /* -------------------------------------------------------------------------- */
243
244 static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* parameters)
245 {
246         const char* l_remaining = option;
247         OPJ_BOOL l_result = OPJ_TRUE;
248         
249         /* reset */
250         if (parameters->precision) {
251                 free(parameters->precision);
252                 parameters->precision = NULL;
253         }
254         parameters->nb_precision = 0U;
255         
256         for(;;)
257         {
258                 int prec;
259                 char mode;
260                 char comma;
261                 int count;
262                 
263                 count = sscanf(l_remaining, "%d%c%c", &prec, &mode, &comma);
264                 if (count == 1) {
265                         mode = 'C';
266                         count++;
267                 }
268                 if ((count == 2) || (mode==',')) {
269                         if (mode==',') {
270                                 mode = 'C';
271                         }
272                         comma=',';
273                         count = 3;
274                 }
275                 if (count == 3) {
276                         if ((prec < 1) || (prec > 32)) {
277                                 fprintf(stderr,"Invalid precision %d in precision option %s\n", prec, option);
278                                 l_result = OPJ_FALSE;
279                                 break;
280                         }
281                         if ((mode != 'C') && (mode != 'S')) {
282                                 fprintf(stderr,"Invalid precision mode %c in precision option %s\n", mode, option);
283                                 l_result = OPJ_FALSE;
284                                 break;
285                         }
286                         if (comma != ',') {
287                                 fprintf(stderr,"Invalid character %c in precision option %s\n", comma, option);
288                                 l_result = OPJ_FALSE;
289                                 break;
290                         }
291                         
292                         if (parameters->precision == NULL) {
293                                 /* first one */
294                                 parameters->precision = malloc(sizeof(opj_precision));
295                                 if (parameters->precision == NULL) {
296                                         fprintf(stderr,"Could not allocate memory for precision option\n");
297                                         l_result = OPJ_FALSE;
298                                         break;
299                                 }
300                         } else {
301                                 OPJ_UINT32 l_new_size = parameters->nb_precision + 1U;
302                                 opj_precision* l_new;
303                                 
304                                 if (l_new_size == 0U) {
305                                         fprintf(stderr,"Could not allocate memory for precision option\n");
306                                         l_result = OPJ_FALSE;
307                                         break;
308                                 }
309                                 
310                                 l_new = realloc(parameters->precision, l_new_size * sizeof(opj_precision));
311                                 if (l_new == NULL) {
312                                         fprintf(stderr,"Could not allocate memory for precision option\n");
313                                         l_result = OPJ_FALSE;
314                                         break;
315                                 }
316                                 parameters->precision = l_new;
317                         }
318                         
319                         parameters->precision[parameters->nb_precision].prec = (OPJ_UINT32)prec;
320                         switch (mode) {
321                                 case 'C':
322                                         parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_CLIP;
323                                         break;
324                                 case 'S':
325                                         parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_SCALE;
326                                         break;
327                                 default:
328                                         break;
329                         }
330                         parameters->nb_precision++;
331                         
332                         l_remaining = strchr(l_remaining, ',');
333                         if (l_remaining == NULL) {
334                                 break;
335                         }
336                         l_remaining += 1;
337                 } else {
338                         fprintf(stderr,"Could not parse precision option %s\n", option);
339                         l_result = OPJ_FALSE;
340                         break;
341                 }
342         }
343         
344         return l_result;
345 }
346
347 /* -------------------------------------------------------------------------- */
348
349 int get_num_images(char *imgdirpath){
350         DIR *dir;
351         struct dirent* content; 
352         int num_images = 0;
353
354         /*Reading the input images from given input directory*/
355
356         dir= opendir(imgdirpath);
357         if(!dir){
358                 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
359                 return 0;
360         }
361         
362         while((content=readdir(dir))!=NULL){
363                 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
364                         continue;
365                 num_images++;
366         }
367         closedir(dir);
368         return num_images;
369 }
370
371 /* -------------------------------------------------------------------------- */
372 int load_images(dircnt_t *dirptr, char *imgdirpath){
373         DIR *dir;
374         struct dirent* content; 
375         int i = 0;
376
377         /*Reading the input images from given input directory*/
378
379         dir= opendir(imgdirpath);
380         if(!dir){
381                 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
382                 return 1;
383         }else   {
384                 fprintf(stderr,"Folder opened successfully\n");
385         }
386         
387         while((content=readdir(dir))!=NULL){
388                 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
389                         continue;
390
391                 strcpy(dirptr->filename[i],content->d_name);
392                 i++;
393         }
394         closedir(dir);
395         return 0;       
396 }
397
398 /* -------------------------------------------------------------------------- */
399 int get_file_format(const char *filename) {
400         unsigned int i;
401         static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
402         static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
403         char * ext = strrchr(filename, '.');
404         if (ext == NULL)
405                 return -1;
406         ext++;
407         if(*ext) {
408                 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
409                         if(strcasecmp(ext, extension[i]) == 0) {
410                                 return format[i];
411                         }
412                 }
413         }
414
415         return -1;
416 }
417
418 #ifdef _WIN32
419 const char* path_separator = "\\";
420 #else
421 const char* path_separator = "/";
422 #endif
423
424 /* -------------------------------------------------------------------------- */
425 char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters){
426         char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN];
427         char *temp_p, temp1[OPJ_PATH_LEN]="";
428
429         strcpy(image_filename,dirptr->filename[imageno]);
430         fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename);
431         sprintf(infilename, "%s%s%s", img_fol->imgdirpath, path_separator, image_filename);
432         parameters->decod_format = infile_format(infilename);
433         if (parameters->decod_format == -1)
434                 return 1;
435         if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) {
436                 return 1;
437         }
438
439         /*Set output file*/
440         strcpy(temp_ofname,strtok(image_filename,"."));
441         while((temp_p = strtok(NULL,".")) != NULL){
442                 strcat(temp_ofname,temp1);
443                 sprintf(temp1,".%s",temp_p);
444         }
445         if(img_fol->set_out_format==1){
446                 sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format);
447                 if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) {
448                         return 1;
449                 }
450         }
451         return 0;
452 }
453
454 /* -------------------------------------------------------------------------- */
455 #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
456 #define JP2_MAGIC "\x0d\x0a\x87\x0a"
457 /* position 45: "\xff\x52" */
458 #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
459
460 static int infile_format(const char *fname)
461 {
462         FILE *reader;
463         const char *s, *magic_s;
464         int ext_format, magic_format;
465         unsigned char buf[12];
466         OPJ_SIZE_T l_nb_read;
467
468         reader = fopen(fname, "rb");
469
470         if (reader == NULL)
471                 return -2;
472
473         memset(buf, 0, 12);
474         l_nb_read = fread(buf, 1, 12, reader);
475         fclose(reader);
476         if (l_nb_read != 12)
477                 return -1;
478
479
480
481         ext_format = get_file_format(fname);
482
483         if (ext_format == JPT_CFMT)
484                 return JPT_CFMT;
485
486         if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
487                 magic_format = JP2_CFMT;
488                 magic_s = ".jp2";
489         }
490         else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
491                 magic_format = J2K_CFMT;
492                 magic_s = ".j2k or .jpc or .j2c";
493         }
494         else
495                 return -1;
496
497         if (magic_format == ext_format)
498                 return ext_format;
499
500         s = fname + strlen(fname) - 4;
501
502         fputs("\n===========================================\n", stderr);
503         fprintf(stderr, "The extension of this file is incorrect.\n"
504                                         "FOUND %s. SHOULD BE %s\n", s, magic_s);
505         fputs("===========================================\n", stderr);
506
507         return magic_format;
508 }
509
510 /* -------------------------------------------------------------------------- */
511 /**
512  * Parse the command line
513  */
514 /* -------------------------------------------------------------------------- */
515 int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol) {
516         /* parse the command line */
517         int totlen, c;
518         opj_option_t long_option[]={
519                 {"ImgDir",    REQ_ARG, NULL,'y'},
520                 {"OutFor",    REQ_ARG, NULL,'O'},
521                 {"force-rgb", NO_ARG,  NULL, 1},
522                 {"upsample",  NO_ARG,  NULL, 1},
523                 {"split-pnm", NO_ARG,  NULL, 1}
524         };
525
526         const char optlist[] = "i:o:r:l:x:d:t:p:"
527
528 /* UniPG>> */
529 #ifdef USE_JPWL
530                                         "W:"
531 #endif /* USE_JPWL */
532 /* <<UniPG */
533             "h"         ;
534
535         long_option[2].flag = &(parameters->force_rgb);
536         long_option[3].flag = &(parameters->upsample);
537         long_option[4].flag = &(parameters->split_pnm);
538         totlen=sizeof(long_option);
539         opj_reset_options_reading();
540         img_fol->set_out_format = 0;
541         do {
542                 c = opj_getopt_long(argc, argv,optlist,long_option,totlen);
543                 if (c == -1)
544                         break;
545                 switch (c) {
546                         case 0: /* long opt with flag */
547                                 break;
548                         case 'i':                       /* input file */
549                         {
550                                 char *infile = opj_optarg;
551                                 parameters->decod_format = infile_format(infile);
552                                 switch(parameters->decod_format) {
553                                         case J2K_CFMT:
554                                                 break;
555                                         case JP2_CFMT:
556                                                 break;
557                                         case JPT_CFMT:
558                                                 break;
559                                         case -2:
560                                                 fprintf(stderr, 
561                                                         "!! infile cannot be read: %s !!\n\n", 
562                                                         infile);
563                                                 return 1;
564                                         default:
565                                                 fprintf(stderr, 
566                             "[ERROR] Unknown input file format: %s \n"
567                             "        Known file formats are *.j2k, *.jp2, *.jpc or *.jpt\n",
568                                                         infile);
569                                                 return 1;
570                                 }
571                                 if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) {
572                                         fprintf(stderr, "[ERROR] Path is too long\n");
573                                         return 1;
574                                 }
575                         }
576                         break;
577                                 
578                                 /* ----------------------------------------------------- */
579
580                         case 'o':                       /* output file */
581                         {
582                                 char *outfile = opj_optarg;
583                                 parameters->cod_format = get_file_format(outfile);
584                                 switch(parameters->cod_format) {
585                                         case PGX_DFMT:
586                                                 break;
587                                         case PXM_DFMT:
588                                                 break;
589                                         case BMP_DFMT:
590                                                 break;
591                                         case TIF_DFMT:
592                                                 break;
593                                         case RAW_DFMT:
594                                                 break;
595                                         case RAWL_DFMT:
596                                                 break;
597                                         case TGA_DFMT:
598                                                 break;
599                                         case PNG_DFMT:
600                                                 break;
601                                         default:
602                                                 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile);
603                                                 return 1;
604                                 }
605                                 if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfile) != 0) {
606                                         fprintf(stderr, "[ERROR] Path is too long\n");
607                                         return 1;
608                                 }
609                         }
610                         break;
611                         
612                                 /* ----------------------------------------------------- */
613
614                         case 'O':                       /* output format */
615                         {
616                                 char outformat[50];
617                                 char *of = opj_optarg;
618                                 sprintf(outformat,".%s",of);
619                                 img_fol->set_out_format = 1;
620                                 parameters->cod_format = get_file_format(outformat);
621                                 switch(parameters->cod_format) {
622                                         case PGX_DFMT:
623                                                 img_fol->out_format = "pgx";
624                                                 break;
625                                         case PXM_DFMT:
626                                                 img_fol->out_format = "ppm";
627                                                 break;
628                                         case BMP_DFMT:
629                                                 img_fol->out_format = "bmp";
630                                                 break;
631                                         case TIF_DFMT:
632                                                 img_fol->out_format = "tif";
633                                                 break;
634                                         case RAW_DFMT:
635                                                 img_fol->out_format = "raw";
636                                                 break;
637                                         case RAWL_DFMT:
638                                                 img_fol->out_format = "rawl";
639                                                 break;
640                                         case TGA_DFMT:
641                                                 img_fol->out_format = "raw";
642                                                 break;
643                                         case PNG_DFMT:
644                                                 img_fol->out_format = "png";
645                                                 break;
646                                         default:
647                                                 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat);
648                                                 return 1;
649                                                 break;
650                                 }
651                         }
652                         break;
653
654                                 /* ----------------------------------------------------- */
655
656
657                         case 'r':               /* reduce option */
658                         {
659                                 sscanf(opj_optarg, "%u", &(parameters->core.cp_reduce));
660                         }
661                         break;
662                         
663                                 /* ----------------------------------------------------- */
664       
665
666                         case 'l':               /* layering option */
667                         {
668                                 sscanf(opj_optarg, "%u", &(parameters->core.cp_layer));
669                         }
670                         break;
671                         
672                                 /* ----------------------------------------------------- */
673
674                         case 'h':                       /* display an help description */
675                                 decode_help_display();
676                                 return 1;                               
677
678             /* ----------------------------------------------------- */
679
680                         case 'y':                       /* Image Directory path */
681                 {
682                                         img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1);
683                                         strcpy(img_fol->imgdirpath,opj_optarg);
684                                         img_fol->set_imgdir=1;
685                                 }
686                                 break;
687
688                                 /* ----------------------------------------------------- */
689
690                         case 'd':               /* Input decode ROI */
691                         {
692                                 size_t size_optarg = (size_t)strlen(opj_optarg) + 1U;
693                                 char *ROI_values = (char*) malloc(size_optarg);
694                                 if (ROI_values == NULL) {
695                                         fprintf(stderr, "[ERROR] Couldn't allocate memory\n");
696                                         return 1;
697                                 }
698                                 ROI_values[0] = '\0';
699                                 memcpy(ROI_values, opj_optarg, size_optarg);
700                                 /*printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg ); */
701                                 parse_DA_values( ROI_values, &parameters->DA_x0, &parameters->DA_y0, &parameters->DA_x1, &parameters->DA_y1);
702
703                                 free(ROI_values);
704                         }
705                         break;
706
707                         /* ----------------------------------------------------- */
708
709                         case 't':               /* Input tile index */
710                         {
711                                 sscanf(opj_optarg, "%u", &parameters->tile_index);
712                                 parameters->nb_tile_to_decode = 1;
713                         }
714                         break;
715
716                                 /* ----------------------------------------------------- */                                                             
717
718                         case 'x':                       /* Creation of index file */
719                                 {
720                                         if (opj_strcpy_s(parameters->indexfilename, sizeof(parameters->indexfilename), opj_optarg) != 0) {
721                                                 fprintf(stderr, "[ERROR] Path is too long\n");
722                                                 return 1;
723                                         }
724                                 }
725                                 break;
726                                 
727                                 /* ----------------------------------------------------- */
728                         case 'p': /* Force precision */
729                                 {
730                                         if (!parse_precision(opj_optarg, parameters))
731                                         {
732                                                 return 1;
733                                         }
734                                 }
735                                 break;
736                                 /* ----------------------------------------------------- */
737                                 
738                                 /* UniPG>> */
739 #ifdef USE_JPWL
740                         
741                         case 'W':                       /* activate JPWL correction */
742                         {
743                                 char *token = NULL;
744
745                                 token = strtok(opj_optarg, ",");
746                                 while(token != NULL) {
747
748                                         /* search expected number of components */
749                                         if (*token == 'c') {
750
751                                                 static int compno;
752
753                                                 compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */
754
755                                                 if(sscanf(token, "c=%d", &compno) == 1) {
756                                                         /* Specified */
757                                                         if ((compno < 1) || (compno > 256)) {
758                                                                 fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);
759                                                                 return 1;
760                                                         }
761                                                         parameters->jpwl_exp_comps = compno;
762
763                                                 } else if (!strcmp(token, "c")) {
764                                                         /* default */
765                                                         parameters->jpwl_exp_comps = compno; /* auto for default size */
766
767                                                 } else {
768                                                         fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);
769                                                         return 1;
770                                                 };
771                                         }
772
773                                         /* search maximum number of tiles */
774                                         if (*token == 't') {
775
776                                                 static int tileno;
777
778                                                 tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */
779
780                                                 if(sscanf(token, "t=%d", &tileno) == 1) {
781                                                         /* Specified */
782                                                         if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {
783                                                                 fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);
784                                                                 return 1;
785                                                         }
786                                                         parameters->jpwl_max_tiles = tileno;
787
788                                                 } else if (!strcmp(token, "t")) {
789                                                         /* default */
790                                                         parameters->jpwl_max_tiles = tileno; /* auto for default size */
791
792                                                 } else {
793                                                         fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);
794                                                         return 1;
795                                                 };
796                                         }
797
798                                         /* next token or bust */
799                                         token = strtok(NULL, ",");
800                                 };
801                                 parameters->jpwl_correct = OPJ_TRUE;
802                                 fprintf(stdout, "JPWL correction capability activated\n");
803                                 fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);
804                         }
805                         break;  
806 #endif /* USE_JPWL */
807 /* <<UniPG */            
808
809                                 /* ----------------------------------------------------- */
810                         
811         default:
812             fprintf(stderr, "[WARNING] An invalid option has been ignored.\n");
813             break;
814                 }
815         }while(c != -1);
816
817         /* check for possible errors */
818         if(img_fol->set_imgdir==1){
819                 if(!(parameters->infile[0]==0)){
820             fprintf(stderr, "[ERROR] options -ImgDir and -i cannot be used together.\n");
821                         return 1;
822                 }
823                 if(img_fol->set_out_format == 0){
824             fprintf(stderr, "[ERROR] When -ImgDir is used, -OutFor <FORMAT> must be used.\n");
825             fprintf(stderr, "Only one format allowed.\n"
826                             "Valid format are PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA.\n");
827                         return 1;
828                 }
829                 if(!((parameters->outfile[0] == 0))){
830             fprintf(stderr, "[ERROR] options -ImgDir and -o cannot be used together.\n");
831                         return 1;
832                 }
833         }else{
834                 if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
835             fprintf(stderr, "[ERROR] Required parameters are missing\n"
836                             "Example: %s -i image.j2k -o image.pgm\n",argv[0]);
837             fprintf(stderr, "   Help: %s -h\n",argv[0]);
838                         return 1;
839                 }
840         }
841
842         return 0;
843 }
844
845 /* -------------------------------------------------------------------------- */
846 /**
847  * Parse decoding area input values
848  * separator = ","
849  */
850 /* -------------------------------------------------------------------------- */
851 int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1)
852 {
853         int it = 0;
854         int values[4];
855         char delims[] = ",";
856         char *result = NULL;
857         result = strtok( inArg, delims );
858
859         while( (result != NULL) && (it < 4 ) ) {
860                 values[it] = atoi(result);
861                 result = strtok( NULL, delims );
862                 it++;
863         }
864
865         if (it != 4) {
866                 return EXIT_FAILURE;
867         }
868         else{
869                 *DA_x0 = (OPJ_UINT32)values[0]; *DA_y0 = (OPJ_UINT32)values[1];
870                 *DA_x1 = (OPJ_UINT32)values[2]; *DA_y1 = (OPJ_UINT32)values[3];
871                 return EXIT_SUCCESS;
872         }
873 }
874
875 OPJ_FLOAT64 opj_clock(void) {
876 #ifdef _WIN32
877         /* _WIN32: use QueryPerformance (very accurate) */
878     LARGE_INTEGER freq , t ;
879     /* freq is the clock speed of the CPU */
880     QueryPerformanceFrequency(&freq) ;
881         /* cout << "freq = " << ((double) freq.QuadPart) << endl; */
882     /* t is the high resolution performance counter (see MSDN) */
883     QueryPerformanceCounter ( & t ) ;
884         return freq.QuadPart ? (t.QuadPart / (OPJ_FLOAT64)freq.QuadPart) : 0;
885 #else
886         /* Unix or Linux: use resource usage */
887     struct rusage t;
888     OPJ_FLOAT64 procTime;
889     /* (1) Get the rusage data structure at this moment (man getrusage) */
890     getrusage(0,&t);
891     /* (2) What is the elapsed time ? - CPU time = User time + System time */
892         /* (2a) Get the seconds */
893     procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec);
894     /* (2b) More precisely! Get the microseconds part ! */
895     return ( procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ;
896 #endif
897 }
898
899 /* -------------------------------------------------------------------------- */
900
901 /**
902 sample error callback expecting a FILE* client object
903 */
904 static void error_callback(const char *msg, void *client_data) {
905         (void)client_data;
906         fprintf(stdout, "[ERROR] %s", msg);
907 }
908 /**
909 sample warning callback expecting a FILE* client object
910 */
911 static void warning_callback(const char *msg, void *client_data) {
912         (void)client_data;
913         fprintf(stdout, "[WARNING] %s", msg);
914 }
915 /**
916 sample debug callback expecting no client object
917 */
918 static void info_callback(const char *msg, void *client_data) {
919         (void)client_data;
920         fprintf(stdout, "[INFO] %s", msg);
921 }
922
923 static void set_default_parameters(opj_decompress_parameters* parameters)
924 {
925         if (parameters) {
926                 memset(parameters, 0, sizeof(opj_decompress_parameters));
927                 
928                 /* default decoding parameters (command line specific) */
929                 parameters->decod_format = -1;
930                 parameters->cod_format = -1;
931                 
932                 /* default decoding parameters (core) */
933                 opj_set_default_decoder_parameters(&(parameters->core));
934         }
935 }
936
937 static void destroy_parameters(opj_decompress_parameters* parameters)
938 {
939         if (parameters) {
940                 if (parameters->precision) {
941                         free(parameters->precision);
942                         parameters->precision = NULL;
943                 }
944         }
945 }
946
947 /* -------------------------------------------------------------------------- */
948
949 static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
950 {
951         OPJ_UINT32 compno;
952         opj_image_t* l_new_image = NULL;
953         opj_image_cmptparm_t* l_new_components = NULL;
954         
955         l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t));
956         if (l_new_components == NULL) {
957                 fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
958                 opj_image_destroy(original);
959                 return NULL;
960         }
961         
962         l_new_components[0].bpp  = l_new_components[1].bpp  = l_new_components[2].bpp  = original->comps[0].bpp;
963         l_new_components[0].dx   = l_new_components[1].dx   = l_new_components[2].dx   = original->comps[0].dx;
964         l_new_components[0].dy   = l_new_components[1].dy   = l_new_components[2].dy   = original->comps[0].dy;
965         l_new_components[0].h    = l_new_components[1].h    = l_new_components[2].h    = original->comps[0].h;
966         l_new_components[0].w    = l_new_components[1].w    = l_new_components[2].w    = original->comps[0].w;
967         l_new_components[0].prec = l_new_components[1].prec = l_new_components[2].prec = original->comps[0].prec;
968         l_new_components[0].sgnd = l_new_components[1].sgnd = l_new_components[2].sgnd = original->comps[0].sgnd;
969         l_new_components[0].x0   = l_new_components[1].x0   = l_new_components[2].x0   = original->comps[0].x0;
970         l_new_components[0].y0   = l_new_components[1].y0   = l_new_components[2].y0   = original->comps[0].y0;
971         
972         for(compno = 1U; compno < original->numcomps; ++compno) {
973                 l_new_components[compno+2U].bpp  = original->comps[compno].bpp;
974                 l_new_components[compno+2U].dx   = original->comps[compno].dx;
975                 l_new_components[compno+2U].dy   = original->comps[compno].dy;
976                 l_new_components[compno+2U].h    = original->comps[compno].h;
977                 l_new_components[compno+2U].w    = original->comps[compno].w;
978                 l_new_components[compno+2U].prec = original->comps[compno].prec;
979                 l_new_components[compno+2U].sgnd = original->comps[compno].sgnd;
980                 l_new_components[compno+2U].x0   = original->comps[compno].x0;
981                 l_new_components[compno+2U].y0   = original->comps[compno].y0;
982         }
983         
984         l_new_image = opj_image_create(original->numcomps + 2U, l_new_components, OPJ_CLRSPC_SRGB);
985         free(l_new_components);
986         if (l_new_image == NULL) {
987                 fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
988                 opj_image_destroy(original);
989                 return NULL;
990         }
991         
992         l_new_image->x0 = original->x0;
993         l_new_image->x1 = original->x1;
994         l_new_image->y0 = original->y0;
995         l_new_image->y1 = original->y1;
996         
997         l_new_image->comps[0].factor        = l_new_image->comps[1].factor        = l_new_image->comps[2].factor        = original->comps[0].factor;
998         l_new_image->comps[0].alpha         = l_new_image->comps[1].alpha         = l_new_image->comps[2].alpha         = original->comps[0].alpha;
999         l_new_image->comps[0].resno_decoded = l_new_image->comps[1].resno_decoded = l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded;
1000         
1001         memcpy(l_new_image->comps[0].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
1002         memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
1003         memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
1004         
1005         for(compno = 1U; compno < original->numcomps; ++compno) {
1006                 l_new_image->comps[compno+2U].factor        = original->comps[compno].factor;
1007                 l_new_image->comps[compno+2U].alpha         = original->comps[compno].alpha;
1008                 l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded;
1009                 memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
1010         }
1011         opj_image_destroy(original);
1012         return l_new_image;
1013 }
1014
1015 /* -------------------------------------------------------------------------- */
1016
1017 static opj_image_t* upsample_image_components(opj_image_t* original)
1018 {
1019         opj_image_t* l_new_image = NULL;
1020         opj_image_cmptparm_t* l_new_components = NULL;
1021         OPJ_BOOL l_upsample_need = OPJ_FALSE;
1022         OPJ_UINT32 compno;
1023
1024         for (compno = 0U; compno < original->numcomps; ++compno) {
1025                 if (original->comps[compno].factor > 0U) {
1026                         fprintf(stderr, "ERROR -> opj_decompress: -upsample not supported with reduction\n");
1027                         opj_image_destroy(original);
1028                         return NULL;
1029                 }
1030                 if ((original->comps[compno].dx > 1U) || (original->comps[compno].dy > 1U)) {
1031                         l_upsample_need = OPJ_TRUE;
1032                         break;
1033                 }
1034         }
1035         if (!l_upsample_need) {
1036                 return original;
1037         }
1038         /* Upsample is needed */
1039         l_new_components = (opj_image_cmptparm_t*)malloc(original->numcomps * sizeof(opj_image_cmptparm_t));
1040         if (l_new_components == NULL) {
1041                 fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for upsampled components!\n");
1042                 opj_image_destroy(original);
1043                 return NULL;
1044         }
1045         
1046         for (compno = 0U; compno < original->numcomps; ++compno) {
1047                 opj_image_cmptparm_t* l_new_cmp = &(l_new_components[compno]);
1048                 opj_image_comp_t*     l_org_cmp = &(original->comps[compno]);
1049                 
1050                 l_new_cmp->bpp  = l_org_cmp->bpp;
1051                 l_new_cmp->prec = l_org_cmp->prec;
1052                 l_new_cmp->sgnd = l_org_cmp->sgnd;
1053                 l_new_cmp->x0   = original->x0;
1054                 l_new_cmp->y0   = original->y0;
1055                 l_new_cmp->dx   = 1;
1056                 l_new_cmp->dy   = 1;
1057                 l_new_cmp->w    = l_org_cmp->w; /* should be original->x1 - original->x0 for dx==1 */
1058                 l_new_cmp->h    = l_org_cmp->h; /* should be original->y1 - original->y0 for dy==0 */
1059                 
1060                 if (l_org_cmp->dx > 1U) {
1061                         l_new_cmp->w = original->x1 - original->x0;
1062                 }
1063                 
1064                 if (l_org_cmp->dy > 1U) {
1065                         l_new_cmp->h = original->y1 - original->y0;
1066                 }
1067         }
1068         
1069         l_new_image = opj_image_create(original->numcomps, l_new_components, original->color_space);
1070         free(l_new_components);
1071         if (l_new_image == NULL) {
1072                 fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for upsampled components!\n");
1073                 opj_image_destroy(original);
1074                 return NULL;
1075         }
1076         
1077         l_new_image->x0 = original->x0;
1078         l_new_image->x1 = original->x1;
1079         l_new_image->y0 = original->y0;
1080         l_new_image->y1 = original->y1;
1081         
1082         for (compno = 0U; compno < original->numcomps; ++compno) {
1083                 opj_image_comp_t* l_new_cmp = &(l_new_image->comps[compno]);
1084                 opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
1085                 
1086                 l_new_cmp->factor        = l_org_cmp->factor;
1087                 l_new_cmp->alpha         = l_org_cmp->alpha;
1088                 l_new_cmp->resno_decoded = l_org_cmp->resno_decoded;
1089                 
1090                 if ((l_org_cmp->dx > 1U) || (l_org_cmp->dy > 1U)) {
1091                         const OPJ_INT32* l_src = l_org_cmp->data;
1092                         OPJ_INT32*       l_dst = l_new_cmp->data;
1093                         OPJ_UINT32 y;
1094                         OPJ_UINT32 xoff, yoff;
1095                         
1096                         /* need to take into account dx & dy */
1097                         xoff = l_org_cmp->dx * l_org_cmp->x0 -  original->x0;
1098                         yoff = l_org_cmp->dy * l_org_cmp->y0 -  original->y0;
1099                         if ((xoff >= l_org_cmp->dx) || (yoff >= l_org_cmp->dy)) {
1100                                 fprintf(stderr, "ERROR -> opj_decompress: Invalid image/component parameters found when upsampling\n");
1101                                 opj_image_destroy(original);
1102                                 opj_image_destroy(l_new_image);
1103                                 return NULL;
1104                         }
1105                         
1106                         for (y = 0U; y < yoff; ++y) {
1107                                 memset(l_dst, 0U, l_new_cmp->w * sizeof(OPJ_INT32));
1108                                 l_dst += l_new_cmp->w;
1109                         }
1110                         
1111                         if(l_new_cmp->h > (l_org_cmp->dy - 1U)) { /* check substraction overflow for really small images */
1112                                 for (; y < l_new_cmp->h - (l_org_cmp->dy - 1U); y += l_org_cmp->dy) {
1113                                         OPJ_UINT32 x, dy;
1114                                         OPJ_UINT32 xorg;
1115                                         
1116                                         xorg = 0U;
1117                                         for (x = 0U; x < xoff; ++x) {
1118                                                 l_dst[x] = 0;
1119                                         }
1120                                         if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */
1121                                                 for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) {
1122                                                         OPJ_UINT32 dx;
1123                                                         for (dx = 0U; dx < l_org_cmp->dx; ++dx) {
1124                                                                 l_dst[x + dx] = l_src[xorg];
1125                                                         }
1126                                                 }
1127                                         }
1128                                         for (; x < l_new_cmp->w; ++x) {
1129                                                 l_dst[x] = l_src[xorg];
1130                                         }
1131                                         l_dst += l_new_cmp->w;
1132                                                 
1133                                         for (dy = 1U; dy < l_org_cmp->dy; ++dy) {
1134                                                 memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(OPJ_INT32));
1135                                                 l_dst += l_new_cmp->w;
1136                                         }
1137                                         l_src += l_org_cmp->w;
1138                                 }
1139                         }
1140                         if (y < l_new_cmp->h) {
1141                                 OPJ_UINT32 x;
1142                                 OPJ_UINT32 xorg;
1143                                 
1144                                 xorg = 0U;
1145                                 for (x = 0U; x < xoff; ++x) {
1146                                         l_dst[x] = 0;
1147                                 }
1148                                 if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */
1149                                         for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) {
1150                                                 OPJ_UINT32 dx;
1151                                                 for (dx = 0U; dx < l_org_cmp->dx; ++dx) {
1152                                                         l_dst[x + dx] = l_src[xorg];
1153                                                 }
1154                                         }
1155                                 }
1156                                 for (; x < l_new_cmp->w; ++x) {
1157                                         l_dst[x] = l_src[xorg];
1158                                 }
1159                                 l_dst += l_new_cmp->w;
1160                                 ++y;
1161                                 for (; y < l_new_cmp->h; ++y) {
1162                                         memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(OPJ_INT32));
1163                                         l_dst += l_new_cmp->w;
1164                                 }
1165                         }
1166                 }
1167                 else {
1168                         memcpy(l_new_cmp->data, l_org_cmp->data, l_org_cmp->w * l_org_cmp->h * sizeof(OPJ_INT32));
1169                 }
1170         }
1171         opj_image_destroy(original);
1172         return l_new_image;
1173 }
1174
1175 /* -------------------------------------------------------------------------- */
1176 /**
1177  * OPJ_DECOMPRESS MAIN
1178  */
1179 /* -------------------------------------------------------------------------- */
1180 int main(int argc, char **argv)
1181 {
1182         opj_decompress_parameters parameters;                   /* decompression parameters */
1183         opj_image_t* image = NULL;
1184         opj_stream_t *l_stream = NULL;                          /* Stream */
1185         opj_codec_t* l_codec = NULL;                            /* Handle to a decompressor */
1186         opj_codestream_index_t* cstr_index = NULL;
1187
1188         OPJ_INT32 num_images, imageno;
1189         img_fol_t img_fol;
1190         dircnt_t *dirptr = NULL;
1191   int failed = 0;
1192   OPJ_FLOAT64 t, tCumulative = 0;
1193   OPJ_UINT32 numDecompressedImages = 0;
1194
1195         /* set decoding parameters to default values */
1196         set_default_parameters(&parameters);
1197
1198         /* Initialize img_fol */
1199         memset(&img_fol,0,sizeof(img_fol_t));
1200
1201         /* parse input and get user encoding parameters */
1202         if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol) == 1) {
1203                 destroy_parameters(&parameters);
1204                 return EXIT_FAILURE;
1205         }
1206
1207         /* Initialize reading of directory */
1208         if(img_fol.set_imgdir==1){      
1209                 int it_image;
1210                 num_images=get_num_images(img_fol.imgdirpath);
1211
1212                 dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
1213                 if(dirptr){
1214                         dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char));     /* Stores at max 10 image file names*/
1215                         dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*));
1216
1217                         if(!dirptr->filename_buf){
1218                                 destroy_parameters(&parameters);
1219                                 return EXIT_FAILURE;
1220                         }
1221                         for(it_image=0;it_image<num_images;it_image++){
1222                                 dirptr->filename[it_image] = dirptr->filename_buf + it_image*OPJ_PATH_LEN;
1223                         }
1224                 }
1225                 if(load_images(dirptr,img_fol.imgdirpath)==1){
1226                         destroy_parameters(&parameters);
1227                         return EXIT_FAILURE;
1228                 }
1229                 if (num_images==0){
1230                         fprintf(stdout,"Folder is empty\n");
1231                         destroy_parameters(&parameters);
1232                         return EXIT_FAILURE;
1233                 }
1234         }else{
1235                 num_images=1;
1236         }
1237
1238         /*Decoding image one by one*/
1239         for(imageno = 0; imageno < num_images ; imageno++)      {
1240
1241                 fprintf(stderr,"\n");
1242
1243                 if(img_fol.set_imgdir==1){
1244                         if (get_next_file(imageno, dirptr,&img_fol, &parameters)) {
1245                                 fprintf(stderr,"skipping file...\n");
1246                                 destroy_parameters(&parameters);
1247                                 continue;
1248                         }
1249                 }
1250
1251                 /* read the input file and put it in memory */
1252                 /* ---------------------------------------- */
1253
1254                 l_stream = opj_stream_create_default_file_stream(parameters.infile,1);
1255                 if (!l_stream){
1256                         fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile);
1257                         destroy_parameters(&parameters);
1258                         return EXIT_FAILURE;
1259                 }
1260
1261                 /* decode the JPEG2000 stream */
1262                 /* ---------------------- */
1263
1264                 switch(parameters.decod_format) {
1265                         case J2K_CFMT:  /* JPEG-2000 codestream */
1266                         {
1267                                 /* Get a decoder handle */
1268                                 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
1269                                 break;
1270                         }
1271                         case JP2_CFMT:  /* JPEG 2000 compressed image data */
1272                         {
1273                                 /* Get a decoder handle */
1274                                 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
1275                                 break;
1276                         }
1277                         case JPT_CFMT:  /* JPEG 2000, JPIP */
1278                         {
1279                                 /* Get a decoder handle */
1280                                 l_codec = opj_create_decompress(OPJ_CODEC_JPT);
1281                                 break;
1282                         }
1283                         default:
1284                                 fprintf(stderr, "skipping file..\n");
1285                                 destroy_parameters(&parameters);
1286                                 opj_stream_destroy(l_stream);
1287                                 continue;
1288                 }
1289
1290                 /* catch events using our callbacks and give a local context */         
1291                 opj_set_info_handler(l_codec, info_callback,00);
1292                 opj_set_warning_handler(l_codec, warning_callback,00);
1293                 opj_set_error_handler(l_codec, error_callback,00);
1294
1295                 t = opj_clock();
1296
1297                 /* Setup the decoder decoding parameters using user parameters */
1298                 if ( !opj_setup_decoder(l_codec, &(parameters.core)) ){
1299                         fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n");
1300                         destroy_parameters(&parameters);
1301                         opj_stream_destroy(l_stream);
1302                         opj_destroy_codec(l_codec);
1303                         return EXIT_FAILURE;
1304                 }
1305
1306
1307                 /* Read the main header of the codestream and if necessary the JP2 boxes*/
1308                 if(! opj_read_header(l_stream, l_codec, &image)){
1309                         fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n");
1310                         destroy_parameters(&parameters);
1311                         opj_stream_destroy(l_stream);
1312                         opj_destroy_codec(l_codec);
1313                         opj_image_destroy(image);
1314                         return EXIT_FAILURE;
1315                 }
1316
1317                 if (!parameters.nb_tile_to_decode) {
1318                         /* Optional if you want decode the entire image */
1319                         if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0,
1320                                         (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){
1321                                 fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n");
1322                                 destroy_parameters(&parameters);
1323                                 opj_stream_destroy(l_stream);
1324                                 opj_destroy_codec(l_codec);
1325                                 opj_image_destroy(image);
1326                                 return EXIT_FAILURE;
1327                         }
1328
1329                         /* Get the decoded image */
1330                         if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec,       l_stream))) {
1331                                 fprintf(stderr,"ERROR -> opj_decompress: failed to decode image!\n");
1332                                 destroy_parameters(&parameters);
1333                                 opj_destroy_codec(l_codec);
1334                                 opj_stream_destroy(l_stream);
1335                                 opj_image_destroy(image);
1336                                 return EXIT_FAILURE;
1337                         }
1338                 }
1339                 else {
1340
1341                         /* It is just here to illustrate how to use the resolution after set parameters */
1342                         /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) {
1343                                 fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n");
1344                                 opj_destroy_codec(l_codec);
1345                                 opj_stream_destroy(l_stream);
1346                                 opj_image_destroy(image);
1347                                 return EXIT_FAILURE;
1348                         }*/
1349
1350                         if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) {
1351                                 fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n");
1352                                 destroy_parameters(&parameters);
1353                                 opj_destroy_codec(l_codec);
1354                                 opj_stream_destroy(l_stream);
1355                                 opj_image_destroy(image);
1356                                 return EXIT_FAILURE;
1357                         }
1358                         fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index);
1359                 }
1360
1361                 tCumulative += opj_clock() - t;
1362                 numDecompressedImages++;
1363
1364                 /* Close the byte stream */
1365                 opj_stream_destroy(l_stream);
1366
1367                 if( image->color_space != OPJ_CLRSPC_SYCC 
1368                         && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy
1369                         && image->comps[1].dx != 1 )
1370                         image->color_space = OPJ_CLRSPC_SYCC;
1371                 else if (image->numcomps <= 2)
1372                         image->color_space = OPJ_CLRSPC_GRAY;
1373
1374                 if(image->color_space == OPJ_CLRSPC_SYCC){
1375                         color_sycc_to_rgb(image);
1376                 }
1377                 else if((image->color_space == OPJ_CLRSPC_CMYK) && (parameters.cod_format != TIF_DFMT)){
1378                         color_cmyk_to_rgb(image);
1379                 }
1380                 else if(image->color_space == OPJ_CLRSPC_EYCC){
1381                         color_esycc_to_rgb(image);
1382                 }
1383                 
1384                 if(image->icc_profile_buf) {
1385 #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
1386                         if(image->icc_profile_len)
1387                          color_apply_icc_profile(image);
1388                         else
1389                          color_cielab_to_rgb(image);
1390 #endif
1391                         free(image->icc_profile_buf);
1392                         image->icc_profile_buf = NULL; image->icc_profile_len = 0;
1393                 }
1394                 
1395                 /* Force output precision */
1396                 /* ---------------------- */
1397                 if (parameters.precision != NULL)
1398                 {
1399                         OPJ_UINT32 compno;
1400                         for (compno = 0; compno < image->numcomps; ++compno)
1401                         {
1402                                 OPJ_UINT32 precno = compno;
1403                                 OPJ_UINT32 prec;
1404                                 
1405                                 if (precno >= parameters.nb_precision) {
1406                                         precno = parameters.nb_precision - 1U;
1407                                 }
1408                                 
1409                                 prec = parameters.precision[precno].prec;
1410                                 if (prec == 0) {
1411                                         prec = image->comps[compno].prec;
1412                                 }
1413                                 
1414                                 switch (parameters.precision[precno].mode) {
1415                                         case OPJ_PREC_MODE_CLIP:
1416                                                 clip_component(&(image->comps[compno]), prec);
1417                                                 break;
1418                                         case OPJ_PREC_MODE_SCALE:
1419                                                 scale_component(&(image->comps[compno]), prec);
1420                                                 break;
1421                                         default:
1422                                                 break;
1423                                 }
1424                                 
1425                         }
1426                 }
1427                 
1428                 /* Upsample components */
1429                 /* ------------------- */
1430                 if (parameters.upsample)
1431                 {
1432                         image = upsample_image_components(image);
1433                         if (image == NULL) {
1434                                 fprintf(stderr, "ERROR -> opj_decompress: failed to upsample image components!\n");
1435                                 destroy_parameters(&parameters);
1436                                 opj_destroy_codec(l_codec);
1437                                 return EXIT_FAILURE;
1438                         }
1439                 }
1440                 
1441                 /* Force RGB output */
1442                 /* ---------------- */
1443                 if (parameters.force_rgb)
1444                 {
1445                         switch (image->color_space) {
1446                                 case OPJ_CLRSPC_SRGB:
1447                                         break;
1448                                 case OPJ_CLRSPC_GRAY:
1449                                         image = convert_gray_to_rgb(image);
1450                                         break;
1451                                 default:
1452                                         fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n");
1453                                         opj_image_destroy(image);
1454                                         image = NULL;
1455                                         break;
1456                         }
1457                         if (image == NULL) {
1458                                 fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n");
1459                                 destroy_parameters(&parameters);
1460                                 opj_destroy_codec(l_codec);
1461                                 return EXIT_FAILURE;
1462                         }
1463                 }
1464
1465                 /* create output image */
1466                 /* ------------------- */
1467                 switch (parameters.cod_format) {
1468                 case PXM_DFMT:                  /* PNM PGM PPM */
1469                         if (imagetopnm(image, parameters.outfile, parameters.split_pnm)) {
1470                 fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile);
1471         failed = 1;
1472                         }
1473                         else {
1474                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1475                         }
1476                         break;
1477
1478                 case PGX_DFMT:                  /* PGX */
1479                         if(imagetopgx(image, parameters.outfile)){
1480                 fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile);
1481         failed = 1;
1482                         }
1483                         else {
1484                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1485                         }
1486                         break;
1487
1488                 case BMP_DFMT:                  /* BMP */
1489                         if(imagetobmp(image, parameters.outfile)){
1490                 fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile);
1491         failed = 1;
1492                         }
1493                         else {
1494                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1495                         }
1496                         break;
1497 #ifdef OPJ_HAVE_LIBTIFF
1498                 case TIF_DFMT:                  /* TIFF */
1499                         if(imagetotif(image, parameters.outfile)){
1500                 fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile);
1501         failed = 1;
1502                         }
1503                         else {
1504                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1505                         }
1506                         break;
1507 #endif /* OPJ_HAVE_LIBTIFF */
1508                 case RAW_DFMT:                  /* RAW */
1509                         if(imagetoraw(image, parameters.outfile)){
1510                 fprintf(stderr,"[ERROR] Error generating raw file. Outfile %s not generated\n",parameters.outfile);
1511         failed = 1;
1512                         }
1513                         else {
1514                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1515                         }
1516                         break;
1517
1518                 case RAWL_DFMT:                 /* RAWL */
1519                         if(imagetorawl(image, parameters.outfile)){
1520                 fprintf(stderr,"[ERROR] Error generating rawl file. Outfile %s not generated\n",parameters.outfile);
1521         failed = 1;
1522                         }
1523                         else {
1524                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1525                         }
1526                         break;
1527
1528                 case TGA_DFMT:                  /* TGA */
1529                         if(imagetotga(image, parameters.outfile)){
1530                 fprintf(stderr,"[ERROR] Error generating tga file. Outfile %s not generated\n",parameters.outfile);
1531         failed = 1;
1532                         }
1533                         else {
1534                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1535                         }
1536                         break;
1537 #ifdef OPJ_HAVE_LIBPNG
1538                 case PNG_DFMT:                  /* PNG */
1539                         if(imagetopng(image, parameters.outfile)){
1540                 fprintf(stderr,"[ERROR] Error generating png file. Outfile %s not generated\n",parameters.outfile);
1541         failed = 1;
1542                         }
1543                         else {
1544                 fprintf(stdout,"[INFO] Generated Outfile %s\n",parameters.outfile);
1545                         }
1546                         break;
1547 #endif /* OPJ_HAVE_LIBPNG */
1548 /* Can happen if output file is TIFF or PNG
1549  * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined
1550 */
1551                         default:
1552                 fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile);
1553         failed = 1;
1554                 }
1555
1556                 /* free remaining structures */
1557                 if (l_codec) {
1558                         opj_destroy_codec(l_codec);
1559                 }
1560
1561
1562                 /* free image data structure */
1563                 opj_image_destroy(image);
1564
1565                 /* destroy the codestream index */
1566                 opj_destroy_cstr_index(&cstr_index);
1567
1568                 if(failed) (void)remove(parameters.outfile); /* ignore return value */
1569         }
1570         destroy_parameters(&parameters);
1571         if (numDecompressedImages) {
1572                 fprintf(stdout, "decode time: %d ms\n", (int)( (tCumulative * 1000.0) / (OPJ_FLOAT64)numDecompressedImages));
1573         }
1574         return failed ? EXIT_FAILURE : EXIT_SUCCESS;
1575 }
1576 /*end main*/