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