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