2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
14 % ImageMagick Validation Suite %
21 % Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % http://www.imagemagick.org/script/license.php %
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. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 #include "MagickWand/MagickWand.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/resource_.h"
52 #include "MagickCore/string-private.h"
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 % V a l i d a t e C o m p a r e C o m m a n d %
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 % ValidateCompareCommand() validates the ImageMagick compare command line
67 % program and returns the number of validation tests that passed and failed.
69 % The format of the ValidateCompareCommand method is:
71 % size_t ValidateCompareCommand(ImageInfo *image_info,
72 % const char *reference_filename,const char *output_filename,
73 % size_t *fail,ExceptionInfo *exception)
75 % A description of each parameter follows:
77 % o image_info: the image info.
79 % o reference_filename: the reference image filename.
81 % o output_filename: the output image filename.
83 % o fail: return the number of validation tests that pass.
85 % o exception: return any errors or warnings in this structure.
88 static size_t ValidateCompareCommand(ImageInfo *image_info,
89 const char *reference_filename,const char *output_filename,size_t *fail,
90 ExceptionInfo *exception)
94 command[MaxTextExtent];
110 (void) FormatLocaleFile(stdout,"validate compare command line program:\n");
111 for (i=0; compare_options[i] != (char *) NULL; i++)
113 CatchException(exception);
114 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
116 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
117 compare_options[i],reference_filename,reference_filename,output_filename);
118 arguments=StringToArgv(command,&number_arguments);
119 if (arguments == (char **) NULL)
121 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
126 status=CompareImagesCommand(image_info,number_arguments,arguments,
127 (char **) NULL,exception);
128 for (j=0; j < (ssize_t) number_arguments; j++)
129 arguments[j]=DestroyString(arguments[j]);
130 arguments=(char **) RelinquishMagickMemory(arguments);
131 if (status != MagickFalse)
133 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
138 (void) FormatLocaleFile(stdout,"... pass.\n");
140 (void) FormatLocaleFile(stdout,
141 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
142 (double) (test-(*fail)),(double) *fail);
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 % V a l i d a t e C o m p o s i t e C o m m a n d %
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 % ValidateCompositeCommand() validates the ImageMagick composite command line
158 % program and returns the number of validation tests that passed and failed.
160 % The format of the ValidateCompositeCommand method is:
162 % size_t ValidateCompositeCommand(ImageInfo *image_info,
163 % const char *reference_filename,const char *output_filename,
164 % size_t *fail,ExceptionInfo *exception)
166 % A description of each parameter follows:
168 % o image_info: the image info.
170 % o reference_filename: the reference image filename.
172 % o output_filename: the output image filename.
174 % o fail: return the number of validation tests that pass.
176 % o exception: return any errors or warnings in this structure.
179 static size_t ValidateCompositeCommand(ImageInfo *image_info,
180 const char *reference_filename,const char *output_filename,size_t *fail,
181 ExceptionInfo *exception)
185 command[MaxTextExtent];
201 (void) FormatLocaleFile(stdout,"validate composite command line program:\n");
202 for (i=0; composite_options[i] != (char *) NULL; i++)
204 CatchException(exception);
205 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
206 composite_options[i]);
207 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
208 reference_filename,composite_options[i],reference_filename,
210 arguments=StringToArgv(command,&number_arguments);
211 if (arguments == (char **) NULL)
213 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
218 status=CompositeImageCommand(image_info,number_arguments,arguments,
219 (char **) NULL,exception);
220 for (j=0; j < (ssize_t) number_arguments; j++)
221 arguments[j]=DestroyString(arguments[j]);
222 arguments=(char **) RelinquishMagickMemory(arguments);
223 if (status != MagickFalse)
225 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
230 (void) FormatLocaleFile(stdout,"... pass.\n");
232 (void) FormatLocaleFile(stdout,
233 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
234 (double) (test-(*fail)),(double) *fail);
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243 % V a l i d a t e C o n v e r t C o m m a n d %
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % ValidateConvertCommand() validates the ImageMagick convert command line
250 % program and returns the number of validation tests that passed and failed.
252 % The format of the ValidateConvertCommand method is:
254 % size_t ValidateConvertCommand(ImageInfo *image_info,
255 % const char *reference_filename,const char *output_filename,
256 % size_t *fail,ExceptionInfo *exception)
258 % A description of each parameter follows:
260 % o image_info: the image info.
262 % o reference_filename: the reference image filename.
264 % o output_filename: the output image filename.
266 % o fail: return the number of validation tests that pass.
268 % o exception: return any errors or warnings in this structure.
271 static size_t ValidateConvertCommand(ImageInfo *image_info,
272 const char *reference_filename,const char *output_filename,size_t *fail,
273 ExceptionInfo *exception)
277 command[MaxTextExtent];
293 (void) FormatLocaleFile(stdout,"validate convert command line program:\n");
294 for (i=0; convert_options[i] != (char *) NULL; i++)
296 CatchException(exception);
297 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++,
299 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
300 reference_filename,convert_options[i],reference_filename,output_filename);
301 arguments=StringToArgv(command,&number_arguments);
302 if (arguments == (char **) NULL)
304 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
309 status=ConvertImageCommand(image_info,number_arguments,arguments,
310 (char **) NULL,exception);
311 for (j=0; j < (ssize_t) number_arguments; j++)
312 arguments[j]=DestroyString(arguments[j]);
313 arguments=(char **) RelinquishMagickMemory(arguments);
314 if (status != MagickFalse)
316 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
321 (void) FormatLocaleFile(stdout,"... pass.\n");
323 (void) FormatLocaleFile(stdout,
324 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
325 (double) (test-(*fail)),(double) *fail);
330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334 % V a l i d a t e I d e n t i f y C o m m a n d %
338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 % ValidateIdentifyCommand() validates the ImageMagick identify command line
341 % program and returns the number of validation tests that passed and failed.
343 % The format of the ValidateIdentifyCommand method is:
345 % size_t ValidateIdentifyCommand(ImageInfo *image_info,
346 % const char *reference_filename,const char *output_filename,
347 % size_t *fail,ExceptionInfo *exception)
349 % A description of each parameter follows:
351 % o image_info: the image info.
353 % o reference_filename: the reference image filename.
355 % o output_filename: the output image filename.
357 % o fail: return the number of validation tests that pass.
359 % o exception: return any errors or warnings in this structure.
362 static size_t ValidateIdentifyCommand(ImageInfo *image_info,
363 const char *reference_filename,const char *output_filename,size_t *fail,
364 ExceptionInfo *exception)
368 command[MaxTextExtent];
383 (void) output_filename;
385 (void) FormatLocaleFile(stdout,"validate identify command line program:\n");
386 for (i=0; identify_options[i] != (char *) NULL; i++)
388 CatchException(exception);
389 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++,
390 identify_options[i]);
391 (void) FormatLocaleString(command,MaxTextExtent,"%s %s",
392 identify_options[i],reference_filename);
393 arguments=StringToArgv(command,&number_arguments);
394 if (arguments == (char **) NULL)
396 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
401 status=IdentifyImageCommand(image_info,number_arguments,arguments,
402 (char **) NULL,exception);
403 for (j=0; j < (ssize_t) number_arguments; j++)
404 arguments[j]=DestroyString(arguments[j]);
405 arguments=(char **) RelinquishMagickMemory(arguments);
406 if (status != MagickFalse)
408 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
413 (void) FormatLocaleFile(stdout,"... pass.\n");
415 (void) FormatLocaleFile(stdout,
416 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
417 (double) (test-(*fail)),(double) *fail);
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 % 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 %
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % ValidateImageFormatsInMemory() validates the ImageMagick image formats in
433 % memory and returns the number of validation tests that passed and failed.
435 % The format of the ValidateImageFormatsInMemory method is:
437 % size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
438 % const char *reference_filename,const char *output_filename,
439 % size_t *fail,ExceptionInfo *exception)
441 % A description of each parameter follows:
443 % o image_info: the image info.
445 % o reference_filename: the reference image filename.
447 % o output_filename: the output image filename.
449 % o fail: return the number of validation tests that pass.
451 % o exception: return any errors or warnings in this structure.
456 Enable this to count remaining $TMPDIR/magick-* files. Note that the count
457 includes any files left over from other runs.
459 #undef MagickCountTempFiles
461 static size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
462 const char *reference_filename,const char *output_filename,size_t *fail,
463 ExceptionInfo *exception)
466 #ifdef MagickCountTempFiles
468 SystemCommand[MaxTextExtent],
500 (void) FormatLocaleFile(stdout,"validate image formats in memory:\n");
502 #ifdef MagickCountTempFiles
503 (void)GetPathTemplate(path);
504 /* Remove file template except for the leading "/path/to/magick-" */
505 path[strlen(path)-17]='\0';
506 (void) FormatLocaleFile(stdout," tmp path is '%s*'\n",path);
509 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
511 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
512 if ((magick_info == (const MagickInfo *) NULL) ||
513 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
514 (magick_info->encoder == (EncodeImageHandler *) NULL))
516 for (j=0; reference_types[j].type != UndefinedType; j++)
519 Generate reference image.
521 CatchException(exception);
522 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits",
523 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic(
524 MagickCompressOptions,reference_formats[i].compression),
525 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
526 (double) reference_types[j].depth);
527 (void) CopyMagickString(image_info->filename,reference_filename,
529 reference_image=ReadImage(image_info,exception);
530 if (reference_image == (Image *) NULL)
532 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
538 Write reference image.
540 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",
541 (double) reference_image->columns,(double) reference_image->rows);
542 (void) CloneString(&image_info->size,size);
543 image_info->depth=reference_types[j].depth;
544 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
545 reference_formats[i].magick,output_filename);
546 status=SetImageType(reference_image,reference_types[j].type,exception);
547 if (status == MagickFalse)
549 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
552 reference_image=DestroyImage(reference_image);
555 status=SetImageDepth(reference_image,reference_types[j].depth,exception);
556 if (status == MagickFalse)
558 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
561 reference_image=DestroyImage(reference_image);
564 reference_image->compression=reference_formats[i].compression;
565 status=WriteImage(image_info,reference_image,exception);
566 reference_image=DestroyImage(reference_image);
567 if (status == MagickFalse)
569 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
575 Ping reference image.
577 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
578 reference_formats[i].magick,output_filename);
579 ping_image=PingImage(image_info,exception);
580 if (ping_image == (Image *) NULL)
582 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
587 ping_image=DestroyImage(ping_image);
589 Read reference image.
591 reference_image=ReadImage(image_info,exception);
592 if (reference_image == (Image *) NULL)
594 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
600 Write reference image.
602 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
603 reference_formats[i].magick,output_filename);
604 (void) CopyMagickString(image_info->magick,reference_formats[i].magick,
606 reference_image->depth=reference_types[j].depth;
607 reference_image->compression=reference_formats[i].compression;
609 blob=ImageToBlob(image_info,reference_image,&length,exception);
610 if (blob == (unsigned char *) NULL)
612 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
615 reference_image=DestroyImage(reference_image);
621 ping_image=PingBlob(image_info,blob,length,exception);
622 if (ping_image == (Image *) NULL)
624 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
627 blob=(unsigned char *) RelinquishMagickMemory(blob);
630 ping_image=DestroyImage(ping_image);
632 Read reconstruct image.
634 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
635 reference_formats[i].magick,output_filename);
636 reconstruct_image=BlobToImage(image_info,blob,length,exception);
637 blob=(unsigned char *) RelinquishMagickMemory(blob);
638 if (reconstruct_image == (Image *) NULL)
640 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
643 reference_image=DestroyImage(reference_image);
647 Compare reference to reconstruct image.
649 fuzz=0.003; /* grayscale */
650 if (reference_formats[i].fuzz != 0.0)
651 fuzz=reference_formats[i].fuzz;
652 difference_image=CompareImages(reference_image,reconstruct_image,
653 RootMeanSquaredErrorMetric,&distortion,exception);
654 reconstruct_image=DestroyImage(reconstruct_image);
655 reference_image=DestroyImage(reference_image);
656 if (difference_image == (Image *) NULL)
658 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
663 difference_image=DestroyImage(difference_image);
664 if ((QuantumScale*distortion) > fuzz)
666 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
667 QuantumScale*distortion);
671 #ifdef MagickCountTempFiles
672 (void) FormatLocaleFile(stdout,"... pass, ");
673 (void) fflush(stdout);
674 SystemCommand[0]='\0';
675 (void) strncat(SystemCommand,"echo `ls ",9);
676 (void) strncat(SystemCommand,path,MaxTextExtent-31);
677 (void) strncat(SystemCommand,"* | wc -w` tmp files.",20);
678 (void) system(SystemCommand);
679 (void) fflush(stdout);
681 (void) FormatLocaleFile(stdout,"... pass\n");
685 (void) FormatLocaleFile(stdout,
686 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
687 (double) (test-(*fail)),(double) *fail);
692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696 % 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 %
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702 % ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk
703 % and returns the number of validation tests that passed and failed.
705 % The format of the ValidateImageFormatsOnDisk method is:
707 % size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
708 % const char *reference_filename,const char *output_filename,
709 % size_t *fail,ExceptionInfo *exception)
711 % A description of each parameter follows:
713 % o image_info: the image info.
715 % o reference_filename: the reference image filename.
717 % o output_filename: the output image filename.
719 % o fail: return the number of validation tests that pass.
721 % o exception: return any errors or warnings in this structure.
724 static size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
725 const char *reference_filename,const char *output_filename,size_t *fail,
726 ExceptionInfo *exception)
754 (void) FormatLocaleFile(stdout,"validate image formats on disk:\n");
755 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
757 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
758 if ((magick_info == (const MagickInfo *) NULL) ||
759 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
760 (magick_info->encoder == (EncodeImageHandler *) NULL))
762 for (j=0; reference_types[j].type != UndefinedType; j++)
765 Generate reference image.
767 CatchException(exception);
768 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits",
769 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic(
770 MagickCompressOptions,reference_formats[i].compression),
771 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
772 (double) reference_types[j].depth);
773 (void) CopyMagickString(image_info->filename,reference_filename,
775 reference_image=ReadImage(image_info,exception);
776 if (reference_image == (Image *) NULL)
778 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
784 Write reference image.
786 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",
787 (double) reference_image->columns,(double) reference_image->rows);
788 (void) CloneString(&image_info->size,size);
789 image_info->depth=reference_types[j].depth;
790 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
791 reference_formats[i].magick,output_filename);
792 status=SetImageType(reference_image,reference_types[j].type,exception);
793 if (status == MagickFalse)
795 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
798 reference_image=DestroyImage(reference_image);
801 status=SetImageDepth(reference_image,reference_types[j].depth,exception);
802 if (status == MagickFalse)
804 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
807 reference_image=DestroyImage(reference_image);
810 reference_image->compression=reference_formats[i].compression;
811 status=WriteImage(image_info,reference_image,exception);
812 reference_image=DestroyImage(reference_image);
813 if (status == MagickFalse)
815 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
821 Read reference image.
823 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
824 reference_formats[i].magick,output_filename);
825 reference_image=ReadImage(image_info,exception);
826 if (reference_image == (Image *) NULL)
828 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
834 Write reference image.
836 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
837 reference_formats[i].magick,output_filename);
838 reference_image->depth=reference_types[j].depth;
839 reference_image->compression=reference_formats[i].compression;
840 status=WriteImage(image_info,reference_image,exception);
841 if (status == MagickFalse)
843 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
846 reference_image=DestroyImage(reference_image);
850 Read reconstruct image.
852 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
853 reference_formats[i].magick,output_filename);
854 reconstruct_image=ReadImage(image_info,exception);
855 if (reconstruct_image == (Image *) NULL)
857 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
860 reference_image=DestroyImage(reference_image);
864 Compare reference to reconstruct image.
866 fuzz=0.003; /* grayscale */
867 if (reference_formats[i].fuzz != 0.0)
868 fuzz=reference_formats[i].fuzz;
869 difference_image=CompareImages(reference_image,reconstruct_image,
870 RootMeanSquaredErrorMetric,&distortion,exception);
871 reconstruct_image=DestroyImage(reconstruct_image);
872 reference_image=DestroyImage(reference_image);
873 if (difference_image == (Image *) NULL)
875 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
880 difference_image=DestroyImage(difference_image);
881 if ((QuantumScale*distortion) > fuzz)
883 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
884 QuantumScale*distortion);
888 (void) FormatLocaleFile(stdout,"... pass.\n");
891 (void) FormatLocaleFile(stdout,
892 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
893 (double) (test-(*fail)),(double) *fail);
898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 % 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 %
906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 % ValidateImportExportPixels() validates the pixel import and export methods.
909 % It returns the number of validation tests that passed and failed.
911 % The format of the ValidateImportExportPixels method is:
913 % size_t ValidateImportExportPixels(ImageInfo *image_info,
914 % const char *reference_filename,const char *output_filename,
915 % size_t *fail,ExceptionInfo *exception)
917 % A description of each parameter follows:
919 % o image_info: the image info.
921 % o reference_filename: the reference image filename.
923 % o output_filename: the output image filename.
925 % o fail: return the number of validation tests that pass.
927 % o exception: return any errors or warnings in this structure.
930 static size_t ValidateImportExportPixels(ImageInfo *image_info,
931 const char *reference_filename,const char *output_filename,size_t *fail,
932 ExceptionInfo *exception)
958 (void) output_filename;
960 (void) FormatLocaleFile(stdout,
961 "validate the import and export of image pixels:\n");
962 for (i=0; reference_map[i] != (char *) NULL; i++)
964 for (j=0; reference_storage[j].type != UndefinedPixel; j++)
967 Generate reference image.
969 CatchException(exception);
970 (void) FormatLocaleFile(stdout," test %.20g: %s/%s",(double) (test++),
971 reference_map[i],CommandOptionToMnemonic(MagickStorageOptions,
972 reference_storage[j].type));
973 (void) CopyMagickString(image_info->filename,reference_filename,
975 reference_image=ReadImage(image_info,exception);
976 if (reference_image == (Image *) NULL)
978 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
983 if (LocaleNCompare(reference_map[i],"cmy",3) == 0)
984 (void) SetImageColorspace(reference_image,CMYKColorspace,exception);
985 length=strlen(reference_map[i])*reference_image->columns*
986 reference_image->rows*reference_storage[j].quantum;
987 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
988 if (pixels == (unsigned char *) NULL)
990 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
993 reference_image=DestroyImage(reference_image);
996 (void) ResetMagickMemory(pixels,0,length*sizeof(*pixels));
997 status=ExportImagePixels(reference_image,0,0,reference_image->columns,
998 reference_image->rows,reference_map[i],reference_storage[j].type,pixels,
1000 if (status == MagickFalse)
1002 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1005 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1006 reference_image=DestroyImage(reference_image);
1009 (void) SetImageBackgroundColor(reference_image,exception);
1010 status=ImportImagePixels(reference_image,0,0,reference_image->columns,
1011 reference_image->rows,reference_map[i],reference_storage[j].type,
1013 if (status == MagickFalse)
1015 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1018 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1019 reference_image=DestroyImage(reference_image);
1023 Read reconstruct image.
1025 reconstruct_image=AcquireImage(image_info,exception);
1026 (void) SetImageExtent(reconstruct_image,reference_image->columns,
1027 reference_image->rows,exception);
1028 (void) SetImageColorspace(reconstruct_image,reference_image->colorspace,
1030 (void) SetImageBackgroundColor(reconstruct_image,exception);
1031 status=ImportImagePixels(reconstruct_image,0,0,reconstruct_image->columns,
1032 reconstruct_image->rows,reference_map[i],reference_storage[j].type,
1034 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1035 if (status == MagickFalse)
1037 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1040 reference_image=DestroyImage(reference_image);
1044 Compare reference to reconstruct image.
1046 difference_image=CompareImages(reference_image,reconstruct_image,
1047 RootMeanSquaredErrorMetric,&distortion,exception);
1048 reconstruct_image=DestroyImage(reconstruct_image);
1049 reference_image=DestroyImage(reference_image);
1050 if (difference_image == (Image *) NULL)
1052 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1057 difference_image=DestroyImage(difference_image);
1058 if ((QuantumScale*distortion) > 0.0)
1060 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
1061 QuantumScale*distortion);
1065 (void) FormatLocaleFile(stdout,"... pass.\n");
1068 (void) FormatLocaleFile(stdout,
1069 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1070 (double) (test-(*fail)),(double) *fail);
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 % V a l i d a t e M o n t a g e C o m m a n d %
1083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 % ValidateMontageCommand() validates the ImageMagick montage command line
1086 % program and returns the number of validation tests that passed and failed.
1088 % The format of the ValidateMontageCommand method is:
1090 % size_t ValidateMontageCommand(ImageInfo *image_info,
1091 % const char *reference_filename,const char *output_filename,
1092 % size_t *fail,ExceptionInfo *exception)
1094 % A description of each parameter follows:
1096 % o image_info: the image info.
1098 % o reference_filename: the reference image filename.
1100 % o output_filename: the output image filename.
1102 % o fail: return the number of validation tests that pass.
1104 % o exception: return any errors or warnings in this structure.
1107 static size_t ValidateMontageCommand(ImageInfo *image_info,
1108 const char *reference_filename,const char *output_filename,size_t *fail,
1109 ExceptionInfo *exception)
1113 command[MaxTextExtent];
1129 (void) FormatLocaleFile(stdout,"validate montage command line program:\n");
1130 for (i=0; montage_options[i] != (char *) NULL; i++)
1132 CatchException(exception);
1133 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
1134 montage_options[i]);
1135 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
1136 reference_filename,montage_options[i],reference_filename,
1138 arguments=StringToArgv(command,&number_arguments);
1139 if (arguments == (char **) NULL)
1141 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1146 status=MontageImageCommand(image_info,number_arguments,arguments,
1147 (char **) NULL,exception);
1148 for (j=0; j < (ssize_t) number_arguments; j++)
1149 arguments[j]=DestroyString(arguments[j]);
1150 arguments=(char **) RelinquishMagickMemory(arguments);
1151 if (status != MagickFalse)
1153 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1158 (void) FormatLocaleFile(stdout,"... pass.\n");
1160 (void) FormatLocaleFile(stdout,
1161 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1162 (double) (test-(*fail)),(double) *fail);
1167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1171 % V a l i d a t e S t r e a m C o m m a n d %
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 % ValidateStreamCommand() validates the ImageMagick stream command line
1178 % program and returns the number of validation tests that passed and failed.
1180 % The format of the ValidateStreamCommand method is:
1182 % size_t ValidateStreamCommand(ImageInfo *image_info,
1183 % const char *reference_filename,const char *output_filename,
1184 % size_t *fail,ExceptionInfo *exception)
1186 % A description of each parameter follows:
1188 % o image_info: the image info.
1190 % o reference_filename: the reference image filename.
1192 % o output_filename: the output image filename.
1194 % o fail: return the number of validation tests that pass.
1196 % o exception: return any errors or warnings in this structure.
1199 static size_t ValidateStreamCommand(ImageInfo *image_info,
1200 const char *reference_filename,const char *output_filename,size_t *fail,
1201 ExceptionInfo *exception)
1205 command[MaxTextExtent];
1221 (void) FormatLocaleFile(stdout,"validate stream command line program:\n");
1222 for (i=0; stream_options[i] != (char *) NULL; i++)
1224 CatchException(exception);
1225 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
1227 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s",
1228 stream_options[i],reference_filename,output_filename);
1229 arguments=StringToArgv(command,&number_arguments);
1230 if (arguments == (char **) NULL)
1232 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1237 status=StreamImageCommand(image_info,number_arguments,arguments,
1238 (char **) NULL,exception);
1239 for (j=0; j < (ssize_t) number_arguments; j++)
1240 arguments[j]=DestroyString(arguments[j]);
1241 arguments=(char **) RelinquishMagickMemory(arguments);
1242 if (status != MagickFalse)
1244 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1249 (void) FormatLocaleFile(stdout,"... pass.\n");
1251 (void) FormatLocaleFile(stdout,
1252 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1253 (double) (test-(*fail)),(double) *fail);
1258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1271 static MagickBooleanType ValidateUsage(void)
1279 "-debug events display copious debugging information",
1280 "-help print program options",
1281 "-log format format of debugging information",
1282 "-validate type validation type",
1283 "-version print version information",
1288 "-regard-warnings pay attention to warning messages",
1289 "-verbose print detailed information about the image",
1293 (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
1294 (void) printf("Copyright: %s\n\n",GetMagickCopyright());
1295 (void) printf("Features: %s\n",GetMagickFeatures());
1296 (void) printf("Usage: %s [options ...] reference-file\n",GetClientName());
1297 (void) printf("\nValidate Settings:\n");
1298 for (p=settings; *p != (char *) NULL; p++)
1299 (void) printf(" %s\n",*p);
1300 (void) printf("\nMiscellaneous Options:\n");
1301 for (p=miscellaneous; *p != (char *) NULL; p++)
1302 (void) printf(" %s\n",*p);
1306 int main(int argc,char **argv)
1308 #define DestroyValidate() \
1310 image_info=DestroyImageInfo(image_info); \
1311 exception=DestroyExceptionInfo(exception); \
1313 #define ThrowValidateException(asperity,tag,option) \
1315 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
1317 CatchException(exception); \
1318 DestroyValidate(); \
1319 return(MagickFalse); \
1323 output_filename[MaxTextExtent],
1324 reference_filename[MaxTextExtent],
1363 Validate the ImageMagick image processing suite.
1365 MagickCoreGenesis(*argv,MagickTrue);
1366 (void) setlocale(LC_ALL,"");
1367 (void) setlocale(LC_NUMERIC,"C");
1371 regard_warnings=MagickFalse;
1372 (void) regard_warnings;
1373 exception=AcquireExceptionInfo();
1374 image_info=AcquireImageInfo();
1375 (void) CopyMagickString(image_info->filename,ReferenceFilename,MaxTextExtent);
1376 for (i=1; i < (ssize_t) argc; i++)
1379 if (IsCommandOption(option) == MagickFalse)
1381 (void) CopyMagickString(image_info->filename,option,MaxTextExtent);
1384 switch (*(option+1))
1388 if (LocaleCompare("bench",option+1) == 0)
1390 iterations=StringToUnsignedLong(argv[++i]);
1393 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1397 if (LocaleCompare("debug",option+1) == 0)
1399 (void) SetLogEventMask(argv[++i]);
1402 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1406 if (LocaleCompare("help",option+1) == 0)
1408 (void) ValidateUsage();
1411 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1415 if (LocaleCompare("log",option+1) == 0)
1418 (void) SetLogFormat(argv[i+1]);
1421 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1425 if (LocaleCompare("regard-warnings",option+1) == 0)
1427 regard_warnings=MagickTrue;
1430 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1434 if (LocaleCompare("validate",option+1) == 0)
1442 if (i == (ssize_t) argc)
1443 ThrowValidateException(OptionError,"MissingArgument",option);
1444 validate=ParseCommandOption(MagickValidateOptions,MagickFalse,
1447 ThrowValidateException(OptionError,"UnrecognizedValidateType",
1449 type=(ValidateType) validate;
1452 if ((LocaleCompare("version",option+1) == 0) ||
1453 (LocaleCompare("-version",option+1) == 0))
1455 (void) FormatLocaleFile(stdout,"Version: %s\n",
1456 GetMagickVersion((size_t *) NULL));
1457 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n",
1458 GetMagickCopyright());
1459 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
1460 GetMagickFeatures());
1463 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1466 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1469 timer=(TimerInfo *) NULL;
1471 timer=AcquireTimerInfo();
1472 reference_image=ReadImage(image_info,exception);
1475 if (reference_image == (Image *) NULL)
1479 if (LocaleCompare(image_info->filename,ReferenceFilename) == 0)
1480 (void) CopyMagickString(reference_image->magick,ReferenceImageFormat,
1482 (void) AcquireUniqueFilename(reference_filename);
1483 (void) AcquireUniqueFilename(output_filename);
1484 (void) CopyMagickString(reference_image->filename,reference_filename,
1486 status=WriteImage(image_info,reference_image,exception);
1487 reference_image=DestroyImage(reference_image);
1488 if (status == MagickFalse)
1492 (void) FormatLocaleFile(stdout,"Version: %s\n",
1493 GetMagickVersion((size_t *) NULL));
1494 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n",
1495 GetMagickCopyright());
1496 (void) FormatLocaleFile(stdout,
1497 "ImageMagick Validation Suite (%s)\n\n",CommandOptionToMnemonic(
1498 MagickValidateOptions,(ssize_t) type));
1499 if ((type & CompareValidate) != 0)
1500 tests+=ValidateCompareCommand(image_info,reference_filename,
1501 output_filename,&fail,exception);
1502 if ((type & CompositeValidate) != 0)
1503 tests+=ValidateCompositeCommand(image_info,reference_filename,
1504 output_filename,&fail,exception);
1505 if ((type & ConvertValidate) != 0)
1506 tests+=ValidateConvertCommand(image_info,reference_filename,
1507 output_filename,&fail,exception);
1508 if ((type & FormatsInMemoryValidate) != 0)
1510 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] ");
1511 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
1512 output_filename,&fail,exception);
1513 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] ");
1514 memory_resource=SetMagickResourceLimit(MemoryResource,0);
1515 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
1516 output_filename,&fail,exception);
1517 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] ");
1518 map_resource=SetMagickResourceLimit(MapResource,0);
1519 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
1520 output_filename,&fail,exception);
1521 (void) SetMagickResourceLimit(MemoryResource,memory_resource);
1522 (void) SetMagickResourceLimit(MapResource,map_resource);
1524 if ((type & FormatsOnDiskValidate) != 0)
1526 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] ");
1527 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
1528 output_filename,&fail,exception);
1529 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] ");
1530 memory_resource=SetMagickResourceLimit(MemoryResource,0);
1531 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
1532 output_filename,&fail,exception);
1533 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] ");
1534 map_resource=SetMagickResourceLimit(MapResource,0);
1535 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
1536 output_filename,&fail,exception);
1537 (void) SetMagickResourceLimit(MemoryResource,memory_resource);
1538 (void) SetMagickResourceLimit(MapResource,map_resource);
1540 if ((type & IdentifyValidate) != 0)
1541 tests+=ValidateIdentifyCommand(image_info,reference_filename,
1542 output_filename,&fail,exception);
1543 if ((type & ImportExportValidate) != 0)
1544 tests+=ValidateImportExportPixels(image_info,reference_filename,
1545 output_filename,&fail,exception);
1546 if ((type & MontageValidate) != 0)
1547 tests+=ValidateMontageCommand(image_info,reference_filename,
1548 output_filename,&fail,exception);
1549 if ((type & StreamValidate) != 0)
1550 tests+=ValidateStreamCommand(image_info,reference_filename,
1551 output_filename,&fail,exception);
1552 (void) FormatLocaleFile(stdout,
1553 "validation suite: %.20g tests; %.20g passed; %.20g failed.\n",
1554 (double) tests,(double) (tests-fail),(double) fail);
1556 (void) RelinquishUniqueFileResource(output_filename);
1557 (void) RelinquishUniqueFileResource(reference_filename);
1559 if (exception->severity != UndefinedException)
1560 CatchException(exception);
1563 elapsed_time=GetElapsedTime(timer);
1564 user_time=GetUserTime(timer);
1565 (void) FormatLocaleFile(stderr,
1566 "Performance: %.20gi %gips %0.3fu %ld:%02ld.%03ld\n",(double)
1567 iterations,1.0*iterations/elapsed_time,user_time,(long)
1568 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)),
1569 (long) (1000.0*(elapsed_time-floor(elapsed_time))));
1570 timer=DestroyTimerInfo(timer);
1573 MagickCoreTerminus();
1574 return(fail == 0 ? 0 : 1);