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