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