[trunk] fixed bug related to r2791
[openjpeg.git] / src / bin / jp3d / opj_jp3d_decompress.c
1 /*\r
2  * Copyright (c) 2001-2003, David Janssens\r
3  * Copyright (c) 2002-2003, Yannick Verschueren\r
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
5  * Copyright (c) 2005, Herve Drolon, FreeImage Team\r
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
7  * Copyright (c) 2006, M�nica D�ez Garc�a, Image Processing Laboratory, University of Valladolid, Spain\r
8  * All rights reserved.\r
9  *\r
10  * Redistribution and use in source and binary forms, with or without\r
11  * modification, are permitted provided that the following conditions\r
12  * are met:\r
13  * 1. Redistributions of source code must retain the above copyright\r
14  *    notice, this list of conditions and the following disclaimer.\r
15  * 2. Redistributions in binary form must reproduce the above copyright\r
16  *    notice, this list of conditions and the following disclaimer in the\r
17  *    documentation and/or other materials provided with the distribution.\r
18  *\r
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
29  * POSSIBILITY OF SUCH DAMAGE.\r
30  */\r
31 #include <stdio.h>\r
32 #include <string.h>\r
33 #include <stdlib.h>\r
34 #include <math.h>\r
35 \r
36 #include "opj_config.h"\r
37 #include "openjp3d.h"\r
38 #include "opj_getopt.h"\r
39 #include "convert.h"\r
40 \r
41 #ifdef _WIN32\r
42 #include <windows.h>\r
43 #else\r
44 #define stricmp strcasecmp\r
45 #define strnicmp strncasecmp\r
46 #endif /* _WIN32 */\r
47 \r
48 /* ----------------------------------------------------------------------- */\r
49 static double calc_PSNR(opj_volume_t *original, opj_volume_t *decoded)\r
50 {\r
51         int max, i, k, compno = 0, size;\r
52         double sum, total = 0;\r
53         int global = 1;\r
54     \r
55         max = (original->comps[compno].prec <= 8) ? 255 : (1 << original->comps[compno].prec) - 1;\r
56         if (global) {\r
57                 size = (original->x1 - original->x0) * (original->y1 - original->y0) * (original->z1 - original->z0);\r
58 \r
59                 for (compno = 0; compno < original->numcomps; compno++) {\r
60                         for(sum = 0, i = 0; i < size; ++i) {\r
61                                 if ((decoded->comps[compno].data[i] < 0) || (decoded->comps[compno].data[i] > max))\r
62                                         fprintf(stdout,"[WARNING] Data out of range during PSNR computing...\n");\r
63                                 else\r
64                                         sum += (original->comps[compno].data[i] - decoded->comps[compno].data[i]) * (original->comps[compno].data[i] - decoded->comps[compno].data[i]);        \r
65                         }\r
66                 }\r
67                 sum /= size;\r
68                 total = ((sum==0.0) ? 0.0 : 10 * log10(max * max / sum));\r
69         } else {\r
70                 size = (original->x1 - original->x0) * (original->y1 - original->y0);\r
71 \r
72                 for (k = 0; k < original->z1 - original->z0; k++) {\r
73                         int offset = k * size;\r
74                         for (sum = 0, compno = 0; compno < original->numcomps; compno++) {\r
75                                 for(i = 0; i < size; ++i) {\r
76                                         if ((decoded->comps[compno].data[i + offset] < 0) || (decoded->comps[compno].data[i + offset] > max))\r
77                                                 fprintf(stdout,"[WARNING] Data out of range during PSNR computing...\n");\r
78                                         else\r
79                                                 sum += (original->comps[compno].data[i + offset] - decoded->comps[compno].data[i + offset]) * (original->comps[compno].data[i + offset] - decoded->comps[compno].data[i + offset]);        \r
80                                 }\r
81                         }\r
82                         sum /= size;\r
83                         total = total + ((sum==0.0) ? 0.0 : 10 * log10(max * max / sum));\r
84                 }\r
85 \r
86         }\r
87         if(total == 0) /* perfect reconstruction, PSNR should return infinity */\r
88                 return -1.0;\r
89         \r
90         return total;\r
91         /*return 20 * log10((max - 1) / sqrt(sum));*/\r
92 }\r
93 \r
94 static double calc_SSIM(opj_volume_t *original, opj_volume_t *decoded)\r
95 {\r
96         int max, i, compno = 0, size, sizeM;\r
97         double sum;\r
98         double mux = 0.0, muy = 0.0, sigmax = 0.0, sigmay = 0.0,\r
99                 sigmaxy = 0.0/*, structx = 0.0, structy = 0.0*/;\r
100         double lcomp,ccomp,scomp;\r
101         double C1,C2,C3;\r
102 \r
103         max = (original->comps[compno].prec <= 8) ? 255 : (1 << original->comps[compno].prec) - 1;\r
104         size = (original->x1 - original->x0) * (original->y1 - original->y0) * (original->z1 - original->z0);\r
105 \r
106         /*MSSIM*/\r
107 \r
108 /*      sizeM = size / (original->z1 - original->z0);*/\r
109 \r
110         sizeM = size;   \r
111         for(sum = 0, i = 0; i < sizeM; ++i) {\r
112                 /* First, the luminance of each signal is compared.*/\r
113                 mux += original->comps[compno].data[i];\r
114                 muy += decoded->comps[compno].data[i];\r
115         }\r
116         mux /= sizeM;\r
117         muy /= sizeM;\r
118         \r
119         /*We use the standard deviation (the square root of variance) as an estimate of the signal contrast.*/\r
120     for(sum = 0, i = 0; i < sizeM; ++i) {\r
121                 /* First, the luminance of each signal is compared.*/\r
122                 sigmax += (original->comps[compno].data[i] - mux) * (original->comps[compno].data[i] - mux);\r
123                 sigmay += (decoded->comps[compno].data[i] - muy) * (decoded->comps[compno].data[i] - muy);\r
124                 sigmaxy += (original->comps[compno].data[i] - mux) * (decoded->comps[compno].data[i] - muy);\r
125         }\r
126         sigmax /= sizeM - 1;\r
127         sigmay /= sizeM - 1;\r
128         sigmaxy /= sizeM - 1;\r
129         \r
130         sigmax = sqrt(sigmax);\r
131         sigmay = sqrt(sigmay);\r
132         sigmaxy = sqrt(sigmaxy);\r
133 \r
134         /*Third, the signal is normalized (divided) by its own standard deviation, */\r
135         /*so that the two signals being compared have unit standard deviation.*/\r
136 \r
137         /*Luminance comparison*/\r
138         C1 = (0.01 * max) * (0.01 * max);\r
139         lcomp = ((2 * mux * muy) + C1)/((mux*mux) + (muy*mux) + C1);\r
140         /*Constrast comparison*/\r
141         C2 = (0.03 * max) * (0.03 * max);\r
142         ccomp = ((2 * sigmax * sigmay) + C2)/((sigmax*sigmax) + (sigmay*sigmay) + C2);\r
143         /*Structure comparison*/\r
144         C3 = C2 / 2;\r
145         scomp = (sigmaxy + C3) / (sigmax * sigmay + C3);\r
146         /*Similarity measure*/\r
147 \r
148         sum = lcomp * ccomp * scomp;\r
149         return sum;\r
150 }\r
151 \r
152 void decode_help_display() {\r
153         fprintf(stdout,"HELP\n----\n\n");\r
154         fprintf(stdout,"- the -h option displays this help information on screen\n\n");\r
155 \r
156         fprintf(stdout,"List of parameters for the JPEG 2000 encoder:\n");\r
157         fprintf(stdout,"\n");\r
158         fprintf(stdout," Required arguments \n");\r
159         fprintf(stdout," ---------------------------- \n");\r
160         fprintf(stdout,"  -i <compressed file> ( *.jp3d, *.j3d )\n");\r
161         fprintf(stdout,"    Currently accepts J3D-files. The file type is identified based on its suffix.\n");\r
162         fprintf(stdout,"  -o <decompressed file> ( *.pgx, *.bin )\n");\r
163         fprintf(stdout,"    Currently accepts PGX-files and BIN-files. Binary data is written to the file (not ascii). \n");\r
164         fprintf(stdout,"    If a PGX filename is given, there will be as many output files as slices; \n");\r
165         fprintf(stdout,"    an indice starting from 0 will then be appended to the output filename,\n");\r
166         fprintf(stdout,"    just before the \"pgx\" extension.\n");\r
167         fprintf(stdout,"  -m <characteristics file> ( *.img ) \n");\r
168         fprintf(stdout,"    Required only for BIN-files. Ascii data of volume characteristics is written. \n");\r
169         fprintf(stdout,"\n");\r
170         fprintf(stdout," Optional  \n");\r
171         fprintf(stdout," ---------------------------- \n");\r
172         fprintf(stdout,"  -h \n ");\r
173         fprintf(stdout,"    Display the help information\n");\r
174         fprintf(stdout,"  -r <RFx,RFy,RFz>\n");\r
175         fprintf(stdout,"    Set the number of highest resolution levels to be discarded on each dimension. \n");\r
176         fprintf(stdout,"    The volume resolution is effectively divided by 2 to the power of the\n");\r
177         fprintf(stdout,"    number of discarded levels. The reduce factor is limited by the\n");\r
178         fprintf(stdout,"    smallest total number of decomposition levels among tiles.\n");\r
179         fprintf(stdout,"  -l <number of quality layers to decode>\n");\r
180         fprintf(stdout,"    Set the maximum number of quality layers to decode. If there are\n");\r
181         fprintf(stdout,"    less quality layers than the specified number, all the quality layers\n");\r
182         fprintf(stdout,"    are decoded. \n");\r
183         fprintf(stdout,"  -O original-file \n");\r
184     fprintf(stdout,"    This option offers the possibility to compute some quality results  \n");\r
185         fprintf(stdout,"    for the decompressed volume, like the PSNR value achieved or the global SSIM value.  \n");\r
186         fprintf(stdout,"    Needs the original file in order to compare with the new one.\n");\r
187     fprintf(stdout,"    NOTE: Only valid when -r option is 0,0,0 (both original and decompressed volumes have same resolutions) \n");\r
188     fprintf(stdout,"    NOTE: If original file is .BIN file, the volume characteristics file shall be defined with the -m option. \n");\r
189         fprintf(stdout,"    (i.e. -O original-BIN-file -m original-IMG-file) \n");\r
190         fprintf(stdout,"  -BE \n");\r
191         fprintf(stdout,"    Define that the recovered volume data will be saved with big endian byte order.\n");\r
192         fprintf(stdout,"    By default, little endian byte order is used.\n");\r
193         fprintf(stdout,"\n");\r
194 }\r
195 \r
196 /* -------------------------------------------------------------------------- */\r
197 \r
198 int get_file_format(char *filename) {\r
199         int i;\r
200         static const char *extension[] = {"pgx", "bin", "j3d", "jp3d", "j2k", "img"};\r
201         static const int format[] = { PGX_DFMT, BIN_DFMT, J3D_CFMT, J3D_CFMT, J2K_CFMT, IMG_DFMT};\r
202         char * ext = strrchr(filename, '.');\r
203         if(ext) {\r
204                 ext++;\r
205                 for(i = 0; i < sizeof(format) / sizeof(format[0]); i++) {\r
206                         if(strnicmp(ext, extension[i], 3) == 0) {\r
207                                 return format[i];\r
208                         }\r
209                 }\r
210         }\r
211 \r
212         return -1;\r
213 }\r
214 \r
215 /* -------------------------------------------------------------------------- */\r
216 \r
217 int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters) {\r
218         /* parse the command line */\r
219 \r
220         while (1) {\r
221                 int c = opj_getopt(argc, argv, "i:o:O:r:l:B:m:h");\r
222                 if (c == -1)                      \r
223                         break;\r
224                 switch (c) {\r
225                         case 'i':                       /* input file */\r
226                         {\r
227                                 char *infile = opj_optarg;\r
228                                 parameters->decod_format = get_file_format(infile);\r
229                                 switch(parameters->decod_format) {\r
230                                         case J3D_CFMT:\r
231                                         case J2K_CFMT:\r
232                                                 break;\r
233                                         default:\r
234                                                 fprintf(stdout, "[ERROR] Unknown format for infile %s [only *.j3d]!! \n", infile);\r
235                                                 return 1;\r
236                                                 break;\r
237                                 }\r
238                                 strncpy(parameters->infile, infile, MAX_PATH);\r
239                                 fprintf(stdout, "[INFO] Infile: %s \n", parameters->infile);\r
240 \r
241                         }\r
242                         break;\r
243 \r
244                         case 'm':                       /* img file */\r
245                         {\r
246                                 char *imgfile = opj_optarg;\r
247                                 int imgformat = get_file_format(imgfile);\r
248                                 switch(imgformat) {\r
249                                         case IMG_DFMT:\r
250                                                 break;\r
251                                         default:\r
252                                                 fprintf(stdout, "[ERROR] Unrecognized format for imgfile : %s [accept only *.img] !!\n\n", imgfile);\r
253                                                 return 1;\r
254                                                 break;\r
255                                 }\r
256                                 strncpy(parameters->imgfile, imgfile, MAX_PATH);\r
257                                 fprintf(stdout, "[INFO] Imgfile: %s Format: %d\n", parameters->imgfile, imgformat);\r
258                         }\r
259                         break;\r
260                                 \r
261                                 /* ----------------------------------------------------- */\r
262 \r
263                         case 'o':                       /* output file */\r
264                         {\r
265                                 char *outfile = opj_optarg;\r
266                                 parameters->cod_format = get_file_format(outfile);\r
267                                 switch(parameters->cod_format) {\r
268                                         case PGX_DFMT:\r
269                                         case BIN_DFMT:\r
270                                                 break;\r
271                                         default:\r
272                                                 fprintf(stdout, "[ERROR] Unrecognized format for outfile : %s [accept only *.pgx or *.bin] !!\n\n", outfile);\r
273                                                 return 1;\r
274                                                 break;\r
275                                 }\r
276                                 strncpy(parameters->outfile, outfile, MAX_PATH);\r
277                                 fprintf(stdout, "[INFO] Outfile: %s \n", parameters->outfile);\r
278 \r
279                         }\r
280                         break;\r
281                         \r
282                                 /* ----------------------------------------------------- */\r
283 \r
284                         case 'O':               /* Original image for PSNR computing */\r
285                         {\r
286                                 char *original = opj_optarg;\r
287                                 parameters->orig_format = get_file_format(original);\r
288                                 switch(parameters->orig_format) {\r
289                                         case PGX_DFMT:\r
290                                         case BIN_DFMT:\r
291                                                 break;\r
292                                         default:\r
293                                                 fprintf(stdout, "[ERROR] Unrecognized format for original file : %s [accept only *.pgx or *.bin] !!\n\n", original);\r
294                                                 return 1;\r
295                                                 break;\r
296                                 }\r
297                                 strncpy(parameters->original, original, MAX_PATH);\r
298                                 fprintf(stdout, "[INFO] Original file: %s \n", parameters->original);\r
299                         }\r
300                         break;\r
301 \r
302                                 /* ----------------------------------------------------- */\r
303             \r
304                         case 'r':               /* reduce option */\r
305                         {\r
306                                 /*sscanf(opj_optarg, "%d, %d, %d", &parameters->cp_reduce[0], &parameters->cp_reduce[1], &parameters->cp_reduce[2]);*/\r
307                                 int aux;\r
308                                 aux = sscanf(opj_optarg, "%d,%d,%d", &parameters->cp_reduce[0], &parameters->cp_reduce[1], &parameters->cp_reduce[2]);\r
309                                 if (aux == 2) \r
310                                         parameters->cp_reduce[2] = 0;\r
311                                 else if (aux == 1) {\r
312                                         parameters->cp_reduce[1] = parameters->cp_reduce[0];\r
313                                         parameters->cp_reduce[2] = 0;\r
314                                 }else if (aux == 0){\r
315                                         parameters->cp_reduce[0] = 0;\r
316                                         parameters->cp_reduce[1] = 0;\r
317                                         parameters->cp_reduce[2] = 0;\r
318                                 }\r
319                         }\r
320                         break;\r
321                         \r
322                                 /* ----------------------------------------------------- */\r
323 \r
324                         case 'l':               /* layering option */\r
325                         {\r
326                                 sscanf(opj_optarg, "%d", &parameters->cp_layer);\r
327                         }\r
328                         break;\r
329 \r
330                                 /* ----------------------------------------------------- */\r
331 \r
332                         case 'B':               /* BIGENDIAN vs. LITTLEENDIAN */\r
333                         {\r
334                                 parameters->bigendian = 1;\r
335                         }\r
336                         break;\r
337                         \r
338                                 /* ----------------------------------------------------- */\r
339 \r
340                         case 'L':               /* BIGENDIAN vs. LITTLEENDIAN */\r
341                         {\r
342                                 parameters->decod_format = LSE_CFMT;\r
343                         }\r
344                         break;\r
345                         \r
346                         /* ----------------------------------------------------- */\r
347                         \r
348                         case 'h':                       /* display an help description */\r
349                         {\r
350                                 decode_help_display();\r
351                                 return 1;\r
352                         }\r
353                         break;\r
354             \r
355                                 /* ----------------------------------------------------- */\r
356                         \r
357                         default:\r
358                                 fprintf(stdout,"[WARNING] This option is not valid \"-%c %s\"\n",c, opj_optarg);\r
359                                 break;\r
360                 }\r
361         }\r
362 \r
363         /* check for possible errors */\r
364 \r
365         if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {\r
366                 fprintf(stdout,"[ERROR] At least one required argument is missing\n Check jp3d_to_volume -help for usage information\n");\r
367                 return 1;\r
368         }\r
369 \r
370         return 0;\r
371 }\r
372 \r
373 /* -------------------------------------------------------------------------- */\r
374 \r
375 /**\r
376 sample error callback expecting a FILE* client object\r
377 */\r
378 void error_callback(const char *msg, void *client_data) {\r
379         FILE *stream = (FILE*)client_data;\r
380         fprintf(stream, "[ERROR] %s", msg);\r
381 }\r
382 /**\r
383 sample warning callback expecting a FILE* client object\r
384 */\r
385 void warning_callback(const char *msg, void *client_data) {\r
386         FILE *stream = (FILE*)client_data;\r
387         fprintf(stream, "[WARNING] %s", msg);\r
388 }\r
389 /**\r
390 sample debug callback expecting no client object\r
391 */\r
392 void info_callback(const char *msg, void *client_data) {\r
393         fprintf(stdout, "[INFO] %s", msg);\r
394 }\r
395 \r
396 /* -------------------------------------------------------------------------- */\r
397 \r
398 int main(int argc, char **argv) {\r
399 \r
400         opj_dparameters_t parameters;   /* decompression parameters */\r
401         opj_event_mgr_t event_mgr;              /* event manager */\r
402         opj_volume_t *volume = NULL;\r
403 \r
404         opj_volume_t *original = NULL;\r
405         opj_cparameters_t cparameters;  /* original parameters */\r
406 \r
407         FILE *fsrc = NULL;\r
408         unsigned char *src = NULL; \r
409         int file_length;\r
410         int decodeok;\r
411         double psnr, ssim;\r
412 \r
413         opj_dinfo_t* dinfo = NULL;      /* handle to a decompressor */\r
414         opj_cio_t *cio = NULL;\r
415 \r
416         /* configure the event callbacks (not required) */\r
417         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
418         event_mgr.error_handler = error_callback;\r
419         event_mgr.warning_handler = warning_callback;\r
420         event_mgr.info_handler = info_callback;\r
421 \r
422         /* set decoding parameters to default values */\r
423         opj_set_default_decoder_parameters(&parameters);\r
424 \r
425     /* parse input and get user decoding parameters */\r
426         strcpy(parameters.original,"NULL");\r
427         strcpy(parameters.imgfile,"NULL");\r
428         if(parse_cmdline_decoder(argc, argv, &parameters) == 1) {\r
429                 return 0;\r
430         }\r
431         \r
432         /* read the input file and put it in memory */\r
433         /* ---------------------------------------- */\r
434         fprintf(stdout, "[INFO] Loading %s file \n",parameters.decod_format==J3D_CFMT ? ".jp3d" : ".j2k");\r
435         fsrc = fopen(parameters.infile, "rb");\r
436         if (!fsrc) {\r
437                 fprintf(stdout, "[ERROR] Failed to open %s for reading\n", parameters.infile);\r
438                 return 1;\r
439         }  \r
440         fseek(fsrc, 0, SEEK_END);\r
441         file_length = ftell(fsrc);\r
442         fseek(fsrc, 0, SEEK_SET);\r
443         src = (unsigned char *) malloc(file_length);\r
444         fread(src, 1, file_length, fsrc);\r
445         fclose(fsrc);\r
446         \r
447         /* decode the code-stream */\r
448         /* ---------------------- */\r
449         if (parameters.decod_format == J3D_CFMT || parameters.decod_format == J2K_CFMT) {               \r
450                 /* get a JP3D or J2K decoder handle */\r
451                 if (parameters.decod_format == J3D_CFMT) \r
452                         dinfo = opj_create_decompress(CODEC_J3D);\r
453                 else if (parameters.decod_format == J2K_CFMT) \r
454                         dinfo = opj_create_decompress(CODEC_J2K);\r
455 \r
456                 /* catch events using our callbacks and give a local context */\r
457                 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);                   \r
458 \r
459                 /* setup the decoder decoding parameters using user parameters */\r
460                 opj_setup_decoder(dinfo, &parameters);\r
461 \r
462                 /* open a byte stream */\r
463                 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
464 \r
465                 /* decode the stream and fill the volume structure */\r
466                 volume = opj_decode(dinfo, cio);\r
467                 if(!volume) {\r
468                         fprintf(stdout, "[ERROR] jp3d_to_volume: failed to decode volume!\n");                          \r
469                         opj_destroy_decompress(dinfo);\r
470                         opj_cio_close(cio);\r
471                         return 1;\r
472                 }       \r
473 \r
474                 /* close the byte stream */\r
475                 opj_cio_close(cio);\r
476         }\r
477   \r
478         /* free the memory containing the code-stream */\r
479         free(src);\r
480         src = NULL;\r
481 \r
482         /* create output volume */\r
483         /* ------------------- */\r
484 \r
485         switch (parameters.cod_format) {\r
486                 case PGX_DFMT:                  /* PGX */\r
487                         decodeok = volumetopgx(volume, parameters.outfile);\r
488                         if (decodeok)\r
489                                 fprintf(stdout,"[ERROR] Unable to write decoded volume into pgx files\n");\r
490                         break;\r
491                 \r
492                 case BIN_DFMT:                  /* BMP */\r
493                         decodeok = volumetobin(volume, parameters.outfile);\r
494                         if (decodeok)\r
495                                 fprintf(stdout,"[ERROR] Unable to write decoded volume into pgx files\n");\r
496                         break;\r
497         }\r
498         switch (parameters.orig_format) {\r
499                 case PGX_DFMT:                  /* PGX */\r
500                         if (strcmp("NULL",parameters.original) != 0){\r
501                                 fprintf(stdout,"Loading original file %s \n",parameters.original);\r
502                                 cparameters.subsampling_dx = 1; cparameters.subsampling_dy = 1; cparameters.subsampling_dz = 1;\r
503                                 cparameters.volume_offset_x0 = 0;cparameters.volume_offset_y0 = 0;cparameters.volume_offset_z0 = 0;\r
504                                 original = pgxtovolume(parameters.original,&cparameters);\r
505                         }\r
506                         break;\r
507                 \r
508                 case BIN_DFMT:                  /* BMP */\r
509                         if (strcmp("NULL",parameters.original) != 0 && strcmp("NULL",parameters.imgfile) != 0){\r
510                                 fprintf(stdout,"Loading original file %s %s\n",parameters.original,parameters.imgfile);\r
511                                 cparameters.subsampling_dx = 1; cparameters.subsampling_dy = 1; cparameters.subsampling_dz = 1;\r
512                                 cparameters.volume_offset_x0 = 0;cparameters.volume_offset_y0 = 0;cparameters.volume_offset_z0 = 0;\r
513                                 original = bintovolume(parameters.original,parameters.imgfile,&cparameters);\r
514                         }\r
515                         break;\r
516         }\r
517 \r
518         fprintf(stdout, "[RESULT] Volume: %d x %d x %d (x %d bpv)\n ", \r
519                          (volume->comps[0].w >> volume->comps[0].factor[0]),\r
520                          (volume->comps[0].h >> volume->comps[0].factor[1]),\r
521                          (volume->comps[0].l >> volume->comps[0].factor[2]),\r
522         volume->comps[0].prec);\r
523 \r
524         if(original){\r
525                 psnr = calc_PSNR(original,volume);\r
526                 ssim = calc_SSIM(original,volume);\r
527                 if (psnr < 0.0)\r
528                         fprintf(stdout, "  PSNR: Inf , SSMI %f -- Perfect reconstruction!\n",ssim);\r
529                 else\r
530                         fprintf(stdout, "  PSNR: %f , SSIM %f \n",psnr,ssim);\r
531         }\r
532         /* free remaining structures */\r
533         if(dinfo) {\r
534                 opj_destroy_decompress(dinfo);\r
535         }\r
536 \r
537         /* free volume data structure */\r
538         opj_volume_destroy(volume);\r
539    \r
540         return 0;\r
541 }\r
542 \r