solve some obvious warnings for WIN platform, increase number of warning reported...
[openjpeg.git] / tests / comparePGXimages.c
1 /*
2  * comparePGXimages.c
3  *
4  *  Created on: 8 juil. 2011
5  *      Author: mickael
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <string.h>
12 #include <ctype.h>
13
14 #include "opj_config.h"
15 #include "getopt.h"
16
17 #include "openjpeg.h"
18 #include "format_defs.h"
19 #include "convert.h"
20
21 double* parseToleranceValues( char* inArg, const int nbcomp);
22 void comparePGXimages_help_display(void);
23 opj_image_t* readImageFromFilePGX(char* filename, int nbFilenamePGX, char *separator);
24 #ifdef HAVE_LIBPNG
25 int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select);
26 #endif
27
28 typedef struct test_cmp_parameters
29 {
30   /**  */
31   char* base_filename;
32   /**  */
33   char* test_filename;
34   /** Number of components */
35   int nbcomp;
36   /**  */
37   double* tabMSEvalues;
38   /**  */
39   double* tabPEAKvalues;
40   /**  */
41   int nr_flag;
42   /**  */
43   char separator_base[2];
44   /**  */
45   char separator_test[2];
46
47 } test_cmp_parameters;
48
49 /*******************************************************************************
50  * Command line help function
51  *******************************************************************************/
52 void comparePGXimages_help_display(void) {
53   fprintf(stdout,"\nList of parameters for the comparePGX function  \n");
54   fprintf(stdout,"\n");
55   fprintf(stdout,"  -b \t REQUIRED \t filename to the reference/baseline PGX image \n");
56   fprintf(stdout,"  -t \t REQUIRED \t filename to the test PGX image\n");
57   fprintf(stdout,"  -n \t REQUIRED \t number of component of the image (used to generate correct filename)\n");
58   fprintf(stdout,"  -m \t OPTIONAL \t list of MSE tolerances, separated by : (size must correspond to the number of component) of \n");
59   fprintf(stdout,"  -p \t OPTIONAL \t list of PEAK tolerances, separated by : (size must correspond to the number of component) \n");
60   fprintf(stdout,"  -s \t OPTIONAL \t 1 or 2 filename separator to take into account PGX image with different components, "
61                                       "please indicate b or t before separator to indicate respectively the separator "
62                                       "for ref/base file and for test file.  \n");
63   fprintf(stdout,"  -r \t OPTIONAL \t indicate if you want to run this function as conformance test or as non regression test\n");
64   fprintf(stdout,"\n");
65 }
66
67 /*******************************************************************************
68  * Parse command line
69  *******************************************************************************/
70 int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
71 {
72   char *MSElistvalues = NULL;  char *PEAKlistvalues= NULL;
73   char *separatorList = NULL;
74   int sizemembasefile, sizememtestfile;
75   int index, flagM=0, flagP=0;
76   const char optlist[] = "b:t:n:m:p:s:d";
77   int c;
78
79   // Init parameters
80   param->base_filename = NULL;
81   param->test_filename = NULL;
82   param->nbcomp = 0;
83   param->tabMSEvalues = NULL;
84   param->tabPEAKvalues = NULL;
85   param->nr_flag = 0;
86
87   opterr = 0;
88
89   while ((c = getopt(argc, argv, optlist)) != -1)
90     switch (c)
91       {
92       case 'b':
93         sizemembasefile = (int)strlen(optarg)+1;
94         param->base_filename = (char*) malloc(sizemembasefile);
95         param->base_filename[0] = '\0';
96         strncpy(param->base_filename, optarg, strlen(optarg));
97         param->base_filename[strlen(optarg)] = '\0';
98         //printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );
99         break;
100       case 't':
101         sizememtestfile = (int) strlen(optarg) + 1;
102         param->test_filename = (char*) malloc(sizememtestfile);
103         param->test_filename[0] = '\0';
104         strncpy(param->test_filename, optarg, strlen(optarg));
105         param->test_filename[strlen(optarg)] = '\0';
106         //printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);
107        break;
108       case 'n':
109         param->nbcomp = atoi(optarg);
110         break;
111       case 'm':
112         MSElistvalues = optarg;
113         flagM = 1;
114         break;
115       case 'p':
116         PEAKlistvalues = optarg;
117         flagP = 1;
118         break;
119       case 'd':
120         param->nr_flag = 1;
121         break;
122       case 's':
123         separatorList = optarg;
124         break;
125       case '?':
126         if ((optopt == 'b') || (optopt == 't') || (optopt == 'n') || (optopt == 'p') || (optopt == 'm') || (optopt
127             == 's'))
128           fprintf(stderr, "Option -%c requires an argument.\n", optopt);
129         else
130           if (isprint(optopt)) fprintf(stderr, "Unknown option `-%c'.\n", optopt);
131           else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
132         return 1;
133       default:
134         fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, optarg);
135         break;
136       }
137
138   if (optind != argc)
139     {
140     for (index = optind; index < argc; index++)
141       fprintf(stderr,"Non-option argument %s\n", argv[index]);
142     return EXIT_FAILURE;
143     }
144
145   if (param->nbcomp == 0)
146     {
147     fprintf(stderr,"Need to indicate the number of components !\n");
148     return EXIT_FAILURE;
149     }
150   else
151     {
152     if ( flagM && flagP )
153       {
154       param->tabMSEvalues = parseToleranceValues( MSElistvalues, param->nbcomp);
155       param->tabPEAKvalues = parseToleranceValues( PEAKlistvalues, param->nbcomp);
156       if ( (param->tabMSEvalues == NULL) || (param->tabPEAKvalues == NULL))
157         {
158         fprintf(stderr,"MSE and PEAK values are not correct (respectively need %d values)\n",param->nbcomp);
159         return EXIT_FAILURE;
160         }
161       }
162     /*else
163       {
164
165       }*/
166     }
167
168   // Get separators after corresponding letter (b or t)
169   if (separatorList != NULL)
170     {
171     if( (strlen(separatorList) ==2) || (strlen(separatorList) ==4) )
172       {
173       // keep original string
174       int sizeseplist = (int)strlen(separatorList)+1;
175       char* separatorList2 = (char*)malloc( sizeseplist );
176       separatorList2[0] = '\0';
177       strncpy(separatorList2, separatorList, strlen(separatorList));
178       separatorList2[strlen(separatorList)] = '\0';
179       //printf("separatorList2 = %s [%d / %d]\n", separatorList2, strlen(separatorList2), sizeseplist);
180
181       if (strlen(separatorList) == 2) // one separator behind b or t
182         {
183         char *resultT = NULL;
184         resultT = strtok(separatorList2, "t");
185         if (strlen(resultT) == strlen(separatorList)) // didn't find t character, try to find b
186           {
187           char *resultB = NULL;
188           resultB = strtok(resultT, "b");
189           if (strlen(resultB) == 1)
190             {
191             param->separator_base[0] = separatorList[1];param->separator_base[1] = '\0';
192             param->separator_test[0] ='\0';
193             }
194           else // not found b
195             {
196             free(separatorList2);
197             return EXIT_FAILURE;
198             }
199           }
200         else // found t
201           {
202           param->separator_base[0] ='\0';
203           param->separator_test[0] = separatorList[1];param->separator_test[1] = '\0';
204           }
205         //printf("sep b = %s [%d] and sep t = %s [%d]\n",param->separator_base, strlen(param->separator_base), param->separator_test, strlen(param->separator_test) );
206         }
207       else // == 4 characters we must found t and b
208         {
209         char *resultT = NULL;
210         resultT = strtok(separatorList2, "t");
211         if (strlen(resultT) == 3) // found t in first place
212           {
213           char *resultB = NULL;
214           resultB = strtok(resultT, "b");
215           if (strlen(resultB) == 1) // found b after t
216             {
217             param->separator_test[0] = separatorList[1];param->separator_test[1] = '\0';
218             param->separator_base[0] = separatorList[3];param->separator_base[1] = '\0';
219             }
220           else // didn't find b after t
221             {
222             free(separatorList2);
223             return EXIT_FAILURE;
224             }
225           }
226         else // == 2, didn't find t in first place
227           {
228           char *resultB = NULL;
229           resultB = strtok(resultT, "b");
230           if (strlen(resultB) == 1) // found b in first place
231             {
232             param->separator_base[0] = separatorList[1]; param->separator_base[1] = '\0';
233             param->separator_test[0] = separatorList[3]; param->separator_test[1] = '\0';
234             }
235           else // didn't found b in first place => problem
236             {
237             free(separatorList2);
238             return EXIT_FAILURE;
239             }
240           }
241         }
242       free(separatorList2);
243       }
244     else // wrong number of argument after -s
245       {
246       return EXIT_FAILURE;
247       }
248     }
249   else
250     {
251     if (param->nbcomp == 1)
252       {
253       param->separator_base[0] = '\0';
254       param->separator_test[0] = '\0';
255       }
256     else
257       {
258       fprintf(stderr,"If number of component is > 1, we need separator\n");
259       return EXIT_FAILURE;
260       }
261     }
262
263
264   if ( (param->nr_flag) && (flagP || flagM) )
265     {
266     fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n");
267     return EXIT_FAILURE;
268     }
269   if ( (!param->nr_flag) && (!flagP || !flagM) )
270     {
271     fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n");
272     return EXIT_FAILURE;
273     }
274
275   return EXIT_SUCCESS;
276 }
277
278 /*******************************************************************************
279  * Parse MSE and PEAK input values (
280  * separator = ":"
281  *******************************************************************************/
282 double* parseToleranceValues( char* inArg, const int nbcomp)
283 {
284   double* outArgs= malloc(nbcomp * sizeof(double));
285   int it_comp = 0;
286   char delims[] = ":";
287   char *result = NULL;
288   result = strtok( inArg, delims );
289
290   while( (result != NULL) && (it_comp < nbcomp ))
291     {
292       outArgs[it_comp] = atof(result);
293       result = strtok( NULL, delims );
294       it_comp++;
295     }
296
297   if (it_comp != nbcomp)
298     return NULL;
299   else
300     return outArgs;
301 }
302 /*******************************************************************************
303  * Create filenames from a filename by used separator and nb components
304  * (begin to 0)
305  *******************************************************************************/
306 char* createMultiComponentsFilename(const char* inFilename, const int indexF, const char* separator)
307 {
308   char s[255];
309   char *outFilename, *ptr;
310   char token = '.';
311   int posToken = 0;
312
313   //printf("inFilename = %s\n", inFilename);
314   if ((ptr = strrchr(inFilename, token)) != NULL)
315     {
316     posToken = (int) (strlen(inFilename) - strlen(ptr));
317     //printf("Position of %c character inside inFilename = %d\n", token, posToken);
318     }
319   else
320     {
321     //printf("Token %c not found\n", token);
322     outFilename = (char*)malloc(1);
323     outFilename[0] = '\0';
324     return outFilename;
325     }
326
327   outFilename = (char*)malloc((posToken + 7) * sizeof(char)); //6
328
329   strncpy(outFilename, inFilename, posToken);
330
331   outFilename[posToken] = '\0';
332
333   strcat(outFilename, separator);
334
335   sprintf(s, "%i", indexF);
336   strcat(outFilename, s);
337
338   strcat(outFilename, ".pgx");
339
340   //printf("outfilename: %s\n", outFilename);
341   return outFilename;
342 }
343 /*******************************************************************************
344  *
345  *******************************************************************************/
346 opj_image_t* readImageFromFilePGX(char* filename, int nbFilenamePGX, char *separator)
347 {
348   int it_file;
349   opj_image_t* image_read = NULL;
350   opj_image_t* image = NULL;
351   opj_cparameters_t parameters;
352   opj_image_cmptparm_t* param_image_read;
353   int** data;
354
355   // If separator is empty => nb file to read is equal to one
356   if ( strlen(separator) == 0 )
357       nbFilenamePGX = 1;
358
359   /* set encoding parameters to default values */
360   opj_set_default_encoder_parameters(&parameters);
361   parameters.decod_format = PGX_DFMT;
362   strncpy(parameters.infile, filename, sizeof(parameters.infile)-1);
363
364   // Allocate memory
365   param_image_read = malloc(nbFilenamePGX * sizeof(opj_image_cmptparm_t));
366   data = malloc(nbFilenamePGX * sizeof(*data));
367
368   it_file = 0;
369   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
370     {
371     // Create the right filename
372     char *filenameComponentPGX;
373     if (strlen(separator) == 0)
374       {
375       filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX));
376       strcpy(filenameComponentPGX, filename);
377       }
378     else
379       filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator);
380
381     // Read the pgx file corresponding to the component
382     image_read = pgxtoimage(filenameComponentPGX, &parameters);
383     if (!image_read)
384       {
385       fprintf(stderr, "Unable to load pgx file\n");
386       return NULL;
387       }
388
389     // Set the image_read parameters
390     param_image_read[it_file].x0 = 0;
391     param_image_read[it_file].y0 = 0;
392     param_image_read[it_file].dx = 0;
393     param_image_read[it_file].dy = 0;
394     param_image_read[it_file].h = image_read->comps->h;
395     param_image_read[it_file].w = image_read->comps->w;
396     param_image_read[it_file].bpp = image_read->comps->bpp;
397     param_image_read[it_file].prec = image_read->comps->prec;
398     param_image_read[it_file].sgnd = image_read->comps->sgnd;
399
400     // Copy data
401     data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int));
402     memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int));
403
404     // Free memory
405     opj_image_destroy(image_read);
406     free(filenameComponentPGX);
407     }
408
409   image = opj_image_create(nbFilenamePGX, param_image_read, CLRSPC_UNSPECIFIED);
410   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
411     {
412     // Copy data into output image and free memory
413     memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int));
414     free(data[it_file]);
415     }
416
417   // Free memory
418   free(param_image_read);
419   free(data);
420
421   return image;
422 }
423
424 /*******************************************************************************
425  *
426  *******************************************************************************/
427 #ifdef HAVE_LIBPNG
428 int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select)
429 {
430   opj_image_cmptparm_t param_image_write;
431   opj_image_t* image_write = NULL;
432
433   param_image_write.x0 = 0;
434   param_image_write.y0 = 0;
435   param_image_write.dx = 0;
436   param_image_write.dy = 0;
437   param_image_write.h = image->comps[num_comp_select].h;
438   param_image_write.w = image->comps[num_comp_select].w;
439   param_image_write.bpp = image->comps[num_comp_select].bpp;
440   param_image_write.prec = image->comps[num_comp_select].prec;
441   param_image_write.sgnd = image->comps[num_comp_select].sgnd;
442
443   image_write = opj_image_create(1, &param_image_write, CLRSPC_GRAY);
444   memcpy(image_write->comps->data, image->comps[num_comp_select].data, param_image_write.h * param_image_write.w * sizeof(int));
445
446   imagetopng(image_write, filename);
447
448   opj_image_destroy(image_write);
449
450   return EXIT_SUCCESS;
451 }
452 #endif
453
454 /*******************************************************************************
455  * MAIN
456  *******************************************************************************/
457 int main(int argc, char **argv)
458 {
459   test_cmp_parameters inParam;
460   int it_comp, itpxl;
461   int failed = 0;
462   int nbFilenamePGXbase, nbFilenamePGXtest;
463   char *filenamePNGtest= NULL, *filenamePNGbase = NULL, *filenamePNGdiff = NULL;
464   int memsizebasefilename, memsizetestfilename, memsizedifffilename;
465   int valueDiff = 0, nbPixelDiff = 0;
466   double sumDiff = 0.0;
467   // Structures to store image parameters and data
468   opj_image_t *imageBase = NULL, *imageTest = NULL, *imageDiff = NULL;
469   opj_image_cmptparm_t* param_image_diff;
470
471   // Get parameters from command line
472   if( parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE )
473     {
474     comparePGXimages_help_display();
475     if (!inParam.tabMSEvalues) free(inParam.tabMSEvalues);
476     if (!inParam.tabPEAKvalues) free(inParam.tabPEAKvalues);
477     if (!inParam.base_filename) free(inParam.base_filename);
478     if (!inParam.test_filename) free(inParam.test_filename);
479     return EXIT_FAILURE;
480     }
481
482   // Display Parameters
483   printf("******Parameters********* \n");
484   printf(" base_filename = %s\n"
485          " test_filename = %s\n"
486          " nb of Components = %d\n"
487          " Non regression test = %d\n"
488          " separator Base = %s\n"
489          " separator Test = %s\n",
490          inParam.base_filename, inParam.test_filename, inParam.nbcomp,
491          inParam.nr_flag, inParam.separator_base, inParam.separator_test);
492
493   if ( (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL))
494   {
495     printf(" MSE values = [");
496     for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++)
497       printf(" %f ", inParam.tabMSEvalues[it_comp]);
498     printf("]\n");
499     printf(" PEAK values = [");
500     for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++)
501       printf(" %f ", inParam.tabPEAKvalues[it_comp]);
502     printf("]\n");
503     printf(" Non-regression test = %d\n", inParam.nr_flag);
504     }
505
506   if (strlen(inParam.separator_base) == 0)
507     nbFilenamePGXbase = 0;
508   else
509     nbFilenamePGXbase = inParam.nbcomp;
510
511   if (strlen(inParam.separator_test) == 0)
512     nbFilenamePGXtest = 0;
513   else
514     nbFilenamePGXtest = inParam.nbcomp;
515
516   printf(" NbFilename to generate from base filename = %d\n", nbFilenamePGXbase);
517   printf(" NbFilename to generate from test filename = %d\n", nbFilenamePGXtest);
518   printf("************************* \n");
519
520   //----------BASELINE IMAGE--------
521   //
522   memsizebasefilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
523   memsizetestfilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
524
525   imageBase = readImageFromFilePGX( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base);
526   if ( imageBase != NULL)
527     {
528     filenamePNGbase = (char*) malloc(memsizebasefilename);
529     filenamePNGbase[0] = '\0';
530     strncpy(filenamePNGbase, inParam.test_filename, strlen(inParam.test_filename));
531     filenamePNGbase[strlen(inParam.test_filename)] = '\0';
532     strcat(filenamePNGbase, ".base");
533     //printf("filenamePNGbase = %s [%d / %d octets]\n",filenamePNGbase, strlen(filenamePNGbase),memsizebasefilename );
534     }
535   else
536     {
537     if (!inParam.tabMSEvalues) free(inParam.tabMSEvalues);
538     if (!inParam.tabPEAKvalues) free(inParam.tabPEAKvalues);
539     if (!inParam.base_filename) free(inParam.base_filename);
540     if (!inParam.test_filename) free(inParam.test_filename);
541     return EXIT_FAILURE;
542     }
543
544   //----------TEST IMAGE--------
545   //
546
547   imageTest = readImageFromFilePGX(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test);
548   if ( imageTest != NULL)
549     {
550     filenamePNGtest = (char*) malloc(memsizetestfilename);
551     filenamePNGtest[0] = '\0';
552     strncpy(filenamePNGtest, inParam.test_filename, strlen(inParam.test_filename));
553     filenamePNGtest[strlen(inParam.test_filename)] = '\0';
554     strcat(filenamePNGtest, ".test");
555     //printf("filenamePNGtest = %s [%d / %d octets]\n",filenamePNGtest, strlen(filenamePNGtest),memsizetestfilename );
556     }
557   else
558     {
559     if (!inParam.tabMSEvalues) free(inParam.tabMSEvalues);
560     if (!inParam.tabPEAKvalues) free(inParam.tabPEAKvalues);
561     if (!inParam.base_filename) free(inParam.base_filename);
562     if (!inParam.test_filename) free(inParam.test_filename);
563     free(filenamePNGbase);
564     return EXIT_FAILURE;
565     }
566
567   //----------DIFF IMAGE--------
568   //
569
570   // Allocate memory
571   param_image_diff = malloc( imageBase->numcomps * sizeof(opj_image_cmptparm_t));
572
573   // Comparison of header parameters
574   printf("Step 1 -> Header comparison\n");
575
576   for (it_comp = 0; it_comp < imageBase->numcomps; it_comp++)
577     {
578     param_image_diff[it_comp].x0 = 0;
579     param_image_diff[it_comp].y0 = 0;
580     param_image_diff[it_comp].dx = 0;
581     param_image_diff[it_comp].dy = 0;
582
583     if (imageBase->comps[it_comp].sgnd != imageTest->comps[it_comp].sgnd)
584       {
585       printf("ERROR: sign mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).sgnd, ((imageTest->comps)[it_comp]).sgnd);
586       failed = 1;
587       }
588     else
589       param_image_diff[it_comp].sgnd = 0 ;
590
591     if (((imageBase->comps)[it_comp]).prec != ((imageTest->comps)[it_comp]).prec)
592       {
593       printf("ERROR: prec mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).prec, ((imageTest->comps)[it_comp]).prec);
594       failed = 1;
595       }
596     else
597       param_image_diff[it_comp].prec = 8 ;
598
599     if (((imageBase->comps)[it_comp]).bpp != ((imageTest->comps)[it_comp]).bpp)
600       {
601       printf("ERROR: byte per pixel mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).bpp, ((imageTest->comps)[it_comp]).bpp);
602       failed = 1;
603       }
604     else
605       param_image_diff[it_comp].bpp = 1 ;
606
607     if (((imageBase->comps)[it_comp]).h != ((imageTest->comps)[it_comp]).h)
608       {
609       printf("ERROR: height mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).h, ((imageTest->comps)[it_comp]).h);
610       failed = 1;
611       }
612     else
613       param_image_diff[it_comp].h = imageBase->comps[it_comp].h ;
614
615     if (((imageBase->comps)[it_comp]).w != ((imageTest->comps)[it_comp]).w)
616       {
617       printf("ERROR: width mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).w, ((imageTest->comps)[it_comp]).w);
618       failed = 1;
619       }
620     else
621       param_image_diff[it_comp].w = imageBase->comps[it_comp].w ;
622     }
623
624    // If only one parameter is different, we stop the test
625    if (failed)
626      {
627      free(inParam.tabMSEvalues);
628      free(inParam.tabPEAKvalues);
629      free(inParam.base_filename);
630      free(inParam.test_filename);
631
632      free(filenamePNGbase);
633      free(filenamePNGtest);
634
635      opj_image_destroy(imageBase);
636      opj_image_destroy(imageTest);
637
638      free(param_image_diff);
639
640      return EXIT_FAILURE;
641      }
642
643    imageDiff = opj_image_create(imageBase->numcomps, param_image_diff, CLRSPC_UNSPECIFIED);
644    // Free memory
645    free(param_image_diff);
646
647    // Measurement computation
648    printf("Step 2 -> measurement comparison\n");
649
650    memsizedifffilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
651    filenamePNGdiff = (char*) malloc(memsizedifffilename);
652    filenamePNGdiff[0] = '\0';
653    strncpy(filenamePNGdiff, inParam.test_filename, strlen(inParam.test_filename));
654    filenamePNGdiff[strlen(inParam.test_filename)] = '\0';
655    strcat(filenamePNGdiff, ".diff");
656    //printf("filenamePNGdiff = %s [%d / %d octets]\n",filenamePNGdiff, strlen(filenamePNGdiff),memsizedifffilename );
657
658    // Compute pixel diff
659    for (it_comp = 0; it_comp < imageDiff->numcomps; it_comp++)
660      {
661      double SE=0,PEAK=0;
662      double MSE=0;
663      char *filenamePNGbase_it_comp, *filenamePNGtest_it_comp, *filenamePNGdiff_it_comp;
664
665      filenamePNGbase_it_comp = (char*) malloc(memsizebasefilename);
666      filenamePNGbase_it_comp[0] = '\0';
667      strncpy(filenamePNGbase_it_comp,filenamePNGbase,strlen(filenamePNGbase));
668      filenamePNGbase_it_comp[strlen(filenamePNGbase)] = '\0';
669
670      filenamePNGtest_it_comp = (char*) malloc(memsizetestfilename);
671      filenamePNGtest_it_comp[0] = '\0';
672      strncpy(filenamePNGtest_it_comp,filenamePNGtest,strlen(filenamePNGtest));
673      filenamePNGtest_it_comp[strlen(filenamePNGtest)] = '\0';
674
675      filenamePNGdiff_it_comp = (char*) malloc(memsizedifffilename);
676      filenamePNGdiff_it_comp[0] = '\0';
677      strncpy(filenamePNGdiff_it_comp,filenamePNGdiff,strlen(filenamePNGdiff));
678      filenamePNGdiff_it_comp[strlen(filenamePNGdiff)] = '\0';
679
680      for (itpxl = 0; itpxl < ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h; itpxl++)
681        {
682        if (abs( ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl] ) > 0)
683          {
684          valueDiff = ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl];
685          ((imageDiff->comps)[it_comp]).data[itpxl] = abs(valueDiff);
686          sumDiff += (double)valueDiff;
687          nbPixelDiff++;
688
689          SE += (double)(valueDiff * valueDiff);
690          PEAK = (PEAK > abs(valueDiff)) ? PEAK : abs(valueDiff);
691          }
692        else
693          ((imageDiff->comps)[it_comp]).data[itpxl] = 0;
694        }// h*w loop
695
696      MSE = SE / ( ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h );
697
698      if (!inParam.nr_flag && (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL))
699        { // Conformance test
700        printf("<DartMeasurement name=\"PEAK_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, PEAK);
701        printf("<DartMeasurement name=\"MSE_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, MSE);
702
703        if ( (MSE > inParam.tabMSEvalues[it_comp]) || (PEAK > inParam.tabPEAKvalues[it_comp]) )
704          {
705          printf("ERROR: MSE (%f) or PEAK (%f) values produced by the decoded file are greater "
706                 "than the allowable error (respectively %f and %f) \n",
707                 MSE, PEAK, inParam.tabMSEvalues[it_comp], inParam.tabPEAKvalues[it_comp]);
708          failed = 1;
709          }
710        }
711      else  // Non regression-test
712        {
713        if ( nbPixelDiff > 0)
714          {
715          char it_compc[255];
716          it_compc[0] = '\0';
717
718          printf("<DartMeasurement name=\"NumberOfPixelsWithDifferences_%d\" type=\"numeric/int\"> %d </DartMeasurement> \n", it_comp, nbPixelDiff);
719          printf("<DartMeasurement name=\"ComponentError_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, sumDiff);
720
721 #ifdef HAVE_LIBPNG
722          sprintf(it_compc, "_%i", it_comp);
723          strcat(it_compc,".png");
724          strcat(filenamePNGbase_it_comp, it_compc);
725          //printf("filenamePNGbase_it = %s [%d / %d octets]\n",filenamePNGbase_it_comp, strlen(filenamePNGbase_it_comp),memsizebasefilename );
726          strcat(filenamePNGtest_it_comp, it_compc);
727          //printf("filenamePNGtest_it = %s [%d / %d octets]\n",filenamePNGtest_it_comp, strlen(filenamePNGtest_it_comp),memsizetestfilename );
728          strcat(filenamePNGdiff_it_comp, it_compc);
729          //printf("filenamePNGdiff_it = %s [%d / %d octets]\n",filenamePNGdiff_it_comp, strlen(filenamePNGdiff_it_comp),memsizedifffilename );
730
731          if ( imageToPNG(imageBase, filenamePNGbase_it_comp, it_comp) == EXIT_SUCCESS )
732            {
733            printf("<DartMeasurementFile name=\"BaselineImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGbase_it_comp);
734            }
735
736          if ( imageToPNG(imageTest, filenamePNGtest_it_comp, it_comp) == EXIT_SUCCESS )
737            {
738            printf("<DartMeasurementFile name=\"TestImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGtest_it_comp);
739            }
740
741          if ( imageToPNG(imageDiff, filenamePNGdiff_it_comp, it_comp) == EXIT_SUCCESS )
742            {
743            printf("<DartMeasurementFile name=\"DiffferenceImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGdiff_it_comp);
744            }
745 #endif
746          failed = 1;
747          }
748        }
749      free(filenamePNGbase_it_comp);
750      free(filenamePNGtest_it_comp);
751      free(filenamePNGdiff_it_comp);
752      } // it_comp loop
753
754   //-----------------------------
755   // Free memory
756   opj_image_destroy(imageBase);
757   opj_image_destroy(imageTest);
758   opj_image_destroy(imageDiff);
759
760   free(filenamePNGbase);
761   free(filenamePNGtest);
762   free(filenamePNGdiff);
763
764   free(inParam.tabMSEvalues);
765   free(inParam.tabPEAKvalues);
766   free(inParam.base_filename);
767   free(inParam.test_filename);
768
769   if (failed)
770     return EXIT_FAILURE;
771   else
772     {
773     printf("---- TEST SUCCEED ----\n");
774     return EXIT_SUCCESS;
775     }
776 }