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