Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4758 | right-hear | 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 |
||
32 | #include |
||
33 | #include |
||
34 | #include |
||
35 | |||
36 | #include "../libjp3dvm/openjpeg3d.h" |
||
37 | #include "getopt.h" |
||
38 | #include "convert.h" |
||
39 | |||
40 | #ifdef _WIN32 |
||
41 | #include |
||
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 |
||
160 | fprintf(stdout," Currently accepts J3D-files. The file type is identified based on its suffix.\n"); |
||
161 | fprintf(stdout," -o |
||
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 |
||
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 |
||
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 |
||
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", ¶meters->cp_reduce[0], ¶meters->cp_reduce[1], ¶meters->cp_reduce[2]); |
||
306 | int aux; |
||
307 | aux = sscanf(optarg, "%d,%d,%d", ¶meters->cp_reduce[0], ¶meters->cp_reduce[1], ¶meters->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", ¶meters->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(¶meters); |
||
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, ¶meters) == 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, ¶meters); |
||
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 |