[trunk] Cleanup commit. Rename compare family since comparePGX now support TIFF.
[openjpeg.git] / tests / compare_images.c
1 /*
2  * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 /*
28  * compare_images.c
29  *
30  *  Created on: 8 juil. 2011
31  *      Author: mickael
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <math.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <assert.h>
40
41 #include "opj_apps_config.h"
42 #include "opj_getopt.h"
43
44 #include "openjpeg.h"
45 #include "format_defs.h"
46 #include "convert.h"
47
48 #ifdef OPJ_HAVE_LIBTIFF
49 #include <tiffio.h> /* TIFFSetWarningHandler */
50 #endif /* OPJ_HAVE_LIBTIFF */
51
52 /*******************************************************************************
53  * Parse MSE and PEAK input values (
54  * separator = ":"
55  *******************************************************************************/
56 static double* parseToleranceValues( char* inArg, const int nbcomp)
57 {
58   double* outArgs= malloc((size_t)nbcomp * sizeof(double));
59   int it_comp = 0;
60   const char delims[] = ":";
61   char *result = strtok( inArg, delims );
62
63   while( (result != NULL) && (it_comp < nbcomp ))
64     {
65     outArgs[it_comp] = atof(result);
66     result = strtok( NULL, delims );
67     it_comp++;
68     }
69
70   if (it_comp != nbcomp)
71     {
72     free(outArgs);
73     return NULL;
74     }
75   /* else */
76   return outArgs;
77 }
78
79 /*******************************************************************************
80  * Command line help function
81  *******************************************************************************/
82 static void compare_images_help_display(void)
83 {
84   fprintf(stdout,"\nList of parameters for the compare_images function  \n");
85   fprintf(stdout,"\n");
86   fprintf(stdout,"  -b \t REQUIRED \t filename to the reference/baseline PGX image \n");
87   fprintf(stdout,"  -t \t REQUIRED \t filename to the test PGX image\n");
88   fprintf(stdout,"  -n \t REQUIRED \t number of component of the image (used to generate correct filename)\n");
89   fprintf(stdout,"  -m \t OPTIONAL \t list of MSE tolerances, separated by : (size must correspond to the number of component) of \n");
90   fprintf(stdout,"  -p \t OPTIONAL \t list of PEAK tolerances, separated by : (size must correspond to the number of component) \n");
91   fprintf(stdout,"  -s \t OPTIONAL \t 1 or 2 filename separator to take into account PGX image with different components, "
92                                       "please indicate b or t before separator to indicate respectively the separator "
93                                       "for ref/base file and for test file.  \n");
94   fprintf(stdout,"  -d \t OPTIONAL \t indicate if you want to run this function as conformance test or as non regression test\n");
95   fprintf(stdout,"\n");
96 }
97
98 /*******************************************************************************
99  * Create filenames from a filename using separator and nb components
100  * (begin from 0)
101  *******************************************************************************/
102 static char* createMultiComponentsFilename(const char* inFilename, const int indexF, const char* separator)
103 {
104   char s[255];
105   char *outFilename, *ptr;
106   const char token = '.';
107   int posToken = 0;
108
109   /*printf("inFilename = %s\n", inFilename);*/
110   if ((ptr = strrchr(inFilename, token)) != NULL)
111     {
112     posToken = (int) (strlen(inFilename) - strlen(ptr));
113     /*printf("Position of %c character inside inFilename = %d\n", token, posToken);*/
114     }
115   else
116     {
117     /*printf("Token %c not found\n", token);*/
118     outFilename = (char*)malloc(1);
119     outFilename[0] = '\0';
120     return outFilename;
121     }
122
123   outFilename = (char*)malloc((size_t)(posToken + 7) * sizeof(char)); /*6*/
124
125   strncpy(outFilename, inFilename, (size_t)posToken);
126
127   outFilename[posToken] = '\0';
128
129   strcat(outFilename, separator);
130
131   sprintf(s, "%i", indexF);
132   strcat(outFilename, s);
133
134   strcat(outFilename, ".pgx");
135
136   /*printf("outfilename: %s\n", outFilename);*/
137   return outFilename;
138 }
139
140 /*******************************************************************************
141  *
142  *******************************************************************************/
143 static opj_image_t* readImageFromFileTIF(const char* filename, int nbFilenamePGX, const char *separator)
144 {
145   int it_file;
146   opj_image_t* image_read = NULL;
147   opj_image_t* image = NULL;
148   opj_cparameters_t parameters;
149   opj_image_cmptparm_t* param_image_read;
150   int** data;
151
152   /* conformance test suite produce annoying warning/error:
153    * TIFFReadDirectory: Warning, /.../data/baseline/conformance/jp2_1.tif: unknown field with tag 37724 (0x935c) encountered.
154    * TIFFOpen: /.../data/baseline/nonregression/opj_jp2_1.tif: Cannot open.
155    * On Win32 this open a message box by default, so remove it from the test suite:
156    */
157   TIFFSetWarningHandler(NULL);
158   TIFFSetErrorHandler(NULL);
159
160   /* If separator is empty => nb file to read is equal to one*/
161   if ( strlen(separator) == 0 )
162     nbFilenamePGX = 1;
163
164   /* set encoding parameters to default values */
165   opj_set_default_encoder_parameters(&parameters);
166   parameters.decod_format = TIF_DFMT;
167   strcpy(parameters.infile, filename);
168
169   /* Allocate memory*/
170   param_image_read = malloc((size_t)nbFilenamePGX * sizeof(opj_image_cmptparm_t));
171   data = malloc((size_t)nbFilenamePGX * sizeof(*data));
172
173   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
174     {
175     /* Create the right filename*/
176     char *filenameComponentPGX;
177     if (strlen(separator) == 0)
178       {
179       filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX));
180       strcpy(filenameComponentPGX, filename);
181       }
182     else
183       filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator);
184
185     /* Read the tif file corresponding to the component */
186     image_read = tiftoimage(filenameComponentPGX, &parameters);
187     if (!image_read)
188       {
189       int it_free_data;
190       fprintf(stderr, "Unable to load pgx file\n");
191
192       free(param_image_read);
193
194       for (it_free_data = 0; it_free_data < it_file; it_free_data++) {
195         free(data[it_free_data]);
196       }
197       free(data);
198
199       free(filenameComponentPGX);
200
201       return NULL;
202       }
203
204     /* Set the image_read parameters*/
205     param_image_read[it_file].x0 = 0;
206     param_image_read[it_file].y0 = 0;
207     param_image_read[it_file].dx = 0;
208     param_image_read[it_file].dy = 0;
209     param_image_read[it_file].h = image_read->comps->h;
210     param_image_read[it_file].w = image_read->comps->w;
211     param_image_read[it_file].bpp = image_read->comps->bpp;
212     param_image_read[it_file].prec = image_read->comps->prec;
213     param_image_read[it_file].sgnd = image_read->comps->sgnd;
214
215     /* Copy data*/
216     data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int));
217     memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int));
218
219     /* Free memory*/
220     opj_image_destroy(image_read);
221     free(filenameComponentPGX);
222     }
223
224   image = opj_image_create((OPJ_UINT32)nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED);
225   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
226     {
227     /* Copy data into output image and free memory*/
228     memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int));
229     free(data[it_file]);
230     }
231
232   /* Free memory*/
233   free(param_image_read);
234   free(data);
235
236   return image;
237 }
238
239 static opj_image_t* readImageFromFilePGX(const char* filename, int nbFilenamePGX, const char *separator)
240 {
241   int it_file;
242   opj_image_t* image_read = NULL;
243   opj_image_t* image = NULL;
244   opj_cparameters_t parameters;
245   opj_image_cmptparm_t* param_image_read;
246   int** data;
247
248   /* If separator is empty => nb file to read is equal to one*/
249   if ( strlen(separator) == 0 )
250     nbFilenamePGX = 1;
251
252   /* set encoding parameters to default values */
253   opj_set_default_encoder_parameters(&parameters);
254   parameters.decod_format = PGX_DFMT;
255   strcpy(parameters.infile, filename);
256
257   /* Allocate memory*/
258   param_image_read = malloc((size_t)nbFilenamePGX * sizeof(opj_image_cmptparm_t));
259   data = malloc((size_t)nbFilenamePGX * sizeof(*data));
260
261   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
262     {
263     /* Create the right filename*/
264     char *filenameComponentPGX;
265     if (strlen(separator) == 0)
266       {
267       filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX));
268       strcpy(filenameComponentPGX, filename);
269       }
270     else
271       filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator);
272
273     /* Read the pgx file corresponding to the component */
274     image_read = pgxtoimage(filenameComponentPGX, &parameters);
275     if (!image_read)
276       {
277       int it_free_data;
278       fprintf(stderr, "Unable to load pgx file\n");
279
280       free(param_image_read);
281
282       for (it_free_data = 0; it_free_data < it_file; it_free_data++) {
283         free(data[it_free_data]);
284       }
285       free(data);
286
287       free(filenameComponentPGX);
288
289       return NULL;
290       }
291
292     /* Set the image_read parameters*/
293     param_image_read[it_file].x0 = 0;
294     param_image_read[it_file].y0 = 0;
295     param_image_read[it_file].dx = 0;
296     param_image_read[it_file].dy = 0;
297     param_image_read[it_file].h = image_read->comps->h;
298     param_image_read[it_file].w = image_read->comps->w;
299     param_image_read[it_file].bpp = image_read->comps->bpp;
300     param_image_read[it_file].prec = image_read->comps->prec;
301     param_image_read[it_file].sgnd = image_read->comps->sgnd;
302
303     /* Copy data*/
304     data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int));
305     memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int));
306
307     /* Free memory*/
308     opj_image_destroy(image_read);
309     free(filenameComponentPGX);
310     }
311
312   image = opj_image_create((OPJ_UINT32)nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED);
313   for (it_file = 0; it_file < nbFilenamePGX; it_file++)
314     {
315     /* Copy data into output image and free memory*/
316     memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int));
317     free(data[it_file]);
318     }
319
320   /* Free memory*/
321   free(param_image_read);
322   free(data);
323
324   return image;
325 }
326
327 #if defined(OPJ_HAVE_LIBPNG) && 0 /* remove for now */
328 /*******************************************************************************
329  *
330  *******************************************************************************/
331 static int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select)
332 {
333   opj_image_cmptparm_t param_image_write;
334   opj_image_t* image_write = NULL;
335
336   param_image_write.x0 = 0;
337   param_image_write.y0 = 0;
338   param_image_write.dx = 0;
339   param_image_write.dy = 0;
340   param_image_write.h = image->comps[num_comp_select].h;
341   param_image_write.w = image->comps[num_comp_select].w;
342   param_image_write.bpp = image->comps[num_comp_select].bpp;
343   param_image_write.prec = image->comps[num_comp_select].prec;
344   param_image_write.sgnd = image->comps[num_comp_select].sgnd;
345
346   image_write = opj_image_create(1u, &param_image_write, OPJ_CLRSPC_GRAY);
347   memcpy(image_write->comps->data, image->comps[num_comp_select].data, param_image_write.h * param_image_write.w * sizeof(int));
348
349   imagetopng(image_write, filename);
350
351   opj_image_destroy(image_write);
352
353   return EXIT_SUCCESS;
354 }
355 #endif
356
357 typedef struct test_cmp_parameters
358 {
359   /**  */
360   char* base_filename;
361   /**  */
362   char* test_filename;
363   /** Number of components */
364   int nbcomp;
365   /**  */
366   double* tabMSEvalues;
367   /**  */
368   double* tabPEAKvalues;
369   /**  */
370   int nr_flag;
371   /**  */
372   char separator_base[2];
373   /**  */
374   char separator_test[2];
375
376 } test_cmp_parameters;
377
378 /* return decode format PGX / TIF , return -1 on error */
379 static int get_decod_format(test_cmp_parameters* param)
380 {
381   const int dot = '.';
382   char * base_ext = strrchr(param->base_filename, dot);
383   char * test_ext = strrchr(param->test_filename, dot);
384   if( !base_ext || !test_ext ) return -1;
385   if( strcmp(base_ext,test_ext) != 0 ) return -1;
386   if( strcmp(base_ext,".pgx") == 0 ) return PGX_DFMT;
387   if( strcmp(base_ext,".tif") == 0 ) return TIF_DFMT;
388   return -1;
389 }
390
391 /*******************************************************************************
392  * Parse command line
393  *******************************************************************************/
394 static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
395 {
396   char *MSElistvalues = NULL;  char *PEAKlistvalues= NULL;
397   char *separatorList = NULL;
398   int sizemembasefile, sizememtestfile;
399   int index, flagM=0, flagP=0;
400   const char optlist[] = "b:t:n:m:p:s:d";
401   int c;
402
403   /* Init parameters*/
404   param->base_filename = NULL;
405   param->test_filename = NULL;
406   param->nbcomp = 0;
407   param->tabMSEvalues = NULL;
408   param->tabPEAKvalues = NULL;
409   param->nr_flag = 0;
410   param->separator_base[0] = 0;
411   param->separator_test[0] = 0;
412
413   opj_opterr = 0;
414
415   while ((c = opj_getopt(argc, argv, optlist)) != -1)
416     switch (c)
417       {
418       case 'b':
419         sizemembasefile = (int)strlen(opj_optarg)+1;
420         param->base_filename = (char*) malloc((size_t)sizemembasefile);
421         param->base_filename[0] = '\0';
422         strncpy(param->base_filename, opj_optarg, strlen(opj_optarg));
423         param->base_filename[strlen(opj_optarg)] = '\0';
424         /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/
425         break;
426       case 't':
427         sizememtestfile = (int) strlen(opj_optarg) + 1;
428         param->test_filename = (char*) malloc((size_t)sizememtestfile);
429         param->test_filename[0] = '\0';
430         strncpy(param->test_filename, opj_optarg, strlen(opj_optarg));
431         param->test_filename[strlen(opj_optarg)] = '\0';
432         /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/
433        break;
434       case 'n':
435         param->nbcomp = atoi(opj_optarg);
436         break;
437       case 'm':
438         MSElistvalues = opj_optarg;
439         flagM = 1;
440         break;
441       case 'p':
442         PEAKlistvalues = opj_optarg;
443         flagP = 1;
444         break;
445       case 'd':
446         param->nr_flag = 1;
447         break;
448       case 's':
449         separatorList = opj_optarg;
450         break;
451       case '?':
452         if ((opj_optopt == 'b') || (opj_optopt == 't') || (opj_optopt == 'n') || (opj_optopt == 'p') || (opj_optopt == 'm') || (opj_optopt
453             == 's'))
454           fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt);
455         else
456           if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt);
457           else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt);
458         return 1;
459       default:
460         fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg);
461         break;
462       }
463
464   if (opj_optind != argc)
465     {
466     for (index = opj_optind; index < argc; index++)
467       fprintf(stderr,"Non-option argument %s\n", argv[index]);
468     return 1;
469     }
470
471   if (param->nbcomp == 0)
472     {
473     fprintf(stderr,"Need to indicate the number of components !\n");
474     return 1;
475     }
476   /* else */
477   if ( flagM && flagP )
478     {
479     param->tabMSEvalues = parseToleranceValues( MSElistvalues, param->nbcomp);
480     param->tabPEAKvalues = parseToleranceValues( PEAKlistvalues, param->nbcomp);
481     if ( (param->tabMSEvalues == NULL) || (param->tabPEAKvalues == NULL))
482       {
483       fprintf(stderr,"MSE and PEAK values are not correct (respectively need %d values)\n",param->nbcomp);
484       return 1;
485       }
486     }
487
488   /* Get separators after corresponding letter (b or t)*/
489   if (separatorList != NULL)
490     {
491     if( (strlen(separatorList) ==2) || (strlen(separatorList) ==4) )
492       {
493       /* keep original string*/
494       int sizeseplist = (int)strlen(separatorList)+1;
495       char* separatorList2 = (char*)malloc( (size_t)sizeseplist );
496       separatorList2[0] = '\0';
497       strncpy(separatorList2, separatorList, strlen(separatorList));
498       separatorList2[strlen(separatorList)] = '\0';
499       /*printf("separatorList2 = %s [%d / %d]\n", separatorList2, strlen(separatorList2), sizeseplist);*/
500
501       if (strlen(separatorList) == 2) /* one separator behind b or t*/
502         {
503         char *resultT = NULL;
504         resultT = strtok(separatorList2, "t");
505         if (strlen(resultT) == strlen(separatorList)) /* didn't find t character, try to find b*/
506           {
507           char *resultB = NULL;
508           resultB = strtok(resultT, "b");
509           if (strlen(resultB) == 1)
510             {
511             param->separator_base[0] = separatorList[1];
512             param->separator_base[1] = 0;
513             param->separator_test[0] = 0;
514             }
515           else /* not found b*/
516             {
517             free(separatorList2);
518             return 1;
519             }
520           }
521         else /* found t*/
522           {
523           param->separator_base[0] = 0;
524           param->separator_test[0] = separatorList[1];
525           param->separator_test[1] = 0;
526           }
527         /*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) );*/
528         }
529       else /* == 4 characters we must found t and b*/
530         {
531         char *resultT = NULL;
532         resultT = strtok(separatorList2, "t");
533         if (strlen(resultT) == 3) /* found t in first place*/
534           {
535           char *resultB = NULL;
536           resultB = strtok(resultT, "b");
537           if (strlen(resultB) == 1) /* found b after t*/
538             {
539             param->separator_test[0] = separatorList[1];
540             param->separator_test[1] = 0;
541             param->separator_base[0] = separatorList[3];
542             param->separator_base[1] = 0;
543             }
544           else /* didn't find b after t*/
545             {
546             free(separatorList2);
547             return 1;
548             }
549           }
550         else /* == 2, didn't find t in first place*/
551           {
552           char *resultB = NULL;
553           resultB = strtok(resultT, "b");
554           if (strlen(resultB) == 1) /* found b in first place*/
555             {
556             param->separator_base[0] = separatorList[1];
557             param->separator_base[1] = 0;
558             param->separator_test[0] = separatorList[3];
559             param->separator_test[1] = 0;
560             }
561           else /* didn't found b in first place => problem*/
562             {
563             free(separatorList2);
564             return 1;
565             }
566           }
567         }
568       free(separatorList2);
569       }
570     else /* wrong number of argument after -s*/
571       {
572       return 1;
573       }
574     }
575   else
576     {
577     if (param->nbcomp == 1)
578       {
579       assert( param->separator_base[0] == 0 );
580       assert( param->separator_test[0] == 0 );
581       }
582     else
583       {
584       fprintf(stderr,"If number of component is > 1, we need separator\n");
585       return 1;
586       }
587     }
588
589
590   if ( (param->nr_flag) && (flagP || flagM) )
591     {
592     fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n");
593     return 1;
594     }
595   if ( (!param->nr_flag) && (!flagP || !flagM) )
596     {
597     fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n");
598     return 1;
599     }
600
601   return 0;
602 }
603
604 /*******************************************************************************
605  * MAIN
606  *******************************************************************************/
607 int main(int argc, char **argv)
608 {
609   test_cmp_parameters inParam;
610   OPJ_UINT32 it_comp, itpxl;
611   int failed = 1;
612   int nbFilenamePGXbase = 0, nbFilenamePGXtest = 0;
613   char *filenamePNGtest= NULL, *filenamePNGbase = NULL, *filenamePNGdiff = NULL;
614   int memsizebasefilename, memsizetestfilename;
615   size_t memsizedifffilename;
616   int valueDiff = 0, nbPixelDiff = 0;
617   double sumDiff = 0.0;
618   /* Structures to store image parameters and data*/
619   opj_image_t *imageBase = NULL, *imageTest = NULL, *imageDiff = NULL;
620   opj_image_cmptparm_t* param_image_diff = NULL;
621   int decod_format;
622
623   /* Get parameters from command line*/
624   if( parse_cmdline_cmp(argc, argv, &inParam) )
625     {
626     compare_images_help_display();
627     goto cleanup;
628     }
629
630   /* Display Parameters*/
631   printf("******Parameters********* \n");
632   printf(" base_filename = %s\n"
633          " test_filename = %s\n"
634          " nb of Components = %d\n"
635          " Non regression test = %d\n"
636          " separator Base = %s\n"
637          " separator Test = %s\n",
638          inParam.base_filename, inParam.test_filename, inParam.nbcomp,
639          inParam.nr_flag, inParam.separator_base, inParam.separator_test);
640
641   if ( (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL))
642     {
643     int it_comp;
644     printf(" MSE values = [");
645     for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++)
646       printf(" %f ", inParam.tabMSEvalues[it_comp]);
647     printf("]\n");
648     printf(" PEAK values = [");
649     for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++)
650       printf(" %f ", inParam.tabPEAKvalues[it_comp]);
651     printf("]\n");
652     printf(" Non-regression test = %d\n", inParam.nr_flag);
653     }
654
655   if (strlen(inParam.separator_base) != 0)
656     nbFilenamePGXbase = inParam.nbcomp;
657
658   if (strlen(inParam.separator_test) != 0)
659     nbFilenamePGXtest = inParam.nbcomp;
660
661   printf(" NbFilename to generate from base filename = %d\n", nbFilenamePGXbase);
662   printf(" NbFilename to generate from test filename = %d\n", nbFilenamePGXtest);
663   printf("************************* \n");
664
665   /*----------BASELINE IMAGE--------*/
666   memsizebasefilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
667   memsizetestfilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
668
669   decod_format = get_decod_format(&inParam);
670   if( decod_format == -1 ) goto cleanup;
671   assert( decod_format == PGX_DFMT || decod_format == TIF_DFMT );
672
673   if( decod_format == PGX_DFMT )
674     {
675     imageBase = readImageFromFilePGX( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base);
676     if ( imageBase == NULL )
677       goto cleanup;
678     }
679   else if( decod_format == TIF_DFMT )
680     {
681     imageBase = readImageFromFileTIF( inParam.base_filename, nbFilenamePGXbase, "");
682     if ( imageBase == NULL )
683       goto cleanup;
684     }
685
686   filenamePNGbase = (char*) malloc((size_t)memsizebasefilename);
687   strcpy(filenamePNGbase, inParam.test_filename);
688   strcat(filenamePNGbase, ".base");
689   /*printf("filenamePNGbase = %s [%d / %d octets]\n",filenamePNGbase, strlen(filenamePNGbase),memsizebasefilename );*/
690
691   /*----------TEST IMAGE--------*/
692
693   if( decod_format == PGX_DFMT )
694     {
695     imageTest = readImageFromFilePGX(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test);
696     if ( imageTest == NULL )
697       goto cleanup;
698     }
699   else if( decod_format == TIF_DFMT )
700     {
701     imageTest = readImageFromFileTIF(inParam.test_filename, nbFilenamePGXtest, "");
702     if ( imageTest == NULL )
703       goto cleanup;
704     }
705
706   filenamePNGtest = (char*) malloc((size_t)memsizetestfilename);
707   strcpy(filenamePNGtest, inParam.test_filename);
708   strcat(filenamePNGtest, ".test");
709   /*printf("filenamePNGtest = %s [%d / %d octets]\n",filenamePNGtest, strlen(filenamePNGtest),memsizetestfilename );*/
710
711   /*----------DIFF IMAGE--------*/
712
713   /* Allocate memory*/
714   param_image_diff = malloc( imageBase->numcomps * sizeof(opj_image_cmptparm_t));
715
716   /* Comparison of header parameters*/
717   printf("Step 1 -> Header comparison\n");
718
719   for (it_comp = 0; it_comp < imageBase->numcomps; it_comp++)
720     {
721     param_image_diff[it_comp].x0 = 0;
722     param_image_diff[it_comp].y0 = 0;
723     param_image_diff[it_comp].dx = 0;
724     param_image_diff[it_comp].dy = 0;
725     param_image_diff[it_comp].sgnd = 0;
726     param_image_diff[it_comp].prec = 8;
727     param_image_diff[it_comp].bpp = 1;
728     param_image_diff[it_comp].h = imageBase->comps[it_comp].h;
729     param_image_diff[it_comp].w = imageBase->comps[it_comp].w;
730
731     if (imageBase->comps[it_comp].sgnd != imageTest->comps[it_comp].sgnd)
732       {
733       printf("ERROR: sign mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).sgnd, ((imageTest->comps)[it_comp]).sgnd);
734       goto cleanup;
735       }
736
737     if (((imageBase->comps)[it_comp]).prec != ((imageTest->comps)[it_comp]).prec)
738       {
739       printf("ERROR: prec mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).prec, ((imageTest->comps)[it_comp]).prec);
740       goto cleanup;
741       }
742
743     if (((imageBase->comps)[it_comp]).bpp != ((imageTest->comps)[it_comp]).bpp)
744       {
745       printf("ERROR: byte per pixel mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).bpp, ((imageTest->comps)[it_comp]).bpp);
746       goto cleanup;
747       }
748
749     if (((imageBase->comps)[it_comp]).h != ((imageTest->comps)[it_comp]).h)
750       {
751       printf("ERROR: height mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).h, ((imageTest->comps)[it_comp]).h);
752       goto cleanup;
753       }
754
755     if (((imageBase->comps)[it_comp]).w != ((imageTest->comps)[it_comp]).w)
756       {
757       printf("ERROR: width mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).w, ((imageTest->comps)[it_comp]).w);
758       goto cleanup;
759       }
760     }
761
762    imageDiff = opj_image_create(imageBase->numcomps, param_image_diff, OPJ_CLRSPC_UNSPECIFIED);
763    /* Free memory*/
764    free(param_image_diff); param_image_diff = NULL;
765
766    /* Measurement computation*/
767    printf("Step 2 -> measurement comparison\n");
768
769    memsizedifffilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4;
770    filenamePNGdiff = (char*) malloc(memsizedifffilename);
771    strcpy(filenamePNGdiff, inParam.test_filename);
772    strcat(filenamePNGdiff, ".diff");
773    /*printf("filenamePNGdiff = %s [%d / %d octets]\n",filenamePNGdiff, strlen(filenamePNGdiff),memsizedifffilename );*/
774
775    /* Compute pixel diff*/
776    for (it_comp = 0; it_comp < imageDiff->numcomps; it_comp++)
777      {
778      double SE=0,PEAK=0;
779      double MSE=0;
780      for (itpxl = 0; itpxl < ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h; itpxl++)
781        {
782        if (abs( ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl] ) > 0)
783          {
784          valueDiff = ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl];
785          ((imageDiff->comps)[it_comp]).data[itpxl] = abs(valueDiff);
786          sumDiff += valueDiff;
787          nbPixelDiff++;
788
789          SE += (double)valueDiff * valueDiff;
790          PEAK = (PEAK > abs(valueDiff)) ? PEAK : abs(valueDiff);
791          }
792        else
793          ((imageDiff->comps)[it_comp]).data[itpxl] = 0;
794        }/* h*w loop */
795
796      MSE = SE / ( ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h );
797
798      if (!inParam.nr_flag && (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL))
799        { /* Conformance test*/
800        printf("<DartMeasurement name=\"PEAK_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, PEAK);
801        printf("<DartMeasurement name=\"MSE_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, MSE);
802
803        if ( (MSE > inParam.tabMSEvalues[it_comp]) || (PEAK > inParam.tabPEAKvalues[it_comp]) )
804          {
805          printf("ERROR: MSE (%f) or PEAK (%f) values produced by the decoded file are greater "
806            "than the allowable error (respectively %f and %f) \n",
807            MSE, PEAK, inParam.tabMSEvalues[it_comp], inParam.tabPEAKvalues[it_comp]);
808          goto cleanup;
809          }
810        }
811      else  /* Non regression-test */
812        {
813        if ( nbPixelDiff > 0)
814          {
815          char it_compc[255];
816          it_compc[0] = 0;
817
818          printf("<DartMeasurement name=\"NumberOfPixelsWithDifferences_%d\" type=\"numeric/int\"> %d </DartMeasurement> \n", it_comp, nbPixelDiff);
819          printf("<DartMeasurement name=\"ComponentError_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, sumDiff);
820
821 #ifdef OPJ_HAVE_LIBPNG
822            {
823            char *filenamePNGbase_it_comp, *filenamePNGtest_it_comp, *filenamePNGdiff_it_comp;
824
825            filenamePNGbase_it_comp = (char*) malloc((size_t)memsizebasefilename);
826            strcpy(filenamePNGbase_it_comp,filenamePNGbase);
827
828            filenamePNGtest_it_comp = (char*) malloc((size_t)memsizetestfilename);
829            strcpy(filenamePNGtest_it_comp,filenamePNGtest);
830
831            filenamePNGdiff_it_comp = (char*) malloc(memsizedifffilename);
832            strcpy(filenamePNGdiff_it_comp,filenamePNGdiff);
833
834            sprintf(it_compc, "_%i", it_comp);
835            strcat(it_compc,".png");
836            strcat(filenamePNGbase_it_comp, it_compc);
837            /*printf("filenamePNGbase_it = %s [%d / %d octets]\n",filenamePNGbase_it_comp, strlen(filenamePNGbase_it_comp),memsizebasefilename );*/
838            strcat(filenamePNGtest_it_comp, it_compc);
839            /*printf("filenamePNGtest_it = %s [%d / %d octets]\n",filenamePNGtest_it_comp, strlen(filenamePNGtest_it_comp),memsizetestfilename );*/
840            strcat(filenamePNGdiff_it_comp, it_compc);
841            /*printf("filenamePNGdiff_it = %s [%d / %d octets]\n",filenamePNGdiff_it_comp, strlen(filenamePNGdiff_it_comp),memsizedifffilename );*/
842
843            /*
844            if ( imageToPNG(imageBase, filenamePNGbase_it_comp, it_comp) == EXIT_SUCCESS )
845            {
846            printf("<DartMeasurementFile name=\"BaselineImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGbase_it_comp);
847            }
848
849            if ( imageToPNG(imageTest, filenamePNGtest_it_comp, it_comp) == EXIT_SUCCESS )
850            {
851            printf("<DartMeasurementFile name=\"TestImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGtest_it_comp);
852            }
853
854            if ( imageToPNG(imageDiff, filenamePNGdiff_it_comp, it_comp) == EXIT_SUCCESS )
855            {
856            printf("<DartMeasurementFile name=\"DiffferenceImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGdiff_it_comp);
857            }
858             */
859
860            free(filenamePNGbase_it_comp);
861            free(filenamePNGtest_it_comp);
862            free(filenamePNGdiff_it_comp);
863            }
864 #endif
865          goto cleanup;
866          }
867        }
868      } /* it_comp loop */
869
870    printf("---- TEST SUCCEED ----\n");
871    failed = 0;
872 cleanup:
873   /*-----------------------------*/
874   free(param_image_diff);
875   /* Free memory */
876   opj_image_destroy(imageBase);
877   opj_image_destroy(imageTest);
878   opj_image_destroy(imageDiff);
879
880   free(filenamePNGbase);
881   free(filenamePNGtest);
882   free(filenamePNGdiff);
883
884   free(inParam.tabMSEvalues);
885   free(inParam.tabPEAKvalues);
886   free(inParam.base_filename);
887   free(inParam.test_filename);
888
889   return failed ? EXIT_FAILURE : EXIT_SUCCESS;
890 }