Fixed issues with generation of SOP marker.
[openjpeg.git] / codec / j2k_to_image.c
1 /*
2  * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2007, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7  * Copyright (c) 2005, Herve Drolon, FreeImage Team
8  * Copyright (c) 2006-2007, Parvatha Elangovan
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <math.h>
36
37 #include "openjpeg.h"
38 #include "compat/getopt.h"
39 #include "convert.h"
40 #include "dirent.h"
41
42 #ifndef WIN32
43 #define stricmp strcasecmp
44 #define strnicmp strncasecmp
45 #endif
46
47 /* ----------------------------------------------------------------------- */
48
49 #define J2K_CFMT 0
50 #define JP2_CFMT 1
51 #define JPT_CFMT 2
52
53 #define PXM_DFMT 10
54 #define PGX_DFMT 11
55 #define BMP_DFMT 12
56 #define YUV_DFMT 13
57 #define TIF_DFMT 14
58 #define RAW_DFMT 15
59 #define TGA_DFMT 16
60
61 /* ----------------------------------------------------------------------- */
62
63 typedef struct dircnt{
64         /** Buffer for holding images read from Directory*/
65         char *filename_buf;
66         /** Pointer to the buffer*/
67         char **filename;
68 }dircnt_t;
69
70
71 typedef struct img_folder{
72         /** The directory path of the folder containing input images*/
73         char *imgdirpath;
74         /** Output format*/
75         char *out_format;
76         /** Enable option*/
77         char set_imgdir;
78         /** Enable Cod Format for output*/
79         char set_out_format;
80
81 }img_fol_t;
82
83 void decode_help_display() {
84         fprintf(stdout,"HELP\n----\n\n");
85         fprintf(stdout,"- the -h option displays this help information on screen\n\n");
86
87 /* UniPG>> */
88         fprintf(stdout,"List of parameters for the JPEG 2000 "
89 #ifdef USE_JPWL
90                 "+ JPWL "
91 #endif /* USE_JPWL */
92                 "decoder:\n");
93 /* <<UniPG */
94         fprintf(stdout,"\n");
95         fprintf(stdout,"\n");
96         fprintf(stdout,"  -ImgDir \n");
97         fprintf(stdout,"        Image file Directory path \n");
98         fprintf(stdout,"  -OutFor \n");
99         fprintf(stdout,"    REQUIRED only if -ImgDir is used\n");
100         fprintf(stdout,"          Need to specify only format without filename <BMP>  \n");
101         fprintf(stdout,"    Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
102         fprintf(stdout,"  -i <compressed file>\n");
103         fprintf(stdout,"    REQUIRED only if an Input image directory not specified\n");
104         fprintf(stdout,"    Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
105         fprintf(stdout,"    is identified based on its suffix.\n");
106         fprintf(stdout,"  -o <decompressed file>\n");
107         fprintf(stdout,"    REQUIRED\n");
108         fprintf(stdout,"    Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA files\n");
109         fprintf(stdout,"    Binary data is written to the file (not ascii). If a PGX\n");
110         fprintf(stdout,"    filename is given, there will be as many output files as there are\n");
111         fprintf(stdout,"    components: an indice starting from 0 will then be appended to the\n");
112         fprintf(stdout,"    output filename, just before the \"pgx\" extension. If a PGM filename\n");
113         fprintf(stdout,"    is given and there are more than one component, only the first component\n");
114         fprintf(stdout,"    will be written to the file.\n");
115         fprintf(stdout,"  -r <reduce factor>\n");
116         fprintf(stdout,"    Set the number of highest resolution levels to be discarded. The\n");
117         fprintf(stdout,"    image resolution is effectively divided by 2 to the power of the\n");
118         fprintf(stdout,"    number of discarded levels. The reduce factor is limited by the\n");
119         fprintf(stdout,"    smallest total number of decomposition levels among tiles.\n");
120         fprintf(stdout,"  -l <number of quality layers to decode>\n");
121         fprintf(stdout,"    Set the maximum number of quality layers to decode. If there are\n");
122         fprintf(stdout,"    less quality layers than the specified number, all the quality layers\n");
123         fprintf(stdout,"    are decoded.\n");
124         fprintf(stdout,"  -x  \n"); 
125         fprintf(stdout,"    Create an index file *.Idx (-x index_name.Idx) \n");
126         fprintf(stdout,"\n");
127 /* UniPG>> */
128 #ifdef USE_JPWL
129         fprintf(stdout,"  -W <options>\n");
130         fprintf(stdout,"    Activates the JPWL correction capability, if the codestream complies.\n");
131         fprintf(stdout,"    Options can be a comma separated list of <param=val> tokens:\n");
132         fprintf(stdout,"    c, c=numcomps\n");
133         fprintf(stdout,"       numcomps is the number of expected components in the codestream\n");
134         fprintf(stdout,"       (search of first EPB rely upon this, default is %d)\n", JPWL_EXPECTED_COMPONENTS);
135 #endif /* USE_JPWL */
136 /* <<UniPG */
137         fprintf(stdout,"\n");
138 }
139
140 /* -------------------------------------------------------------------------- */
141
142 int get_num_images(char *imgdirpath){
143         DIR *dir;
144         struct dirent* content; 
145         int num_images = 0;
146
147         /*Reading the input images from given input directory*/
148
149         dir= opendir(imgdirpath);
150         if(!dir){
151                 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
152                 return 0;
153         }
154         
155         while((content=readdir(dir))!=NULL){
156                 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
157                         continue;
158                 num_images++;
159         }
160         return num_images;
161 }
162
163 int load_images(dircnt_t *dirptr, char *imgdirpath){
164         DIR *dir;
165         struct dirent* content; 
166         int i = 0;
167
168         /*Reading the input images from given input directory*/
169
170         dir= opendir(imgdirpath);
171         if(!dir){
172                 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
173                 return 1;
174         }else   {
175                 fprintf(stderr,"Folder opened successfully\n");
176         }
177         
178         while((content=readdir(dir))!=NULL){
179                 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
180                         continue;
181
182                 strcpy(dirptr->filename[i],content->d_name);
183                 i++;
184         }
185         return 0;       
186 }
187
188 int get_file_format(char *filename) {
189         unsigned int i;
190         static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "j2k", "jp2", "jpt", "j2c" };
191         static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT };
192         char * ext = strrchr(filename, '.');
193         if (ext == NULL)
194                 return -1;
195         ext++;
196         if(ext) {
197                 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
198                         if(strnicmp(ext, extension[i], 3) == 0) {
199                                 return format[i];
200                         }
201                 }
202         }
203
204         return -1;
205 }
206
207 char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
208         char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN];
209         char *temp_p, temp1[OPJ_PATH_LEN]="";
210
211         strcpy(image_filename,dirptr->filename[imageno]);
212         fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename);
213         parameters->decod_format = get_file_format(image_filename);
214         if (parameters->decod_format == -1)
215                 return 1;
216         sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename);
217         strncpy(parameters->infile, infilename, sizeof(infilename));
218
219         //Set output file
220         strcpy(temp_ofname,strtok(image_filename,"."));
221         while((temp_p = strtok(NULL,".")) != NULL){
222                 strcat(temp_ofname,temp1);
223                 sprintf(temp1,".%s",temp_p);
224         }
225         if(img_fol->set_out_format==1){
226                 sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format);
227                 strncpy(parameters->outfile, outfilename, sizeof(outfilename));
228         }
229         return 0;
230 }
231
232 /* ------------------------------------------------------------------------------------ */
233
234 /**
235 Create an index and write it to a file
236 @param cstr_info Codestream information 
237 @param index Index filename
238 @return Returns 0 if successful, returns 1 otherwise
239 */
240 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {
241         int tileno, compno, layno, resno, precno, pack_nb, x, y;
242         FILE *stream = NULL;
243         int tilepartno;
244
245         if (!cstr_info)         
246                 return 1;
247
248         stream = fopen(index, "w");
249         if (!stream) {
250                 fprintf(stderr, "failed to open index file [%s] for writing\n", index);
251                 return 1;
252         }
253         
254         fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
255         fprintf(stream, "%d\n", cstr_info->prog);
256         fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
257         fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
258         fprintf(stream, "%d\n", cstr_info->numcomps);
259         fprintf(stream, "%d\n", cstr_info->numlayers);
260         fprintf(stream, "%d\n", cstr_info->numdecompos);
261         
262         for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
263                 fprintf(stream, "[%d,%d] ", 
264                         (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno]));    /* based on tile 0 and component 0*/
265         }
266         fprintf(stream, "\n");
267         fprintf(stream, "%d\n", cstr_info->main_head_start);
268         fprintf(stream, "%d\n", cstr_info->main_head_end);
269         fprintf(stream, "%d\n", cstr_info->codestream_size);
270         
271         fprintf(stream, "\nINFO ON TILES\n");
272         fprintf(stream, "tileno start_pos  end_hd  end_tile   nbparts\n");
273         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
274                 fprintf(stream, "%4d %9d %9d %9d %9d\n",
275                         cstr_info->tile[tileno].tileno,
276                         cstr_info->tile[tileno].start_pos,
277                         cstr_info->tile[tileno].end_header,
278                         cstr_info->tile[tileno].end_pos,
279                         cstr_info->tile[tileno].num_tps);
280         }
281                 
282         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
283                 int start_pos, end_ph_pos, end_pos;
284                 int max_numdecompos = 0;
285                 pack_nb = 0;    
286
287                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
288                         if (max_numdecompos < cstr_info->numdecompos[compno])
289                                 max_numdecompos = cstr_info->numdecompos[compno];
290                 }
291
292                 fprintf(stream, "\nTILE %d DETAILS\n", tileno); 
293                 fprintf(stream, "part_nb tileno  num_packs  start_pos end_tph_pos   end_pos\n");
294                 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
295                         fprintf(stream, "%4d %9d  %9d  %9d %11d %9d\n",
296                                 tilepartno, tileno,
297                                 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
298                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
299                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
300                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
301                                 );
302                 if (cstr_info->prog == LRCP) {  /* LRCP */
303                         fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos\n");
304
305                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
306                                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
307                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
308                                                 int prec_max;
309                                                 if (resno > cstr_info->numdecompos[compno])
310                                                         break;
311                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
312                                                 for (precno = 0; precno < prec_max; precno++) {
313                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
314                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
315                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
316                                                         fprintf(stream, "%4d %6d %7d %5d %6d  %6d    %6d     %6d %7d\n",
317                                                                 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
318                                                         pack_nb++;
319                                                 }
320                                         }
321                                 }
322                         }
323                 } /* LRCP */
324                 else if (cstr_info->prog == RLCP) {     /* RLCP */
325
326                         fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
327
328                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
329                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
330                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
331                                                 int prec_max;
332                                                 if (resno > cstr_info->numdecompos[compno])
333                                                         break;
334                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
335                                                 for (precno = 0; precno < prec_max; precno++) {
336                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
337                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
338                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
339                                                         fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d   %9d %7d\n",
340                                                                 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
341                                                         pack_nb++;
342                                                 }
343                                         }
344                                 }
345                         }
346                 } /* RLCP */
347                 else if (cstr_info->prog == RPCL) {     /* RPCL */
348
349                         fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos\n"); 
350
351                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
352                                 /* I suppose components have same XRsiz, YRsiz */
353                                 int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
354                                 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
355                                 int x1 = x0 + cstr_info->tile_x;
356                                 int y1 = y0 + cstr_info->tile_y;
357                                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
358                                         int prec_max;
359                                         if (resno > cstr_info->numdecompos[compno])
360                                                         break;
361                                         prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
362                                         for (precno = 0; precno < prec_max; precno++) {
363                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
364                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
365                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
366                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
367                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
368                                                 for(y = y0; y < y1; y++) {                                                      
369                                                         if (precno_y*pcy == y ) {
370                                                                 for (x = x0; x < x1; x++) {                                                                     
371                                                                         if (precno_x*pcx == x ) {
372                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
373                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
374                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
375                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
376                                                                                         fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d   %9d %7d\n",
377                                                                                                 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos); 
378                                                                                         pack_nb++; 
379                                                                                 }
380                                                                         }
381                                                                 }/* x = x0..x1 */
382                                                         } 
383                                                 }  /* y = y0..y1 */
384                                         } /* precno */
385                                 } /* compno */
386                         } /* resno */
387                 } /* RPCL */
388                 else if (cstr_info->prog == PCRL) {     /* PCRL */
389                         /* I suppose components have same XRsiz, YRsiz */
390                         int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
391                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
392                         int x1 = x0 + cstr_info->tile_x;
393                         int y1 = y0 + cstr_info->tile_y;
394
395                         fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos\n"); 
396
397                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
398                                 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
399                                         int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
400                                         for (precno = 0; precno < prec_max; precno++) {
401                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
402                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
403                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
404                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
405                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
406                                                 for(y = y0; y < y1; y++) {                                                      
407                                                         if (precno_y*pcy == y ) {
408                                                                 for (x = x0; x < x1; x++) {                                                                     
409                                                                         if (precno_x*pcx == x ) {
410                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
411                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
412                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
413                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
414                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d\n",
415                                                                                                 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos); 
416                                                                                         pack_nb++; 
417                                                                                 }
418                                                                         }
419                                                                 }/* x = x0..x1 */
420                                                         } 
421                                                 }  /* y = y0..y1 */
422                                         } /* precno */
423                                 } /* resno */
424                         } /* compno */
425                 } /* PCRL */
426                 else {  /* CPRL */
427
428                         fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos\n"); 
429
430                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
431                                 /* I suppose components have same XRsiz, YRsiz */
432                                 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
433                                 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
434                                 int x1 = x0 + cstr_info->tile_x;
435                                 int y1 = y0 + cstr_info->tile_y;
436                                 
437                                 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
438                                         int prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
439                                         for (precno = 0; precno < prec_max; precno++) {
440                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
441                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
442                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
443                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
444                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
445                                                 for(y = y0; y < y1; y++) {
446                                                         if (precno_y*pcy == y ) {
447                                                                 for (x = x0; x < x1; x++) {
448                                                                         if (precno_x*pcx == x ) {
449                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
450                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
451                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
452                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
453                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d\n",
454                                                                                                 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos); 
455                                                                                         pack_nb++; 
456                                                                                 }
457                                                                         }
458                                                                 }/* x = x0..x1 */
459                                                         }
460                                                 } /* y = y0..y1 */
461                                         } /* precno */
462                                 } /* resno */
463                         } /* compno */
464                 } /* CPRL */   
465         } /* tileno */
466         
467         fclose(stream);
468
469         fprintf(stderr,"Generated index file %s\n", index);
470
471         return 0;
472 }
473
474 /* ------------------------------------------------------------------------------------ */
475
476 /* -------------------------------------------------------------------------- */
477 int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) {
478         /* parse the command line */
479         int totlen;
480         option_t long_option[]={
481                 {"ImgDir",REQ_ARG, NULL ,'y'},
482                 {"OutFor",REQ_ARG, NULL ,'O'},
483         };
484
485         const char optlist[] = "i:o:r:l:hx:"
486
487 /* UniPG>> */
488 #ifdef USE_JPWL
489                                         "W:"
490 #endif /* USE_JPWL */
491 /* <<UniPG */
492                                         ;
493         totlen=sizeof(long_option);
494         img_fol->set_out_format = 0;
495         while (1) {
496                 int c = getopt_long(argc, argv,optlist,long_option,totlen);
497                 if (c == -1)
498                         break;
499                 switch (c) {
500                         case 'i':                       /* input file */
501                         {
502                                 char *infile = optarg;
503                                 parameters->decod_format = get_file_format(infile);
504                                 switch(parameters->decod_format) {
505                                         case J2K_CFMT:
506                                         case JP2_CFMT:
507                                         case JPT_CFMT:
508                                                 break;
509                                         default:
510                                                 fprintf(stderr, 
511                                                         "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n", 
512                                                         infile);
513                                                 return 1;
514                                 }
515                                 strncpy(parameters->infile, infile, sizeof(parameters->infile)-1);
516                         }
517                         break;
518                                 
519                                 /* ----------------------------------------------------- */
520
521                         case 'o':                       /* output file */
522                         {
523                                 char *outfile = optarg;
524                                 parameters->cod_format = get_file_format(outfile);
525                                 switch(parameters->cod_format) {
526                                         case PGX_DFMT:
527                                         case PXM_DFMT:
528                                         case BMP_DFMT:
529                                         case TIF_DFMT:
530                                         case RAW_DFMT:
531                                         case TGA_DFMT:
532                                                 break;
533                                         default:
534                                                 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile);
535                                                 return 1;
536                                 }
537                                 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
538                         }
539                         break;
540                         
541                                 /* ----------------------------------------------------- */
542
543                         case 'O':                       /* output format */
544                         {
545                                 char outformat[50];
546                                 char *of = optarg;
547                                 sprintf(outformat,".%s",of);
548                                 img_fol->set_out_format = 1;
549                                 parameters->cod_format = get_file_format(outformat);
550                                 switch(parameters->cod_format) {
551                                         case PGX_DFMT:
552                                                 img_fol->out_format = "pgx";
553                                                 break;
554                                         case PXM_DFMT:
555                                                 img_fol->out_format = "ppm";
556                                                 break;
557                                         case BMP_DFMT:
558                                                 img_fol->out_format = "bmp";
559                                                 break;
560                                         case TIF_DFMT:
561                                                 img_fol->out_format = "tif";
562                                                 break;
563                                         case RAW_DFMT:
564                                                 img_fol->out_format = "raw";
565                                                 break;
566                                         case TGA_DFMT:
567                                                 img_fol->out_format = "raw";
568                                                 break;
569                                         default:
570                                                 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat);
571                                                 return 1;
572                                                 break;
573                                 }
574                         }
575                         break;
576
577                                 /* ----------------------------------------------------- */
578
579
580                         case 'r':               /* reduce option */
581                         {
582                                 sscanf(optarg, "%d", &parameters->cp_reduce);
583                         }
584                         break;
585                         
586                                 /* ----------------------------------------------------- */
587       
588
589                         case 'l':               /* layering option */
590                         {
591                                 sscanf(optarg, "%d", &parameters->cp_layer);
592                         }
593                         break;
594                         
595                                 /* ----------------------------------------------------- */
596
597                         case 'h':                       /* display an help description */
598                                 decode_help_display();
599                                 return 1;                               
600
601                                 /* ------------------------------------------------------ */
602
603                         case 'y':                       /* Image Directory path */
604                                 {
605                                         img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
606                                         strcpy(img_fol->imgdirpath,optarg);
607                                         img_fol->set_imgdir=1;
608                                 }
609                                 break;
610                                 /* ----------------------------------------------------- */                                                             
611                         case 'x':                       /* Creation of index file */
612                                 {
613                                         char *index = optarg;
614                                         strncpy(indexfilename, index, OPJ_PATH_LEN);
615                                 }
616                                 break;
617                                 /* ----------------------------------------------------- */
618                                 /* UniPG>> */
619 #ifdef USE_JPWL
620                         
621                         case 'W':                       /* activate JPWL correction */
622                         {
623                                 char *token = NULL;
624
625                                 token = strtok(optarg, ",");
626                                 while(token != NULL) {
627
628                                         /* search expected number of components */
629                                         if (*token == 'c') {
630
631                                                 static int compno;
632
633                                                 compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */
634
635                                                 if(sscanf(token, "c=%d", &compno) == 1) {
636                                                         /* Specified */
637                                                         if ((compno < 1) || (compno > 256)) {
638                                                                 fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);
639                                                                 return 1;
640                                                         }
641                                                         parameters->jpwl_exp_comps = compno;
642
643                                                 } else if (!strcmp(token, "c")) {
644                                                         /* default */
645                                                         parameters->jpwl_exp_comps = compno; /* auto for default size */
646
647                                                 } else {
648                                                         fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);
649                                                         return 1;
650                                                 };
651                                         }
652
653                                         /* search maximum number of tiles */
654                                         if (*token == 't') {
655
656                                                 static int tileno;
657
658                                                 tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */
659
660                                                 if(sscanf(token, "t=%d", &tileno) == 1) {
661                                                         /* Specified */
662                                                         if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {
663                                                                 fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);
664                                                                 return 1;
665                                                         }
666                                                         parameters->jpwl_max_tiles = tileno;
667
668                                                 } else if (!strcmp(token, "t")) {
669                                                         /* default */
670                                                         parameters->jpwl_max_tiles = tileno; /* auto for default size */
671
672                                                 } else {
673                                                         fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);
674                                                         return 1;
675                                                 };
676                                         }
677
678                                         /* next token or bust */
679                                         token = strtok(NULL, ",");
680                                 };
681                                 parameters->jpwl_correct = true;
682                                 fprintf(stdout, "JPWL correction capability activated\n");
683                                 fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);
684                         }
685                         break;  
686 #endif /* USE_JPWL */
687 /* <<UniPG */            
688
689                                 /* ----------------------------------------------------- */
690                         
691                         default:
692                                 fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, optarg);
693                                 break;
694                 }
695         }
696
697         /* check for possible errors */
698         if(img_fol->set_imgdir==1){
699                 if(!(parameters->infile[0]==0)){
700                         fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n");
701                         return 1;
702                 }
703                 if(img_fol->set_out_format == 0){
704                         fprintf(stderr, "Error: When -ImgDir is used, -OutFor <FORMAT> must be used !!\n");
705                         fprintf(stderr, "Only one format allowed! Valid format PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA!!\n");
706                         return 1;
707                 }
708                 if(!((parameters->outfile[0] == 0))){
709                         fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n");
710                         return 1;
711                 }
712         }else{
713                 if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
714                         fprintf(stderr, "Error: One of the options -i or -ImgDir must be specified\n");
715                         fprintf(stderr, "Error: When using -i, -o must be used\n");
716                         fprintf(stderr, "usage: image_to_j2k -i *.j2k/jp2/j2c -o *.pgm/ppm/pnm/pgx/bmp/tif/raw/tga(+ options)\n");
717                         return 1;
718                 }
719         }
720
721         return 0;
722 }
723
724 /* -------------------------------------------------------------------------- */
725
726 /**
727 sample error callback expecting a FILE* client object
728 */
729 void error_callback(const char *msg, void *client_data) {
730         FILE *stream = (FILE*)client_data;
731         fprintf(stream, "[ERROR] %s", msg);
732 }
733 /**
734 sample warning callback expecting a FILE* client object
735 */
736 void warning_callback(const char *msg, void *client_data) {
737         FILE *stream = (FILE*)client_data;
738         fprintf(stream, "[WARNING] %s", msg);
739 }
740 /**
741 sample debug callback expecting no client object
742 */
743 void info_callback(const char *msg, void *client_data) {
744         (void)client_data;
745         fprintf(stdout, "[INFO] %s", msg);
746 }
747
748 /* -------------------------------------------------------------------------- */
749
750 int main(int argc, char **argv) {
751         opj_dparameters_t parameters;   /* decompression parameters */
752         img_fol_t img_fol;
753         opj_event_mgr_t event_mgr;              /* event manager */
754         opj_image_t *image = NULL;
755         FILE *fsrc = NULL;
756         unsigned char *src = NULL;
757         int file_length;
758         int num_images;
759         int i,imageno;
760         dircnt_t *dirptr;
761         opj_dinfo_t* dinfo = NULL;      /* handle to a decompressor */
762         opj_cio_t *cio = NULL;
763         opj_codestream_info_t cstr_info;  /* Codestream information structure */
764         char indexfilename[OPJ_PATH_LEN];       /* index file name */
765
766         /* configure the event callbacks (not required) */
767         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
768         event_mgr.error_handler = error_callback;
769         event_mgr.warning_handler = warning_callback;
770         event_mgr.info_handler = info_callback;
771
772         /* set decoding parameters to default values */
773         opj_set_default_decoder_parameters(&parameters);
774
775         /* Initialize indexfilename and img_fol */
776         *indexfilename = 0;
777         memset(&img_fol,0,sizeof(img_fol_t));
778
779         /* parse input and get user encoding parameters */
780         if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol, indexfilename) == 1) {
781                 return 1;
782         }
783
784         /* Initialize reading of directory */
785         if(img_fol.set_imgdir==1){      
786                 num_images=get_num_images(img_fol.imgdirpath);
787
788                 dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
789                 if(dirptr){
790                         dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char));     // Stores at max 10 image file names
791                         dirptr->filename = (char**) malloc(num_images*sizeof(char*));
792
793                         if(!dirptr->filename_buf){
794                                 return 0;
795                         }
796                         for(i=0;i<num_images;i++){
797                                 dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN;
798                         }
799                 }
800                 if(load_images(dirptr,img_fol.imgdirpath)==1){
801                         return 0;
802                 }
803                 if (num_images==0){
804                         fprintf(stdout,"Folder is empty\n");
805                         return 0;
806                 }
807         }else{
808                 num_images=1;
809         }
810
811         /*Encoding image one by one*/
812         for(imageno = 0; imageno < num_images ; imageno++)      {
813                 image = NULL;
814                 fprintf(stderr,"\n");
815
816                 if(img_fol.set_imgdir==1){
817                         if (get_next_file(imageno, dirptr,&img_fol, &parameters)) {
818                                 fprintf(stderr,"skipping file...\n");
819                                 continue;
820                         }
821                 }
822
823                 /* read the input file and put it in memory */
824                 /* ---------------------------------------- */
825                 fsrc = fopen(parameters.infile, "rb");
826                 if (!fsrc) {
827                         fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
828                         return 1;
829                 }
830                 fseek(fsrc, 0, SEEK_END);
831                 file_length = ftell(fsrc);
832                 fseek(fsrc, 0, SEEK_SET);
833                 src = (unsigned char *) malloc(file_length);
834                 fread(src, 1, file_length, fsrc);
835                 fclose(fsrc);
836
837                 /* decode the code-stream */
838                 /* ---------------------- */
839
840                 switch(parameters.decod_format) {
841                 case J2K_CFMT:
842                 {
843                         /* JPEG-2000 codestream */
844
845                         /* get a decoder handle */
846                         dinfo = opj_create_decompress(CODEC_J2K);
847
848                         /* catch events using our callbacks and give a local context */
849                         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
850
851                         /* setup the decoder decoding parameters using user parameters */
852                         opj_setup_decoder(dinfo, &parameters);
853
854                         /* open a byte stream */
855                         cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
856
857                         /* decode the stream and fill the image structure */
858                         if (*indexfilename)                             // If need to extract codestream information
859                                 image = opj_decode_with_info(dinfo, cio, &cstr_info);
860                         else
861                                 image = opj_decode(dinfo, cio);
862                         if(!image) {
863                                 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
864                                 opj_destroy_decompress(dinfo);
865                                 opj_cio_close(cio);
866                                 return 1;
867                         }
868
869                         /* close the byte stream */
870                         opj_cio_close(cio);
871
872                         /* Write the index to disk */
873                         if (*indexfilename) {
874                                 char bSuccess;
875                                 bSuccess = write_index_file(&cstr_info, indexfilename);
876                                 if (bSuccess) {
877                                         fprintf(stderr, "Failed to output index file\n");
878                                 }
879                         }
880                 }
881                 break;
882
883                 case JP2_CFMT:
884                 {
885                         /* JPEG 2000 compressed image data */
886
887                         /* get a decoder handle */
888                         dinfo = opj_create_decompress(CODEC_JP2);
889
890                         /* catch events using our callbacks and give a local context */
891                         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
892
893                         /* setup the decoder decoding parameters using the current image and user parameters */
894                         opj_setup_decoder(dinfo, &parameters);
895
896                         /* open a byte stream */
897                         cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
898
899                         /* decode the stream and fill the image structure */
900                         if (*indexfilename)                             // If need to extract codestream information
901                                 image = opj_decode_with_info(dinfo, cio, &cstr_info);
902                         else
903                                 image = opj_decode(dinfo, cio);                 
904                         if(!image) {
905                                 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
906                                 opj_destroy_decompress(dinfo);
907                                 opj_cio_close(cio);
908                                 return 1;
909                         }
910
911                         /* close the byte stream */
912                         opj_cio_close(cio);
913
914                         /* Write the index to disk */
915                         if (*indexfilename) {
916                                 char bSuccess;
917                                 bSuccess = write_index_file(&cstr_info, indexfilename);
918                                 if (bSuccess) {
919                                         fprintf(stderr, "Failed to output index file\n");
920                                 }
921                         }
922                 }
923                 break;
924
925                 case JPT_CFMT:
926                 {
927                         /* JPEG 2000, JPIP */
928
929                         /* get a decoder handle */
930                         dinfo = opj_create_decompress(CODEC_JPT);
931
932                         /* catch events using our callbacks and give a local context */
933                         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
934
935                         /* setup the decoder decoding parameters using user parameters */
936                         opj_setup_decoder(dinfo, &parameters);
937
938                         /* open a byte stream */
939                         cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
940
941                         /* decode the stream and fill the image structure */
942                         if (*indexfilename)                             // If need to extract codestream information
943                                 image = opj_decode_with_info(dinfo, cio, &cstr_info);
944                         else
945                                 image = opj_decode(dinfo, cio);
946                         if(!image) {
947                                 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
948                                 opj_destroy_decompress(dinfo);
949                                 opj_cio_close(cio);
950                                 return 1;
951                         }
952
953                         /* close the byte stream */
954                         opj_cio_close(cio);
955
956                         /* Write the index to disk */
957                         if (*indexfilename) {
958                                 char bSuccess;
959                                 bSuccess = write_index_file(&cstr_info, indexfilename);
960                                 if (bSuccess) {
961                                         fprintf(stderr, "Failed to output index file\n");
962                                 }
963                         }
964                 }
965                 break;
966
967                 default:
968                         fprintf(stderr, "skipping file..\n");
969                         continue;
970         }
971
972                 /* free the memory containing the code-stream */
973                 free(src);
974                 src = NULL;
975
976                 /* create output image */
977                 /* ------------------- */
978                 switch (parameters.cod_format) {
979                 case PXM_DFMT:                  /* PNM PGM PPM */
980                         if (imagetopnm(image, parameters.outfile)) {
981                                 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
982                         }
983                         else {
984                                 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
985                         }
986                         break;
987
988                 case PGX_DFMT:                  /* PGX */
989                         if(imagetopgx(image, parameters.outfile)){
990                                 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
991                         }
992                         else {
993                                 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
994                         }
995                         break;
996
997                 case BMP_DFMT:                  /* BMP */
998                         if(imagetobmp(image, parameters.outfile)){
999                                 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
1000                         }
1001                         else {
1002                                 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
1003                         }
1004                         break;
1005
1006                 case TIF_DFMT:                  /* TIFF */
1007                         if(imagetotif(image, parameters.outfile)){
1008                                 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
1009                         }
1010                         else {
1011                                 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
1012                         }
1013                         break;
1014
1015                 case RAW_DFMT:                  /* RAW */
1016                         if(imagetoraw(image, parameters.outfile)){
1017                                 fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile);
1018                         }
1019                         else {
1020                                 fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
1021                         }
1022                         break;
1023
1024                 case TGA_DFMT:                  /* TGA */
1025                         if(imagetotga(image, parameters.outfile)){
1026                                 fprintf(stdout,"Error generating tga file. Outfile %s not generated\n",parameters.outfile);
1027                         }
1028                         else {
1029                                 fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
1030                         }
1031                         break;
1032                 }
1033
1034                 /* free remaining structures */
1035                 if(dinfo) {
1036                         opj_destroy_decompress(dinfo);
1037                 }
1038                 /* free codestream information structure */
1039                 if (*indexfilename)     
1040                         opj_destroy_cstr_info(&cstr_info);
1041                 /* free image data structure */
1042                 opj_image_destroy(image);
1043
1044         }
1045         return 0;
1046 }
1047 //end main
1048
1049
1050
1051