Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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