operation.c revision d2cdc860e4860173edebd04bf4a33437724edece
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N % 7% O O P P E R R A A TT I O O NN N % 8% O O PPPP EEE RRRR AAAA TT I O O N N N % 9% O O P E R R A A TT I O O N NN % 10% OOO P EEEE R RR A A TT III OOO N N % 11% % 12% % 13% MagickWand Module Methods % 14% % 15% Software Design % 16% John Cristy % 17% September 2011 % 18% % 19% % 20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% Apply the given options (settings, and simple, or sequence operations) to 37% the given image(s) according to the current "image_info" and "draw_info" 38% settings. 39% 40% The final goal is to allow the execution in a strict one option at a time 41% manner that is needed for 'pipelining and file scripting' of options in 42% IMv7. 43% 44% Anthony Thyssen, Sept 2011 45*/ 46#if 0 47 48/* 49 Include declarations. 50*/ 51#include "MagickWand/studio.h" 52#include "MagickWand/MagickWand.h" 53#include "MagickWand/mogrify-private.h" 54#include "MagickCore/monitor-private.h" 55#include "MagickCore/thread-private.h" 56#include "MagickCore/string-private.h" 57 58/* 59 Define declarations. 60*/ 61#define UndefinedCompressionQuality 0UL 62/* 63 Constant declaration. (temporary exports) 64*/ 65static const char 66 BackgroundColor[] = "#fff", /* white */ 67 BorderColor[] = "#dfdfdf", /* gray */ 68 MatteColor[] = "#bdbdbd"; /* gray */ 69 70/* 71** Function to report on the progress of image operations 72*/ 73static MagickBooleanType MonitorProgress(const char *text, 74 const MagickOffsetType offset,const MagickSizeType extent, 75 void *wand_unused(client_data)) 76{ 77 char 78 message[MaxTextExtent], 79 tag[MaxTextExtent]; 80 81 const char 82 *locale_message; 83 84 register char 85 *p; 86 87 if (extent < 2) 88 return(MagickTrue); 89 (void) CopyMagickMemory(tag,text,MaxTextExtent); 90 p=strrchr(tag,'/'); 91 if (p != (char *) NULL) 92 *p='\0'; 93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag); 94 locale_message=GetLocaleMessage(message); 95 if (locale_message == message) 96 locale_message=tag; 97 if (p == (char *) NULL) 98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r", 99 locale_message,(long) offset,(unsigned long) extent,(long) 100 (100L*offset/(extent-1))); 101 else 102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r", 103 locale_message,p+1,(long) offset,(unsigned long) extent,(long) 104 (100L*offset/(extent-1))); 105 if (offset == (MagickOffsetType) (extent-1)) 106 (void) FormatLocaleFile(stderr,"\n"); 107 (void) fflush(stderr); 108 return(MagickTrue); 109} 110 111/* 112** GetImageCache() will read an image into a image cache if not already 113** present then return the image that is in the cache under that filename. 114*/ 115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path, 116 ExceptionInfo *exception) 117{ 118 char 119 key[MaxTextExtent]; 120 121 ExceptionInfo 122 *sans_exception; 123 124 Image 125 *image; 126 127 ImageInfo 128 *read_info; 129 130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path); 131 sans_exception=AcquireExceptionInfo(); 132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception); 133 sans_exception=DestroyExceptionInfo(sans_exception); 134 if (image != (Image *) NULL) 135 return(image); 136 read_info=CloneImageInfo(image_info); 137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent); 138 image=ReadImage(read_info,exception); 139 read_info=DestroyImageInfo(read_info); 140 if (image != (Image *) NULL) 141 (void) SetImageRegistry(ImageRegistryType,key,image,exception); 142 return(image); 143} 144 145/* 146 SparseColorOption() parse the complex -sparse-color argument into an 147 an array of floating point values than call SparseColorImage(). 148 Argument is a complex mix of floating-point pixel coodinates, and color 149 specifications (or direct floating point numbers). The number of floats 150 needed to represent a color varies depending on teh current channel 151 setting. 152*/ 153static Image *SparseColorOption(const Image *image, 154 const SparseColorMethod method,const char *arguments, 155 const MagickBooleanType color_from_image,ExceptionInfo *exception) 156{ 157 char 158 token[MaxTextExtent]; 159 160 const char 161 *p; 162 163 double 164 *sparse_arguments; 165 166 Image 167 *sparse_image; 168 169 PixelInfo 170 color; 171 172 MagickBooleanType 173 error; 174 175 register size_t 176 x; 177 178 size_t 179 number_arguments, 180 number_colors; 181 182 assert(image != (Image *) NULL); 183 assert(image->signature == MagickSignature); 184 if (image->debug != MagickFalse) 185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 186 assert(exception != (ExceptionInfo *) NULL); 187 assert(exception->signature == MagickSignature); 188 /* 189 Limit channels according to image - and add up number of color channel. 190 */ 191 number_colors=0; 192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 193 number_colors++; 194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 195 number_colors++; 196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 197 number_colors++; 198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) && 199 (image->colorspace == CMYKColorspace)) 200 number_colors++; 201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) && 202 (image->matte != MagickFalse)) 203 number_colors++; 204 205 /* 206 Read string, to determine number of arguments needed, 207 */ 208 p=arguments; 209 x=0; 210 while( *p != '\0' ) 211 { 212 GetMagickToken(p,&p,token); 213 if ( token[0] == ',' ) continue; 214 if ( isalpha((int) token[0]) || token[0] == '#' ) { 215 if ( color_from_image ) { 216 (void) ThrowMagickException(exception,GetMagickModule(), 217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color", 218 "Color arg given, when colors are coming from image"); 219 return( (Image *)NULL); 220 } 221 x += number_colors; /* color argument */ 222 } 223 else { 224 x++; /* floating point argument */ 225 } 226 } 227 error=MagickTrue; 228 if ( color_from_image ) { 229 /* just the control points are being given */ 230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse; 231 number_arguments=(x/2)*(2+number_colors); 232 } 233 else { 234 /* control points and color values */ 235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse; 236 number_arguments=x; 237 } 238 if ( error ) { 239 (void) ThrowMagickException(exception,GetMagickModule(), 240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color", 241 "Invalid number of Arguments"); 242 return( (Image *)NULL); 243 } 244 245 /* Allocate and fill in the floating point arguments */ 246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments, 247 sizeof(*sparse_arguments)); 248 if (sparse_arguments == (double *) NULL) { 249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, 250 "MemoryAllocationFailed","%s","SparseColorOption"); 251 return( (Image *)NULL); 252 } 253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments* 254 sizeof(*sparse_arguments)); 255 p=arguments; 256 x=0; 257 while( *p != '\0' && x < number_arguments ) { 258 /* X coordinate */ 259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token); 260 if ( token[0] == '\0' ) break; 261 if ( isalpha((int) token[0]) || token[0] == '#' ) { 262 (void) ThrowMagickException(exception,GetMagickModule(), 263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color", 264 "Color found, instead of X-coord"); 265 error = MagickTrue; 266 break; 267 } 268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 269 /* Y coordinate */ 270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token); 271 if ( token[0] == '\0' ) break; 272 if ( isalpha((int) token[0]) || token[0] == '#' ) { 273 (void) ThrowMagickException(exception,GetMagickModule(), 274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color", 275 "Color found, instead of Y-coord"); 276 error = MagickTrue; 277 break; 278 } 279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 280 /* color values for this control point */ 281#if 0 282 if ( (color_from_image ) { 283 /* get color from image */ 284 /* HOW??? */ 285 } 286 else 287#endif 288 { 289 /* color name or function given in string argument */ 290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token); 291 if ( token[0] == '\0' ) break; 292 if ( isalpha((int) token[0]) || token[0] == '#' ) { 293 /* Color string given */ 294 (void) QueryMagickColorCompliance(token,AllCompliance,&color, 295 exception); 296 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 297 sparse_arguments[x++] = QuantumScale*color.red; 298 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 299 sparse_arguments[x++] = QuantumScale*color.green; 300 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 301 sparse_arguments[x++] = QuantumScale*color.blue; 302 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) && 303 (image->colorspace == CMYKColorspace)) 304 sparse_arguments[x++] = QuantumScale*color.black; 305 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) && 306 (image->matte != MagickFalse)) 307 sparse_arguments[x++] = QuantumScale*color.alpha; 308 } 309 else { 310 /* Colors given as a set of floating point values - experimental */ 311 /* NB: token contains the first floating point value to use! */ 312 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 313 { 314 while ( token[0] == ',' ) GetMagickToken(p,&p,token); 315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' ) 316 break; 317 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 318 token[0] = ','; /* used this token - get another */ 319 } 320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 321 { 322 while ( token[0] == ',' ) GetMagickToken(p,&p,token); 323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' ) 324 break; 325 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 326 token[0] = ','; /* used this token - get another */ 327 } 328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 329 { 330 while ( token[0] == ',' ) GetMagickToken(p,&p,token); 331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' ) 332 break; 333 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 334 token[0] = ','; /* used this token - get another */ 335 } 336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) && 337 (image->colorspace == CMYKColorspace)) 338 { 339 while ( token[0] == ',' ) GetMagickToken(p,&p,token); 340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' ) 341 break; 342 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 343 token[0] = ','; /* used this token - get another */ 344 } 345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) && 346 (image->matte != MagickFalse)) 347 { 348 while ( token[0] == ',' ) GetMagickToken(p,&p,token); 349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' ) 350 break; 351 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL); 352 token[0] = ','; /* used this token - get another */ 353 } 354 } 355 } 356 } 357 if ( number_arguments != x && !error ) { 358 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 359 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error"); 360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments); 361 return( (Image *)NULL); 362 } 363 if ( error ) 364 return( (Image *)NULL); 365 366 /* Call the Interpolation function with the parsed arguments */ 367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments, 368 exception); 369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments); 370 return( sparse_image ); 371} 372 373/* 374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 375% % 376% % 377% % 378+ A p p l y S e t t i n g O p t i o n % 379% % 380% % 381% % 382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 383% 384% ApplySettingOption() saves the given single settings option into a CLI wand 385% holding the image_info, draw_info, quantize_info structures that is later 386% used for reading, processing, and writing images. 387% 388% No image in the wand is actually modified (setting options only) 389% 390% The format of the ApplySettingOption method is: 391% 392% MagickBooleanType ApplySettingOption(MagickWand *wand, 393% const int argc, const char **argv,ExceptionInfo *exception) 394% 395% A description of each parameter follows: 396% 397% o wand: structure holding settings to be applied 398% 399% o argc: Specifies a pointer to an integer describing the number of 400% elements in the argument vector. 401% 402% o argv: Specifies a pointer to a text array containing the command line 403% arguments. 404% 405% o exception: return any errors or warnings in this structure. 406% 407*/ 408WandExport MagickBooleanType ApplySettingsOption(ImageInfo *image_info, 409 const int argc,const char **argv,ExceptionInfo *exception) 410{ 411 GeometryInfo 412 geometry_info; 413 414 ImageInfo 415 *image_info; 416 417 DrawInfo 418 *draw_info; 419 420 const char 421 *option; 422 423 assert(wand != (MagickWand *) NULL); 424 assert(wand->signature == WandSignature); 425 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */ 426 assert(wand->quantize_info == (QuantizeInfo *) NULL); 427 if (wand->debug != MagickFalse) 428 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 429 if (argc < 0) 430 return(MagickTrue); 431 432 option=argv[0]+1; 433 image_info=wand->image_info; 434 draw_info=wand->_info; 435 436#define DeleteOption (const char*)NULL 437#define IfSetOption ((*argv[0])=='-') 438 439 switch (*option) 440 { 441 case 'a': 442 { 443 if (LocaleCompare("adjoin",option) == 0) 444 { 445 image_info->adjoin = IfSetOption ? MagickTrue : MagickFalse; 446 break; 447 } 448 if (LocaleCompare("affine",option) == 0) 449 { 450 if (IfSetOption) 451 (void) ParseAffineGeometry(argv[1],draw_info->affine, 452 exception); 453 else 454 GetAffineMatrix(draw_info->affine); 455 break; 456 } 457 if (LocaleCompare("antialias",option) == 0) 458 { 459 image_info->antialias = 460 draw_info->stroke_antialias = 461 draw_info->text_antialias = 462 IfSetOption ? MagickTrue : MagickFalse; 463 break; 464 } 465 if (LocaleCompare("attenuate",option) == 0) 466 { 467 (void) SetImageOption(image_info,option, 468 IfSetOption ? argv[1] : DeleteOption); 469 break; 470 } 471 if (LocaleCompare("authenticate",option) == 0) 472 { 473 (void) SetImageOption(image_info,option, 474 IfSetOption ? argv[1] : DeleteOption); 475 break; 476 } 477 break; 478 } 479 case 'b': 480 { 481 if (LocaleCompare("background",option) == 0) 482 { 483 /* FUTURE: both image_info attribute & ImageOption in use! 484 Note that +background, means fall-back to image attribute 485 so ImageOption is deleted, not set to a default. 486 */ 487 if (IfSetOption) 488 { 489 (void) DeleteImageOption(image_info,option); 490 (void) QueryColorCompliance(BackgroundColor,AllCompliance, 491 image_info->background_color,exception); 492 break; 493 } 494 (void) SetImageOption(image_info,option,argv[1]); 495 (void) QueryColorCompliance(argv[1],AllCompliance, 496 image_info->background_color,exception); 497 break; 498 } 499 if (LocaleCompare("bias",option) == 0) 500 { 501 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias" 502 as it is actually rarely used except in direct convolve 503 Usage outside direct convolve is actally non-sensible! 504 */ 505 (void) SetImageOption(image_info,option, 506 IfSetOption ? argv[1] : "0"); 507 break; 508 } 509 if (LocaleCompare("black-point-compensation",option) == 0) 510 { 511 (void) SetImageOption(image_info,option, 512 IfSetOption ? "true" : "false" ); 513 break; 514 } 515 if (LocaleCompare("blue-primary",option) == 0) 516 { 517 (void) SetImageOption(image_info,option, 518 IfSetOption ? argv[1] : "0" ); 519 break; 520 } 521 if (LocaleCompare("bordercolor",option) == 0) 522 { 523 /* FUTURE: both image_info attribute & ImageOption in use! */ 524 if (IfSetOption) 525 { 526 (void) SetImageOption(image_info,option,argv[1]); 527 (void) QueryColorCompliance(argv[1],AllCompliece, 528 &image_info->border_color,exception); 529 (void) QueryColorCompliance(argv[1],AllCompliance, 530 &draw_info->border_color,exception); 531 break; 532 } 533 (void) DeleteImageOption(image_info,option); 534 (void) QueryColorCompliance(BorderColor,AllCompliance, 535 &image_info->border_color,exception); 536 (void) QueryColorCompliance(BorderColor,AllCompliance, 537 &draw_info->border_color,exception); 538 break; 539 } 540 if (LocaleCompare("box",option) == 0) 541 { 542 const char 543 *value = IfSetOption ? argv[1] : "none"; 544 (void) SetImageOption(image_info,option,value); 545 (void) QueryColorCompliance(value,AllCompliance, 546 &draw_info->undercolor,exception); 547 break; 548 } 549 break; 550 } 551 case 'c': 552 { 553 if (LocaleCompare("cache",option) == 0) 554 { 555 MagickSizeType 556 limit; 557 558 limit=MagickResourceInfinity; 559 if (LocaleCompare("unlimited",argv[1]) != 0) 560 limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0); 561 (void) SetMagickResourceLimit(MemoryResource,limit); 562 (void) SetMagickResourceLimit(MapResource,2*limit); 563 break; 564 } 565 if (LocaleCompare("caption",option) == 0) 566 { 567 (void) SetImageOption(image_info,option, 568 IfSetOption ? argv[1] : DeleteOption); 569 break; 570 } 571 if (LocaleCompare("channel",option) == 0) 572 { 573 image_info->channel=(ChannelType) ( 574 IfSetOption ? ParseChannelOption(argv[1]) : DefaultChannels ); 575 /* This is also a SimpleImageOperator */ 576 break; 577 } 578 if (LocaleCompare("colorspace",option) == 0) 579 { 580 /* This is also a SimpleImageOperator */ 581 /* Undefined colorspace means don't modify images */ 582 image_info->colorspace=UndefinedColorspace; 583 if (IfSetOption) 584 image_info->colorspace=(ColorspaceType) ParseCommandOption( 585 MagickColorspaceOptions,MagickFalse,argv[1]) 586 break; 587 } 588 if (LocaleCompare("comment",option) == 0) 589 { 590 (void) SetImageOption(image_info,option, 591 IfSetOption ? argv[1] : DeleteOption); 592 break; 593 } 594 if (LocaleCompare("compose",option) == 0) 595 { 596 /* FUTURE: What should be used? image_info or ImageOption ??? 597 The former is more efficent, the later cristy prefers! 598 */ 599 const char 600 *value; 601 602 value = IfSetOption ? argv[1] : "undefined"; 603 (void) SetImageOption(image_info,option,value); 604 image_info->compose=(CompositeOperator) ParseCommandOption( 605 MagickComposeOptions,MagickFalse,value); 606 break; 607 } 608 if (LocaleCompare("compress",option) == 0) 609 { 610 if (*argv[0] == '+') 611 { 612 image_info->compression=UndefinedCompression; 613 (void) SetImageOption(image_info,option,"undefined"); 614 break; 615 } 616 image_info->compression=(CompressionType) ParseCommandOption( 617 MagickCompressOptions,MagickFalse,argv[1]); 618 (void) SetImageOption(image_info,option,argv[1]); 619 break; 620 } 621 break; 622 } 623 case 'd': 624 { 625 if (LocaleCompare("debug",option) == 0) 626 { 627 if (*argv[0] == '+') 628 (void) SetLogEventMask("none"); 629 else 630 (void) SetLogEventMask(argv[1]); 631 image_info->debug=IsEventLogging(); 632 break; 633 } 634 if (LocaleCompare("define",option) == 0) 635 { 636 if (*argv[0] == '+') 637 { 638 if (LocaleNCompare(argv[1],"registry:",9) == 0) 639 (void) DeleteImageRegistry(argv[1]+9); 640 else 641 (void) DeleteImageOption(image_info,argv[1]); 642 break; 643 } 644 if (LocaleNCompare(argv[1],"registry:",9) == 0) 645 { 646 (void) DefineImageRegistry(StringRegistryType,argv[1]+9, 647 exception); 648 break; 649 } 650 (void) DefineImageOption(image_info,argv[1]); 651 break; 652 } 653 if (LocaleCompare("delay",option) == 0) 654 { 655 if (*argv[0] == '+') 656 { 657 (void) SetImageOption(image_info,option,"0"); 658 break; 659 } 660 (void) SetImageOption(image_info,option,argv[1]); 661 break; 662 } 663 if (LocaleCompare("density",option) == 0) 664 { 665 /* 666 Set image density. 667 */ 668 if (*argv[0] == '+') 669 { 670 if (image_info->density != (char *) NULL) 671 image_info->density=DestroyString(image_info->density); 672 (void) SetImageOption(image_info,option,"72"); 673 break; 674 } 675 (void) CloneString(&image_info->density,argv[1]); 676 (void) SetImageOption(image_info,option,argv[1]); 677 break; 678 } 679 if (LocaleCompare("depth",option) == 0) 680 { 681 if (*argv[0] == '+') 682 { 683 image_info->depth=MAGICKCORE_QUANTUM_DEPTH; 684 break; 685 } 686 image_info->depth=StringToUnsignedLong(argv[1]); 687 break; 688 } 689 if (LocaleCompare("direction",option) == 0) 690 { 691 if (*argv[0] == '+') 692 { 693 (void) SetImageOption(image_info,option,"undefined"); 694 break; 695 } 696 (void) SetImageOption(image_info,option,argv[1]); 697 break; 698 } 699 if (LocaleCompare("display",option) == 0) 700 { 701 if (*argv[0] == '+') 702 { 703 if (image_info->server_name != (char *) NULL) 704 image_info->server_name=DestroyString( 705 image_info->server_name); 706 break; 707 } 708 (void) CloneString(&image_info->server_name,argv[1]); 709 break; 710 } 711 if (LocaleCompare("dispose",option) == 0) 712 { 713 if (*argv[0] == '+') 714 { 715 (void) SetImageOption(image_info,option,"undefined"); 716 break; 717 } 718 (void) SetImageOption(image_info,option,argv[1]); 719 break; 720 } 721 if (LocaleCompare("dither",option) == 0) 722 { 723 if (*argv[0] == '+') 724 { 725 image_info->dither=MagickFalse; 726 (void) SetImageOption(image_info,option,"none"); 727 break; 728 } 729 (void) SetImageOption(image_info,option,argv[1]); 730 image_info->dither=MagickTrue; 731 break; 732 } 733 break; 734 } 735 case 'e': 736 { 737 if (LocaleCompare("encoding",option) == 0) 738 { 739 if (*argv[0] == '+') 740 { 741 (void) SetImageOption(image_info,option,"undefined"); 742 break; 743 } 744 (void) SetImageOption(image_info,option,argv[1]); 745 break; 746 } 747 if (LocaleCompare("endian",option) == 0) 748 { 749 if (*argv[0] == '+') 750 { 751 image_info->endian=UndefinedEndian; 752 (void) SetImageOption(image_info,option,"undefined"); 753 break; 754 } 755 image_info->endian=(EndianType) ParseCommandOption( 756 MagickEndianOptions,MagickFalse,argv[1]); 757 (void) SetImageOption(image_info,option,argv[1]); 758 break; 759 } 760 if (LocaleCompare("extract",option) == 0) 761 { 762 /* 763 Set image extract geometry. 764 */ 765 if (*argv[0] == '+') 766 { 767 if (image_info->extract != (char *) NULL) 768 image_info->extract=DestroyString(image_info->extract); 769 break; 770 } 771 (void) CloneString(&image_info->extract,argv[1]); 772 break; 773 } 774 break; 775 } 776 case 'f': 777 { 778 if (LocaleCompare("fill",option) == 0) 779 { 780 if (*argv[0] == '+') 781 { 782 (void) SetImageOption(image_info,option,"none"); 783 break; 784 } 785 (void) SetImageOption(image_info,option,argv[1]); 786 break; 787 } 788 if (LocaleCompare("filter",option) == 0) 789 { 790 if (*argv[0] == '+') 791 { 792 (void) SetImageOption(image_info,option,"undefined"); 793 break; 794 } 795 (void) SetImageOption(image_info,option,argv[1]); 796 break; 797 } 798 if (LocaleCompare("font",option) == 0) 799 { 800 if (*argv[0] == '+') 801 { 802 if (image_info->font != (char *) NULL) 803 image_info->font=DestroyString(image_info->font); 804 break; 805 } 806 (void) CloneString(&image_info->font,argv[1]); 807 break; 808 } 809 if (LocaleCompare("format",option) == 0) 810 { 811 register const char 812 *q; 813 814 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%')) 815 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL) 816 image_info->ping=MagickFalse; 817 (void) SetImageOption(image_info,option,argv[1]); 818 break; 819 } 820 if (LocaleCompare("fuzz",option) == 0) 821 { 822 if (*argv[0] == '+') 823 { 824 image_info->fuzz=0.0; 825 (void) SetImageOption(image_info,option,"0"); 826 break; 827 } 828 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+ 829 1.0); 830 (void) SetImageOption(image_info,option,argv[1]); 831 break; 832 } 833 break; 834 } 835 case 'g': 836 { 837 if (LocaleCompare("gravity",option) == 0) 838 { 839 if (*argv[0] == '+') 840 { 841 (void) SetImageOption(image_info,option,"undefined"); 842 break; 843 } 844 (void) SetImageOption(image_info,option,argv[1]); 845 break; 846 } 847 if (LocaleCompare("green-primary",option) == 0) 848 { 849 if (*argv[0] == '+') 850 { 851 (void) SetImageOption(image_info,option,"0.0"); 852 break; 853 } 854 (void) SetImageOption(image_info,option,argv[1]); 855 break; 856 } 857 break; 858 } 859 case 'i': 860 { 861 if (LocaleCompare("intent",option) == 0) 862 { 863 if (*argv[0] == '+') 864 { 865 (void) SetImageOption(image_info,option,"undefined"); 866 break; 867 } 868 (void) SetImageOption(image_info,option,argv[1]); 869 break; 870 } 871 if (LocaleCompare("interlace",option) == 0) 872 { 873 if (*argv[0] == '+') 874 { 875 image_info->interlace=UndefinedInterlace; 876 (void) SetImageOption(image_info,option,"undefined"); 877 break; 878 } 879 image_info->interlace=(InterlaceType) ParseCommandOption( 880 MagickInterlaceOptions,MagickFalse,argv[1]); 881 (void) SetImageOption(image_info,option,argv[1]); 882 break; 883 } 884 if (LocaleCompare("interline-spacing",option) == 0) 885 { 886 if (*argv[0] == '+') 887 { 888 (void) SetImageOption(image_info,option,"undefined"); 889 break; 890 } 891 (void) SetImageOption(image_info,option,argv[1]); 892 break; 893 } 894 if (LocaleCompare("interpolate",option) == 0) 895 { 896 if (*argv[0] == '+') 897 { 898 (void) SetImageOption(image_info,option,"undefined"); 899 break; 900 } 901 (void) SetImageOption(image_info,option,argv[1]); 902 break; 903 } 904 if (LocaleCompare("interword-spacing",option) == 0) 905 { 906 if (*argv[0] == '+') 907 { 908 (void) SetImageOption(image_info,option,"undefined"); 909 break; 910 } 911 (void) SetImageOption(image_info,option,argv[1]); 912 break; 913 } 914 break; 915 } 916 case 'k': 917 { 918 if (LocaleCompare("kerning",option) == 0) 919 { 920 if (*argv[0] == '+') 921 { 922 (void) SetImageOption(image_info,option,"undefined"); 923 break; 924 } 925 (void) SetImageOption(image_info,option,argv[1]); 926 break; 927 } 928 break; 929 } 930 case 'l': 931 { 932 if (LocaleCompare("label",option) == 0) 933 { 934 if (*argv[0] == '+') 935 { 936 (void) DeleteImageOption(image_info,option); 937 break; 938 } 939 (void) SetImageOption(image_info,option,argv[1]); 940 break; 941 } 942 if (LocaleCompare("limit",option) == 0) 943 { 944 MagickSizeType 945 limit; 946 947 ResourceType 948 type; 949 950 if (*argv[0] == '+') 951 break; 952 type=(ResourceType) ParseCommandOption(MagickResourceOptions, 953 MagickFalse,argv[1]); 954 limit=MagickResourceInfinity; 955 if (LocaleCompare("unlimited",argv[2]) != 0) 956 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0); 957 (void) SetMagickResourceLimit(type,limit); 958 break; 959 } 960 if (LocaleCompare("list",option) == 0) 961 { 962 ssize_t 963 list; 964 965 /* 966 Display configuration list. 967 */ 968 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]); 969 switch (list) 970 { 971 case MagickCoderOptions: 972 { 973 (void) ListCoderInfo((FILE *) NULL,exception); 974 break; 975 } 976 case MagickColorOptions: 977 { 978 (void) ListColorInfo((FILE *) NULL,exception); 979 break; 980 } 981 case MagickConfigureOptions: 982 { 983 (void) ListConfigureInfo((FILE *) NULL,exception); 984 break; 985 } 986 case MagickDelegateOptions: 987 { 988 (void) ListDelegateInfo((FILE *) NULL,exception); 989 break; 990 } 991 case MagickFontOptions: 992 { 993 (void) ListTypeInfo((FILE *) NULL,exception); 994 break; 995 } 996 case MagickFormatOptions: 997 { 998 (void) ListMagickInfo((FILE *) NULL,exception); 999 break; 1000 } 1001 case MagickLocaleOptions: 1002 { 1003 (void) ListLocaleInfo((FILE *) NULL,exception); 1004 break; 1005 } 1006 case MagickLogOptions: 1007 { 1008 (void) ListLogInfo((FILE *) NULL,exception); 1009 break; 1010 } 1011 case MagickMagicOptions: 1012 { 1013 (void) ListMagicInfo((FILE *) NULL,exception); 1014 break; 1015 } 1016 case MagickMimeOptions: 1017 { 1018 (void) ListMimeInfo((FILE *) NULL,exception); 1019 break; 1020 } 1021 case MagickModuleOptions: 1022 { 1023 (void) ListModuleInfo((FILE *) NULL,exception); 1024 break; 1025 } 1026 case MagickPolicyOptions: 1027 { 1028 (void) ListPolicyInfo((FILE *) NULL,exception); 1029 break; 1030 } 1031 case MagickResourceOptions: 1032 { 1033 (void) ListMagickResourceInfo((FILE *) NULL,exception); 1034 break; 1035 } 1036 case MagickThresholdOptions: 1037 { 1038 (void) ListThresholdMaps((FILE *) NULL,exception); 1039 break; 1040 } 1041 default: 1042 { 1043 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list, 1044 exception); 1045 break; 1046 } 1047 } 1048 break; 1049 } 1050 if (LocaleCompare("log",option) == 0) 1051 { 1052 if (*argv[0] == '+') 1053 break; 1054 (void) SetLogFormat(argv[1]); 1055 break; 1056 } 1057 if (LocaleCompare("loop",option) == 0) 1058 { 1059 if (*argv[0] == '+') 1060 { 1061 (void) SetImageOption(image_info,option,"0"); 1062 break; 1063 } 1064 (void) SetImageOption(image_info,option,argv[1]); 1065 break; 1066 } 1067 break; 1068 } 1069 case 'm': 1070 { 1071 if (LocaleCompare("matte",option) == 0) 1072 { 1073 if (*argv[0] == '+') 1074 { 1075 (void) SetImageOption(image_info,option,"false"); 1076 break; 1077 } 1078 (void) SetImageOption(image_info,option,"true"); 1079 break; 1080 } 1081 if (LocaleCompare("mattecolor",option) == 0) 1082 { 1083 if (*argv[0] == '+') 1084 { 1085 (void) SetImageOption(image_info,option,argv[1]); 1086 (void) QueryColorCompliance(MatteColor,AllCompliance, 1087 &image_info->matte_color,exception); 1088 break; 1089 } 1090 (void) SetImageOption(image_info,option,argv[1]); 1091 (void) QueryColorCompliance(argv[1],AllCompliance,&image_info->matte_color, 1092 exception); 1093 break; 1094 } 1095 if (LocaleCompare("monitor",option) == 0) 1096 { 1097 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress, 1098 (void *) NULL); 1099 break; 1100 } 1101 if (LocaleCompare("monochrome",option) == 0) 1102 { 1103 image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse; 1104 break; 1105 } 1106 break; 1107 } 1108 case 'o': 1109 { 1110 if (LocaleCompare("orient",option) == 0) 1111 { 1112 if (*argv[0] == '+') 1113 { 1114 image_info->orientation=UndefinedOrientation; 1115 (void) SetImageOption(image_info,option,"undefined"); 1116 break; 1117 } 1118 image_info->orientation=(OrientationType) ParseCommandOption( 1119 MagickOrientationOptions,MagickFalse,argv[1]); 1120 (void) SetImageOption(image_info,option,argv[1]); 1121 break; 1122 } 1123 } 1124 case 'p': 1125 { 1126 if (LocaleCompare("page",option) == 0) 1127 { 1128 char 1129 *canonical_page, 1130 page[MaxTextExtent]; 1131 1132 const char 1133 *image_option; 1134 1135 MagickStatusType 1136 flags; 1137 1138 RectangleInfo 1139 geometry; 1140 1141 if (*argv[0] == '+') 1142 { 1143 (void) DeleteImageOption(image_info,option); 1144 (void) CloneString(&image_info->page,(char *) NULL); 1145 break; 1146 } 1147 (void) ResetMagickMemory(&geometry,0,sizeof(geometry)); 1148 image_option=GetImageOption(image_info,"page"); 1149 if (image_option != (const char *) NULL) 1150 flags=ParseAbsoluteGeometry(image_option,&geometry); 1151 canonical_page=GetPageGeometry(argv[1]); 1152 flags=ParseAbsoluteGeometry(canonical_page,&geometry); 1153 canonical_page=DestroyString(canonical_page); 1154 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu", 1155 (unsigned long) geometry.width,(unsigned long) geometry.height); 1156 if (((flags & XValue) != 0) || ((flags & YValue) != 0)) 1157 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld", 1158 (unsigned long) geometry.width,(unsigned long) geometry.height, 1159 (long) geometry.x,(long) geometry.y); 1160 (void) SetImageOption(image_info,option,page); 1161 (void) CloneString(&image_info->page,page); 1162 break; 1163 } 1164 if (LocaleCompare("pen",option) == 0) 1165 { 1166 if (*argv[0] == '+') 1167 { 1168 (void) SetImageOption(image_info,option,"none"); 1169 break; 1170 } 1171 (void) SetImageOption(image_info,option,argv[1]); 1172 break; 1173 } 1174 if (LocaleCompare("ping",option) == 0) 1175 { 1176 image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse; 1177 break; 1178 } 1179 if (LocaleCompare("pointsize",option) == 0) 1180 { 1181 if (*argv[0] == '+') 1182 geometry_info.rho=0.0; 1183 else 1184 (void) ParseGeometry(argv[1],&geometry_info); 1185 image_info->pointsize=geometry_info.rho; 1186 break; 1187 } 1188 if (LocaleCompare("precision",option) == 0) 1189 { 1190 (void) SetMagickPrecision(StringToInteger(argv[1])); 1191 break; 1192 } 1193 if (LocaleCompare("preview",option) == 0) 1194 { 1195 /* 1196 Preview image. 1197 */ 1198 if (*argv[0] == '+') 1199 { 1200 image_info->preview_type=UndefinedPreview; 1201 break; 1202 } 1203 image_info->preview_type=(PreviewType) ParseCommandOption( 1204 MagickPreviewOptions,MagickFalse,argv[1]); 1205 break; 1206 } 1207 break; 1208 } 1209 case 'q': 1210 { 1211 if (LocaleCompare("quality",option) == 0) 1212 { 1213 /* 1214 Set image compression quality. 1215 */ 1216 if (*argv[0] == '+') 1217 { 1218 image_info->quality=UndefinedCompressionQuality; 1219 (void) SetImageOption(image_info,option,"0"); 1220 break; 1221 } 1222 image_info->quality=StringToUnsignedLong(argv[1]); 1223 (void) SetImageOption(image_info,option,argv[1]); 1224 break; 1225 } 1226 if (LocaleCompare("quiet",option) == 0) 1227 { 1228 static WarningHandler 1229 warning_handler = (WarningHandler) NULL; 1230 1231 if (*argv[0] == '+') 1232 { 1233 /* 1234 Restore error or warning messages. 1235 */ 1236 warning_handler=SetWarningHandler(warning_handler); 1237 break; 1238 } 1239 /* 1240 Suppress error or warning messages. 1241 */ 1242 warning_handler=SetWarningHandler((WarningHandler) NULL); 1243 break; 1244 } 1245 break; 1246 } 1247 case 'r': 1248 { 1249 if (LocaleCompare("red-primary",option) == 0) 1250 { 1251 if (*argv[0] == '+') 1252 { 1253 (void) SetImageOption(image_info,option,"0.0"); 1254 break; 1255 } 1256 (void) SetImageOption(image_info,option,argv[1]); 1257 break; 1258 } 1259 break; 1260 } 1261 case 's': 1262 { 1263 if (LocaleCompare("sampling-factor",option) == 0) 1264 { 1265 /* 1266 Set image sampling factor. 1267 */ 1268 if (*argv[0] == '+') 1269 { 1270 if (image_info->sampling_factor != (char *) NULL) 1271 image_info->sampling_factor=DestroyString( 1272 image_info->sampling_factor); 1273 break; 1274 } 1275 (void) CloneString(&image_info->sampling_factor,argv[1]); 1276 break; 1277 } 1278 if (LocaleCompare("scene",option) == 0) 1279 { 1280 /* 1281 Set image scene. 1282 */ 1283 if (*argv[0] == '+') 1284 { 1285 image_info->scene=0; 1286 (void) SetImageOption(image_info,option,"0"); 1287 break; 1288 } 1289 image_info->scene=StringToUnsignedLong(argv[1]); 1290 (void) SetImageOption(image_info,option,argv[1]); 1291 break; 1292 } 1293 if (LocaleCompare("seed",option) == 0) 1294 { 1295 size_t 1296 seed; 1297 1298 if (*argv[0] == '+') 1299 { 1300 seed=(size_t) time((time_t *) NULL); 1301 SeedPseudoRandomGenerator(seed); 1302 break; 1303 } 1304 seed=StringToUnsignedLong(argv[1]); 1305 SeedPseudoRandomGenerator(seed); 1306 break; 1307 } 1308 if (LocaleCompare("size",option) == 0) 1309 { 1310 /* FUTURE: convert to ImageOption 1311 Look at special handling for "size" in SetImageOption() 1312 */ 1313 if (*argv[0] == '+') 1314 { 1315 if (image_info->size != (char *) NULL) 1316 image_info->size=DestroyString(image_info->size); 1317 break; 1318 } 1319 (void) CloneString(&image_info->size,argv[1]); 1320 break; 1321 } 1322 if (LocaleCompare("stroke",option) == 0) 1323 { 1324 if (*argv[0] == '+') 1325 { 1326 (void) SetImageOption(image_info,option,"none"); 1327 break; 1328 } 1329 (void) SetImageOption(image_info,option,argv[1]); 1330 break; 1331 } 1332 if (LocaleCompare("strokewidth",option) == 0) 1333 { 1334 if (*argv[0] == '+') 1335 { 1336 (void) SetImageOption(image_info,option,"0"); 1337 break; 1338 } 1339 (void) SetImageOption(image_info,option,argv[1]); 1340 break; 1341 } 1342 if (LocaleCompare("synchronize",option) == 0) 1343 { 1344 if (*argv[0] == '+') 1345 { 1346 image_info->synchronize=MagickFalse; 1347 break; 1348 } 1349 image_info->synchronize=MagickTrue; 1350 break; 1351 } 1352 break; 1353 } 1354 case 't': 1355 { 1356 if (LocaleCompare("taint",option) == 0) 1357 { 1358 if (*argv[0] == '+') 1359 { 1360 (void) SetImageOption(image_info,option,"false"); 1361 break; 1362 } 1363 (void) SetImageOption(image_info,option,"true"); 1364 break; 1365 } 1366 if (LocaleCompare("texture",option) == 0) 1367 { 1368 if (*argv[0] == '+') 1369 { 1370 if (image_info->texture != (char *) NULL) 1371 image_info->texture=DestroyString(image_info->texture); 1372 break; 1373 } 1374 (void) CloneString(&image_info->texture,argv[1]); 1375 break; 1376 } 1377 if (LocaleCompare("tile-offset",option) == 0) 1378 { 1379 if (*argv[0] == '+') 1380 { 1381 (void) SetImageOption(image_info,option,"0"); 1382 break; 1383 } 1384 (void) SetImageOption(image_info,option,argv[1]); 1385 break; 1386 } 1387 if (LocaleCompare("transparent-color",option) == 0) 1388 { 1389 if (*argv[0] == '+') 1390 { 1391 (void) QueryColorCompliance("none",AllCompliance, 1392 &image_info->transparent_color,exception); 1393 (void) SetImageOption(image_info,option,"none"); 1394 break; 1395 } 1396 (void) QueryColorCompliance("none",AllCompliance, 1397 &image_info->transparent_color,exception); 1398 exception); 1399 (void) SetImageOption(image_info,option,argv[1]); 1400 break; 1401 } 1402 if (LocaleCompare("type",option) == 0) 1403 { 1404 if (*argv[0] == '+') 1405 { 1406 image_info->type=UndefinedType; 1407 (void) SetImageOption(image_info,option,"undefined"); 1408 break; 1409 } 1410 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions, 1411 MagickFalse,argv[1]); 1412 (void) SetImageOption(image_info,option,argv[1]); 1413 break; 1414 } 1415 break; 1416 } 1417 case 'u': 1418 { 1419 if (LocaleCompare("undercolor",option) == 0) 1420 { 1421 if (*argv[0] == '+') 1422 { 1423 (void) DeleteImageOption(image_info,option); 1424 break; 1425 } 1426 (void) SetImageOption(image_info,option,argv[1]); 1427 break; 1428 } 1429 if (LocaleCompare("units",option) == 0) 1430 { 1431 if (*argv[0] == '+') 1432 { 1433 image_info->units=UndefinedResolution; 1434 (void) SetImageOption(image_info,option,"undefined"); 1435 break; 1436 } 1437 image_info->units=(ResolutionType) ParseCommandOption( 1438 MagickResolutionOptions,MagickFalse,argv[1]); 1439 (void) SetImageOption(image_info,option,argv[1]); 1440 break; 1441 } 1442 break; 1443 } 1444 case 'v': 1445 { 1446 if (LocaleCompare("verbose",option) == 0) 1447 { 1448 if (*argv[0] == '+') 1449 { 1450 image_info->verbose=MagickFalse; 1451 break; 1452 } 1453 image_info->verbose=MagickTrue; 1454 image_info->ping=MagickFalse; 1455 break; 1456 } 1457 if (LocaleCompare("view",option) == 0) 1458 { 1459 if (*argv[0] == '+') 1460 { 1461 if (image_info->view != (char *) NULL) 1462 image_info->view=DestroyString(image_info->view); 1463 break; 1464 } 1465 (void) CloneString(&image_info->view,argv[1]); 1466 break; 1467 } 1468 if (LocaleCompare("virtual-pixel",option) == 0) 1469 { 1470 if (*argv[0] == '+') 1471 { 1472 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod; 1473 (void) SetImageOption(image_info,option,"undefined"); 1474 break; 1475 } 1476 image_info->virtual_pixel_method=(VirtualPixelMethod) 1477 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]); 1478 (void) SetImageOption(image_info,option,argv[1]); 1479 break; 1480 } 1481 break; 1482 } 1483 case 'w': 1484 { 1485 if (LocaleCompare("white-point",option) == 0) 1486 { 1487 if (*argv[0] == '+') 1488 { 1489 (void) SetImageOption(image_info,option,"0.0"); 1490 break; 1491 } 1492 (void) SetImageOption(image_info,option,argv[1]); 1493 break; 1494 } 1495 break; 1496 } 1497 default: 1498 break; 1499 } 1500 return(MagickTrue); 1501} 1502 1503/* 1504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1505% % 1506% % 1507% % 1508+ A p p l y I m a g e O p e r a t o r % 1509% % 1510% % 1511% % 1512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1513% 1514% ApplyImageOperator() apply one simple image operation to just the current 1515% image. 1516% 1517% The image in the list may be modified in three different ways... 1518% 1519% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw), 1520% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology) 1521% * replace by a list of images (-separate and -crop only!) 1522% 1523% In each case the result is returned into the list, and the pointer to the 1524% modified image (last image added if replaced by a list of images) is 1525% returned. As the image pointed to may be replaced, the first image in the 1526% list may also change. GetFirstImageInList() should be used by caller if 1527% they wish return the Image pointer to the first image in list. 1528% 1529% The format of the ApplyImageOperator method is: 1530% 1531% MagickBooleanType ApplyImageOperator(MagickWand *wand, 1532% const int argc,const char **argv) 1533% 1534% A description of each parameter follows: 1535% 1536% o wand: The CLI wand holding all the settings and pointer to image 1537% 1538% o argc: Specifies a pointer to an integer describing the number of 1539% elements in the argument vector. 1540% 1541% o argv: Specifies a pointer to a text array containing the command line 1542% arguments. 1543% 1544% o exception: return any errors or warnings in this structure. 1545% 1546*/ 1547MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand, 1548 const int wand_unused(argc), const char **argv, ExceptionInfo *exception) 1549{ 1550 Image * 1551 new_image; 1552 1553 ChannelType 1554 channel; 1555 1556 const char 1557 *format; 1558 1559 DrawInfo 1560 *draw_info; 1561 1562 GeometryInfo 1563 geometry_info; 1564 1565 RectangleInfo 1566 geometry; 1567 1568 MagickStatusType 1569 status; 1570 1571 PixelInfo 1572 fill; 1573 1574 MagickStatusType 1575 flags; 1576 1577 QuantizeInfo 1578 *quantize_info; 1579 1580 assert(image_info != (const ImageInfo *) NULL); 1581 assert(image_info->signature == MagickSignature); 1582 assert(image != (Image **) NULL); 1583 assert((*image)->signature == MagickSignature); 1584 if ((*image)->debug != MagickFalse) 1585 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename); 1586 if (argc < 0) 1587 return(MagickTrue); 1588 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); 1589 quantize_info=AcquireQuantizeInfo(image_info); 1590 SetGeometryInfo(&geometry_info); 1591 GetPixelInfo(*image,&fill); 1592 SetPixelInfoPacket(*image,&(*image)->background_color,&fill); 1593 channel=image_info->channel; 1594 format=GetImageOption(image_info,"format"); 1595 1596 new_image = (Image *)NULL; 1597 1598 switch (*(argv[0]+1)) 1599 { 1600 case 'a': 1601 { 1602 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0) 1603 { 1604 (void) SyncImageSettings(image_info,*image); 1605 flags=ParseGeometry(argv[1],&geometry_info); 1606 if ((flags & SigmaValue) == 0) 1607 geometry_info.sigma=1.0; 1608 if ((flags & XiValue) == 0) 1609 geometry_info.xi=0.0; 1610 new_image=AdaptiveBlurImage(*image,geometry_info.rho, 1611 geometry_info.sigma,geometry_info.xi,exception); 1612 break; 1613 } 1614 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0) 1615 { 1616 /* FUTURE: this is really a "interpolate-resize" operator 1617 "adaptive-resize" uses a fixed "Mesh" interpolation 1618 */ 1619 (void) SyncImageSettings(image_info,*image); 1620 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception); 1621 new_image=AdaptiveResizeImage(*image,geometry.width, 1622 geometry.height,interpolate_method,exception); 1623 break; 1624 } 1625 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0) 1626 { 1627 /* 1628 Adaptive sharpen image. 1629 */ 1630 (void) SyncImageSettings(image_info,*image); 1631 flags=ParseGeometry(argv[1],&geometry_info); 1632 if ((flags & SigmaValue) == 0) 1633 geometry_info.sigma=1.0; 1634 if ((flags & XiValue) == 0) 1635 geometry_info.xi=0.0; 1636 new_image=AdaptiveSharpenImage(*image,geometry_info.rho, 1637 geometry_info.sigma,geometry_info.xi,exception); 1638 break; 1639 } 1640 if (LocaleCompare("alpha",argv[0]+1) == 0) 1641 { 1642 AlphaChannelType 1643 alpha_type; 1644 1645 (void) SyncImageSettings(image_info,*image); 1646 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions, 1647 MagickFalse,argv[1]); 1648 (void) SetImageAlphaChannel(*image,alpha_type,exception); 1649 break; 1650 } 1651 if (LocaleCompare("annotate",argv[0]+1) == 0) 1652 { 1653 char 1654 *text, 1655 geometry[MaxTextExtent]; 1656 1657 (void) SyncImageSettings(image_info,*image); 1658 SetGeometryInfo(&geometry_info); 1659 flags=ParseGeometry(argv[1],&geometry_info); 1660 if ((flags & SigmaValue) == 0) 1661 geometry_info.sigma=geometry_info.rho; 1662 text=InterpretImageProperties(image_info,*image,argv[2], 1663 exception); 1664 if (text == (char *) NULL) 1665 break; 1666 (void) CloneString(&draw_info->text,text); 1667 text=DestroyString(text); 1668 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f", 1669 geometry_info.xi,geometry_info.psi); 1670 (void) CloneString(&draw_info->geometry,geometry); 1671 draw_info->affine.sx=cos(DegreesToRadians( 1672 fmod(geometry_info.rho,360.0))); 1673 draw_info->affine.rx=sin(DegreesToRadians( 1674 fmod(geometry_info.rho,360.0))); 1675 draw_info->affine.ry=(-sin(DegreesToRadians( 1676 fmod(geometry_info.sigma,360.0)))); 1677 draw_info->affine.sy=cos(DegreesToRadians( 1678 fmod(geometry_info.sigma,360.0))); 1679 (void) AnnotateImage(*image,draw_info,exception); 1680 break; 1681 } 1682 if (LocaleCompare("auto-gamma",argv[0]+1) == 0) 1683 { 1684 /* 1685 Auto Adjust Gamma of image based on its mean 1686 */ 1687 (void) SyncImageSettings(image_info,*image); 1688 (void) AutoGammaImage(*image,exception); 1689 break; 1690 } 1691 if (LocaleCompare("auto-level",argv[0]+1) == 0) 1692 { 1693 /* 1694 Perfectly Normalize (max/min stretch) the image 1695 */ 1696 (void) SyncImageSettings(image_info,*image); 1697 (void) AutoLevelImage(*image,exception); 1698 break; 1699 } 1700 if (LocaleCompare("auto-orient",argv[0]+1) == 0) 1701 { 1702 (void) SyncImageSettings(image_info,*image); 1703 switch ((*image)->orientation) 1704 { 1705 case TopRightOrientation: 1706 { 1707 new_image=FlopImage(*image,exception); 1708 break; 1709 } 1710 case BottomRightOrientation: 1711 { 1712 new_image=RotateImage(*image,180.0,exception); 1713 break; 1714 } 1715 case BottomLeftOrientation: 1716 { 1717 new_image=FlipImage(*image,exception); 1718 break; 1719 } 1720 case LeftTopOrientation: 1721 { 1722 new_image=TransposeImage(*image,exception); 1723 break; 1724 } 1725 case RightTopOrientation: 1726 { 1727 new_image=RotateImage(*image,90.0,exception); 1728 break; 1729 } 1730 case RightBottomOrientation: 1731 { 1732 new_image=TransverseImage(*image,exception); 1733 break; 1734 } 1735 case LeftBottomOrientation: 1736 { 1737 new_image=RotateImage(*image,270.0,exception); 1738 break; 1739 } 1740 default: 1741 break; 1742 } 1743 if (new_image != (Image *) NULL) 1744 new_image->orientation=TopLeftOrientation; 1745 break; 1746 } 1747 break; 1748 } 1749 case 'b': 1750 { 1751 if (LocaleCompare("black-threshold",argv[0]+1) == 0) 1752 { 1753 (void) SyncImageSettings(image_info,*image); 1754 (void) BlackThresholdImage(*image,argv[1],exception); 1755 InheritException(exception,&(*image)->exception); 1756 break; 1757 } 1758 if (LocaleCompare("blue-shift",argv[0]+1) == 0) 1759 { 1760 (void) SyncImageSettings(image_info,*image); 1761 geometry_info.rho=1.5; 1762 if (*argv[0] == '-') 1763 flags=ParseGeometry(argv[1],&geometry_info); 1764 new_image=BlueShiftImage(*image,geometry_info.rho,exception); 1765 break; 1766 } 1767 if (LocaleCompare("blur",argv[0]+1) == 0) 1768 { 1769 /* FUTURE: use of "bias" in a blur is non-sensible */ 1770 (void) SyncImageSettings(image_info,*image); 1771 flags=ParseGeometry(argv[1],&geometry_info); 1772 if ((flags & SigmaValue) == 0) 1773 geometry_info.sigma=1.0; 1774 if ((flags & XiValue) == 0) 1775 geometry_info.xi=0.0; 1776 new_image=BlurImage(*image,geometry_info.rho, 1777 geometry_info.sigma,geometry_info.xi,exception); 1778 break; 1779 } 1780 if (LocaleCompare("border",argv[0]+1) == 0) 1781 { 1782 (void) SyncImageSettings(image_info,*image); 1783 flags=ParsePageGeometry(*image,argv[1],&geometry,exception); 1784 if ((flags & SigmaValue) == 0) 1785 geometry.height=geometry.width; 1786 new_image=BorderImage(*image,&geometry,compose,exception); 1787 break; 1788 } 1789 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0) 1790 { 1791 double 1792 brightness, 1793 contrast; 1794 1795 GeometryInfo 1796 geometry_info; 1797 1798 MagickStatusType 1799 flags; 1800 1801 (void) SyncImageSettings(image_info,*image); 1802 flags=ParseGeometry(argv[1],&geometry_info); 1803 brightness=geometry_info.rho; 1804 contrast=0.0; 1805 if ((flags & SigmaValue) != 0) 1806 contrast=geometry_info.sigma; 1807 (void) BrightnessContrastImage(*image,brightness,contrast, 1808 exception); 1809 InheritException(exception,&(*image)->exception); 1810 break; 1811 } 1812 break; 1813 } 1814 case 'c': 1815 { 1816 if (LocaleCompare("cdl",argv[0]+1) == 0) 1817 { 1818 char 1819 *color_correction_collection; 1820 1821 /* 1822 Color correct with a color decision list. 1823 */ 1824 (void) SyncImageSettings(image_info,*image); 1825 color_correction_collection=FileToString(argv[1],~0,exception); 1826 if (color_correction_collection == (char *) NULL) 1827 break; 1828 (void) ColorDecisionListImage(*image,color_correction_collection, 1829 exception); 1830 InheritException(exception,&(*image)->exception); 1831 break; 1832 } 1833 if (LocaleCompare("channel",argv[0]+1) == 0) 1834 { 1835 /* The "channel" setting has already been set */ 1836 SetPixelChannelMap(*image,image_info->channel); 1837 break; 1838 } 1839 if (LocaleCompare("charcoal",argv[0]+1) == 0) 1840 { 1841 (void) SyncImageSettings(image_info,*image); 1842 flags=ParseGeometry(argv[1],&geometry_info); 1843 if ((flags & SigmaValue) == 0) 1844 geometry_info.sigma=1.0; 1845 if ((flags & XiValue) == 0) 1846 geometry_info.xi=1.0; 1847 new_image=CharcoalImage(*image,geometry_info.rho, 1848 geometry_info.sigma,geometry_info.xi,exception); 1849 break; 1850 } 1851 if (LocaleCompare("chop",argv[0]+1) == 0) 1852 { 1853 (void) SyncImageSettings(image_info,*image); 1854 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception); 1855 new_image=ChopImage(*image,&geometry,exception); 1856 break; 1857 } 1858 if (LocaleCompare("clamp",argv[0]+1) == 0) 1859 { 1860 (void) SyncImageSettings(image_info,*image); 1861 (void) ClampImage(*image); 1862 InheritException(exception,&(*image)->exception); 1863 break; 1864 } 1865 if (LocaleCompare("clip",argv[0]+1) == 0) 1866 { 1867 (void) SyncImageSettings(image_info,*image); 1868 if (*argv[0] == '+') 1869 { 1870 (void) SetImageClipMask(*image,(Image *) NULL,exception); 1871 break; 1872 } 1873 (void) ClipImage(*image,exception); 1874 break; 1875 } 1876 if (LocaleCompare("clip-mask",argv[0]+1) == 0) 1877 { 1878 CacheView 1879 *mask_view; 1880 1881 Image 1882 *mask_image; 1883 1884 register Quantum 1885 *restrict q; 1886 1887 register ssize_t 1888 x; 1889 1890 ssize_t 1891 y; 1892 1893 (void) SyncImageSettings(image_info,*image); 1894 if (*argv[0] == '+') 1895 { 1896 /* Remove the write mask */ 1897 (void) SetImageMask(*image,(Image *) NULL,exception); 1898 break; 1899 } 1900 mask_image=GetImageCache(image_info,argv[1],exception); 1901 if (mask_image == (Image *) NULL) 1902 break; 1903 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse) 1904 return(MagickFalse); 1905 /* create a write mask from clip-mask image */ 1906 /* FUTURE: use Alpha operations instead */ 1907 mask_view=AcquireCacheView(mask_image); 1908 for (y=0; y < (ssize_t) mask_image->rows; y++) 1909 { 1910 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1, 1911 exception); 1912 if (q == (Quantum *) NULL) 1913 break; 1914 for (x=0; x < (ssize_t) mask_image->columns; x++) 1915 { 1916 if (mask_image->matte == MagickFalse) 1917 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q); 1918 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q); 1919 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q); 1920 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q); 1921 q+=GetPixelChannels(mask_image); 1922 } 1923 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse) 1924 break; 1925 } 1926 /* set the write mask */ 1927 mask_view=DestroyCacheView(mask_view); 1928 mask_image->matte=MagickTrue; 1929 (void) SetImageClipMask(*image,mask_image,exception); 1930 mask_image=DestroyImage(mask_image); 1931 InheritException(exception,&(*image)->exception); 1932 break; 1933 } 1934 if (LocaleCompare("clip-path",argv[0]+1) == 0) 1935 { 1936 (void) SyncImageSettings(image_info,*image); 1937 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue : 1938 MagickFalse,exception); 1939 break; 1940 } 1941 if (LocaleCompare("colorize",argv[0]+1) == 0) 1942 { 1943 (void) SyncImageSettings(image_info,*image); 1944 new_image=ColorizeImage(*image,argv[1],draw_info->fill, 1945 exception); 1946 break; 1947 } 1948 if (LocaleCompare("color-matrix",argv[0]+1) == 0) 1949 { 1950 KernelInfo 1951 *kernel; 1952 1953 (void) SyncImageSettings(image_info,*image); 1954 kernel=AcquireKernelInfo(argv[1]); 1955 if (kernel == (KernelInfo *) NULL) 1956 break; 1957 new_image=ColorMatrixImage(*image,kernel,exception); 1958 kernel=DestroyKernelInfo(kernel); 1959 break; 1960 } 1961 if (LocaleCompare("colors",argv[0]+1) == 0) 1962 { 1963 /* Reduce the number of colors in the image. */ 1964 (void) SyncImageSettings(image_info,*image); 1965 quantize_info->number_colors=StringToUnsignedLong(argv[1]); 1966 if (quantize_info->number_colors == 0) 1967 break; 1968 if (((*image)->storage_class == DirectClass) || 1969 (*image)->colors > quantize_info->number_colors) 1970 (void) QuantizeImage(quantize_info,*image,exception); 1971 else 1972 (void) CompressImageColormap(*image,exception); 1973 break; 1974 } 1975 if (LocaleCompare("colorspace",argv[0]+1) == 0) 1976 { 1977 /* This is a Image Setting, which should already been set */ 1978 /* FUTURE: default colorspace should be sRGB! 1979 Unless some type of 'linear colorspace' mode is set. 1980 Note that +colorspace sets "undefined" or no effect on 1981 new images, but forces images already in memory back to RGB! 1982 */ 1983 (void) SyncImageSettings(image_info,*image); 1984 (void) TransformImageColorspace(*image, 1985 IfSetOption ? image_info->colorspace : RGBColorspace); 1986 InheritException(exception,&(*image)->exception); 1987 break; 1988 } 1989 if (LocaleCompare("contrast",argv[0]+1) == 0) 1990 { 1991 (void) SyncImageSettings(image_info,*image); 1992 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue : 1993 MagickFalse,exception); 1994 break; 1995 } 1996 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0) 1997 { 1998 double 1999 black_point, 2000 white_point; 2001 2002 MagickStatusType 2003 flags; 2004 2005 /* 2006 Contrast stretch image. 2007 */ 2008 (void) SyncImageSettings(image_info,*image); 2009 flags=ParseGeometry(argv[1],&geometry_info); 2010 black_point=geometry_info.rho; 2011 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : 2012 black_point; 2013 if ((flags & PercentValue) != 0) 2014 { 2015 black_point*=(double) (*image)->columns*(*image)->rows/100.0; 2016 white_point*=(double) (*image)->columns*(*image)->rows/100.0; 2017 } 2018 white_point=(MagickRealType) (*image)->columns*(*image)->rows- 2019 white_point; 2020 (void) ContrastStretchImage(*image,black_point,white_point, 2021 exception); 2022 InheritException(exception,&(*image)->exception); 2023 break; 2024 } 2025 if (LocaleCompare("convolve",argv[0]+1) == 0) 2026 { 2027 KernelInfo 2028 *kernel_info; 2029 2030 (void) SyncImageSettings(image_info,*image); 2031 kernel_info=AcquireKernelInfo(argv[1]); 2032 if (kernel_info == (KernelInfo *) NULL) 2033 break; 2034 kernel_info->bias=(*image)->bias; 2035 new_image=ConvolveImage(*image,kernel_info,exception); 2036 kernel_info=DestroyKernelInfo(kernel_info); 2037 break; 2038 } 2039 if (LocaleCompare("crop",argv[0]+1) == 0) 2040 { 2041 /* 2042 Crop a image to a smaller size 2043 */ 2044 (void) SyncImageSettings(image_info,*image); 2045 new_image=CropImageToTiles(*image,argv[1],exception); 2046 break; 2047 } 2048 if (LocaleCompare("cycle",argv[0]+1) == 0) 2049 { 2050 /* 2051 Cycle an image colormap. 2052 */ 2053 (void) SyncImageSettings(image_info,*image); 2054 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]), 2055 exception); 2056 break; 2057 } 2058 break; 2059 } 2060 case 'd': 2061 { 2062 if (LocaleCompare("decipher",argv[0]+1) == 0) 2063 { 2064 StringInfo 2065 *passkey; 2066 2067 /* 2068 Decipher pixels. 2069 */ 2070 (void) SyncImageSettings(image_info,*image); 2071 passkey=FileToStringInfo(argv[1],~0,exception); 2072 if (passkey != (StringInfo *) NULL) 2073 { 2074 (void) PasskeyDecipherImage(*image,passkey,exception); 2075 passkey=DestroyStringInfo(passkey); 2076 } 2077 break; 2078 } 2079 if (LocaleCompare("density",argv[0]+1) == 0) 2080 { 2081 /* 2082 Set image density. 2083 */ 2084 (void) CloneString(&draw_info->density,argv[1]); 2085 break; 2086 } 2087 if (LocaleCompare("depth",argv[0]+1) == 0) 2088 { 2089 (void) SyncImageSettings(image_info,*image); 2090 if (*argv[0] == '+') 2091 { 2092 (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH); 2093 break; 2094 } 2095 (void) SetImageDepth(*image,StringToUnsignedLong(argv[1])); 2096 break; 2097 } 2098 if (LocaleCompare("deskew",argv[0]+1) == 0) 2099 { 2100 double 2101 threshold; 2102 2103 /* 2104 Straighten the image. 2105 */ 2106 (void) SyncImageSettings(image_info,*image); 2107 if (*argv[0] == '+') 2108 threshold=40.0*QuantumRange/100.0; 2109 else 2110 threshold=SiPrefixToDouble(argv[1],QuantumRange); 2111 new_image=DeskewImage(*image,threshold,exception); 2112 break; 2113 } 2114 if (LocaleCompare("despeckle",argv[0]+1) == 0) 2115 { 2116 /* 2117 Reduce the speckles within an image. 2118 */ 2119 (void) SyncImageSettings(image_info,*image); 2120 new_image=DespeckleImage(*image,exception); 2121 break; 2122 } 2123 if (LocaleCompare("display",argv[0]+1) == 0) 2124 { 2125 (void) CloneString(&draw_info->server_name,argv[1]); 2126 break; 2127 } 2128 if (LocaleCompare("distort",argv[0]+1) == 0) 2129 { 2130 char 2131 *args, 2132 token[MaxTextExtent]; 2133 2134 const char 2135 *p; 2136 2137 DistortImageMethod 2138 method; 2139 2140 double 2141 *arguments; 2142 2143 register ssize_t 2144 x; 2145 2146 size_t 2147 number_arguments; 2148 2149 /* 2150 Distort image. 2151 */ 2152 (void) SyncImageSettings(image_info,*image); 2153 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions, 2154 MagickFalse,argv[1]); 2155 if ( method == ResizeDistortion ) 2156 { 2157 /* Special Case - Argument is actually a resize geometry! 2158 ** Convert that to an appropriate distortion argument array. 2159 */ 2160 double 2161 resize_args[2]; 2162 (void) ParseRegionGeometry(*image,argv[2],&geometry, 2163 exception); 2164 resize_args[0]=(double)geometry.width; 2165 resize_args[1]=(double)geometry.height; 2166 new_image=DistortImage(*image,method,(size_t)2, 2167 resize_args,MagickTrue,exception); 2168 break; 2169 } 2170 args=InterpretImageProperties(image_info,*image,argv[2], 2171 exception); 2172 if (args == (char *) NULL) 2173 break; 2174 p=(char *) args; 2175 for (x=0; *p != '\0'; x++) 2176 { 2177 GetMagickToken(p,&p,token); 2178 if (*token == ',') 2179 GetMagickToken(p,&p,token); 2180 } 2181 number_arguments=(size_t) x; 2182 arguments=(double *) AcquireQuantumMemory(number_arguments, 2183 sizeof(*arguments)); 2184 if (arguments == (double *) NULL) 2185 ThrowWandFatalException(ResourceLimitFatalError, 2186 "MemoryAllocationFailed",(*image)->filename); 2187 (void) ResetMagickMemory(arguments,0,number_arguments* 2188 sizeof(*arguments)); 2189 p=(char *) args; 2190 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++) 2191 { 2192 GetMagickToken(p,&p,token); 2193 if (*token == ',') 2194 GetMagickToken(p,&p,token); 2195 arguments[x]=InterpretLocaleValue(token,(char **) NULL); 2196 } 2197 args=DestroyString(args); 2198 new_image=DistortImage(*image,method,number_arguments,arguments, 2199 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception); 2200 arguments=(double *) RelinquishMagickMemory(arguments); 2201 break; 2202 } 2203 if (LocaleCompare("dither",argv[0]+1) == 0) 2204 { 2205 if (*argv[0] == '+') 2206 { 2207 quantize_info->dither=MagickFalse; 2208 break; 2209 } 2210 quantize_info->dither=MagickTrue; 2211 quantize_info->dither_method=(DitherMethod) ParseCommandOption( 2212 MagickDitherOptions,MagickFalse,argv[1]); 2213 if (quantize_info->dither_method == NoDitherMethod) 2214 quantize_info->dither=MagickFalse; 2215 break; 2216 } 2217 if (LocaleCompare("draw",argv[0]+1) == 0) 2218 { 2219 /* 2220 Draw image. 2221 */ 2222 (void) SyncImageSettings(image_info,*image); 2223 (void) CloneString(&draw_info->primitive,argv[1]); 2224 (void) DrawImage(*image,draw_info,exception); 2225 break; 2226 } 2227 break; 2228 } 2229 case 'e': 2230 { 2231 if (LocaleCompare("edge",argv[0]+1) == 0) 2232 { 2233 /* 2234 Enhance edges in the image. 2235 */ 2236 (void) SyncImageSettings(image_info,*image); 2237 flags=ParseGeometry(argv[1],&geometry_info); 2238 if ((flags & SigmaValue) == 0) 2239 geometry_info.sigma=1.0; 2240 new_image=EdgeImage(*image,geometry_info.rho, 2241 geometry_info.sigma,exception); 2242 break; 2243 } 2244 if (LocaleCompare("emboss",argv[0]+1) == 0) 2245 { 2246 /* 2247 Gaussian embossen image. 2248 */ 2249 (void) SyncImageSettings(image_info,*image); 2250 flags=ParseGeometry(argv[1],&geometry_info); 2251 if ((flags & SigmaValue) == 0) 2252 geometry_info.sigma=1.0; 2253 new_image=EmbossImage(*image,geometry_info.rho, 2254 geometry_info.sigma,exception); 2255 break; 2256 } 2257 if (LocaleCompare("encipher",argv[0]+1) == 0) 2258 { 2259 StringInfo 2260 *passkey; 2261 2262 /* 2263 Encipher pixels. 2264 */ 2265 (void) SyncImageSettings(image_info,*image); 2266 passkey=FileToStringInfo(argv[1],~0,exception); 2267 if (passkey != (StringInfo *) NULL) 2268 { 2269 (void) PasskeyEncipherImage(*image,passkey,exception); 2270 passkey=DestroyStringInfo(passkey); 2271 } 2272 break; 2273 } 2274 if (LocaleCompare("encoding",argv[0]+1) == 0) 2275 { 2276 (void) CloneString(&draw_info->encoding,argv[1]); 2277 break; 2278 } 2279 if (LocaleCompare("enhance",argv[0]+1) == 0) 2280 { 2281 /* 2282 Enhance image. 2283 */ 2284 (void) SyncImageSettings(image_info,*image); 2285 new_image=EnhanceImage(*image,exception); 2286 break; 2287 } 2288 if (LocaleCompare("equalize",argv[0]+1) == 0) 2289 { 2290 /* 2291 Equalize image. 2292 */ 2293 (void) SyncImageSettings(image_info,*image); 2294 (void) EqualizeImage(*image,exception); 2295 break; 2296 } 2297 if (LocaleCompare("evaluate",argv[0]+1) == 0) 2298 { 2299 double 2300 constant; 2301 2302 MagickEvaluateOperator 2303 op; 2304 2305 (void) SyncImageSettings(image_info,*image); 2306 op=(MagickEvaluateOperator) ParseCommandOption( 2307 MagickEvaluateOptions,MagickFalse,argv[1]); 2308 constant=SiPrefixToDouble(argv[2],QuantumRange); 2309 (void) EvaluateImage(*image,op,constant,exception); 2310 break; 2311 } 2312 if (LocaleCompare("extent",argv[0]+1) == 0) 2313 { 2314 /* 2315 Set the image extent. 2316 */ 2317 (void) SyncImageSettings(image_info,*image); 2318 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception); 2319 if (geometry.width == 0) 2320 geometry.width=(*image)->columns; 2321 if (geometry.height == 0) 2322 geometry.height=(*image)->rows; 2323 new_image=ExtentImage(*image,&geometry,exception); 2324 break; 2325 } 2326 break; 2327 } 2328 case 'f': 2329 { 2330 if (LocaleCompare("family",argv[0]+1) == 0) 2331 { 2332 if (*argv[0] == '+') 2333 { 2334 if (draw_info->family != (char *) NULL) 2335 draw_info->family=DestroyString(draw_info->family); 2336 break; 2337 } 2338 (void) CloneString(&draw_info->family,argv[1]); 2339 break; 2340 } 2341 if (LocaleCompare("features",argv[0]+1) == 0) 2342 { 2343 if (*argv[0] == '+') 2344 { 2345 (void) DeleteImageArtifact(*image,"identify:features"); 2346 break; 2347 } 2348 (void) SetImageArtifact(*image,"identify:features",argv[1]); 2349 break; 2350 } 2351 if (LocaleCompare("fill",argv[0]+1) == 0) 2352 { 2353 ExceptionInfo 2354 *sans; 2355 2356 GetPixelInfo(*image,&fill); 2357 if (*argv[0] == '+') 2358 { 2359 (void) QueryMagickColorCompliance("none",AllCompliance,&fill, 2360 exception); 2361 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill, 2362 exception); 2363 if (draw_info->fill_pattern != (Image *) NULL) 2364 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern); 2365 break; 2366 } 2367 sans=AcquireExceptionInfo(); 2368 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&fill,sans); 2369 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,sans); 2370 sans=DestroyExceptionInfo(sans); 2371 if (status == MagickFalse) 2372 draw_info->fill_pattern=GetImageCache(image_info,argv[1], 2373 exception); 2374 break; 2375 } 2376 if (LocaleCompare("flip",argv[0]+1) == 0) 2377 { 2378 /* 2379 Flip image scanlines. 2380 */ 2381 (void) SyncImageSettings(image_info,*image); 2382 new_image=FlipImage(*image,exception); 2383 break; 2384 } 2385 if (LocaleCompare("flop",argv[0]+1) == 0) 2386 { 2387 /* 2388 Flop image scanlines. 2389 */ 2390 (void) SyncImageSettings(image_info,*image); 2391 new_image=FlopImage(*image,exception); 2392 break; 2393 } 2394 if (LocaleCompare("floodfill",argv[0]+1) == 0) 2395 { 2396 PixelInfo 2397 target; 2398 2399 /* 2400 Floodfill image. 2401 */ 2402 (void) SyncImageSettings(image_info,*image); 2403 (void) ParsePageGeometry(*image,argv[1],&geometry,exception); 2404 (void) QueryMagickColorCompliance(argv[2],AllCompliance,&target, 2405 exception); 2406 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x, 2407 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception); 2408 break; 2409 } 2410 if (LocaleCompare("font",argv[0]+1) == 0) 2411 { 2412 if (*argv[0] == '+') 2413 { 2414 if (draw_info->font != (char *) NULL) 2415 draw_info->font=DestroyString(draw_info->font); 2416 break; 2417 } 2418 (void) CloneString(&draw_info->font,argv[1]); 2419 break; 2420 } 2421 if (LocaleCompare("format",argv[0]+1) == 0) 2422 { 2423 format=argv[1]; 2424 break; 2425 } 2426 if (LocaleCompare("frame",argv[0]+1) == 0) 2427 { 2428 FrameInfo 2429 frame_info; 2430 2431 /* 2432 Surround image with an ornamental border. 2433 */ 2434 (void) SyncImageSettings(image_info,*image); 2435 flags=ParsePageGeometry(*image,argv[1],&geometry,exception); 2436 frame_info.width=geometry.width; 2437 frame_info.height=geometry.height; 2438 if ((flags & HeightValue) == 0) 2439 frame_info.height=geometry.width; 2440 frame_info.outer_bevel=geometry.x; 2441 frame_info.inner_bevel=geometry.y; 2442 frame_info.x=(ssize_t) frame_info.width; 2443 frame_info.y=(ssize_t) frame_info.height; 2444 frame_info.width=(*image)->columns+2*frame_info.width; 2445 frame_info.height=(*image)->rows+2*frame_info.height; 2446 new_image=FrameImage(*image,&frame_info,compose,exception); 2447 break; 2448 } 2449 if (LocaleCompare("function",argv[0]+1) == 0) 2450 { 2451 char 2452 *arguments, 2453 token[MaxTextExtent]; 2454 2455 const char 2456 *p; 2457 2458 double 2459 *parameters; 2460 2461 MagickFunction 2462 function; 2463 2464 register ssize_t 2465 x; 2466 2467 size_t 2468 number_parameters; 2469 2470 /* 2471 Function Modify Image Values 2472 */ 2473 (void) SyncImageSettings(image_info,*image); 2474 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions, 2475 MagickFalse,argv[1]); 2476 arguments=InterpretImageProperties(image_info,*image,argv[2], 2477 exception); 2478 if (arguments == (char *) NULL) 2479 break; 2480 p=(char *) arguments; 2481 for (x=0; *p != '\0'; x++) 2482 { 2483 GetMagickToken(p,&p,token); 2484 if (*token == ',') 2485 GetMagickToken(p,&p,token); 2486 } 2487 number_parameters=(size_t) x; 2488 parameters=(double *) AcquireQuantumMemory(number_parameters, 2489 sizeof(*parameters)); 2490 if (parameters == (double *) NULL) 2491 ThrowWandFatalException(ResourceLimitFatalError, 2492 "MemoryAllocationFailed",(*image)->filename); 2493 (void) ResetMagickMemory(parameters,0,number_parameters* 2494 sizeof(*parameters)); 2495 p=(char *) arguments; 2496 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) 2497 { 2498 GetMagickToken(p,&p,token); 2499 if (*token == ',') 2500 GetMagickToken(p,&p,token); 2501 parameters[x]=InterpretLocaleValue(token,(char **) NULL); 2502 } 2503 arguments=DestroyString(arguments); 2504 (void) FunctionImage(*image,function,number_parameters,parameters, 2505 exception); 2506 parameters=(double *) RelinquishMagickMemory(parameters); 2507 break; 2508 } 2509 break; 2510 } 2511 case 'g': 2512 { 2513 if (LocaleCompare("gamma",argv[0]+1) == 0) 2514 { 2515 /* 2516 Gamma image. 2517 */ 2518 (void) SyncImageSettings(image_info,*image); 2519 if (*argv[0] == '+') 2520 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL); 2521 else 2522 (void) GammaImage(*image,InterpretLocaleValue(argv[1], 2523 (char **) NULL),exception); 2524 break; 2525 } 2526 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) || 2527 (LocaleCompare("gaussian",argv[0]+1) == 0)) 2528 { 2529 /* 2530 Gaussian blur image. 2531 */ 2532 (void) SyncImageSettings(image_info,*image); 2533 flags=ParseGeometry(argv[1],&geometry_info); 2534 if ((flags & SigmaValue) == 0) 2535 geometry_info.sigma=1.0; 2536 if ((flags & XiValue) == 0) 2537 geometry_info.xi=0.0; 2538 new_image=GaussianBlurImage(*image,geometry_info.rho, 2539 geometry_info.sigma,geometry_info.xi,exception); 2540 break; 2541 } 2542 if (LocaleCompare("geometry",argv[0]+1) == 0) 2543 { 2544 /* 2545 Record Image offset, Resize last image. 2546 */ 2547 (void) SyncImageSettings(image_info,*image); 2548 if (*argv[0] == '+') 2549 { 2550 if ((*image)->geometry != (char *) NULL) 2551 (*image)->geometry=DestroyString((*image)->geometry); 2552 break; 2553 } 2554 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception); 2555 if (((flags & XValue) != 0) || ((flags & YValue) != 0)) 2556 (void) CloneString(&(*image)->geometry,argv[1]); 2557 else 2558 new_image=ResizeImage(*image,geometry.width,geometry.height, 2559 (*image)->filter,(*image)->blur,exception); 2560 break; 2561 } 2562 if (LocaleCompare("gravity",argv[0]+1) == 0) 2563 { 2564 if (*argv[0] == '+') 2565 { 2566 draw_info->gravity=UndefinedGravity; 2567 break; 2568 } 2569 draw_info->gravity=(GravityType) ParseCommandOption( 2570 MagickGravityOptions,MagickFalse,argv[1]); 2571 break; 2572 } 2573 break; 2574 } 2575 case 'h': 2576 { 2577 if (LocaleCompare("highlight-color",argv[0]+1) == 0) 2578 { 2579 (void) SetImageArtifact(*image,argv[0]+1,argv[1]); 2580 break; 2581 } 2582 break; 2583 } 2584 case 'i': 2585 { 2586 if (LocaleCompare("identify",argv[0]+1) == 0) 2587 { 2588 char 2589 *text; 2590 2591 (void) SyncImageSettings(image_info,*image); 2592 if (format == (char *) NULL) 2593 { 2594 (void) IdentifyImage(*image,stdout,image_info->verbose, 2595 exception); 2596 break; 2597 } 2598 text=InterpretImageProperties(image_info,*image,format, 2599 exception); 2600 if (text == (char *) NULL) 2601 break; 2602 (void) fputs(text,stdout); 2603 (void) fputc('\n',stdout); 2604 text=DestroyString(text); 2605 break; 2606 } 2607 if (LocaleCompare("implode",argv[0]+1) == 0) 2608 { 2609 /* 2610 Implode image. 2611 */ 2612 (void) SyncImageSettings(image_info,*image); 2613 (void) ParseGeometry(argv[1],&geometry_info); 2614 new_image=ImplodeImage(*image,geometry_info.rho, 2615 interpolate_method,exception); 2616 break; 2617 } 2618 if (LocaleCompare("interline-spacing",argv[0]+1) == 0) 2619 { 2620 if (*argv[0] == '+') 2621 (void) ParseGeometry("0",&geometry_info); 2622 else 2623 (void) ParseGeometry(argv[1],&geometry_info); 2624 draw_info->interline_spacing=geometry_info.rho; 2625 break; 2626 } 2627 if (LocaleCompare("interpolate",argv[0]+1) == 0) 2628 { 2629 interpolate_method=(PixelInterpolateMethod) ParseCommandOption( 2630 MagickInterpolateOptions,MagickFalse,argv[1]); 2631 break; 2632 } 2633 if (LocaleCompare("interword-spacing",argv[0]+1) == 0) 2634 { 2635 if (*argv[0] == '+') 2636 (void) ParseGeometry("0",&geometry_info); 2637 else 2638 (void) ParseGeometry(argv[1],&geometry_info); 2639 draw_info->interword_spacing=geometry_info.rho; 2640 break; 2641 } 2642 break; 2643 } 2644 case 'k': 2645 { 2646 if (LocaleCompare("kerning",argv[0]+1) == 0) 2647 { 2648 if (*argv[0] == '+') 2649 (void) ParseGeometry("0",&geometry_info); 2650 else 2651 (void) ParseGeometry(argv[1],&geometry_info); 2652 draw_info->kerning=geometry_info.rho; 2653 break; 2654 } 2655 break; 2656 } 2657 case 'l': 2658 { 2659 if (LocaleCompare("lat",argv[0]+1) == 0) 2660 { 2661 /* 2662 Local adaptive threshold image. 2663 */ 2664 (void) SyncImageSettings(image_info,*image); 2665 flags=ParseGeometry(argv[1],&geometry_info); 2666 if ((flags & PercentValue) != 0) 2667 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0; 2668 new_image=AdaptiveThresholdImage(*image,(size_t) 2669 geometry_info.rho,(size_t) geometry_info.sigma,(double) 2670 geometry_info.xi,exception); 2671 break; 2672 } 2673 if (LocaleCompare("level",argv[0]+1) == 0) 2674 { 2675 MagickRealType 2676 black_point, 2677 gamma, 2678 white_point; 2679 2680 MagickStatusType 2681 flags; 2682 2683 /* 2684 Parse levels. 2685 */ 2686 (void) SyncImageSettings(image_info,*image); 2687 flags=ParseGeometry(argv[1],&geometry_info); 2688 black_point=geometry_info.rho; 2689 white_point=(MagickRealType) QuantumRange; 2690 if ((flags & SigmaValue) != 0) 2691 white_point=geometry_info.sigma; 2692 gamma=1.0; 2693 if ((flags & XiValue) != 0) 2694 gamma=geometry_info.xi; 2695 if ((flags & PercentValue) != 0) 2696 { 2697 black_point*=(MagickRealType) (QuantumRange/100.0); 2698 white_point*=(MagickRealType) (QuantumRange/100.0); 2699 } 2700 if ((flags & SigmaValue) == 0) 2701 white_point=(MagickRealType) QuantumRange-black_point; 2702 if ((*argv[0] == '+') || ((flags & AspectValue) != 0)) 2703 (void) LevelizeImage(*image,black_point,white_point,gamma, 2704 exception); 2705 else 2706 (void) LevelImage(*image,black_point,white_point,gamma, 2707 exception); 2708 InheritException(exception,&(*image)->exception); 2709 break; 2710 } 2711 if (LocaleCompare("level-colors",argv[0]+1) == 0) 2712 { 2713 char 2714 token[MaxTextExtent]; 2715 2716 const char 2717 *p; 2718 2719 PixelInfo 2720 black_point, 2721 white_point; 2722 2723 p=(const char *) argv[1]; 2724 GetMagickToken(p,&p,token); /* get black point color */ 2725 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0)) 2726 (void) QueryMagickColorCompliance(token,AllCompliance, 2727 &black_point,exception); 2728 else 2729 (void) QueryMagickColorCompliance("#000000",AllCompliance, 2730 &black_point,exception); 2731 if (isalpha((int) token[0]) || (token[0] == '#')) 2732 GetMagickToken(p,&p,token); 2733 if (*token == '\0') 2734 white_point=black_point; /* set everything to that color */ 2735 else 2736 { 2737 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0)) 2738 GetMagickToken(p,&p,token); /* Get white point color. */ 2739 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0)) 2740 (void) QueryMagickColorCompliance(token,AllCompliance, 2741 &white_point,exception); 2742 else 2743 (void) QueryMagickColorCompliance("#ffffff",AllCompliance, 2744 &white_point,exception); 2745 } 2746 (void) LevelImageColors(*image,&black_point,&white_point, 2747 *argv[0] == '+' ? MagickTrue : MagickFalse,exception); 2748 break; 2749 } 2750 if (LocaleCompare("linear-stretch",argv[0]+1) == 0) 2751 { 2752 double 2753 black_point, 2754 white_point; 2755 2756 MagickStatusType 2757 flags; 2758 2759 (void) SyncImageSettings(image_info,*image); 2760 flags=ParseGeometry(argv[1],&geometry_info); 2761 black_point=geometry_info.rho; 2762 white_point=(MagickRealType) (*image)->columns*(*image)->rows; 2763 if ((flags & SigmaValue) != 0) 2764 white_point=geometry_info.sigma; 2765 if ((flags & PercentValue) != 0) 2766 { 2767 black_point*=(double) (*image)->columns*(*image)->rows/100.0; 2768 white_point*=(double) (*image)->columns*(*image)->rows/100.0; 2769 } 2770 if ((flags & SigmaValue) == 0) 2771 white_point=(MagickRealType) (*image)->columns*(*image)->rows- 2772 black_point; 2773 (void) LinearStretchImage(*image,black_point,white_point,exception); 2774 InheritException(exception,&(*image)->exception); 2775 break; 2776 } 2777 if (LocaleCompare("linewidth",argv[0]+1) == 0) 2778 { 2779 draw_info->stroke_width=InterpretLocaleValue(argv[1], 2780 (char **) NULL); 2781 break; 2782 } 2783 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0) 2784 { 2785 /* 2786 Liquid rescale image. 2787 */ 2788 (void) SyncImageSettings(image_info,*image); 2789 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception); 2790 if ((flags & XValue) == 0) 2791 geometry.x=1; 2792 if ((flags & YValue) == 0) 2793 geometry.y=0; 2794 new_image=LiquidRescaleImage(*image,geometry.width, 2795 geometry.height,1.0*geometry.x,1.0*geometry.y,exception); 2796 break; 2797 } 2798 if (LocaleCompare("lowlight-color",argv[0]+1) == 0) 2799 { 2800 (void) SetImageArtifact(*image,argv[0]+1,argv[1]); 2801 break; 2802 } 2803 break; 2804 } 2805 case 'm': 2806 { 2807 if (LocaleCompare("map",argv[0]+1) == 0) 2808 { 2809 Image 2810 *remap_image; 2811 2812 /* 2813 Transform image colors to match this set of colors. 2814 */ 2815 (void) SyncImageSettings(image_info,*image); 2816 if (*argv[0] == '+') 2817 break; 2818 remap_image=GetImageCache(image_info,argv[1],exception); 2819 if (remap_image == (Image *) NULL) 2820 break; 2821 (void) RemapImage(quantize_info,*image,remap_image,exception); 2822 remap_image=DestroyImage(remap_image); 2823 break; 2824 } 2825 if (LocaleCompare("mask",argv[0]+1) == 0) 2826 { 2827 Image 2828 *mask; 2829 2830 (void) SyncImageSettings(image_info,*image); 2831 if (*argv[0] == '+') 2832 { 2833 /* 2834 Remove a mask. 2835 */ 2836 (void) SetImageMask(*image,(Image *) NULL,exception); 2837 break; 2838 } 2839 /* 2840 Set the image mask. 2841 */ 2842 mask=GetImageCache(image_info,argv[1],exception); 2843 if (mask == (Image *) NULL) 2844 break; 2845 (void) SetImageMask(*image,mask,exception); 2846 mask=DestroyImage(mask); 2847 break; 2848 } 2849 if (LocaleCompare("matte",argv[0]+1) == 0) 2850 { 2851 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ? 2852 SetAlphaChannel : DeactivateAlphaChannel,exception); 2853 break; 2854 } 2855 if (LocaleCompare("median",argv[0]+1) == 0) 2856 { 2857 /* 2858 Median filter image. 2859 */ 2860 (void) SyncImageSettings(image_info,*image); 2861 flags=ParseGeometry(argv[1],&geometry_info); 2862 if ((flags & SigmaValue) == 0) 2863 geometry_info.sigma=geometry_info.rho; 2864 new_image=StatisticImage(*image,MedianStatistic,(size_t) 2865 geometry_info.rho,(size_t) geometry_info.sigma,exception); 2866 break; 2867 } 2868 if (LocaleCompare("mode",argv[0]+1) == 0) 2869 { 2870 /* 2871 Mode image. 2872 */ 2873 (void) SyncImageSettings(image_info,*image); 2874 flags=ParseGeometry(argv[1],&geometry_info); 2875 if ((flags & SigmaValue) == 0) 2876 geometry_info.sigma=geometry_info.rho; 2877 new_image=StatisticImage(*image,ModeStatistic,(size_t) 2878 geometry_info.rho,(size_t) geometry_info.sigma,exception); 2879 break; 2880 } 2881 if (LocaleCompare("modulate",argv[0]+1) == 0) 2882 { 2883 (void) SyncImageSettings(image_info,*image); 2884 (void) ModulateImage(*image,argv[1],exception); 2885 break; 2886 } 2887 if (LocaleCompare("monitor",argv[0]+1) == 0) 2888 { 2889 if (*argv[0] == '+') 2890 { 2891 (void) SetImageProgressMonitor(*image, 2892 (MagickProgressMonitor) NULL,(void *) NULL); 2893 break; 2894 } 2895 (void) SetImageProgressMonitor(*image,MonitorProgress, 2896 (void *) NULL); 2897 break; 2898 } 2899 if (LocaleCompare("monochrome",argv[0]+1) == 0) 2900 { 2901 (void) SyncImageSettings(image_info,*image); 2902 (void) SetImageType(*image,BilevelType,exception); 2903 break; 2904 } 2905 if (LocaleCompare("morphology",argv[0]+1) == 0) 2906 { 2907 char 2908 token[MaxTextExtent]; 2909 2910 const char 2911 *p; 2912 2913 KernelInfo 2914 *kernel; 2915 2916 MorphologyMethod 2917 method; 2918 2919 ssize_t 2920 iterations; 2921 2922 /* 2923 Morphological Image Operation 2924 */ 2925 (void) SyncImageSettings(image_info,*image); 2926 p=argv[1]; 2927 GetMagickToken(p,&p,token); 2928 method=(MorphologyMethod) ParseCommandOption( 2929 MagickMorphologyOptions,MagickFalse,token); 2930 iterations=1L; 2931 GetMagickToken(p,&p,token); 2932 if ((*p == ':') || (*p == ',')) 2933 GetMagickToken(p,&p,token); 2934 if ((*p != '\0')) 2935 iterations=(ssize_t) StringToLong(p); 2936 kernel=AcquireKernelInfo(argv[2]); 2937 if (kernel == (KernelInfo *) NULL) 2938 { 2939 (void) ThrowMagickException(exception,GetMagickModule(), 2940 OptionError,"UnabletoParseKernel","morphology"); 2941 status=MagickFalse; 2942 break; 2943 } 2944 new_image=MorphologyImage(*image,method,iterations,kernel, 2945 exception); 2946 kernel=DestroyKernelInfo(kernel); 2947 break; 2948 } 2949 if (LocaleCompare("motion-blur",argv[0]+1) == 0) 2950 { 2951 /* 2952 Motion blur image. 2953 */ 2954 (void) SyncImageSettings(image_info,*image); 2955 flags=ParseGeometry(argv[1],&geometry_info); 2956 if ((flags & SigmaValue) == 0) 2957 geometry_info.sigma=1.0; 2958 new_image=MotionBlurImage(*image,geometry_info.rho, 2959 geometry_info.sigma,geometry_info.xi,geometry_info.psi, 2960 exception); 2961 break; 2962 } 2963 break; 2964 } 2965 case 'n': 2966 { 2967 if (LocaleCompare("negate",argv[0]+1) == 0) 2968 { 2969 (void) SyncImageSettings(image_info,*image); 2970 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue : 2971 MagickFalse,exception); 2972 break; 2973 } 2974 if (LocaleCompare("noise",argv[0]+1) == 0) 2975 { 2976 (void) SyncImageSettings(image_info,*image); 2977 if (*argv[0] == '-') 2978 { 2979 flags=ParseGeometry(argv[1],&geometry_info); 2980 if ((flags & SigmaValue) == 0) 2981 geometry_info.sigma=geometry_info.rho; 2982 new_image=StatisticImage(*image,NonpeakStatistic,(size_t) 2983 geometry_info.rho,(size_t) geometry_info.sigma,exception); 2984 } 2985 else 2986 { 2987 NoiseType 2988 noise; 2989 2990 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions, 2991 MagickFalse,argv[1]); 2992 new_image=AddNoiseImage(*image,noise,exception); 2993 } 2994 break; 2995 } 2996 if (LocaleCompare("normalize",argv[0]+1) == 0) 2997 { 2998 (void) SyncImageSettings(image_info,*image); 2999 (void) NormalizeImage(*image,exception); 3000 break; 3001 } 3002 break; 3003 } 3004 case 'o': 3005 { 3006 if (LocaleCompare("opaque",argv[0]+1) == 0) 3007 { 3008 PixelInfo 3009 target; 3010 3011 (void) SyncImageSettings(image_info,*image); 3012 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target, 3013 exception); 3014 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ? 3015 MagickFalse : MagickTrue,exception); 3016 break; 3017 } 3018 if (LocaleCompare("ordered-dither",argv[0]+1) == 0) 3019 { 3020 (void) SyncImageSettings(image_info,*image); 3021 (void) OrderedPosterizeImage(*image,argv[1],exception); 3022 break; 3023 } 3024 break; 3025 } 3026 case 'p': 3027 { 3028 if (LocaleCompare("paint",argv[0]+1) == 0) 3029 { 3030 (void) SyncImageSettings(image_info,*image); 3031 (void) ParseGeometry(argv[1],&geometry_info); 3032 new_image=OilPaintImage(*image,geometry_info.rho, 3033 geometry_info.sigma,exception); 3034 break; 3035 } 3036 if (LocaleCompare("pen",argv[0]+1) == 0) 3037 { 3038 if (*argv[0] == '+') 3039 { 3040 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill, 3041 exception); 3042 break; 3043 } 3044 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill, 3045 exception); 3046 break; 3047 } 3048 if (LocaleCompare("pointsize",argv[0]+1) == 0) 3049 { 3050 if (*argv[0] == '+') 3051 (void) ParseGeometry("12",&geometry_info); 3052 else 3053 (void) ParseGeometry(argv[1],&geometry_info); 3054 draw_info->pointsize=geometry_info.rho; 3055 break; 3056 } 3057 if (LocaleCompare("polaroid",argv[0]+1) == 0) 3058 { 3059 double 3060 angle; 3061 3062 RandomInfo 3063 *random_info; 3064 3065 /* 3066 Simulate a Polaroid picture. 3067 */ 3068 (void) SyncImageSettings(image_info,*image); 3069 random_info=AcquireRandomInfo(); 3070 angle=22.5*(GetPseudoRandomValue(random_info)-0.5); 3071 random_info=DestroyRandomInfo(random_info); 3072 if (*argv[0] == '-') 3073 { 3074 SetGeometryInfo(&geometry_info); 3075 flags=ParseGeometry(argv[1],&geometry_info); 3076 angle=geometry_info.rho; 3077 } 3078 new_image=PolaroidImage(*image,draw_info,angle, 3079 interpolate_method,exception); 3080 break; 3081 } 3082 if (LocaleCompare("posterize",argv[0]+1) == 0) 3083 { 3084 /* 3085 Posterize image. 3086 */ 3087 (void) SyncImageSettings(image_info,*image); 3088 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]), 3089 quantize_info->dither,exception); 3090 break; 3091 } 3092 if (LocaleCompare("preview",argv[0]+1) == 0) 3093 { 3094 PreviewType 3095 preview_type; 3096 3097 /* 3098 Preview image. 3099 */ 3100 (void) SyncImageSettings(image_info,*image); 3101 if (*argv[0] == '+') 3102 preview_type=UndefinedPreview; 3103 else 3104 preview_type=(PreviewType) ParseCommandOption( 3105 MagickPreviewOptions,MagickFalse,argv[1]); 3106 new_image=PreviewImage(*image,preview_type,exception); 3107 break; 3108 } 3109 if (LocaleCompare("profile",argv[0]+1) == 0) 3110 { 3111 const char 3112 *name; 3113 3114 const StringInfo 3115 *profile; 3116 3117 Image 3118 *profile_image; 3119 3120 ImageInfo 3121 *profile_info; 3122 3123 (void) SyncImageSettings(image_info,*image); 3124 if (*argv[0] == '+') 3125 { 3126 /* 3127 Remove a profile from the image. 3128 */ 3129 (void) ProfileImage(*image,argv[1],(const unsigned char *) 3130 NULL,0,MagickTrue); 3131 InheritException(exception,&(*image)->exception); 3132 break; 3133 } 3134 /* 3135 Associate a profile with the image. 3136 */ 3137 profile_info=CloneImageInfo(image_info); 3138 profile=GetImageProfile(*image,"iptc"); 3139 if (profile != (StringInfo *) NULL) 3140 profile_info->profile=(void *) CloneStringInfo(profile); 3141 profile_image=GetImageCache(profile_info,argv[1],exception); 3142 profile_info=DestroyImageInfo(profile_info); 3143 if (profile_image == (Image *) NULL) 3144 { 3145 StringInfo 3146 *profile; 3147 3148 profile_info=CloneImageInfo(image_info); 3149 (void) CopyMagickString(profile_info->filename,argv[1], 3150 MaxTextExtent); 3151 profile=FileToStringInfo(profile_info->filename,~0UL,exception); 3152 if (profile != (StringInfo *) NULL) 3153 { 3154 (void) ProfileImage(*image,profile_info->magick, 3155 GetStringInfoDatum(profile),(size_t) 3156 GetStringInfoLength(profile),MagickFalse); 3157 profile=DestroyStringInfo(profile); 3158 } 3159 profile_info=DestroyImageInfo(profile_info); 3160 break; 3161 } 3162 ResetImageProfileIterator(profile_image); 3163 name=GetNextImageProfile(profile_image); 3164 while (name != (const char *) NULL) 3165 { 3166 profile=GetImageProfile(profile_image,name); 3167 if (profile != (StringInfo *) NULL) 3168 (void) ProfileImage(*image,name,GetStringInfoDatum(profile), 3169 (size_t) GetStringInfoLength(profile),MagickFalse); 3170 name=GetNextImageProfile(profile_image); 3171 } 3172 profile_image=DestroyImage(profile_image); 3173 break; 3174 } 3175 break; 3176 } 3177 case 'q': 3178 { 3179 if (LocaleCompare("quantize",argv[0]+1) == 0) 3180 { 3181 if (*argv[0] == '+') 3182 { 3183 quantize_info->colorspace=UndefinedColorspace; 3184 break; 3185 } 3186 quantize_info->colorspace=(ColorspaceType) ParseCommandOption( 3187 MagickColorspaceOptions,MagickFalse,argv[1]); 3188 break; 3189 } 3190 break; 3191 } 3192 case 'r': 3193 { 3194 if (LocaleCompare("radial-blur",argv[0]+1) == 0) 3195 { 3196 /* 3197 Radial blur image. 3198 */ 3199 (void) SyncImageSettings(image_info,*image); 3200 flags=ParseGeometry(argv[1],&geometry_info); 3201 new_image=RadialBlurImage(*image,geometry_info.rho, 3202 geometry_info.sigma,exception); 3203 break; 3204 } 3205 if (LocaleCompare("raise",argv[0]+1) == 0) 3206 { 3207 /* 3208 Surround image with a raise of solid color. 3209 */ 3210 flags=ParsePageGeometry(*image,argv[1],&geometry,exception); 3211 if ((flags & SigmaValue) == 0) 3212 geometry.height=geometry.width; 3213 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue : 3214 MagickFalse,exception); 3215 break; 3216 } 3217 if (LocaleCompare("random-threshold",argv[0]+1) == 0) 3218 { 3219 /* 3220 Threshold image. 3221 */ 3222 (void) SyncImageSettings(image_info,*image); 3223 (void) RandomThresholdImage(*image,argv[1],exception); 3224 break; 3225 } 3226 if (LocaleCompare("recolor",argv[0]+1) == 0) 3227 { 3228 KernelInfo 3229 *kernel; 3230 3231 (void) SyncImageSettings(image_info,*image); 3232 kernel=AcquireKernelInfo(argv[1]); 3233 if (kernel == (KernelInfo *) NULL) 3234 break; 3235 new_image=ColorMatrixImage(*image,kernel,exception); 3236 kernel=DestroyKernelInfo(kernel); 3237 break; 3238 } 3239 if (LocaleCompare("render",argv[0]+1) == 0) 3240 { 3241 (void) SyncImageSettings(image_info,*image); 3242 draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse; 3243 break; 3244 } 3245 if (LocaleCompare("remap",argv[0]+1) == 0) 3246 { 3247 Image 3248 *remap_image; 3249 3250 /* 3251 Transform image colors to match this set of colors. 3252 */ 3253 (void) SyncImageSettings(image_info,*image); 3254 if (*argv[0] == '+') 3255 break; 3256 remap_image=GetImageCache(image_info,argv[1],exception); 3257 if (remap_image == (Image *) NULL) 3258 break; 3259 (void) RemapImage(quantize_info,*image,remap_image,exception); 3260 remap_image=DestroyImage(remap_image); 3261 break; 3262 } 3263 if (LocaleCompare("repage",argv[0]+1) == 0) 3264 { 3265 if (*argv[0] == '+') 3266 { 3267 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page); 3268 break; 3269 } 3270 (void) ResetImagePage(*image,argv[1]); 3271 InheritException(exception,&(*image)->exception); 3272 break; 3273 } 3274 if (LocaleCompare("resample",argv[0]+1) == 0) 3275 { 3276 /* 3277 Resample image. 3278 */ 3279 (void) SyncImageSettings(image_info,*image); 3280 flags=ParseGeometry(argv[1],&geometry_info); 3281 if ((flags & SigmaValue) == 0) 3282 geometry_info.sigma=geometry_info.rho; 3283 new_image=ResampleImage(*image,geometry_info.rho, 3284 geometry_info.sigma,(*image)->filter,(*image)->blur,exception); 3285 break; 3286 } 3287 if (LocaleCompare("resize",argv[0]+1) == 0) 3288 { 3289 /* 3290 Resize image. 3291 */ 3292 (void) SyncImageSettings(image_info,*image); 3293 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception); 3294 new_image=ResizeImage(*image,geometry.width,geometry.height, 3295 (*image)->filter,(*image)->blur,exception); 3296 break; 3297 } 3298 if (LocaleCompare("roll",argv[0]+1) == 0) 3299 { 3300 /* 3301 Roll image. 3302 */ 3303 (void) SyncImageSettings(image_info,*image); 3304 (void) ParsePageGeometry(*image,argv[1],&geometry,exception); 3305 new_image=RollImage(*image,geometry.x,geometry.y,exception); 3306 break; 3307 } 3308 if (LocaleCompare("rotate",argv[0]+1) == 0) 3309 { 3310 char 3311 *geometry; 3312 3313 /* 3314 Check for conditional image rotation. 3315 */ 3316 (void) SyncImageSettings(image_info,*image); 3317 if (strchr(argv[1],'>') != (char *) NULL) 3318 if ((*image)->columns <= (*image)->rows) 3319 break; 3320 if (strchr(argv[1],'<') != (char *) NULL) 3321 if ((*image)->columns >= (*image)->rows) 3322 break; 3323 /* 3324 Rotate image. 3325 */ 3326 geometry=ConstantString(argv[1]); 3327 (void) SubstituteString(&geometry,">",""); 3328 (void) SubstituteString(&geometry,"<",""); 3329 (void) ParseGeometry(geometry,&geometry_info); 3330 geometry=DestroyString(geometry); 3331 new_image=RotateImage(*image,geometry_info.rho,exception); 3332 break; 3333 } 3334 break; 3335 } 3336 case 's': 3337 { 3338 if (LocaleCompare("sample",argv[0]+1) == 0) 3339 { 3340 /* 3341 Sample image with pixel replication. 3342 */ 3343 (void) SyncImageSettings(image_info,*image); 3344 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception); 3345 new_image=SampleImage(*image,geometry.width,geometry.height, 3346 exception); 3347 break; 3348 } 3349 if (LocaleCompare("scale",argv[0]+1) == 0) 3350 { 3351 /* 3352 Resize image. 3353 */ 3354 (void) SyncImageSettings(image_info,*image); 3355 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception); 3356 new_image=ScaleImage(*image,geometry.width,geometry.height, 3357 exception); 3358 break; 3359 } 3360 if (LocaleCompare("selective-blur",argv[0]+1) == 0) 3361 { 3362 /* 3363 Selectively blur pixels within a contrast threshold. 3364 */ 3365 (void) SyncImageSettings(image_info,*image); 3366 flags=ParseGeometry(argv[1],&geometry_info); 3367 if ((flags & PercentValue) != 0) 3368 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0; 3369 new_image=SelectiveBlurImage(*image,geometry_info.rho, 3370 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception); 3371 break; 3372 } 3373 if (LocaleCompare("separate",argv[0]+1) == 0) 3374 { 3375 /* 3376 Break channels into separate images. 3377 WARNING: This can generate multiple images! 3378 */ 3379 (void) SyncImageSettings(image_info,*image); 3380 new_image=SeparateImages(*image,exception); 3381 break; 3382 } 3383 if (LocaleCompare("sepia-tone",argv[0]+1) == 0) 3384 { 3385 double 3386 threshold; 3387 3388 /* 3389 Sepia-tone image. 3390 */ 3391 (void) SyncImageSettings(image_info,*image); 3392 threshold=SiPrefixToDouble(argv[1],QuantumRange); 3393 new_image=SepiaToneImage(*image,threshold,exception); 3394 break; 3395 } 3396 if (LocaleCompare("segment",argv[0]+1) == 0) 3397 { 3398 /* 3399 Segment image. 3400 */ 3401 (void) SyncImageSettings(image_info,*image); 3402 flags=ParseGeometry(argv[1],&geometry_info); 3403 if ((flags & SigmaValue) == 0) 3404 geometry_info.sigma=1.0; 3405 (void) SegmentImage(*image,(*image)->colorspace, 3406 image_info->verbose,geometry_info.rho,geometry_info.sigma, 3407 exception); 3408 break; 3409 } 3410 if (LocaleCompare("set",argv[0]+1) == 0) 3411 { 3412 char 3413 *value; 3414 3415 if (*argv[0] == '+') 3416 { 3417 if (LocaleNCompare(argv[1],"registry:",9) == 0) 3418 (void) DeleteImageRegistry(argv[1]+9); 3419 else 3420 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0) 3421 { 3422 (void) DeleteImageOption(image_info,argv[1]+7); 3423 (void) DeleteImageArtifact(*image,argv[1]+7); 3424 } 3425 else 3426 (void) DeleteImageProperty(*image,argv[1]); 3427 break; 3428 } 3429 value=InterpretImageProperties(image_info,*image,argv[2], 3430 exception); 3431 if (value == (char *) NULL) 3432 break; 3433 if (LocaleNCompare(argv[1],"registry:",9) == 0) 3434 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value, 3435 exception); 3436 else 3437 if (LocaleNCompare(argv[1],"option:",7) == 0) 3438 { 3439 (void) SetImageOption(image_info,argv[1]+7,value); 3440 (void) SetImageArtifact(*image,argv[1]+7,value); 3441 } 3442 else 3443 (void) SetImageProperty(*image,argv[1],value); 3444 value=DestroyString(value); 3445 break; 3446 } 3447 if (LocaleCompare("shade",argv[0]+1) == 0) 3448 { 3449 /* 3450 Shade image. 3451 */ 3452 (void) SyncImageSettings(image_info,*image); 3453 flags=ParseGeometry(argv[1],&geometry_info); 3454 if ((flags & SigmaValue) == 0) 3455 geometry_info.sigma=1.0; 3456 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue : 3457 MagickFalse,geometry_info.rho,geometry_info.sigma,exception); 3458 break; 3459 } 3460 if (LocaleCompare("shadow",argv[0]+1) == 0) 3461 { 3462 /* 3463 Shadow image. 3464 */ 3465 (void) SyncImageSettings(image_info,*image); 3466 flags=ParseGeometry(argv[1],&geometry_info); 3467 if ((flags & SigmaValue) == 0) 3468 geometry_info.sigma=1.0; 3469 if ((flags & XiValue) == 0) 3470 geometry_info.xi=4.0; 3471 if ((flags & PsiValue) == 0) 3472 geometry_info.psi=4.0; 3473 new_image=ShadowImage(*image,geometry_info.rho, 3474 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) 3475 ceil(geometry_info.psi-0.5),exception); 3476 break; 3477 } 3478 if (LocaleCompare("sharpen",argv[0]+1) == 0) 3479 { 3480 /* 3481 Sharpen image. 3482 */ 3483 (void) SyncImageSettings(image_info,*image); 3484 flags=ParseGeometry(argv[1],&geometry_info); 3485 if ((flags & SigmaValue) == 0) 3486 geometry_info.sigma=1.0; 3487 if ((flags & XiValue) == 0) 3488 geometry_info.xi=0.0; 3489 new_image=SharpenImage(*image,geometry_info.rho, 3490 geometry_info.sigma,geometry_info.xi,exception); 3491 break; 3492 } 3493 if (LocaleCompare("shave",argv[0]+1) == 0) 3494 { 3495 /* 3496 Shave the image edges. 3497 */ 3498 (void) SyncImageSettings(image_info,*image); 3499 flags=ParsePageGeometry(*image,argv[1],&geometry,exception); 3500 new_image=ShaveImage(*image,&geometry,exception); 3501 break; 3502 } 3503 if (LocaleCompare("shear",argv[0]+1) == 0) 3504 { 3505 /* 3506 Shear image. 3507 */ 3508 (void) SyncImageSettings(image_info,*image); 3509 flags=ParseGeometry(argv[1],&geometry_info); 3510 if ((flags & SigmaValue) == 0) 3511 geometry_info.sigma=geometry_info.rho; 3512 new_image=ShearImage(*image,geometry_info.rho, 3513 geometry_info.sigma,exception); 3514 break; 3515 } 3516 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0) 3517 { 3518 /* 3519 Sigmoidal non-linearity contrast control. 3520 */ 3521 (void) SyncImageSettings(image_info,*image); 3522 flags=ParseGeometry(argv[1],&geometry_info); 3523 if ((flags & SigmaValue) == 0) 3524 geometry_info.sigma=(double) QuantumRange/2.0; 3525 if ((flags & PercentValue) != 0) 3526 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/ 3527 100.0; 3528 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ? 3529 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma, 3530 exception); 3531 break; 3532 } 3533 if (LocaleCompare("sketch",argv[0]+1) == 0) 3534 { 3535 /* 3536 Sketch image. 3537 */ 3538 (void) SyncImageSettings(image_info,*image); 3539 flags=ParseGeometry(argv[1],&geometry_info); 3540 if ((flags & SigmaValue) == 0) 3541 geometry_info.sigma=1.0; 3542 new_image=SketchImage(*image,geometry_info.rho, 3543 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception); 3544 break; 3545 } 3546 if (LocaleCompare("solarize",argv[0]+1) == 0) 3547 { 3548 double 3549 threshold; 3550 3551 (void) SyncImageSettings(image_info,*image); 3552 threshold=SiPrefixToDouble(argv[1],QuantumRange); 3553 (void) SolarizeImage(*image,threshold,exception); 3554 break; 3555 } 3556 if (LocaleCompare("sparse-color",argv[0]+1) == 0) 3557 { 3558 SparseColorMethod 3559 method; 3560 3561 char 3562 *arguments; 3563 3564 /* 3565 Sparse Color Interpolated Gradient 3566 */ 3567 (void) SyncImageSettings(image_info,*image); 3568 method=(SparseColorMethod) ParseCommandOption( 3569 MagickSparseColorOptions,MagickFalse,argv[1]); 3570 arguments=InterpretImageProperties(image_info,*image,argv[2], 3571 exception); 3572 if (arguments == (char *) NULL) 3573 break; 3574 new_image=SparseColorOption(*image,method,arguments, 3575 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception); 3576 arguments=DestroyString(arguments); 3577 break; 3578 } 3579 if (LocaleCompare("splice",argv[0]+1) == 0) 3580 { 3581 /* 3582 Splice a solid color into the image. 3583 */ 3584 (void) SyncImageSettings(image_info,*image); 3585 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception); 3586 new_image=SpliceImage(*image,&geometry,exception); 3587 break; 3588 } 3589 if (LocaleCompare("spread",argv[0]+1) == 0) 3590 { 3591 /* 3592 Spread an image. 3593 */ 3594 (void) SyncImageSettings(image_info,*image); 3595 (void) ParseGeometry(argv[1],&geometry_info); 3596 new_image=SpreadImage(*image,geometry_info.rho, 3597 interpolate_method,exception); 3598 break; 3599 } 3600 if (LocaleCompare("statistic",argv[0]+1) == 0) 3601 { 3602 StatisticType 3603 type; 3604 3605 (void) SyncImageSettings(image_info,*image); 3606 type=(StatisticType) ParseCommandOption(MagickStatisticOptions, 3607 MagickFalse,argv[1]); 3608 (void) ParseGeometry(argv[2],&geometry_info); 3609 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho, 3610 (size_t) geometry_info.sigma,exception); 3611 break; 3612 } 3613 if (LocaleCompare("stretch",argv[0]+1) == 0) 3614 { 3615 if (*argv[0] == '+') 3616 { 3617 draw_info->stretch=UndefinedStretch; 3618 break; 3619 } 3620 draw_info->stretch=(StretchType) ParseCommandOption( 3621 MagickStretchOptions,MagickFalse,argv[1]); 3622 break; 3623 } 3624 if (LocaleCompare("strip",argv[0]+1) == 0) 3625 { 3626 /* 3627 Strip image of profiles and comments. 3628 */ 3629 (void) SyncImageSettings(image_info,*image); 3630 (void) StripImage(*image); 3631 InheritException(exception,&(*image)->exception); 3632 break; 3633 } 3634 if (LocaleCompare("stroke",argv[0]+1) == 0) 3635 { 3636 ExceptionInfo 3637 *sans; 3638 3639 if (*argv[0] == '+') 3640 { 3641 (void) QueryColorCompliance("none",AllCompliance,&draw_info->stroke, 3642 exception); 3643 if (draw_info->stroke_pattern != (Image *) NULL) 3644 draw_info->stroke_pattern=DestroyImage( 3645 draw_info->stroke_pattern); 3646 break; 3647 } 3648 sans=AcquireExceptionInfo(); 3649 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->stroke,sans); 3650 sans=DestroyExceptionInfo(sans); 3651 if (status == MagickFalse) 3652 draw_info->stroke_pattern=GetImageCache(image_info,argv[1], 3653 exception); 3654 break; 3655 } 3656 if (LocaleCompare("strokewidth",argv[0]+1) == 0) 3657 { 3658 draw_info->stroke_width=InterpretLocaleValue(argv[1], 3659 (char **) NULL); 3660 break; 3661 } 3662 if (LocaleCompare("style",argv[0]+1) == 0) 3663 { 3664 if (*argv[0] == '+') 3665 { 3666 draw_info->style=UndefinedStyle; 3667 break; 3668 } 3669 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions, 3670 MagickFalse,argv[1]); 3671 break; 3672 } 3673 if (LocaleCompare("swirl",argv[0]+1) == 0) 3674 { 3675 /* 3676 Swirl image. 3677 */ 3678 (void) SyncImageSettings(image_info,*image); 3679 (void) ParseGeometry(argv[1],&geometry_info); 3680 new_image=SwirlImage(*image,geometry_info.rho, 3681 interpolate_method,exception); 3682 break; 3683 } 3684 break; 3685 } 3686 case 't': 3687 { 3688 if (LocaleCompare("threshold",argv[0]+1) == 0) 3689 { 3690 double 3691 threshold; 3692 3693 /* 3694 Threshold image. 3695 */ 3696 (void) SyncImageSettings(image_info,*image); 3697 if (*argv[0] == '+') 3698 threshold=(double) QuantumRange/2; 3699 else 3700 threshold=SiPrefixToDouble(argv[1],QuantumRange); 3701 (void) BilevelImage(*image,threshold); 3702 InheritException(exception,&(*image)->exception); 3703 break; 3704 } 3705 if (LocaleCompare("thumbnail",argv[0]+1) == 0) 3706 { 3707 /* 3708 Thumbnail image. 3709 */ 3710 (void) SyncImageSettings(image_info,*image); 3711 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception); 3712 new_image=ThumbnailImage(*image,geometry.width,geometry.height, 3713 exception); 3714 break; 3715 } 3716 if (LocaleCompare("tile",argv[0]+1) == 0) 3717 { 3718 if (*argv[0] == '+') 3719 { 3720 if (draw_info->fill_pattern != (Image *) NULL) 3721 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern); 3722 break; 3723 } 3724 draw_info->fill_pattern=GetImageCache(image_info,argv[1], 3725 exception); 3726 break; 3727 } 3728 if (LocaleCompare("tint",argv[0]+1) == 0) 3729 { 3730 /* 3731 Tint the image. 3732 */ 3733 (void) SyncImageSettings(image_info,*image); 3734 new_image=TintImage(*image,argv[1],&fill,exception); 3735 break; 3736 } 3737 if (LocaleCompare("transform",argv[0]+1) == 0) 3738 { 3739 /* 3740 Affine transform image. 3741 */ 3742 (void) SyncImageSettings(image_info,*image); 3743 new_image=AffineTransformImage(*image,&draw_info->affine, 3744 exception); 3745 break; 3746 } 3747 if (LocaleCompare("transparent",argv[0]+1) == 0) 3748 { 3749 PixelInfo 3750 target; 3751 3752 (void) SyncImageSettings(image_info,*image); 3753 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target, 3754 exception); 3755 (void) TransparentPaintImage(*image,&target,(Quantum) 3756 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue, 3757 &(*image)->exception); 3758 break; 3759 } 3760 if (LocaleCompare("transpose",argv[0]+1) == 0) 3761 { 3762 /* 3763 Transpose image scanlines. 3764 */ 3765 (void) SyncImageSettings(image_info,*image); 3766 new_image=TransposeImage(*image,exception); 3767 break; 3768 } 3769 if (LocaleCompare("transverse",argv[0]+1) == 0) 3770 { 3771 /* 3772 Transverse image scanlines. 3773 */ 3774 (void) SyncImageSettings(image_info,*image); 3775 new_image=TransverseImage(*image,exception); 3776 break; 3777 } 3778 if (LocaleCompare("treedepth",argv[0]+1) == 0) 3779 { 3780 quantize_info->tree_depth=StringToUnsignedLong(argv[1]); 3781 break; 3782 } 3783 if (LocaleCompare("trim",argv[0]+1) == 0) 3784 { 3785 /* 3786 Trim image. 3787 */ 3788 (void) SyncImageSettings(image_info,*image); 3789 new_image=TrimImage(*image,exception); 3790 break; 3791 } 3792 if (LocaleCompare("type",argv[0]+1) == 0) 3793 { 3794 ImageType 3795 type; 3796 3797 (void) SyncImageSettings(image_info,*image); 3798 if (*argv[0] == '+') 3799 type=UndefinedType; 3800 else 3801 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse, 3802 argv[1]); 3803 (*image)->type=UndefinedType; 3804 (void) SetImageType(*image,type,exception); 3805 break; 3806 } 3807 break; 3808 } 3809 case 'u': 3810 { 3811 if (LocaleCompare("undercolor",argv[0]+1) == 0) 3812 { 3813 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->undercolor, 3814 exception); 3815 break; 3816 } 3817 if (LocaleCompare("unique",argv[0]+1) == 0) 3818 { 3819 if (*argv[0] == '+') 3820 { 3821 (void) DeleteImageArtifact(*image,"identify:unique-colors"); 3822 break; 3823 } 3824 (void) SetImageArtifact(*image,"identify:unique-colors","true"); 3825 (void) SetImageArtifact(*image,"verbose","true"); 3826 break; 3827 } 3828 if (LocaleCompare("unique-colors",argv[0]+1) == 0) 3829 { 3830 /* 3831 Unique image colors. 3832 */ 3833 (void) SyncImageSettings(image_info,*image); 3834 new_image=UniqueImageColors(*image,exception); 3835 break; 3836 } 3837 if (LocaleCompare("unsharp",argv[0]+1) == 0) 3838 { 3839 /* 3840 Unsharp mask image. 3841 */ 3842 (void) SyncImageSettings(image_info,*image); 3843 flags=ParseGeometry(argv[1],&geometry_info); 3844 if ((flags & SigmaValue) == 0) 3845 geometry_info.sigma=1.0; 3846 if ((flags & XiValue) == 0) 3847 geometry_info.xi=1.0; 3848 if ((flags & PsiValue) == 0) 3849 geometry_info.psi=0.05; 3850 new_image=UnsharpMaskImage(*image,geometry_info.rho, 3851 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception); 3852 break; 3853 } 3854 break; 3855 } 3856 case 'v': 3857 { 3858 if (LocaleCompare("verbose",argv[0]+1) == 0) 3859 { 3860 (void) SetImageArtifact(*image,argv[0]+1, 3861 *argv[0] == '+' ? "false" : "true"); 3862 break; 3863 } 3864 if (LocaleCompare("vignette",argv[0]+1) == 0) 3865 { 3866 /* 3867 Vignette image. 3868 */ 3869 (void) SyncImageSettings(image_info,*image); 3870 flags=ParseGeometry(argv[1],&geometry_info); 3871 if ((flags & SigmaValue) == 0) 3872 geometry_info.sigma=1.0; 3873 if ((flags & XiValue) == 0) 3874 geometry_info.xi=0.1*(*image)->columns; 3875 if ((flags & PsiValue) == 0) 3876 geometry_info.psi=0.1*(*image)->rows; 3877 new_image=VignetteImage(*image,geometry_info.rho, 3878 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) 3879 ceil(geometry_info.psi-0.5),exception); 3880 break; 3881 } 3882 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0) 3883 { 3884 if (*argv[0] == '+') 3885 { 3886 (void) SetImageVirtualPixelMethod(*image, 3887 UndefinedVirtualPixelMethod); 3888 break; 3889 } 3890 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod) 3891 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse, 3892 argv[1])); 3893 break; 3894 } 3895 break; 3896 } 3897 case 'w': 3898 { 3899 if (LocaleCompare("wave",argv[0]+1) == 0) 3900 { 3901 /* 3902 Wave image. 3903 */ 3904 (void) SyncImageSettings(image_info,*image); 3905 flags=ParseGeometry(argv[1],&geometry_info); 3906 if ((flags & SigmaValue) == 0) 3907 geometry_info.sigma=1.0; 3908 new_image=WaveImage(*image,geometry_info.rho, 3909 geometry_info.sigma,interpolate_method,exception); 3910 break; 3911 } 3912 if (LocaleCompare("weight",argv[0]+1) == 0) 3913 { 3914 draw_info->weight=StringToUnsignedLong(argv[1]); 3915 if (LocaleCompare(argv[1],"all") == 0) 3916 draw_info->weight=0; 3917 if (LocaleCompare(argv[1],"bold") == 0) 3918 draw_info->weight=700; 3919 if (LocaleCompare(argv[1],"bolder") == 0) 3920 if (draw_info->weight <= 800) 3921 draw_info->weight+=100; 3922 if (LocaleCompare(argv[1],"lighter") == 0) 3923 if (draw_info->weight >= 100) 3924 draw_info->weight-=100; 3925 if (LocaleCompare(argv[1],"normal") == 0) 3926 draw_info->weight=400; 3927 break; 3928 } 3929 if (LocaleCompare("white-threshold",argv[0]+1) == 0) 3930 { 3931 /* 3932 White threshold image. 3933 */ 3934 (void) SyncImageSettings(image_info,*image); 3935 (void) WhiteThresholdImage(*image,argv[1],exception); 3936 InheritException(exception,&(*image)->exception); 3937 break; 3938 } 3939 break; 3940 } 3941 default: 3942 break; 3943 } 3944 /* 3945 Replace current image with any image that was generated 3946 */ 3947 if (new_image != (Image *) NULL) 3948 ReplaceImageInListReturnLast(image,new_image); 3949 3950 /* 3951 Free resources. 3952 */ 3953 quantize_info=DestroyQuantizeInfo(quantize_info); 3954 draw_info=DestroyDrawInfo(draw_info); 3955 status=(MagickStatusType) ((*image)->exception.severity == 3956 UndefinedException ? 1 : 0); 3957 return(status == 0 ? MagickFalse : MagickTrue); 3958} 3959 3960/* 3961%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3962% % 3963% % 3964% % 3965+ S e q u e n c e O p e r a t i o n I m a g e s % 3966% % 3967% % 3968% % 3969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3970% 3971% SequenceOperationImages() applies a single operation that apply to the 3972% entire image list (e.g. -append, -layers, -coalesce, etc.). 3973% 3974% The format of the MogrifyImage method is: 3975% 3976% MagickBooleanType SequenceOperationImages(ImageInfo *image_info, 3977% const int argc, const char **argv,Image **images, 3978% ExceptionInfo *exception) 3979% 3980% A description of each parameter follows: 3981% 3982% o image_info: the image info.. 3983% 3984% o argc: Specifies a pointer to an integer describing the number of 3985% elements in the argument vector. 3986% 3987% o argv: Specifies a pointer to a text array containing the command line 3988% arguments. 3989% 3990% o images: pointer to pointer of the first image in image list. 3991% 3992% o exception: return any errors or warnings in this structure. 3993% 3994*/ 3995WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info, 3996 const int argc,const char **argv,Image **images,ExceptionInfo *exception) 3997{ 3998 3999 MagickStatusType 4000 status; 4001 4002 QuantizeInfo 4003 *quantize_info; 4004 4005 assert(image_info != (ImageInfo *) NULL); 4006 assert(image_info->signature == MagickSignature); 4007 assert(images != (Image **) NULL); 4008 assert((*images)->previous == (Image *) NULL); 4009 assert((*images)->signature == MagickSignature); 4010 if ((*images)->debug != MagickFalse) 4011 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 4012 (*images)->filename); 4013 if ((argc <= 0) || (*argv == (char *) NULL)) 4014 return(MagickTrue); 4015 status=MagickTrue; 4016 4017 switch (*(argv[0]+1)) 4018 { 4019 case 'a': 4020 { 4021 if (LocaleCompare("affinity",argv[0]+1) == 0) 4022 { 4023 (void) SyncImagesSettings(image_info,*images); 4024 if (*argv[0] == '+') 4025 { 4026 (void) RemapImages(quantize_info,*images,(Image *) NULL, 4027 exception); 4028 break; 4029 } 4030 break; 4031 } 4032 if (LocaleCompare("append",argv[0]+1) == 0) 4033 { 4034 Image 4035 *append_image; 4036 4037 (void) SyncImagesSettings(image_info,*images); 4038 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue : 4039 MagickFalse,exception); 4040 if (append_image == (Image *) NULL) 4041 { 4042 status=MagickFalse; 4043 break; 4044 } 4045 *images=DestroyImageList(*images); 4046 *images=append_image; 4047 break; 4048 } 4049 if (LocaleCompare("average",argv[0]+1) == 0) 4050 { 4051 Image 4052 *average_image; 4053 4054 /* 4055 Average an image sequence (deprecated). 4056 */ 4057 (void) SyncImagesSettings(image_info,*images); 4058 average_image=EvaluateImages(*images,MeanEvaluateOperator, 4059 exception); 4060 if (average_image == (Image *) NULL) 4061 { 4062 status=MagickFalse; 4063 break; 4064 } 4065 *images=DestroyImageList(*images); 4066 *images=average_image; 4067 break; 4068 } 4069 break; 4070 } 4071 case 'c': 4072 { 4073 if (LocaleCompare("channel",argv[0]+1) == 0) 4074 { 4075 ChannelType 4076 channel; 4077 4078 if (*argv[0] == '+') 4079 { 4080 channel=DefaultChannels; 4081 break; 4082 } 4083 channel=(ChannelType) ParseChannelOption(argv[1]); 4084 SetPixelChannelMap(*images,channel); 4085 break; 4086 } 4087 if (LocaleCompare("clut",argv[0]+1) == 0) 4088 { 4089 Image 4090 *clut_image, 4091 *image; 4092 4093 (void) SyncImagesSettings(image_info,*images); 4094 image=RemoveFirstImageFromList(images); 4095 clut_image=RemoveFirstImageFromList(images); 4096 if (clut_image == (Image *) NULL) 4097 { 4098 status=MagickFalse; 4099 break; 4100 } 4101 (void) ClutImage(image,clut_image,interpolate_method,exception); 4102 clut_image=DestroyImage(clut_image); 4103 *images=DestroyImageList(*images); 4104 *images=image; 4105 break; 4106 } 4107 if (LocaleCompare("coalesce",argv[0]+1) == 0) 4108 { 4109 Image 4110 *coalesce_image; 4111 4112 (void) SyncImagesSettings(image_info,*images); 4113 coalesce_image=CoalesceImages(*images,exception); 4114 if (coalesce_image == (Image *) NULL) 4115 { 4116 status=MagickFalse; 4117 break; 4118 } 4119 *images=DestroyImageList(*images); 4120 *images=coalesce_image; 4121 break; 4122 } 4123 if (LocaleCompare("combine",argv[0]+1) == 0) 4124 { 4125 Image 4126 *combine_image; 4127 4128 (void) SyncImagesSettings(image_info,*images); 4129 combine_image=CombineImages(*images,exception); 4130 if (combine_image == (Image *) NULL) 4131 { 4132 status=MagickFalse; 4133 break; 4134 } 4135 *images=DestroyImageList(*images); 4136 *images=combine_image; 4137 break; 4138 } 4139 if (LocaleCompare("composite",argv[0]+1) == 0) 4140 { 4141 Image 4142 *mask_image, 4143 *composite_image, 4144 *image; 4145 4146 RectangleInfo 4147 geometry; 4148 4149 (void) SyncImagesSettings(image_info,*images); 4150 image=RemoveFirstImageFromList(images); 4151 composite_image=RemoveFirstImageFromList(images); 4152 if (composite_image == (Image *) NULL) 4153 { 4154 status=MagickFalse; 4155 break; 4156 } 4157 (void) TransformImage(&composite_image,(char *) NULL, 4158 composite_image->geometry); 4159 SetGeometry(composite_image,&geometry); 4160 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry); 4161 GravityAdjustGeometry(image->columns,image->rows,image->gravity, 4162 &geometry); 4163 mask_image=RemoveFirstImageFromList(images); 4164 if (mask_image != (Image *) NULL) 4165 { 4166 if ((image->compose == DisplaceCompositeOp) || 4167 (image->compose == DistortCompositeOp)) 4168 { 4169 /* 4170 Merge Y displacement into X displacement image. 4171 */ 4172 (void) CompositeImage(composite_image,CopyGreenCompositeOp, 4173 mask_image,0,0); 4174 mask_image=DestroyImage(mask_image); 4175 } 4176 else 4177 { 4178 /* 4179 Set a blending mask for the composition. 4180 Posible error, what if image->mask already set. 4181 */ 4182 image->mask=mask_image; 4183 (void) NegateImage(image->mask,MagickFalse,exception); 4184 } 4185 } 4186 (void) CompositeImage(image,image->compose,composite_image, 4187 geometry.x,geometry.y); 4188 if (mask_image != (Image *) NULL) 4189 mask_image=image->mask=DestroyImage(image->mask); 4190 composite_image=DestroyImage(composite_image); 4191 InheritException(exception,&image->exception); 4192 *images=DestroyImageList(*images); 4193 *images=image; 4194 break; 4195 } 4196 break; 4197 } 4198 case 'd': 4199 { 4200 if (LocaleCompare("deconstruct",argv[0]+1) == 0) 4201 { 4202 Image 4203 *deconstruct_image; 4204 4205 (void) SyncImagesSettings(image_info,*images); 4206 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer, 4207 exception); 4208 if (deconstruct_image == (Image *) NULL) 4209 { 4210 status=MagickFalse; 4211 break; 4212 } 4213 *images=DestroyImageList(*images); 4214 *images=deconstruct_image; 4215 break; 4216 } 4217 if (LocaleCompare("delete",argv[0]+1) == 0) 4218 { 4219 if (*argv[0] == '+') 4220 DeleteImages(images,"-1",exception); 4221 else 4222 DeleteImages(images,argv[1],exception); 4223 break; 4224 } 4225 if (LocaleCompare("dither",argv[0]+1) == 0) 4226 { 4227 if (*argv[0] == '+') 4228 { 4229 quantize_info->dither=MagickFalse; 4230 break; 4231 } 4232 quantize_info->dither=MagickTrue; 4233 quantize_info->dither_method=(DitherMethod) ParseCommandOption( 4234 MagickDitherOptions,MagickFalse,argv[1]); 4235 break; 4236 } 4237 if (LocaleCompare("duplicate",argv[0]+1) == 0) 4238 { 4239 Image 4240 *duplicate_images; 4241 4242 if (*argv[0] == '+') 4243 duplicate_images=DuplicateImages(*images,1,"-1",exception); 4244 else 4245 { 4246 const char 4247 *p; 4248 4249 size_t 4250 number_duplicates; 4251 4252 number_duplicates=(size_t) StringToLong(argv[1]); 4253 p=strchr(argv[1],','); 4254 if (p == (const char *) NULL) 4255 duplicate_images=DuplicateImages(*images,number_duplicates, 4256 "-1",exception); 4257 else 4258 duplicate_images=DuplicateImages(*images,number_duplicates,p, 4259 exception); 4260 } 4261 AppendImageToList(images, duplicate_images); 4262 (void) SyncImagesSettings(image_info,*images); 4263 break; 4264 } 4265 break; 4266 } 4267 case 'e': 4268 { 4269 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0) 4270 { 4271 Image 4272 *evaluate_image; 4273 4274 MagickEvaluateOperator 4275 op; 4276 4277 (void) SyncImageSettings(image_info,*images); 4278 op=(MagickEvaluateOperator) ParseCommandOption( 4279 MagickEvaluateOptions,MagickFalse,argv[1]); 4280 evaluate_image=EvaluateImages(*images,op,exception); 4281 if (evaluate_image == (Image *) NULL) 4282 { 4283 status=MagickFalse; 4284 break; 4285 } 4286 *images=DestroyImageList(*images); 4287 *images=evaluate_image; 4288 break; 4289 } 4290 break; 4291 } 4292 case 'f': 4293 { 4294 if (LocaleCompare("fft",argv[0]+1) == 0) 4295 { 4296 Image 4297 *fourier_image; 4298 4299 /* 4300 Implements the discrete Fourier transform (DFT). 4301 */ 4302 (void) SyncImageSettings(image_info,*images); 4303 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ? 4304 MagickTrue : MagickFalse,exception); 4305 if (fourier_image == (Image *) NULL) 4306 break; 4307 *images=DestroyImage(*images); 4308 *images=fourier_image; 4309 break; 4310 } 4311 if (LocaleCompare("flatten",argv[0]+1) == 0) 4312 { 4313 Image 4314 *flatten_image; 4315 4316 (void) SyncImagesSettings(image_info,*images); 4317 flatten_image=MergeImageLayers(*images,FlattenLayer,exception); 4318 if (flatten_image == (Image *) NULL) 4319 break; 4320 *images=DestroyImageList(*images); 4321 *images=flatten_image; 4322 break; 4323 } 4324 if (LocaleCompare("fx",argv[0]+1) == 0) 4325 { 4326 Image 4327 *fx_image; 4328 4329 (void) SyncImagesSettings(image_info,*images); 4330 fx_image=FxImage(*images,argv[1],exception); 4331 if (fx_image == (Image *) NULL) 4332 { 4333 status=MagickFalse; 4334 break; 4335 } 4336 *images=DestroyImageList(*images); 4337 *images=fx_image; 4338 break; 4339 } 4340 break; 4341 } 4342 case 'h': 4343 { 4344 if (LocaleCompare("hald-clut",argv[0]+1) == 0) 4345 { 4346 Image 4347 *hald_image, 4348 *image; 4349 4350 (void) SyncImagesSettings(image_info,*images); 4351 image=RemoveFirstImageFromList(images); 4352 hald_image=RemoveFirstImageFromList(images); 4353 if (hald_image == (Image *) NULL) 4354 { 4355 status=MagickFalse; 4356 break; 4357 } 4358 (void) HaldClutImage(image,hald_image,exception); 4359 hald_image=DestroyImage(hald_image); 4360 if (*images != (Image *) NULL) 4361 *images=DestroyImageList(*images); 4362 *images=image; 4363 break; 4364 } 4365 break; 4366 } 4367 case 'i': 4368 { 4369 if (LocaleCompare("ift",argv[0]+1) == 0) 4370 { 4371 Image 4372 *fourier_image, 4373 *magnitude_image, 4374 *phase_image; 4375 4376 /* 4377 Implements the inverse fourier discrete Fourier transform (DFT). 4378 */ 4379 (void) SyncImagesSettings(image_info,*images); 4380 magnitude_image=RemoveFirstImageFromList(images); 4381 phase_image=RemoveFirstImageFromList(images); 4382 if (phase_image == (Image *) NULL) 4383 { 4384 status=MagickFalse; 4385 break; 4386 } 4387 fourier_image=InverseFourierTransformImage(magnitude_image, 4388 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception); 4389 if (fourier_image == (Image *) NULL) 4390 break; 4391 if (*images != (Image *) NULL) 4392 *images=DestroyImage(*images); 4393 *images=fourier_image; 4394 break; 4395 } 4396 if (LocaleCompare("insert",argv[0]+1) == 0) 4397 { 4398 Image 4399 *p, 4400 *q; 4401 4402 index=0; 4403 if (*argv[0] != '+') 4404 index=(ssize_t) StringToLong(argv[1]); 4405 p=RemoveLastImageFromList(images); 4406 if (p == (Image *) NULL) 4407 { 4408 (void) ThrowMagickException(exception,GetMagickModule(), 4409 OptionError,"NoSuchImage","`%s'",argv[1]); 4410 status=MagickFalse; 4411 break; 4412 } 4413 q=p; 4414 if (index == 0) 4415 PrependImageToList(images,q); 4416 else 4417 if (index == (ssize_t) GetImageListLength(*images)) 4418 AppendImageToList(images,q); 4419 else 4420 { 4421 q=GetImageFromList(*images,index-1); 4422 if (q == (Image *) NULL) 4423 { 4424 (void) ThrowMagickException(exception,GetMagickModule(), 4425 OptionError,"NoSuchImage","`%s'",argv[1]); 4426 status=MagickFalse; 4427 break; 4428 } 4429 InsertImageInList(&q,p); 4430 } 4431 *images=GetFirstImageInList(q); 4432 break; 4433 } 4434 if (LocaleCompare("interpolate",argv[0]+1) == 0) 4435 { 4436 interpolate_method=(PixelInterpolateMethod) ParseCommandOption( 4437 MagickInterpolateOptions,MagickFalse,argv[1]); 4438 break; 4439 } 4440 break; 4441 } 4442 case 'l': 4443 { 4444 if (LocaleCompare("layers",argv[0]+1) == 0) 4445 { 4446 Image 4447 *layers; 4448 4449 ImageLayerMethod 4450 method; 4451 4452 (void) SyncImagesSettings(image_info,*images); 4453 layers=(Image *) NULL; 4454 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions, 4455 MagickFalse,argv[1]); 4456 switch (method) 4457 { 4458 case CoalesceLayer: 4459 { 4460 layers=CoalesceImages(*images,exception); 4461 break; 4462 } 4463 case CompareAnyLayer: 4464 case CompareClearLayer: 4465 case CompareOverlayLayer: 4466 default: 4467 { 4468 layers=CompareImagesLayers(*images,method,exception); 4469 break; 4470 } 4471 case MergeLayer: 4472 case FlattenLayer: 4473 case MosaicLayer: 4474 case TrimBoundsLayer: 4475 { 4476 layers=MergeImageLayers(*images,method,exception); 4477 break; 4478 } 4479 case DisposeLayer: 4480 { 4481 layers=DisposeImages(*images,exception); 4482 break; 4483 } 4484 case OptimizeImageLayer: 4485 { 4486 layers=OptimizeImageLayers(*images,exception); 4487 break; 4488 } 4489 case OptimizePlusLayer: 4490 { 4491 layers=OptimizePlusImageLayers(*images,exception); 4492 break; 4493 } 4494 case OptimizeTransLayer: 4495 { 4496 OptimizeImageTransparency(*images,exception); 4497 break; 4498 } 4499 case RemoveDupsLayer: 4500 { 4501 RemoveDuplicateLayers(images,exception); 4502 break; 4503 } 4504 case RemoveZeroLayer: 4505 { 4506 RemoveZeroDelayLayers(images,exception); 4507 break; 4508 } 4509 case OptimizeLayer: 4510 { 4511 /* 4512 General Purpose, GIF Animation Optimizer. 4513 */ 4514 layers=CoalesceImages(*images,exception); 4515 if (layers == (Image *) NULL) 4516 { 4517 status=MagickFalse; 4518 break; 4519 } 4520 *images=DestroyImageList(*images); 4521 *images=layers; 4522 layers=OptimizeImageLayers(*images,exception); 4523 if (layers == (Image *) NULL) 4524 { 4525 status=MagickFalse; 4526 break; 4527 } 4528 *images=DestroyImageList(*images); 4529 *images=layers; 4530 layers=(Image *) NULL; 4531 OptimizeImageTransparency(*images,exception); 4532 (void) RemapImages(quantize_info,*images,(Image *) NULL, 4533 exception); 4534 break; 4535 } 4536 case CompositeLayer: 4537 { 4538 CompositeOperator 4539 compose; 4540 4541 Image 4542 *source; 4543 4544 RectangleInfo 4545 geometry; 4546 4547 /* 4548 Split image sequence at the first 'NULL:' image. 4549 */ 4550 source=(*images); 4551 while (source != (Image *) NULL) 4552 { 4553 source=GetNextImageInList(source); 4554 if ((source != (Image *) NULL) && 4555 (LocaleCompare(source->magick,"NULL") == 0)) 4556 break; 4557 } 4558 if (source != (Image *) NULL) 4559 { 4560 if ((GetPreviousImageInList(source) == (Image *) NULL) || 4561 (GetNextImageInList(source) == (Image *) NULL)) 4562 source=(Image *) NULL; 4563 else 4564 { 4565 /* 4566 Separate the two lists, junk the null: image. 4567 */ 4568 source=SplitImageList(source->previous); 4569 DeleteImageFromList(&source); 4570 } 4571 } 4572 if (source == (Image *) NULL) 4573 { 4574 (void) ThrowMagickException(exception,GetMagickModule(), 4575 OptionError,"MissingNullSeparator","layers Composite"); 4576 status=MagickFalse; 4577 break; 4578 } 4579 /* 4580 Adjust offset with gravity and virtual canvas. 4581 */ 4582 SetGeometry(*images,&geometry); 4583 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry); 4584 geometry.width=source->page.width != 0 ? 4585 source->page.width : source->columns; 4586 geometry.height=source->page.height != 0 ? 4587 source->page.height : source->rows; 4588 GravityAdjustGeometry((*images)->page.width != 0 ? 4589 (*images)->page.width : (*images)->columns, 4590 (*images)->page.height != 0 ? (*images)->page.height : 4591 (*images)->rows,(*images)->gravity,&geometry); 4592 compose=OverCompositeOp; 4593 argv[0]=GetImageOption(image_info,"compose"); 4594 if (argv[0] != (const char *) NULL) 4595 compose=(CompositeOperator) ParseCommandOption( 4596 MagickComposeOptions,MagickFalse,argv[0]); 4597 CompositeLayers(*images,compose,source,geometry.x,geometry.y, 4598 exception); 4599 source=DestroyImageList(source); 4600 break; 4601 } 4602 } 4603 if (layers == (Image *) NULL) 4604 break; 4605 InheritException(exception,&layers->exception); 4606 *images=DestroyImageList(*images); 4607 *images=layers; 4608 break; 4609 } 4610 break; 4611 } 4612 case 'm': 4613 { 4614 if (LocaleCompare("map",argv[0]+1) == 0) 4615 { 4616 (void) SyncImagesSettings(image_info,*images); 4617 if (*argv[0] == '+') 4618 { 4619 (void) RemapImages(quantize_info,*images,(Image *) NULL, 4620 exception); 4621 break; 4622 } 4623 break; 4624 } 4625 if (LocaleCompare("maximum",argv[0]+1) == 0) 4626 { 4627 Image 4628 *maximum_image; 4629 4630 /* 4631 Maximum image sequence (deprecated). 4632 */ 4633 (void) SyncImagesSettings(image_info,*images); 4634 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception); 4635 if (maximum_image == (Image *) NULL) 4636 { 4637 status=MagickFalse; 4638 break; 4639 } 4640 *images=DestroyImageList(*images); 4641 *images=maximum_image; 4642 break; 4643 } 4644 if (LocaleCompare("minimum",argv[0]+1) == 0) 4645 { 4646 Image 4647 *minimum_image; 4648 4649 /* 4650 Minimum image sequence (deprecated). 4651 */ 4652 (void) SyncImagesSettings(image_info,*images); 4653 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception); 4654 if (minimum_image == (Image *) NULL) 4655 { 4656 status=MagickFalse; 4657 break; 4658 } 4659 *images=DestroyImageList(*images); 4660 *images=minimum_image; 4661 break; 4662 } 4663 if (LocaleCompare("morph",argv[0]+1) == 0) 4664 { 4665 Image 4666 *morph_image; 4667 4668 (void) SyncImagesSettings(image_info,*images); 4669 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]), 4670 exception); 4671 if (morph_image == (Image *) NULL) 4672 { 4673 status=MagickFalse; 4674 break; 4675 } 4676 *images=DestroyImageList(*images); 4677 *images=morph_image; 4678 break; 4679 } 4680 if (LocaleCompare("mosaic",argv[0]+1) == 0) 4681 { 4682 Image 4683 *mosaic_image; 4684 4685 (void) SyncImagesSettings(image_info,*images); 4686 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception); 4687 if (mosaic_image == (Image *) NULL) 4688 { 4689 status=MagickFalse; 4690 break; 4691 } 4692 *images=DestroyImageList(*images); 4693 *images=mosaic_image; 4694 break; 4695 } 4696 break; 4697 } 4698 case 'p': 4699 { 4700 if (LocaleCompare("print",argv[0]+1) == 0) 4701 { 4702 char 4703 *string; 4704 4705 (void) SyncImagesSettings(image_info,*images); 4706 string=InterpretImageProperties(image_info,*images,argv[1], 4707 exception); 4708 if (string == (char *) NULL) 4709 break; 4710 (void) FormatLocaleFile(stdout,"%s",string); 4711 string=DestroyString(string); 4712 } 4713 if (LocaleCompare("process",argv[0]+1) == 0) 4714 { 4715 char 4716 **arguments; 4717 4718 int 4719 j, 4720 number_arguments; 4721 4722 (void) SyncImagesSettings(image_info,*images); 4723 arguments=StringToArgv(argv[1],&number_arguments); 4724 if (arguments == (char **) NULL) 4725 break; 4726 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL)) 4727 { 4728 char 4729 breaker, 4730 quote, 4731 *token; 4732 4733 const char 4734 *arguments; 4735 4736 int 4737 next, 4738 status; 4739 4740 size_t 4741 length; 4742 4743 TokenInfo 4744 *token_info; 4745 4746 /* 4747 Support old style syntax, filter="-option arg". 4748 */ 4749 length=strlen(argv[1]); 4750 token=(char *) NULL; 4751 if (~length >= (MaxTextExtent-1)) 4752 token=(char *) AcquireQuantumMemory(length+MaxTextExtent, 4753 sizeof(*token)); 4754 if (token == (char *) NULL) 4755 break; 4756 next=0; 4757 arguments=argv[1]; 4758 token_info=AcquireTokenInfo(); 4759 status=Tokenizer(token_info,0,token,length,arguments,"","=", 4760 "\"",'\0',&breaker,&next,"e); 4761 token_info=DestroyTokenInfo(token_info); 4762 if (status == 0) 4763 { 4764 const char 4765 *argv; 4766 4767 argv=(&(arguments[next])); 4768 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv, 4769 exception); 4770 } 4771 token=DestroyString(token); 4772 break; 4773 } 4774 (void) SubstituteString(&arguments[1],"-",""); 4775 (void) InvokeDynamicImageFilter(arguments[1],&(*images), 4776 number_arguments-2,(const char **) arguments+2,exception); 4777 for (j=0; j < number_arguments; j++) 4778 arguments[j]=DestroyString(arguments[j]); 4779 arguments=(char **) RelinquishMagickMemory(arguments); 4780 break; 4781 } 4782 break; 4783 } 4784 case 'r': 4785 { 4786 if (LocaleCompare("reverse",argv[0]+1) == 0) 4787 { 4788 ReverseImageList(images); 4789 InheritException(exception,&(*images)->exception); 4790 break; 4791 } 4792 break; 4793 } 4794 case 's': 4795 { 4796 if (LocaleCompare("smush",argv[0]+1) == 0) 4797 { 4798 Image 4799 *smush_image; 4800 4801 ssize_t 4802 offset; 4803 4804 (void) SyncImagesSettings(image_info,*images); 4805 offset=(ssize_t) StringToLong(argv[1]); 4806 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue : 4807 MagickFalse,offset,exception); 4808 if (smush_image == (Image *) NULL) 4809 { 4810 status=MagickFalse; 4811 break; 4812 } 4813 *images=DestroyImageList(*images); 4814 *images=smush_image; 4815 break; 4816 } 4817 if (LocaleCompare("swap",argv[0]+1) == 0) 4818 { 4819 Image 4820 *p, 4821 *q, 4822 *swap; 4823 4824 ssize_t 4825 swap_index; 4826 4827 index=(-1); 4828 swap_index=(-2); 4829 if (*argv[0] != '+') 4830 { 4831 GeometryInfo 4832 geometry_info; 4833 4834 MagickStatusType 4835 flags; 4836 4837 swap_index=(-1); 4838 flags=ParseGeometry(argv[1],&geometry_info); 4839 index=(ssize_t) geometry_info.rho; 4840 if ((flags & SigmaValue) != 0) 4841 swap_index=(ssize_t) geometry_info.sigma; 4842 } 4843 p=GetImageFromList(*images,index); 4844 q=GetImageFromList(*images,swap_index); 4845 if ((p == (Image *) NULL) || (q == (Image *) NULL)) 4846 { 4847 (void) ThrowMagickException(exception,GetMagickModule(), 4848 OptionError,"NoSuchImage","`%s'",(*images)->filename); 4849 status=MagickFalse; 4850 break; 4851 } 4852 if (p == q) 4853 break; 4854 swap=CloneImage(p,0,0,MagickTrue,exception); 4855 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception)); 4856 ReplaceImageInList(&q,swap); 4857 *images=GetFirstImageInList(q); 4858 break; 4859 } 4860 break; 4861 } 4862 case 'w': 4863 { 4864 if (LocaleCompare("write",argv[0]+1) == 0) 4865 { 4866 char 4867 key[MaxTextExtent]; 4868 4869 Image 4870 *write_images; 4871 4872 ImageInfo 4873 *write_info; 4874 4875 (void) SyncImagesSettings(image_info,*images); 4876 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]); 4877 (void) DeleteImageRegistry(key); 4878 write_images=(*images); 4879 if (*argv[0] == '+') 4880 write_images=CloneImageList(*images,exception); 4881 write_info=CloneImageInfo(image_info); 4882 status&=WriteImages(write_info,write_images,argv[1],exception); 4883 write_info=DestroyImageInfo(write_info); 4884 if (*argv[0] == '+') 4885 write_images=DestroyImageList(write_images); 4886 break; 4887 } 4888 break; 4889 } 4890 default: 4891 break; 4892 } 4893 quantize_info=DestroyQuantizeInfo(quantize_info); 4894 4895 status=(MagickStatusType) ((*image)->exception.severity == 4896 UndefinedException ? 1 : 0); 4897 return(status != 0 ? MagickTrue : MagickFalse); 4898} 4899#endif 4900