]> granicus.if.org Git - imagemagick/blob - tests/validate.c
minor note
[imagemagick] / tests / validate.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                                                                             %
7 %           V   V   AAA   L      IIIII  DDDD    AAA   TTTTT  EEEEE            %
8 %           V   V  A   A  L        I    D   D  A   A    T    E                %
9 %           V   V  AAAAA  L        I    D   D  AAAAA    T    EEE              %
10 %            V V   A   A  L        I    D   D  A   A    T    E                %
11 %             V    A   A  LLLLL  IIIII  DDDD   A   A    T    EEEEE            %
12 %                                                                             %
13 %                                                                             %
14 %                        ImageMagick Validation Suite                         %
15 %                                                                             %
16 %                             Software Design                                 %
17 %                               John Cristy                                   %
18 %                               March 2001                                    %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
22 %  dedicated to making software imaging solutions freely available.           %
23 %                                                                             %
24 %  You may not use this file except in compliance with the License.  You may  %
25 %  obtain a copy of the License at                                            %
26 %                                                                             %
27 %    http://www.imagemagick.org/script/license.php                            %
28 %                                                                             %
29 %  Unless required by applicable law or agreed to in writing, software        %
30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32 %  see the License for the specific language governing permissions and        %
33 %  limitations under the License.                                             %
34 %                                                                             %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <ctype.h>
47 #include <math.h>
48 #include "wand/MagickWand.h"
49 #include "magick/string-private.h"
50 #include "validate.h"
51 \f
52 /*
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 %                                                                             %
55 %                                                                             %
56 %                                                                             %
57 %   V a l i d a t e C o m p a r e C o m m a n d                               %
58 %                                                                             %
59 %                                                                             %
60 %                                                                             %
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 %
63 %  ValidateCompareCommand() validates the ImageMagick compare command line
64 %  program and returns the number of validation tests that passed and failed.
65 %
66 %  The format of the ValidateCompareCommand method is:
67 %
68 %      size_t ValidateCompareCommand(ImageInfo *image_info,
69 %        const char *reference_filename,const char *output_filename,
70 %        size_t *fail,ExceptionInfo *exception)
71 %
72 %  A description of each parameter follows:
73 %
74 %    o image_info: the image info.
75 %
76 %    o reference_filename: the reference image filename.
77 %
78 %    o output_filename: the output image filename.
79 %
80 %    o fail: return the number of validation tests that pass.
81 %
82 %    o exception: return any errors or warnings in this structure.
83 %
84 */
85 static size_t ValidateCompareCommand(ImageInfo *image_info,
86   const char *reference_filename,const char *output_filename,
87   size_t *fail,ExceptionInfo *exception)
88 {
89   char
90     **arguments,
91     command[MaxTextExtent];
92
93   int
94     number_arguments;
95
96   MagickBooleanType
97     status;
98
99   register ssize_t
100     i,
101     j;
102
103   size_t
104     test;
105
106   test=0;
107   (void) fprintf(stdout,"validate compare command line program:\n");
108   for (i=0; compare_options[i] != (char *) NULL; i++)
109   {
110     CatchException(exception);
111     (void) fprintf(stdout,"  test %.20g: %s",(double) (test++),
112       compare_options[i]);
113     (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
114       compare_options[i],reference_filename,reference_filename,output_filename);
115     arguments=StringToArgv(command,&number_arguments);
116     if (arguments == (char **) NULL)
117       {
118         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
119         (*fail)++;
120         continue;
121       }
122     status=CompareImageCommand(image_info,number_arguments,arguments,
123       (char **) NULL,exception);
124     for (j=0; j < number_arguments; j++)
125       arguments[j]=DestroyString(arguments[j]);
126     arguments=(char **) RelinquishMagickMemory(arguments);
127     if (status != MagickFalse)
128       {
129         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
130         (*fail)++;
131         continue;
132       }
133     (void) fprintf(stdout,"... pass.\n");
134   }
135   (void) fprintf(stdout,
136     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
137     (double) (test-(*fail)),(double) *fail);
138   return(test);
139 }
140 \f
141 /*
142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 %                                                                             %
144 %                                                                             %
145 %                                                                             %
146 %   V a l i d a t e C o m p o s i t e C o m m a n d                           %
147 %                                                                             %
148 %                                                                             %
149 %                                                                             %
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 %
152 %  ValidateCompositeCommand() validates the ImageMagick composite command line
153 %  program and returns the number of validation tests that passed and failed.
154 %
155 %  The format of the ValidateCompositeCommand method is:
156 %
157 %      size_t ValidateCompositeCommand(ImageInfo *image_info,
158 %        const char *reference_filename,const char *output_filename,
159 %        size_t *fail,ExceptionInfo *exception)
160 %
161 %  A description of each parameter follows:
162 %
163 %    o image_info: the image info.
164 %
165 %    o reference_filename: the reference image filename.
166 %
167 %    o output_filename: the output image filename.
168 %
169 %    o fail: return the number of validation tests that pass.
170 %
171 %    o exception: return any errors or warnings in this structure.
172 %
173 */
174 static size_t ValidateCompositeCommand(ImageInfo *image_info,
175   const char *reference_filename,const char *output_filename,
176   size_t *fail,ExceptionInfo *exception)
177 {
178   char
179     **arguments,
180     command[MaxTextExtent];
181
182   int
183     number_arguments;
184
185   MagickBooleanType
186     status;
187
188   register ssize_t
189     i,
190     j;
191
192   size_t
193     test;
194
195   test=0;
196   (void) fprintf(stdout,"validate composite command line program:\n");
197   for (i=0; composite_options[i] != (char *) NULL; i++)
198   {
199     CatchException(exception);
200     (void) fprintf(stdout,"  test %.20g: %s",(double) (test++),
201       composite_options[i]);
202     (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
203       reference_filename,composite_options[i],reference_filename,
204       output_filename);
205     arguments=StringToArgv(command,&number_arguments);
206     if (arguments == (char **) NULL)
207       {
208         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
209         (*fail)++;
210         continue;
211       }
212     status=CompositeImageCommand(image_info,number_arguments,arguments,
213       (char **) NULL,exception);
214     for (j=0; j < number_arguments; j++)
215       arguments[j]=DestroyString(arguments[j]);
216     arguments=(char **) RelinquishMagickMemory(arguments);
217     if (status != MagickFalse)
218       {
219         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
220         (*fail)++;
221         continue;
222       }
223     (void) fprintf(stdout,"... pass.\n");
224   }
225   (void) fprintf(stdout,
226     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
227     (double) (test-(*fail)),(double) *fail);
228   return(test);
229 }
230 \f
231 /*
232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233 %                                                                             %
234 %                                                                             %
235 %                                                                             %
236 %   V a l i d a t e C o n v e r t C o m m a n d                               %
237 %                                                                             %
238 %                                                                             %
239 %                                                                             %
240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241 %
242 %  ValidateConvertCommand() validates the ImageMagick convert command line
243 %  program and returns the number of validation tests that passed and failed.
244 %
245 %  The format of the ValidateConvertCommand method is:
246 %
247 %      size_t ValidateConvertCommand(ImageInfo *image_info,
248 %        const char *reference_filename,const char *output_filename,
249 %        size_t *fail,ExceptionInfo *exception)
250 %
251 %  A description of each parameter follows:
252 %
253 %    o image_info: the image info.
254 %
255 %    o reference_filename: the reference image filename.
256 %
257 %    o output_filename: the output image filename.
258 %
259 %    o fail: return the number of validation tests that pass.
260 %
261 %    o exception: return any errors or warnings in this structure.
262 %
263 */
264 static size_t ValidateConvertCommand(ImageInfo *image_info,
265   const char *reference_filename,const char *output_filename,
266   size_t *fail,ExceptionInfo *exception)
267 {
268   char
269     **arguments,
270     command[MaxTextExtent];
271
272   int
273     number_arguments;
274
275   MagickBooleanType
276     status;
277
278   register ssize_t
279     i,
280     j;
281
282   size_t
283     test;
284
285   test=0;
286   (void) fprintf(stdout,"validate convert command line program:\n");
287   for (i=0; convert_options[i] != (char *) NULL; i++)
288   {
289     CatchException(exception);
290     (void) fprintf(stdout,"  test %.20g: %s",(double) test++,
291       convert_options[i]);
292     (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
293       reference_filename,convert_options[i],reference_filename,output_filename);
294     arguments=StringToArgv(command,&number_arguments);
295     if (arguments == (char **) NULL)
296       {
297         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
298         (*fail)++;
299         continue;
300       }
301     status=ConvertImageCommand(image_info,number_arguments,arguments,
302       (char **) NULL,exception);
303     for (j=0; j < number_arguments; j++)
304       arguments[j]=DestroyString(arguments[j]);
305     arguments=(char **) RelinquishMagickMemory(arguments);
306     if (status != MagickFalse)
307       {
308         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
309         (*fail)++;
310         continue;
311       }
312     (void) fprintf(stdout,"... pass.\n");
313   }
314   (void) fprintf(stdout,
315     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
316     (double) (test-(*fail)),(double) *fail);
317   return(test);
318 }
319 \f
320 /*
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322 %                                                                             %
323 %                                                                             %
324 %                                                                             %
325 %   V a l i d a t e I d e n t i f y C o m m a n d                             %
326 %                                                                             %
327 %                                                                             %
328 %                                                                             %
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330 %
331 %  ValidateIdentifyCommand() validates the ImageMagick identify command line
332 %  program and returns the number of validation tests that passed and failed.
333 %
334 %  The format of the ValidateIdentifyCommand method is:
335 %
336 %      size_t ValidateIdentifyCommand(ImageInfo *image_info,
337 %        const char *reference_filename,const char *output_filename,
338 %        size_t *fail,ExceptionInfo *exception)
339 %
340 %  A description of each parameter follows:
341 %
342 %    o image_info: the image info.
343 %
344 %    o reference_filename: the reference image filename.
345 %
346 %    o output_filename: the output image filename.
347 %
348 %    o fail: return the number of validation tests that pass.
349 %
350 %    o exception: return any errors or warnings in this structure.
351 %
352 */
353 static size_t ValidateIdentifyCommand(ImageInfo *image_info,
354   const char *reference_filename,const char *output_filename,
355   size_t *fail,ExceptionInfo *exception)
356 {
357   char
358     **arguments,
359     command[MaxTextExtent];
360
361   int
362     number_arguments;
363
364   MagickBooleanType
365     status;
366
367   register ssize_t
368     i,
369     j;
370
371   size_t
372     test;
373
374   (void) output_filename;
375   test=0;
376   (void) fprintf(stdout,"validate identify command line program:\n");
377   for (i=0; identify_options[i] != (char *) NULL; i++)
378   {
379     CatchException(exception);
380     (void) fprintf(stdout,"  test %.20g: %s",(double) test++,
381       identify_options[i]);
382     (void) FormatMagickString(command,MaxTextExtent,"%s %s",
383       identify_options[i],reference_filename);
384     arguments=StringToArgv(command,&number_arguments);
385     if (arguments == (char **) NULL)
386       {
387         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
388         (*fail)++;
389         continue;
390       }
391     status=IdentifyImageCommand(image_info,number_arguments,arguments,
392       (char **) NULL,exception);
393     for (j=0; j < number_arguments; j++)
394       arguments[j]=DestroyString(arguments[j]);
395     arguments=(char **) RelinquishMagickMemory(arguments);
396     if (status != MagickFalse)
397       {
398         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
399         (*fail)++;
400         continue;
401       }
402     (void) fprintf(stdout,"... pass.\n");
403   }
404   (void) fprintf(stdout,
405     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
406     (double) (test-(*fail)),(double) *fail);
407   return(test);
408 }
409 \f
410 /*
411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 %                                                                             %
413 %                                                                             %
414 %                                                                             %
415 %   V a l i d a t e I m a g e F o r m a t s I n M e m o r y                   %
416 %                                                                             %
417 %                                                                             %
418 %                                                                             %
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420 %
421 %  ValidateImageFormatsInMemory() validates the ImageMagick image formats in
422 %  memory and returns the number of validation tests that passed and failed.
423 %
424 %  The format of the ValidateImageFormatsInMemory method is:
425 %
426 %      size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
427 %        const char *reference_filename,const char *output_filename,
428 %        size_t *fail,ExceptionInfo *exception)
429 %
430 %  A description of each parameter follows:
431 %
432 %    o image_info: the image info.
433 %
434 %    o reference_filename: the reference image filename.
435 %
436 %    o output_filename: the output image filename.
437 %
438 %    o fail: return the number of validation tests that pass.
439 %
440 %    o exception: return any errors or warnings in this structure.
441 %
442 */
443 static size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
444   const char *reference_filename,const char *output_filename,
445   size_t *fail,ExceptionInfo *exception)
446 {
447   char
448     size[MaxTextExtent];
449
450   const MagickInfo
451     *magick_info;
452
453   double
454     distortion,
455     fuzz;
456
457   Image
458     *difference_image,
459     *reference_image,
460     *reconstruct_image;
461
462   MagickBooleanType
463     status;
464
465   register ssize_t
466     i,
467     j;
468
469   size_t
470     length;
471
472   unsigned char
473     *blob;
474
475   size_t
476     test;
477
478   test=0;
479   (void) fprintf(stdout,"validate image formats in memory:\n");
480   for (i=0; reference_formats[i].magick != (char *) NULL; i++)
481   {
482     magick_info=GetMagickInfo(reference_formats[i].magick,exception);
483     if ((magick_info == (const MagickInfo *) NULL) ||
484         (magick_info->decoder == (DecodeImageHandler *) NULL) ||
485         (magick_info->encoder == (EncodeImageHandler *) NULL))
486       continue;
487     for (j=0; reference_types[j].type != UndefinedType; j++)
488     {
489       /*
490         Generate reference image.
491       */
492       CatchException(exception);
493       (void) fprintf(stdout,"  test %.20g: %s/%s/%s/%.20g-bits",(double)
494         (test++),reference_formats[i].magick,MagickOptionToMnemonic(
495         MagickCompressOptions,reference_formats[i].compression),
496         MagickOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
497         (double) reference_types[j].depth);
498       (void) CopyMagickString(image_info->filename,reference_filename,
499         MaxTextExtent);
500       reference_image=ReadImage(image_info,exception);
501       if (reference_image == (Image *) NULL)
502         {
503           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
504           (*fail)++;
505           continue;
506         }
507       /*
508         Write reference image.
509       */
510       (void) FormatMagickString(size,MaxTextExtent,"%.20gx%.20g",
511         (double) reference_image->columns,(double) reference_image->rows);
512       (void) CloneString(&image_info->size,size);
513       image_info->depth=reference_types[j].depth;
514       (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
515         reference_formats[i].magick,output_filename);
516       status=SetImageType(reference_image,reference_types[j].type);
517       InheritException(exception,&reference_image->exception);
518       if (status == MagickFalse)
519         {
520           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
521           (*fail)++;
522           reference_image=DestroyImage(reference_image);
523           continue;
524         }
525       status=SetImageDepth(reference_image,reference_types[j].depth);
526       InheritException(exception,&reference_image->exception);
527       if (status == MagickFalse)
528         {
529           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
530           (*fail)++;
531           reference_image=DestroyImage(reference_image);
532           continue;
533         }
534       reference_image->compression=reference_formats[i].compression;
535       status=WriteImage(image_info,reference_image);
536       InheritException(exception,&reference_image->exception);
537       reference_image=DestroyImage(reference_image);
538       if (status == MagickFalse)
539         {
540           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
541           (*fail)++;
542           continue;
543         }
544       /*
545         Read reference image.
546       */
547       (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
548         reference_formats[i].magick,output_filename);
549       reference_image=ReadImage(image_info,exception);
550       if (reference_image == (Image *) NULL)
551         {
552           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
553           (*fail)++;
554           continue;
555         }
556       /*
557         Write reference image.
558       */
559       (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
560         reference_formats[i].magick,output_filename);
561       (void) CopyMagickString(image_info->magick,reference_formats[i].magick,
562         MaxTextExtent);
563       reference_image->depth=reference_types[j].depth;
564       reference_image->compression=reference_formats[i].compression;
565       length=8192;
566       blob=ImageToBlob(image_info,reference_image,&length,exception);
567       if (blob == (unsigned char *) NULL)
568         {
569           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
570           (*fail)++;
571           reference_image=DestroyImage(reference_image);
572           continue;
573         }
574       /*
575         Read reconstruct image.
576       */
577       (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
578         reference_formats[i].magick,output_filename);
579       reconstruct_image=BlobToImage(image_info,blob,length,exception);
580       blob=(unsigned char *) RelinquishMagickMemory(blob);
581       if (reconstruct_image == (Image *) NULL)
582         {
583           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
584           (*fail)++;
585           reference_image=DestroyImage(reference_image);
586           continue;
587         }
588       /*
589         Compare reference to reconstruct image.
590       */
591       fuzz=0.0;
592       if (reference_formats[i].fuzz != 0.0)
593         fuzz=reference_formats[i].fuzz;
594 #if defined(MAGICKCORE_HDRI_SUPPORT)
595       fuzz+=0.003;
596 #endif
597       if (reference_image->colorspace != RGBColorspace)
598         fuzz+=0.3;
599       fuzz+=MagickEpsilon;
600       difference_image=CompareImageChannels(reference_image,reconstruct_image,
601         AllChannels,MeanSquaredErrorMetric,&distortion,exception);
602       reconstruct_image=DestroyImage(reconstruct_image);
603       reference_image=DestroyImage(reference_image);
604       if (difference_image == (Image *) NULL)
605         {
606           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
607           (*fail)++;
608           continue;
609         }
610       difference_image=DestroyImage(difference_image);
611       if ((distortion/QuantumRange) > fuzz)
612         {
613           (void) fprintf(stdout,"... fail (with distortion %g).\n",
614             distortion/QuantumRange);
615           (*fail)++;
616           continue;
617         }
618       (void) fprintf(stdout,"... pass.\n");
619     }
620   }
621   (void) fprintf(stdout,
622     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
623     (double) (test-(*fail)),(double) *fail);
624   return(test);
625 }
626 \f
627 /*
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 %                                                                             %
630 %                                                                             %
631 %                                                                             %
632 %   V a l i d a t e I m a g e F o r m a t s O n D i s k                       %
633 %                                                                             %
634 %                                                                             %
635 %                                                                             %
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637 %
638 %  ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk
639 %  and returns the number of validation tests that passed and failed.
640 %
641 %  The format of the ValidateImageFormatsOnDisk method is:
642 %
643 %      size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
644 %        const char *reference_filename,const char *output_filename,
645 %        size_t *fail,ExceptionInfo *exception)
646 %
647 %  A description of each parameter follows:
648 %
649 %    o image_info: the image info.
650 %
651 %    o reference_filename: the reference image filename.
652 %
653 %    o output_filename: the output image filename.
654 %
655 %    o fail: return the number of validation tests that pass.
656 %
657 %    o exception: return any errors or warnings in this structure.
658 %
659 */
660 static size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
661   const char *reference_filename,const char *output_filename,
662   size_t *fail,ExceptionInfo *exception)
663 {
664   char
665     size[MaxTextExtent];
666
667   const MagickInfo
668     *magick_info;
669
670   double
671     distortion,
672     fuzz;
673
674   Image
675     *difference_image,
676     *reference_image,
677     *reconstruct_image;
678
679   MagickBooleanType
680     status;
681
682   register ssize_t
683     i,
684     j;
685
686   size_t
687     test;
688
689   test=0;
690   (void) fprintf(stdout,"validate image formats on disk:\n");
691   for (i=0; reference_formats[i].magick != (char *) NULL; i++)
692   {
693     magick_info=GetMagickInfo(reference_formats[i].magick,exception);
694     if ((magick_info == (const MagickInfo *) NULL) ||
695         (magick_info->decoder == (DecodeImageHandler *) NULL) ||
696         (magick_info->encoder == (EncodeImageHandler *) NULL))
697       continue;
698     for (j=0; reference_types[j].type != UndefinedType; j++)
699     {
700       /*
701         Generate reference image.
702       */
703       CatchException(exception);
704       (void) fprintf(stdout,"  test %.20g: %s/%s/%s/%.20g-bits",(double)
705         (test++),reference_formats[i].magick,MagickOptionToMnemonic(
706         MagickCompressOptions,reference_formats[i].compression),
707         MagickOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
708         (double) reference_types[j].depth);
709       (void) CopyMagickString(image_info->filename,reference_filename,
710         MaxTextExtent);
711       reference_image=ReadImage(image_info,exception);
712       if (reference_image == (Image *) NULL)
713         {
714           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
715           (*fail)++;
716           continue;
717         }
718       /*
719         Write reference image.
720       */
721       (void) FormatMagickString(size,MaxTextExtent,"%.20gx%.20g",
722         (double) reference_image->columns,(double) reference_image->rows);
723       (void) CloneString(&image_info->size,size);
724       image_info->depth=reference_types[j].depth;
725       (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
726         reference_formats[i].magick,output_filename);
727       status=SetImageType(reference_image,reference_types[j].type);
728       InheritException(exception,&reference_image->exception);
729       if (status == MagickFalse)
730         {
731           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
732           (*fail)++;
733           reference_image=DestroyImage(reference_image);
734           continue;
735         }
736       status=SetImageDepth(reference_image,reference_types[j].depth);
737       InheritException(exception,&reference_image->exception);
738       if (status == MagickFalse)
739         {
740           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
741           (*fail)++;
742           reference_image=DestroyImage(reference_image);
743           continue;
744         }
745       reference_image->compression=reference_formats[i].compression;
746       status=WriteImage(image_info,reference_image);
747       InheritException(exception,&reference_image->exception);
748       reference_image=DestroyImage(reference_image);
749       if (status == MagickFalse)
750         {
751           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
752           (*fail)++;
753           continue;
754         }
755       /*
756         Read reference image.
757       */
758       (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
759         reference_formats[i].magick,output_filename);
760       reference_image=ReadImage(image_info,exception);
761       if (reference_image == (Image *) NULL)
762         {
763           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
764           (*fail)++;
765           continue;
766         }
767       /*
768         Write reference image.
769       */
770       (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
771         reference_formats[i].magick,output_filename);
772       reference_image->depth=reference_types[j].depth;
773       reference_image->compression=reference_formats[i].compression;
774       status=WriteImage(image_info,reference_image);
775       InheritException(exception,&reference_image->exception);
776       if (status == MagickFalse)
777         {
778           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
779           (*fail)++;
780           reference_image=DestroyImage(reference_image);
781           continue;
782         }
783       /*
784         Read reconstruct image.
785       */
786       (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
787         reference_formats[i].magick,output_filename);
788       reconstruct_image=ReadImage(image_info,exception);
789       if (reconstruct_image == (Image *) NULL)
790         {
791           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
792           (*fail)++;
793           reference_image=DestroyImage(reference_image);
794           continue;
795         }
796       /*
797         Compare reference to reconstruct image.
798       */
799       fuzz=0.0;
800       if (reference_formats[i].fuzz != 0.0)
801         fuzz=reference_formats[i].fuzz;
802 #if defined(MAGICKCORE_HDRI_SUPPORT)
803       fuzz+=0.003;
804 #endif
805       if (reference_image->colorspace != RGBColorspace)
806         fuzz+=0.3;
807       fuzz+=MagickEpsilon;
808       difference_image=CompareImageChannels(reference_image,reconstruct_image,
809         AllChannels,MeanSquaredErrorMetric,&distortion,exception);
810       reconstruct_image=DestroyImage(reconstruct_image);
811       reference_image=DestroyImage(reference_image);
812       if (difference_image == (Image *) NULL)
813         {
814           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
815           (*fail)++;
816           continue;
817         }
818       difference_image=DestroyImage(difference_image);
819       if ((distortion/QuantumRange) > fuzz)
820         {
821           (void) fprintf(stdout,"... fail (with distortion %g).\n",
822             distortion/QuantumRange);
823           (*fail)++;
824           continue;
825         }
826       (void) fprintf(stdout,"... pass.\n");
827     }
828   }
829   (void) fprintf(stdout,
830     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
831     (double) (test-(*fail)),(double) *fail);
832   return(test);
833 }
834 \f
835 /*
836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837 %                                                                             %
838 %                                                                             %
839 %                                                                             %
840 %   V a l i d a t e I m p o r t E x p o r t P i x e l s                       %
841 %                                                                             %
842 %                                                                             %
843 %                                                                             %
844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845 %
846 %  ValidateImportExportPixels() validates the pixel import and export methods.
847 %  It returns the number of validation tests that passed and failed.
848 %
849 %  The format of the ValidateImportExportPixels method is:
850 %
851 %      size_t ValidateImportExportPixels(ImageInfo *image_info,
852 %        const char *reference_filename,const char *output_filename,
853 %        size_t *fail,ExceptionInfo *exception)
854 %
855 %  A description of each parameter follows:
856 %
857 %    o image_info: the image info.
858 %
859 %    o reference_filename: the reference image filename.
860 %
861 %    o output_filename: the output image filename.
862 %
863 %    o fail: return the number of validation tests that pass.
864 %
865 %    o exception: return any errors or warnings in this structure.
866 %
867 */
868 static size_t ValidateImportExportPixels(ImageInfo *image_info,
869   const char *reference_filename,const char *output_filename,
870   size_t *fail,ExceptionInfo *exception)
871 {
872   double
873     distortion;
874
875   Image
876     *difference_image,
877     *reference_image,
878     *reconstruct_image;
879
880   MagickBooleanType
881     status;
882
883   register ssize_t
884     i,
885     j;
886
887   size_t
888     length;
889
890   unsigned char
891     *pixels;
892
893   size_t
894     test;
895
896   (void) output_filename;
897   test=0;
898   (void) fprintf(stdout,"validate the import and export of image pixels:\n");
899   for (i=0; reference_map[i] != (char *) NULL; i++)
900   {
901     for (j=0; reference_storage[j].type != UndefinedPixel; j++)
902     {
903       /*
904         Generate reference image.
905       */
906       CatchException(exception);
907       (void) fprintf(stdout,"  test %.20g: %s/%s",(double) (test++),
908         reference_map[i],MagickOptionToMnemonic(MagickStorageOptions,
909         reference_storage[j].type));
910       (void) CopyMagickString(image_info->filename,reference_filename,
911         MaxTextExtent);
912       reference_image=ReadImage(image_info,exception);
913       if (reference_image == (Image *) NULL)
914         {
915           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
916           (*fail)++;
917           continue;
918         }
919       if (LocaleNCompare(reference_map[i],"cmy",3) == 0)
920         (void) TransformImageColorspace(reference_image,CMYKColorspace);
921       length=strlen(reference_map[i])*reference_image->columns*
922         reference_image->rows*reference_storage[j].quantum;
923       pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
924       if (pixels == (unsigned char *) NULL)
925         {
926           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
927           (*fail)++;
928           reference_image=DestroyImage(reference_image);
929           continue;
930         }
931       (void) ResetMagickMemory(pixels,0,length*sizeof(*pixels));
932       status=ExportImagePixels(reference_image,0,0,reference_image->columns,
933         reference_image->rows,reference_map[i],reference_storage[j].type,pixels,
934         exception);
935       if (status == MagickFalse)
936         {
937           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
938           (*fail)++;
939           pixels=(unsigned char *) RelinquishMagickMemory(pixels);
940           reference_image=DestroyImage(reference_image);
941           continue;
942         }
943       (void) SetImageBackgroundColor(reference_image);
944       status=ImportImagePixels(reference_image,0,0,reference_image->columns,
945         reference_image->rows,reference_map[i],reference_storage[j].type,
946         pixels);
947       InheritException(exception,&reference_image->exception);
948       if (status == MagickFalse)
949         {
950           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
951           (*fail)++;
952            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
953           reference_image=DestroyImage(reference_image);
954           continue;
955         }
956       /*
957         Read reconstruct image.
958       */
959       reconstruct_image=AcquireImage(image_info);
960       (void) SetImageExtent(reconstruct_image,reference_image->columns,
961         reference_image->rows);
962       (void) SetImageColorspace(reconstruct_image,reference_image->colorspace);
963       (void) SetImageBackgroundColor(reconstruct_image);
964       status=ImportImagePixels(reconstruct_image,0,0,reconstruct_image->columns,
965         reconstruct_image->rows,reference_map[i],reference_storage[j].type,
966         pixels);
967       InheritException(exception,&reconstruct_image->exception);
968       pixels=(unsigned char *) RelinquishMagickMemory(pixels);
969       if (status == MagickFalse)
970         {
971           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
972           (*fail)++;
973           reference_image=DestroyImage(reference_image);
974           continue;
975         }
976       /*
977         Compare reference to reconstruct image.
978       */
979       difference_image=CompareImageChannels(reference_image,reconstruct_image,
980         AllChannels,MeanSquaredErrorMetric,&distortion,exception);
981       reconstruct_image=DestroyImage(reconstruct_image);
982       reference_image=DestroyImage(reference_image);
983       if (difference_image == (Image *) NULL)
984         {
985           (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
986           (*fail)++;
987           continue;
988         }
989       difference_image=DestroyImage(difference_image);
990       if ((distortion/QuantumRange) > 0.0)
991         {
992           (void) fprintf(stdout,"... fail (with distortion %g).\n",
993             distortion/QuantumRange);
994           (*fail)++;
995           continue;
996         }
997       (void) fprintf(stdout,"... pass.\n");
998     }
999   }
1000   (void) fprintf(stdout,
1001     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1002     (double) (test-(*fail)),(double) *fail);
1003   return(test);
1004 }
1005 \f
1006 /*
1007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008 %                                                                             %
1009 %                                                                             %
1010 %                                                                             %
1011 %   V a l i d a t e M o n t a g e C o m m a n d                               %
1012 %                                                                             %
1013 %                                                                             %
1014 %                                                                             %
1015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016 %
1017 %  ValidateMontageCommand() validates the ImageMagick montage command line
1018 %  program and returns the number of validation tests that passed and failed.
1019 %
1020 %  The format of the ValidateMontageCommand method is:
1021 %
1022 %      size_t ValidateMontageCommand(ImageInfo *image_info,
1023 %        const char *reference_filename,const char *output_filename,
1024 %        size_t *fail,ExceptionInfo *exception)
1025 %
1026 %  A description of each parameter follows:
1027 %
1028 %    o image_info: the image info.
1029 %
1030 %    o reference_filename: the reference image filename.
1031 %
1032 %    o output_filename: the output image filename.
1033 %
1034 %    o fail: return the number of validation tests that pass.
1035 %
1036 %    o exception: return any errors or warnings in this structure.
1037 %
1038 */
1039 static size_t ValidateMontageCommand(ImageInfo *image_info,
1040   const char *reference_filename,const char *output_filename,
1041   size_t *fail,ExceptionInfo *exception)
1042 {
1043   char
1044     **arguments,
1045     command[MaxTextExtent];
1046
1047   int
1048     number_arguments;
1049
1050   MagickBooleanType
1051     status;
1052
1053   register ssize_t
1054     i,
1055     j;
1056
1057   size_t
1058     test;
1059
1060   test=0;
1061   (void) fprintf(stdout,"validate montage command line program:\n");
1062   for (i=0; montage_options[i] != (char *) NULL; i++)
1063   {
1064     CatchException(exception);
1065     (void) fprintf(stdout,"  test %.20g: %s",(double) (test++),
1066       montage_options[i]);
1067     (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
1068       reference_filename,montage_options[i],reference_filename,
1069       output_filename);
1070     arguments=StringToArgv(command,&number_arguments);
1071     if (arguments == (char **) NULL)
1072       {
1073         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
1074         (*fail)++;
1075         continue;
1076       }
1077     status=MontageImageCommand(image_info,number_arguments,arguments,
1078       (char **) NULL,exception);
1079     for (j=0; j < number_arguments; j++)
1080       arguments[j]=DestroyString(arguments[j]);
1081     arguments=(char **) RelinquishMagickMemory(arguments);
1082     if (status != MagickFalse)
1083       {
1084         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
1085         (*fail)++;
1086         continue;
1087       }
1088     (void) fprintf(stdout,"... pass.\n");
1089   }
1090   (void) fprintf(stdout,
1091     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1092     (double) (test-(*fail)),(double) *fail);
1093   return(test);
1094 }
1095 \f
1096 /*
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1098 %                                                                             %
1099 %                                                                             %
1100 %                                                                             %
1101 %   V a l i d a t e S t r e a m C o m m a n d                                 %
1102 %                                                                             %
1103 %                                                                             %
1104 %                                                                             %
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1106 %
1107 %  ValidateStreamCommand() validates the ImageMagick stream command line
1108 %  program and returns the number of validation tests that passed and failed.
1109 %
1110 %  The format of the ValidateStreamCommand method is:
1111 %
1112 %      size_t ValidateStreamCommand(ImageInfo *image_info,
1113 %        const char *reference_filename,const char *output_filename,
1114 %        size_t *fail,ExceptionInfo *exception)
1115 %
1116 %  A description of each parameter follows:
1117 %
1118 %    o image_info: the image info.
1119 %
1120 %    o reference_filename: the reference image filename.
1121 %
1122 %    o output_filename: the output image filename.
1123 %
1124 %    o fail: return the number of validation tests that pass.
1125 %
1126 %    o exception: return any errors or warnings in this structure.
1127 %
1128 */
1129 static size_t ValidateStreamCommand(ImageInfo *image_info,
1130   const char *reference_filename,const char *output_filename,
1131   size_t *fail,ExceptionInfo *exception)
1132 {
1133   char
1134     **arguments,
1135     command[MaxTextExtent];
1136
1137   int
1138     number_arguments;
1139
1140   MagickBooleanType
1141     status;
1142
1143   register ssize_t
1144     i,
1145     j;
1146
1147   size_t
1148     test;
1149
1150   test=0;
1151   (void) fprintf(stdout,"validate stream command line program:\n");
1152   for (i=0; stream_options[i] != (char *) NULL; i++)
1153   {
1154     CatchException(exception);
1155     (void) fprintf(stdout,"  test %.20g: %s",(double) (test++),
1156       stream_options[i]);
1157     (void) FormatMagickString(command,MaxTextExtent,"%s %s %s",
1158       stream_options[i],reference_filename,output_filename);
1159     arguments=StringToArgv(command,&number_arguments);
1160     if (arguments == (char **) NULL)
1161       {
1162         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
1163         (*fail)++;
1164         continue;
1165       }
1166     status=StreamImageCommand(image_info,number_arguments,arguments,
1167       (char **) NULL,exception);
1168     for (j=0; j < number_arguments; j++)
1169       arguments[j]=DestroyString(arguments[j]);
1170     arguments=(char **) RelinquishMagickMemory(arguments);
1171     if (status != MagickFalse)
1172       {
1173         (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
1174         (*fail)++;
1175         continue;
1176       }
1177     (void) fprintf(stdout,"... pass.\n");
1178   }
1179   (void) fprintf(stdout,
1180     "  summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1181     (double) (test-(*fail)),(double) *fail);
1182   return(test);
1183 }
1184 \f
1185 /*
1186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187 %                                                                             %
1188 %                                                                             %
1189 %                                                                             %
1190 %  M a i n                                                                    %
1191 %                                                                             %
1192 %                                                                             %
1193 %                                                                             %
1194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1195 %
1196 %
1197 */
1198
1199 static MagickBooleanType ValidateUsage(void)
1200 {
1201   const char
1202     **p;
1203
1204   static const char
1205     *miscellaneous[]=
1206     {
1207       "-debug events        display copious debugging information",
1208       "-help                print program options",
1209       "-log format          format of debugging information",
1210       "-validate type       validation type",
1211       "-version             print version information",
1212       (char *) NULL
1213     },
1214     *settings[]=
1215     {
1216       "-regard-warnings     pay attention to warning messages",
1217       "-verbose             print detailed information about the image",
1218       (char *) NULL
1219     };
1220
1221   (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
1222   (void) printf("Copyright: %s\n\n",GetMagickCopyright());
1223   (void) printf("Features: %s\n",GetMagickFeatures());
1224   (void) printf("Usage: %s [options ...] reference-file\n",GetClientName());
1225   (void) printf("\nValidate Settings:\n");
1226   for (p=settings; *p != (char *) NULL; p++)
1227     (void) printf("  %s\n",*p);
1228   (void) printf("\nMiscellaneous Options:\n");
1229   for (p=miscellaneous; *p != (char *) NULL; p++)
1230     (void) printf("  %s\n",*p);
1231   return(MagickTrue);
1232 }
1233
1234 int main(int argc,char **argv)
1235 {
1236 #define DestroyValidate() \
1237 { \
1238   image_info=DestroyImageInfo(image_info); \
1239   exception=DestroyExceptionInfo(exception); \
1240 }
1241 #define ThrowValidateException(asperity,tag,option) \
1242 { \
1243   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
1244     option); \
1245   CatchException(exception); \
1246   DestroyValidate(); \
1247   return(MagickFalse); \
1248 }
1249
1250   char
1251     output_filename[MaxTextExtent],
1252     reference_filename[MaxTextExtent],
1253     *option;
1254
1255   double
1256     elapsed_time,
1257     user_time;
1258
1259   ExceptionInfo
1260     *exception;
1261
1262   Image
1263     *reference_image;
1264
1265   ImageInfo
1266     *image_info;
1267
1268   MagickBooleanType
1269     regard_warnings,
1270     status;
1271
1272   register ssize_t
1273     i;
1274
1275   TimerInfo
1276     *timer;
1277
1278   size_t
1279     fail,
1280     iterations,
1281     tests;
1282
1283   ValidateType
1284     type;
1285
1286   /*
1287     Validate the ImageMagick image processing suite.
1288   */
1289   MagickCoreGenesis(*argv,MagickFalse);
1290   iterations=1;
1291   status=MagickFalse;
1292   type=AllValidate;
1293   regard_warnings=MagickFalse;
1294   (void) regard_warnings;
1295   exception=AcquireExceptionInfo();
1296   image_info=AcquireImageInfo();
1297   (void) CopyMagickString(image_info->filename,ReferenceFilename,MaxTextExtent);
1298   for (i=1; i < (ssize_t) argc; i++)
1299   {
1300     option=argv[i];
1301     if (IsMagickOption(option) == MagickFalse)
1302       {
1303         (void) CopyMagickString(image_info->filename,option,MaxTextExtent);
1304         continue;
1305       }
1306     switch (*(option+1))
1307     {
1308       case 'b':
1309       {
1310         if (LocaleCompare("bench",option+1) == 0)
1311           {
1312             iterations=StringToUnsignedLong(argv[++i]);
1313             break;
1314           }
1315         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1316       }
1317       case 'd':
1318       {
1319         if (LocaleCompare("debug",option+1) == 0)
1320           {
1321             (void) SetLogEventMask(argv[++i]);
1322             break;
1323           }
1324         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1325       }
1326       case 'h':
1327       {
1328         if (LocaleCompare("help",option+1) == 0)
1329           {
1330             (void) ValidateUsage();
1331             return(0);
1332           }
1333         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1334       }
1335       case 'l':
1336       {
1337         if (LocaleCompare("log",option+1) == 0)
1338           {
1339             if (*option != '+')
1340               (void) SetLogFormat(argv[i+1]);
1341             break;
1342           }
1343         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1344       }
1345       case 'r':
1346       {
1347         if (LocaleCompare("regard-warnings",option+1) == 0)
1348           {
1349             regard_warnings=MagickTrue;
1350             break;
1351           }
1352         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1353       }
1354       case 'v':
1355       {
1356         if (LocaleCompare("validate",option+1) == 0)
1357           {
1358             ssize_t
1359               validate;
1360
1361             if (*option == '+')
1362               break;
1363             i++;
1364             if (i == (ssize_t) argc)
1365               ThrowValidateException(OptionError,"MissingArgument",option);
1366             validate=ParseMagickOption(MagickValidateOptions,MagickFalse,
1367               argv[i]);
1368             if (validate < 0)
1369               ThrowValidateException(OptionError,"UnrecognizedValidateType",
1370                 argv[i]);
1371             type=(ValidateType) validate;
1372             break;
1373           }
1374         if ((LocaleCompare("version",option+1) == 0) ||
1375             (LocaleCompare("-version",option+1) == 0))
1376           {
1377             (void) fprintf(stdout,"Version: %s\n",
1378               GetMagickVersion((size_t *) NULL));
1379             (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
1380             (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
1381             return(0);
1382           }
1383         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1384       }
1385       default:
1386         ThrowValidateException(OptionError,"UnrecognizedOption",option)
1387     }
1388   }
1389   timer=(TimerInfo *) NULL;
1390   if (iterations > 1)
1391     timer=AcquireTimerInfo();
1392   reference_image=ReadImage(image_info,exception);
1393   tests=0;
1394   fail=0;
1395   if (reference_image == (Image *) NULL)
1396     fail++;
1397   else
1398     {
1399       if (LocaleCompare(image_info->filename,ReferenceFilename) == 0)
1400         (void) CopyMagickString(reference_image->magick,ReferenceImageFormat,
1401           MaxTextExtent);
1402       (void) AcquireUniqueFilename(reference_filename);
1403       (void) AcquireUniqueFilename(output_filename);
1404       (void) CopyMagickString(reference_image->filename,reference_filename,
1405         MaxTextExtent);
1406       status=WriteImage(image_info,reference_image);
1407       InheritException(exception,&reference_image->exception);
1408       reference_image=DestroyImage(reference_image);
1409       if (status == MagickFalse)
1410         fail++;
1411       else
1412         {
1413           (void) fprintf(stdout,"Version: %s\n",
1414             GetMagickVersion((size_t *) NULL));
1415           (void) fprintf(stdout,"Copyright: %s\n\n",
1416             GetMagickCopyright());
1417           (void) fprintf(stdout,"ImageMagick Validation Suite (%s)\n\n",
1418             MagickOptionToMnemonic(MagickValidateOptions,(ssize_t) type));
1419           if ((type & CompareValidate) != 0)
1420             tests+=ValidateCompareCommand(image_info,reference_filename,
1421               output_filename,&fail,exception);
1422           if ((type & CompositeValidate) != 0)
1423             tests+=ValidateCompositeCommand(image_info,reference_filename,
1424               output_filename,&fail,exception);
1425           if ((type & ConvertValidate) != 0)
1426             tests+=ValidateConvertCommand(image_info,reference_filename,
1427               output_filename,&fail,exception);
1428           if ((type & FormatsInMemoryValidate) != 0)
1429             tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
1430               output_filename,&fail,exception);
1431           if ((type & FormatsOnDiskValidate) != 0)
1432             tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
1433               output_filename,&fail,exception);
1434           if ((type & IdentifyValidate) != 0)
1435             tests+=ValidateIdentifyCommand(image_info,reference_filename,
1436               output_filename,&fail,exception);
1437           if ((type & ImportExportValidate) != 0)
1438             tests+=ValidateImportExportPixels(image_info,reference_filename,
1439               output_filename,&fail,exception);
1440           if ((type & MontageValidate) != 0)
1441             tests+=ValidateMontageCommand(image_info,reference_filename,
1442               output_filename,&fail,exception);
1443           if ((type & StreamValidate) != 0)
1444             tests+=ValidateStreamCommand(image_info,reference_filename,
1445               output_filename,&fail,exception);
1446           (void) fprintf(stdout,
1447             "validation suite: %.20g tests; %.20g passed; %.20g failed.\n",
1448             (double) tests,(double) (tests-fail),(double) fail);
1449         }
1450       (void) RelinquishUniqueFileResource(output_filename);
1451       (void) RelinquishUniqueFileResource(reference_filename);
1452     }
1453   if (exception->severity != UndefinedException)
1454     CatchException(exception);
1455   if (iterations > 1)
1456     {
1457       elapsed_time=GetElapsedTime(timer);
1458       user_time=GetUserTime(timer);
1459       (void) fprintf(stderr,
1460         "Performance: %.20gi %gips %0.3fu %ld:%02ld.%03ld\n",(double)
1461         iterations,1.0*iterations/elapsed_time,user_time,(long)
1462         (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)),
1463         (long) (1000.0*(elapsed_time-floor(elapsed_time))));
1464       timer=DestroyTimerInfo(timer);
1465     }
1466   DestroyValidate();
1467   MagickCoreTerminus();
1468   return(fail == 0 ? 0 : 1);
1469 }