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