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