00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "wand/studio.h"
00044 #include "wand/MagickWand.h"
00045 #include "wand/mogrify-private.h"
00046
00047
00048
00049
00050 #define UndefinedCompressionQuality 0UL
00051
00052
00053
00054
00055 static const char
00056 *BackgroundColor = "#fff",
00057 *BorderColor = "#dfdfdf",
00058 *MatteColor = "#bdbdbd";
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static int IsPathDirectory(const char *path)
00096 {
00097 #if !defined(X_OK)
00098 #define X_OK 1
00099 #endif
00100
00101 MagickBooleanType
00102 status;
00103
00104 struct stat
00105 attributes;
00106
00107 if ((path == (const char *) NULL) || (*path == '\0'))
00108 return(MagickFalse);
00109 status=GetPathAttributes(path,&attributes);
00110 if (status == MagickFalse)
00111 return(-1);
00112 if (S_ISDIR(attributes.st_mode) == 0)
00113 return(0);
00114 if (access(path,X_OK) != 0)
00115 return(0);
00116 return(1);
00117 }
00118
00119 static inline long MagickMax(const long x,const long y)
00120 {
00121 if (x > y)
00122 return(x);
00123 return(y);
00124 }
00125
00126 static MagickBooleanType MonitorProgress(const char *text,
00127 const MagickOffsetType quantum,const MagickSizeType span,
00128 void *wand_unused(client_data))
00129 {
00130 char
00131 message[MaxTextExtent],
00132 tag[MaxTextExtent];
00133
00134 const char
00135 *locale_message;
00136
00137 register char
00138 *p;
00139
00140 if (span < 2)
00141 return(MagickTrue);
00142 (void) CopyMagickMemory(tag,text,MaxTextExtent);
00143 p=strrchr(tag,'/');
00144 if (p != (char *) NULL)
00145 *p='\0';
00146 (void) FormatMagickString(message,MaxTextExtent,"Monitor/%s",tag);
00147 locale_message=GetLocaleMessage(message);
00148 if (locale_message == message)
00149 locale_message=tag;
00150 if (p == (char *) NULL)
00151 (void) fprintf(stderr,"%s: %02ld%%\r",locale_message,(long)
00152 (100L*quantum/(span-1)));
00153 else
00154 (void) fprintf(stderr,"%s: %02ld%% [%s]\r",locale_message,(long)
00155 (100L*quantum/(span-1)),p+1);
00156 if ((MagickSizeType) quantum == (span-1))
00157 (void) fprintf(stderr,"\n");
00158 (void) fflush(stderr);
00159 return(MagickTrue);
00160 }
00161
00162 static Image *SparseColorOption(const Image *image,const ChannelType channel,
00163 const SparseColorMethod method,const char *arguments,
00164 const MagickBooleanType color_from_image,ExceptionInfo *exception)
00165 {
00166 ChannelType
00167 channels;
00168
00169 char
00170 token[MaxTextExtent];
00171
00172 const char
00173 *p;
00174
00175 double
00176 *sparse_arguments;
00177
00178 register unsigned long
00179 x;
00180
00181 unsigned long
00182 number_arguments;
00183
00184 unsigned long
00185 number_colors;
00186
00187 Image
00188 *sparse_image;
00189
00190 MagickPixelPacket
00191 color;
00192
00193 MagickBooleanType
00194 error;
00195
00196 assert(image != (Image *) NULL);
00197 assert(image->signature == MagickSignature);
00198 if (image->debug != MagickFalse)
00199 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00200 assert(exception != (ExceptionInfo *) NULL);
00201 assert(exception->signature == MagickSignature);
00202
00203
00204 channels=channel;
00205 if ( image->colorspace != CMYKColorspace )
00206 channels = (ChannelType) (channels & ~IndexChannel);
00207 if ( image->matte == MagickFalse )
00208 channels = (ChannelType) (channels & ~OpacityChannel);
00209 number_colors=0;
00210 if ( channels & RedChannel ) number_colors++;
00211 if ( channels & GreenChannel ) number_colors++;
00212 if ( channels & BlueChannel ) number_colors++;
00213 if ( channels & IndexChannel ) number_colors++;
00214 if ( channels & OpacityChannel ) number_colors++;
00215
00216
00217 p=arguments;
00218 x=0;
00219 while( *p != '\0' ) {
00220 GetMagickToken(p,&p,token);
00221 if ( token[0] == ',' ) continue;
00222 if ( isalpha((int) token[0]) || token[0] == '#' ) {
00223 if ( color_from_image ) {
00224 (void) ThrowMagickException(exception,GetMagickModule(),
00225 OptionError, "InvalidArgument", "`%s': %s", "sparse-colors",
00226 "Color arg given, when colors are coming from image");
00227 return( (Image *)NULL);
00228 }
00229 x += number_colors;
00230 }
00231 else {
00232 x++;
00233 }
00234 }
00235 error=MagickTrue;
00236 if ( color_from_image ) {
00237
00238 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
00239 number_arguments=(x/2)*(2+number_colors);
00240 }
00241 else {
00242
00243 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
00244 number_arguments=x;
00245 }
00246 if ( error ) {
00247 (void) ThrowMagickException(exception,GetMagickModule(),
00248 OptionError, "InvalidArgument", "`%s': %s", "sparse-colors",
00249 "Invalid number of Arguments");
00250 return( (Image *)NULL);
00251 }
00252
00253
00254 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
00255 sizeof(*sparse_arguments));
00256 if (sparse_arguments == (double *) NULL) {
00257 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
00258 "MemoryAllocationFailed","%s","SparseColorOption");
00259 return( (Image *)NULL);
00260 }
00261 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
00262 sizeof(*sparse_arguments));
00263 p=arguments;
00264 x=0;
00265 while( *p != '\0' && x < number_arguments ) {
00266
00267 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00268 if ( token[0] == '\0' ) break;
00269 if ( isalpha((int) token[0]) || token[0] == '#' ) {
00270 (void) ThrowMagickException(exception,GetMagickModule(),
00271 OptionError, "InvalidArgument", "`%s': %s", "sparse-colors",
00272 "Color found, instead of X-coord");
00273 error = MagickTrue;
00274 break;
00275 }
00276 sparse_arguments[x++]=atof(token);
00277
00278 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00279 if ( token[0] == '\0' ) break;
00280 if ( isalpha((int) token[0]) || token[0] == '#' ) {
00281 (void) ThrowMagickException(exception,GetMagickModule(),
00282 OptionError, "InvalidArgument", "`%s': %s", "sparse-colors",
00283 "Color found, instead of Y-coord");
00284 error = MagickTrue;
00285 break;
00286 }
00287 sparse_arguments[x++]=atof(token);
00288
00289 #if 0
00290 if ( (color_from_image ) {
00291
00292
00293 }
00294 else
00295 #endif
00296 {
00297
00298 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00299 if ( token[0] == '\0' ) break;
00300 if ( isalpha((int) token[0]) || token[0] == '#' ) {
00301
00302 (void) QueryMagickColor(token,&color,exception);
00303 if ( channels & RedChannel )
00304 sparse_arguments[x++] = QuantumScale*color.red;
00305 if ( channels & GreenChannel )
00306 sparse_arguments[x++] = QuantumScale*color.green;
00307 if ( channels & BlueChannel )
00308 sparse_arguments[x++] = QuantumScale*color.blue;
00309 if ( channels & IndexChannel )
00310 sparse_arguments[x++] = QuantumScale*color.index;
00311 if ( channels & OpacityChannel )
00312 sparse_arguments[x++] = QuantumScale*color.opacity;
00313 }
00314 else {
00315 #if 0
00316
00317 break;
00318 #else
00319
00320
00321 if ( channels & RedChannel ) {
00322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
00324 break;
00325 sparse_arguments[x++] = atof(token);
00326 token[0] = ',';
00327 }
00328 if ( channels & GreenChannel ) {
00329 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00330 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
00331 break;
00332 sparse_arguments[x++] = atof(token);
00333 token[0] = ',';
00334 }
00335 if ( channels & BlueChannel ) {
00336 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00337 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
00338 break;
00339 sparse_arguments[x++] = atof(token);
00340 token[0] = ',';
00341 }
00342 if ( channels & IndexChannel ) {
00343 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00344 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
00345 break;
00346 sparse_arguments[x++] = atof(token);
00347 token[0] = ',';
00348 }
00349 if ( channels & OpacityChannel ) {
00350 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
00351 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
00352 break;
00353 sparse_arguments[x++] = atof(token);
00354 token[0] = ',';
00355 }
00356 #endif
00357 }
00358 }
00359 }
00360 if ( number_arguments != x && !error ) {
00361 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
00362 "InvalidArgument","`%s': %s","sparse-colors","Argument Parsing Error");
00363 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
00364 return( (Image *)NULL);
00365 }
00366 if ( error )
00367 return( (Image *)NULL);
00368
00369
00370 sparse_image=SparseColorImage(image,channels,method,number_arguments,
00371 sparse_arguments,exception);
00372 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
00373 return( sparse_image );
00374 }
00375
00376 WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
00377 const char **argv,Image **image,ExceptionInfo *exception)
00378 {
00379 ChannelType
00380 channel;
00381
00382 const char
00383 *format,
00384 *option;
00385
00386 DrawInfo
00387 *draw_info;
00388
00389 GeometryInfo
00390 geometry_info;
00391
00392 Image
00393 *region_image;
00394
00395 long
00396 count;
00397
00398 MagickBooleanType
00399 status;
00400
00401 MagickPixelPacket
00402 fill;
00403
00404 MagickStatusType
00405 flags;
00406
00407 QuantizeInfo
00408 *quantize_info;
00409
00410 RectangleInfo
00411 geometry,
00412 region_geometry;
00413
00414 register long
00415 i;
00416
00417
00418
00419
00420 assert(image_info != (const ImageInfo *) NULL);
00421 assert(image_info->signature == MagickSignature);
00422 assert(image != (Image **) NULL);
00423 assert((*image)->signature == MagickSignature);
00424 if ((*image)->debug != MagickFalse)
00425 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
00426 if (argc < 0)
00427 return(MagickTrue);
00428 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
00429 quantize_info=AcquireQuantizeInfo(image_info);
00430 SetGeometryInfo(&geometry_info);
00431 GetMagickPixelPacket(*image,&fill);
00432 SetMagickPixelPacket(*image,&(*image)->background_color,(IndexPacket *) NULL,
00433 &fill);
00434 channel=image_info->channel;
00435 format=GetImageOption(image_info,"format");
00436 SetGeometry(*image,®ion_geometry);
00437 region_image=NewImageList();
00438
00439
00440
00441 for (i=0; i < (long) argc; i++)
00442 {
00443 option=argv[i];
00444 if (IsMagickOption(option) == MagickFalse)
00445 continue;
00446 count=MagickMax(ParseMagickOption(MagickCommandOptions,MagickFalse,option),
00447 0L);
00448 if ((i+count) >= argc)
00449 break;
00450 status=MogrifyImageInfo(image_info,count+1,argv+i,exception);
00451 switch (*(option+1))
00452 {
00453 case 'a':
00454 {
00455 if (LocaleCompare("adaptive-blur",option+1) == 0)
00456 {
00457 Image
00458 *blur_image;
00459
00460
00461
00462
00463 (void) SyncImageSettings(image_info,*image);
00464 flags=ParseGeometry(argv[i+1],&geometry_info);
00465 if ((flags & SigmaValue) == 0)
00466 geometry_info.sigma=1.0;
00467 blur_image=AdaptiveBlurImageChannel(*image,channel,
00468 geometry_info.rho,geometry_info.sigma,exception);
00469 if (blur_image == (Image *) NULL)
00470 break;
00471 *image=DestroyImage(*image);
00472 *image=blur_image;
00473 break;
00474 }
00475 if (LocaleCompare("adaptive-resize",option+1) == 0)
00476 {
00477 Image
00478 *resize_image;
00479
00480
00481
00482
00483 (void) SyncImageSettings(image_info,*image);
00484 (void) ParseSizeGeometry(*image,argv[i+1],&geometry);
00485 resize_image=AdaptiveResizeImage(*image,geometry.width,
00486 geometry.height,exception);
00487 if (resize_image == (Image *) NULL)
00488 break;
00489 *image=DestroyImage(*image);
00490 *image=resize_image;
00491 break;
00492 }
00493 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
00494 {
00495 Image
00496 *sharp_image;
00497
00498
00499
00500
00501 (void) SyncImageSettings(image_info,*image);
00502 flags=ParseGeometry(argv[i+1],&geometry_info);
00503 if ((flags & SigmaValue) == 0)
00504 geometry_info.sigma=1.0;
00505 sharp_image=AdaptiveSharpenImageChannel(*image,channel,
00506 geometry_info.rho,geometry_info.sigma,exception);
00507 if (sharp_image == (Image *) NULL)
00508 break;
00509 *image=DestroyImage(*image);
00510 *image=sharp_image;
00511 break;
00512 }
00513 if (LocaleCompare("affine",option+1) == 0)
00514 {
00515
00516
00517
00518 if (*option == '+')
00519 {
00520 GetAffineMatrix(&draw_info->affine);
00521 break;
00522 }
00523 (void) ParseAffineGeometry(argv[i+1],&draw_info->affine);
00524 break;
00525 }
00526 if (LocaleCompare("alpha",option+1) == 0)
00527 {
00528 AlphaChannelType
00529 alpha_type;
00530
00531 (void) SyncImageSettings(image_info,*image);
00532 alpha_type=(AlphaChannelType) ParseMagickOption(MagickAlphaOptions,
00533 MagickFalse,argv[i+1]);
00534 (void) SetImageAlphaChannel(*image,alpha_type);
00535 InheritException(exception,&(*image)->exception);
00536 break;
00537 }
00538 if (LocaleCompare("annotate",option+1) == 0)
00539 {
00540 char
00541 *text,
00542 geometry[MaxTextExtent];
00543
00544
00545
00546
00547 (void) SyncImageSettings(image_info,*image);
00548 SetGeometryInfo(&geometry_info);
00549 flags=ParseGeometry(argv[i+1],&geometry_info);
00550 if ((flags & SigmaValue) == 0)
00551 geometry_info.sigma=geometry_info.rho;
00552 text=InterpretImageProperties(image_info,*image,argv[i+2]);
00553 InheritException(exception,&(*image)->exception);
00554 if (text == (char *) NULL)
00555 break;
00556 (void) CloneString(&draw_info->text,text);
00557 text=DestroyString(text);
00558 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
00559 geometry_info.xi,geometry_info.psi);
00560 (void) CloneString(&draw_info->geometry,geometry);
00561 draw_info->affine.sx=cos(DegreesToRadians(
00562 fmod(geometry_info.rho,360.0)));
00563 draw_info->affine.rx=sin(DegreesToRadians(
00564 fmod(geometry_info.rho,360.0)));
00565 draw_info->affine.ry=(-sin(DegreesToRadians(
00566 fmod(geometry_info.sigma,360.0))));
00567 draw_info->affine.sy=cos(DegreesToRadians(
00568 fmod(geometry_info.sigma,360.0)));
00569 (void) AnnotateImage(*image,draw_info);
00570 InheritException(exception,&(*image)->exception);
00571 break;
00572 }
00573 if (LocaleCompare("antialias",option+1) == 0)
00574 {
00575 draw_info->stroke_antialias=(*option == '-') ? MagickTrue :
00576 MagickFalse;
00577 draw_info->text_antialias=(*option == '-') ? MagickTrue :
00578 MagickFalse;
00579 break;
00580 }
00581 if (LocaleCompare("auto-orient",option+1) == 0)
00582 {
00583 Image
00584 *orient_image;
00585
00586 (void) SyncImageSettings(image_info,*image);
00587 orient_image=NewImageList();
00588 switch ((*image)->orientation)
00589 {
00590 case TopRightOrientation:
00591 {
00592 orient_image=FlopImage(*image,exception);
00593 break;
00594 }
00595 case BottomRightOrientation:
00596 {
00597 orient_image=RotateImage(*image,180.0,exception);
00598 break;
00599 }
00600 case BottomLeftOrientation:
00601 {
00602 orient_image=FlipImage(*image,exception);
00603 break;
00604 }
00605 case LeftTopOrientation:
00606 {
00607 orient_image=TransposeImage(*image,exception);
00608 break;
00609 }
00610 case RightTopOrientation:
00611 {
00612 orient_image=RotateImage(*image,90.0,exception);
00613 break;
00614 }
00615 case RightBottomOrientation:
00616 {
00617 orient_image=TransverseImage(*image,exception);
00618 break;
00619 }
00620 case LeftBottomOrientation:
00621 {
00622 orient_image=RotateImage(*image,270.0,exception);
00623 break;
00624 }
00625 default:
00626 break;
00627 }
00628 if (orient_image == (Image *) NULL)
00629 break;
00630 orient_image->orientation=TopLeftOrientation;
00631 *image=DestroyImage(*image);
00632 *image=orient_image;
00633 break;
00634 }
00635 break;
00636 }
00637 case 'b':
00638 {
00639 if (LocaleCompare("black-threshold",option+1) == 0)
00640 {
00641
00642
00643
00644 (void) SyncImageSettings(image_info,*image);
00645 (void) BlackThresholdImageChannel(*image,channel,argv[i+1],
00646 exception);
00647 InheritException(exception,&(*image)->exception);
00648 break;
00649 }
00650 if (LocaleCompare("blur",option+1) == 0)
00651 {
00652 Image
00653 *blur_image;
00654
00655
00656
00657
00658 (void) SyncImageSettings(image_info,*image);
00659 flags=ParseGeometry(argv[i+1],&geometry_info);
00660 if ((flags & SigmaValue) == 0)
00661 geometry_info.sigma=1.0;
00662 blur_image=BlurImageChannel(*image,channel,geometry_info.rho,
00663 geometry_info.sigma,exception);
00664 if (blur_image == (Image *) NULL)
00665 break;
00666 *image=DestroyImage(*image);
00667 *image=blur_image;
00668 break;
00669 }
00670 if (LocaleCompare("border",option+1) == 0)
00671 {
00672 Image
00673 *border_image;
00674
00675
00676
00677
00678 (void) SyncImageSettings(image_info,*image);
00679 flags=ParsePageGeometry(*image,argv[i+1],&geometry);
00680 if ((flags & SigmaValue) == 0)
00681 geometry.height=geometry.width;
00682 border_image=BorderImage(*image,&geometry,exception);
00683 if (border_image == (Image *) NULL)
00684 break;
00685 *image=DestroyImage(*image);
00686 *image=border_image;
00687 break;
00688 }
00689 if (LocaleCompare("bordercolor",option+1) == 0)
00690 {
00691 if (*option == '+')
00692 {
00693 (void) QueryColorDatabase(BorderColor,&draw_info->border_color,
00694 exception);
00695 break;
00696 }
00697 (void) QueryColorDatabase(argv[i+1],&draw_info->border_color,
00698 exception);
00699 break;
00700 }
00701 if (LocaleCompare("box",option+1) == 0)
00702 {
00703 (void) QueryColorDatabase(argv[i+1],&draw_info->undercolor,
00704 exception);
00705 break;
00706 }
00707 break;
00708 }
00709 case 'c':
00710 {
00711 if (LocaleCompare("channel",option+1) == 0)
00712 {
00713 if (*option == '+')
00714 {
00715 channel=DefaultChannels;
00716 break;
00717 }
00718 channel=(ChannelType) ParseChannelOption(argv[i+1]);
00719 break;
00720 }
00721 if (LocaleCompare("charcoal",option+1) == 0)
00722 {
00723 Image
00724 *charcoal_image;
00725
00726
00727
00728
00729 (void) SyncImageSettings(image_info,*image);
00730 flags=ParseGeometry(argv[i+1],&geometry_info);
00731 if ((flags & SigmaValue) == 0)
00732 geometry_info.sigma=1.0;
00733 charcoal_image=CharcoalImage(*image,geometry_info.rho,
00734 geometry_info.sigma,exception);
00735 if (charcoal_image == (Image *) NULL)
00736 break;
00737 *image=DestroyImage(*image);
00738 *image=charcoal_image;
00739 break;
00740 }
00741 if (LocaleCompare("chop",option+1) == 0)
00742 {
00743 Image
00744 *chop_image;
00745
00746
00747
00748
00749 (void) SyncImageSettings(image_info,*image);
00750 (void) ParseGravityGeometry(*image,argv[i+1],&geometry);
00751 chop_image=ChopImage(*image,&geometry,exception);
00752 if (chop_image == (Image *) NULL)
00753 break;
00754 *image=DestroyImage(*image);
00755 *image=chop_image;
00756 break;
00757 }
00758 if (LocaleCompare("clip",option+1) == 0)
00759 {
00760 (void) SyncImageSettings(image_info,*image);
00761 if (*option == '+')
00762 {
00763 (void) SetImageClipMask(*image,(Image *) NULL);
00764 InheritException(exception,&(*image)->exception);
00765 break;
00766 }
00767 (void) ClipImage(*image);
00768 InheritException(exception,&(*image)->exception);
00769 break;
00770 }
00771 if (LocaleCompare("clip-mask",option+1) == 0)
00772 {
00773 Image
00774 *mask;
00775
00776 ImageInfo
00777 *mask_info;
00778
00779 long
00780 y;
00781
00782 register long
00783 x;
00784
00785 register PixelPacket
00786 *q;
00787
00788 (void) SyncImageSettings(image_info,*image);
00789 if (*option == '+')
00790 {
00791
00792
00793
00794 (void) SetImageMask(*image,(Image *) NULL);
00795 InheritException(exception,&(*image)->exception);
00796 break;
00797 }
00798
00799
00800
00801 mask_info=CloneImageInfo(image_info);
00802 (void) CopyMagickString(mask_info->filename,argv[i+1],
00803 MaxTextExtent);
00804 mask=ReadImage(mask_info,exception);
00805 CatchException(exception);
00806 mask_info=DestroyImageInfo(mask_info);
00807 if (mask == (Image *) NULL)
00808 break;
00809 for (y=0; y < (long) mask->rows; y++)
00810 {
00811 q=GetAuthenticPixels(mask,0,y,mask->columns,1,exception);
00812 if (q == (PixelPacket *) NULL)
00813 break;
00814 for (x=0; x < (long) mask->columns; x++)
00815 {
00816 if (mask->matte == MagickFalse)
00817 q->opacity=PixelIntensityToQuantum(q);
00818 q->red=q->opacity;
00819 q->green=q->opacity;
00820 q->blue=q->opacity;
00821 q++;
00822 }
00823 if (SyncAuthenticPixels(mask,exception) == MagickFalse)
00824 break;
00825 }
00826 if (SetImageStorageClass(mask,DirectClass) == MagickFalse)
00827 return(MagickFalse);
00828 mask->matte=MagickTrue;
00829 (void) SetImageClipMask(*image,mask);
00830 InheritException(exception,&(*image)->exception);
00831 break;
00832 }
00833 if (LocaleCompare("clip-path",option+1) == 0)
00834 {
00835 (void) SyncImageSettings(image_info,*image);
00836 (void) ClipImagePath(*image,argv[i+1],*option == '-' ? MagickTrue :
00837 MagickFalse);
00838 InheritException(exception,&(*image)->exception);
00839 break;
00840 }
00841 if (LocaleCompare("colorize",option+1) == 0)
00842 {
00843 Image
00844 *colorize_image;
00845
00846
00847
00848
00849 (void) SyncImageSettings(image_info,*image);
00850 colorize_image=ColorizeImage(*image,argv[i+1],draw_info->fill,
00851 exception);
00852 if (colorize_image == (Image *) NULL)
00853 break;
00854 *image=DestroyImage(*image);
00855 *image=colorize_image;
00856 break;
00857 }
00858 if (LocaleCompare("colors",option+1) == 0)
00859 {
00860
00861
00862
00863 (void) SyncImageSettings(image_info,*image);
00864 quantize_info->number_colors=(unsigned long) atol(argv[i+1]);
00865 if (quantize_info->number_colors == 0)
00866 break;
00867 if (((*image)->storage_class == DirectClass) ||
00868 (*image)->colors > quantize_info->number_colors)
00869 (void) QuantizeImage(quantize_info,*image);
00870 else
00871 (void) CompressImageColormap(*image);
00872 InheritException(exception,&(*image)->exception);
00873 break;
00874 }
00875 if (LocaleCompare("colorspace",option+1) == 0)
00876 {
00877 ColorspaceType
00878 colorspace;
00879
00880 (void) SyncImageSettings(image_info,*image);
00881 if (*option == '+')
00882 {
00883 (void) SetImageColorspace(*image,RGBColorspace);
00884 InheritException(exception,&(*image)->exception);
00885 break;
00886 }
00887 colorspace=(ColorspaceType) ParseMagickOption(
00888 MagickColorspaceOptions,MagickFalse,argv[i+1]);
00889 (void) SetImageColorspace(*image,colorspace);
00890 InheritException(exception,&(*image)->exception);
00891 break;
00892 }
00893 if (LocaleCompare("contrast",option+1) == 0)
00894 {
00895 (void) SyncImageSettings(image_info,*image);
00896 (void) ContrastImage(*image,(*option == '-') ? MagickTrue :
00897 MagickFalse);
00898 InheritException(exception,&(*image)->exception);
00899 break;
00900 }
00901 if (LocaleCompare("contrast-stretch",option+1) == 0)
00902 {
00903 double
00904 black_point,
00905 white_point;
00906
00907 GeometryInfo
00908 geometry_info;
00909
00910 MagickStatusType
00911 flags;
00912
00913
00914
00915
00916 (void) SyncImageSettings(image_info,*image);
00917 flags=ParseGeometry(argv[i+1],&geometry_info);
00918 black_point=geometry_info.rho;
00919 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
00920 black_point;
00921 if ((flags & PercentValue) != 0)
00922 {
00923 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
00924 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
00925 }
00926 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
00927 white_point;
00928 (void) ContrastStretchImageChannel(*image,channel,black_point,
00929 white_point);
00930 InheritException(exception,&(*image)->exception);
00931 break;
00932 }
00933 if (LocaleCompare("convolve",option+1) == 0)
00934 {
00935 char
00936 token[MaxTextExtent];
00937
00938 const char
00939 *p;
00940
00941 double
00942 *kernel;
00943
00944 Image
00945 *convolve_image;
00946
00947 register long
00948 x;
00949
00950 unsigned long
00951 order;
00952
00953
00954
00955
00956 (void) SyncImageSettings(image_info,*image);
00957 p=(char *) argv[i+1];
00958 for (x=0; *p != '\0'; x++)
00959 {
00960 GetMagickToken(p,&p,token);
00961 if (*token == ',')
00962 GetMagickToken(p,&p,token);
00963 }
00964 order=(unsigned long) sqrt((double) x+1.0);
00965 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
00966 if (kernel == (double *) NULL)
00967 ThrowWandFatalException(ResourceLimitFatalError,
00968 "MemoryAllocationFailed",(*image)->filename);
00969 p=(char *) argv[i+1];
00970 for (x=0; (x < (long) (order*order)) && (*p != '\0'); x++)
00971 {
00972 GetMagickToken(p,&p,token);
00973 if (*token == ',')
00974 GetMagickToken(p,&p,token);
00975 kernel[x]=atof(token);
00976 }
00977 for ( ; x < (long) (order*order); x++)
00978 kernel[x]=0.0;
00979 convolve_image=ConvolveImageChannel(*image,channel,order,kernel,
00980 exception);
00981 kernel=(double *) RelinquishMagickMemory(kernel);
00982 if (convolve_image == (Image *) NULL)
00983 break;
00984 *image=DestroyImage(*image);
00985 *image=convolve_image;
00986 break;
00987 }
00988 if (LocaleCompare("cycle",option+1) == 0)
00989 {
00990
00991
00992
00993 (void) SyncImageSettings(image_info,*image);
00994 (void) CycleColormapImage(*image,atoi(argv[i+1]));
00995 InheritException(exception,&(*image)->exception);
00996 break;
00997 }
00998 break;
00999 }
01000 case 'd':
01001 {
01002 if (LocaleCompare("decipher",option+1) == 0)
01003 {
01004 char
01005 *passphrase;
01006
01007
01008
01009
01010 (void) SyncImageSettings(image_info,*image);
01011 passphrase=FileToString(argv[i+1],~0,exception);
01012 if (passphrase != (char *) NULL)
01013 {
01014 (void) DecipherImage(*image,passphrase,exception);
01015 passphrase=DestroyString(passphrase);
01016 }
01017 break;
01018 }
01019 if (LocaleCompare("density",option+1) == 0)
01020 {
01021
01022
01023
01024 (void) CloneString(&draw_info->density,argv[i+1]);
01025 break;
01026 }
01027 if (LocaleCompare("depth",option+1) == 0)
01028 {
01029 (void) SyncImageSettings(image_info,*image);
01030 if (*option == '+')
01031 {
01032 (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH);
01033 break;
01034 }
01035 (void) SetImageDepth(*image,(unsigned long) atol(argv[i+1]));
01036 break;
01037 }
01038 if (LocaleCompare("deskew",option+1) == 0)
01039 {
01040 double
01041 threshold;
01042
01043 Image
01044 *deskew_image;
01045
01046
01047
01048
01049 (void) SyncImageSettings(image_info,*image);
01050 if (*option == '+')
01051 threshold=40.0*QuantumRange/100.0;
01052 else
01053 threshold=StringToDouble(argv[i+1],QuantumRange);
01054 deskew_image=DeskewImage(*image,threshold,exception);
01055 if (deskew_image == (Image *) NULL)
01056 break;
01057 *image=DestroyImage(*image);
01058 *image=deskew_image;
01059 break;
01060 }
01061 if (LocaleCompare("despeckle",option+1) == 0)
01062 {
01063 Image
01064 *despeckle_image;
01065
01066
01067
01068
01069 (void) SyncImageSettings(image_info,*image);
01070 despeckle_image=DespeckleImage(*image,exception);
01071 if (despeckle_image == (Image *) NULL)
01072 break;
01073 *image=DestroyImage(*image);
01074 *image=despeckle_image;
01075 break;
01076 }
01077 if (LocaleCompare("display",option+1) == 0)
01078 {
01079 (void) CloneString(&draw_info->server_name,argv[i+1]);
01080 break;
01081 }
01082 if (LocaleCompare("distort",option+1) == 0)
01083 {
01084 char
01085 *args,
01086 token[MaxTextExtent];
01087
01088 const char
01089 *p;
01090
01091 DistortImageMethod
01092 method;
01093
01094 double
01095 *arguments;
01096
01097 Image
01098 *distort_image;
01099
01100 register long
01101 x;
01102
01103 unsigned long
01104 number_arguments;
01105
01106
01107
01108
01109 (void) SyncImageSettings(image_info,*image);
01110 method=(DistortImageMethod) ParseMagickOption(MagickDistortOptions,
01111 MagickFalse,argv[i+1]);
01112 args=InterpretImageProperties(image_info,*image,argv[i+2]);
01113 InheritException(exception,&(*image)->exception);
01114 if (args == (char *) NULL)
01115 break;
01116 p=(char *) args;
01117 for (x=0; *p != '\0'; x++)
01118 {
01119 GetMagickToken(p,&p,token);
01120 if (*token == ',')
01121 GetMagickToken(p,&p,token);
01122 }
01123 number_arguments=(unsigned long) x;
01124 arguments=(double *) AcquireQuantumMemory(number_arguments,
01125 sizeof(*arguments));
01126 if (arguments == (double *) NULL)
01127 ThrowWandFatalException(ResourceLimitFatalError,
01128 "MemoryAllocationFailed",(*image)->filename);
01129 (void) ResetMagickMemory(arguments,0,number_arguments*
01130 sizeof(*arguments));
01131 p=(char *) args;
01132 for (x=0; (x < (long) number_arguments) && (*p != '\0'); x++)
01133 {
01134 GetMagickToken(p,&p,token);
01135 if (*token == ',')
01136 GetMagickToken(p,&p,token);
01137 arguments[x]=atof(token);
01138 }
01139 args=DestroyString(args);
01140 distort_image=DistortImage(*image,method,number_arguments,arguments,
01141 (*option == '+') ? MagickTrue : MagickFalse,exception);
01142 arguments=(double *) RelinquishMagickMemory(arguments);
01143 if (distort_image == (Image *) NULL)
01144 break;
01145 *image=DestroyImage(*image);
01146 *image=distort_image;
01147 break;
01148 }
01149 if (LocaleCompare("dither",option+1) == 0)
01150 {
01151 if (*option == '+')
01152 {
01153 quantize_info->dither=MagickFalse;
01154 break;
01155 }
01156 quantize_info->dither=MagickTrue;
01157 quantize_info->dither_method=(DitherMethod) ParseMagickOption(
01158 MagickDitherOptions,MagickFalse,argv[i+1]);
01159 break;
01160 }
01161 if (LocaleCompare("draw",option+1) == 0)
01162 {
01163
01164
01165
01166 (void) SyncImageSettings(image_info,*image);
01167 (void) CloneString(&draw_info->primitive,argv[i+1]);
01168 (void) DrawImage(*image,draw_info);
01169 InheritException(exception,&(*image)->exception);
01170 break;
01171 }
01172 break;
01173 }
01174 case 'e':
01175 {
01176 if (LocaleCompare("edge",option+1) == 0)
01177 {
01178 Image
01179 *edge_image;
01180
01181
01182
01183
01184 (void) SyncImageSettings(image_info,*image);
01185 flags=ParseGeometry(argv[i+1],&geometry_info);
01186 if ((flags & SigmaValue) == 0)
01187 geometry_info.sigma=1.0;
01188 edge_image=EdgeImage(*image,geometry_info.rho,exception);
01189 if (edge_image == (Image *) NULL)
01190 break;
01191 *image=DestroyImage(*image);
01192 *image=edge_image;
01193 break;
01194 }
01195 if (LocaleCompare("emboss",option+1) == 0)
01196 {
01197 Image
01198 *emboss_image;
01199
01200
01201
01202
01203 (void) SyncImageSettings(image_info,*image);
01204 flags=ParseGeometry(argv[i+1],&geometry_info);
01205 if ((flags & SigmaValue) == 0)
01206 geometry_info.sigma=1.0;
01207 emboss_image=EmbossImage(*image,geometry_info.rho,
01208 geometry_info.sigma,exception);
01209 if (emboss_image == (Image *) NULL)
01210 break;
01211 *image=DestroyImage(*image);
01212 *image=emboss_image;
01213 break;
01214 }
01215 if (LocaleCompare("encipher",option+1) == 0)
01216 {
01217 char
01218 *passphrase;
01219
01220
01221
01222
01223 (void) SyncImageSettings(image_info,*image);
01224 passphrase=FileToString(argv[i+1],~0,exception);
01225 if (passphrase != (char *) NULL)
01226 {
01227 (void) EncipherImage(*image,passphrase,exception);
01228 passphrase=DestroyString(passphrase);
01229 }
01230 break;
01231 }
01232 if (LocaleCompare("encoding",option+1) == 0)
01233 {
01234 (void) CloneString(&draw_info->encoding,argv[i+1]);
01235 break;
01236 }
01237 if (LocaleCompare("enhance",option+1) == 0)
01238 {
01239 Image
01240 *enhance_image;
01241
01242
01243
01244
01245 (void) SyncImageSettings(image_info,*image);
01246 enhance_image=EnhanceImage(*image,exception);
01247 if (enhance_image == (Image *) NULL)
01248 break;
01249 *image=DestroyImage(*image);
01250 *image=enhance_image;
01251 break;
01252 }
01253 if (LocaleCompare("equalize",option+1) == 0)
01254 {
01255
01256
01257
01258 (void) SyncImageSettings(image_info,*image);
01259 (void) EqualizeImageChannel(*image,channel);
01260 InheritException(exception,&(*image)->exception);
01261 break;
01262 }
01263 if (LocaleCompare("evaluate",option+1) == 0)
01264 {
01265 double
01266 constant;
01267
01268 MagickEvaluateOperator
01269 op;
01270
01271 (void) SyncImageSettings(image_info,*image);
01272 op=(MagickEvaluateOperator) ParseMagickOption(MagickEvaluateOptions,
01273 MagickFalse,argv[i+1]);
01274 constant=StringToDouble(argv[i+2],QuantumRange);
01275 (void) EvaluateImageChannel(*image,channel,op,constant,exception);
01276 break;
01277 }
01278 if (LocaleCompare("extent",option+1) == 0)
01279 {
01280 Image
01281 *extent_image;
01282
01283
01284
01285
01286 (void) SyncImageSettings(image_info,*image);
01287 SetGeometry(*image,&geometry);
01288 (void) ParseAbsoluteGeometry(argv[i+1],&geometry);
01289 GravityAdjustGeometry((*image)->columns,(*image)->rows,
01290 (*image)->gravity,&geometry);
01291 extent_image=ExtentImage(*image,&geometry,exception);
01292 if (extent_image == (Image *) NULL)
01293 break;
01294 *image=DestroyImage(*image);
01295 *image=extent_image;
01296 break;
01297 }
01298 break;
01299 }
01300 case 'f':
01301 {
01302 if (LocaleCompare("family",option+1) == 0)
01303 {
01304 if (*option == '+')
01305 {
01306 if (draw_info->family != (char *) NULL)
01307 draw_info->family=DestroyString(draw_info->family);
01308 break;
01309 }
01310 (void) CloneString(&draw_info->family,argv[i+1]);
01311 break;
01312 }
01313 if (LocaleCompare("fill",option+1) == 0)
01314 {
01315 ExceptionInfo
01316 *sans;
01317
01318 GetMagickPixelPacket(*image,&fill);
01319 if (*option == '+')
01320 {
01321 (void) QueryMagickColor("none",&fill,exception);
01322 (void) QueryColorDatabase("none",&draw_info->fill,exception);
01323 if (draw_info->fill_pattern != (Image *) NULL)
01324 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
01325 break;
01326 }
01327 sans=AcquireExceptionInfo();
01328 (void) QueryMagickColor(argv[i+1],&fill,sans);
01329 status=QueryColorDatabase(argv[i+1],&draw_info->fill,sans);
01330 sans=DestroyExceptionInfo(sans);
01331 if (status == MagickFalse)
01332 {
01333 ImageInfo
01334 *read_info;
01335
01336 read_info=CloneImageInfo(image_info);
01337 (void) CopyMagickString(read_info->filename,argv[i+1],
01338 MaxTextExtent);
01339 draw_info->fill_pattern=ReadImage(read_info,exception);
01340 read_info=DestroyImageInfo(read_info);
01341 }
01342 break;
01343 }
01344 if (LocaleCompare("flip",option+1) == 0)
01345 {
01346 Image
01347 *flip_image;
01348
01349
01350
01351
01352 (void) SyncImageSettings(image_info,*image);
01353 flip_image=FlipImage(*image,exception);
01354 if (flip_image == (Image *) NULL)
01355 break;
01356 *image=DestroyImage(*image);
01357 *image=flip_image;
01358 break;
01359 }
01360 if (LocaleCompare("flop",option+1) == 0)
01361 {
01362 Image
01363 *flop_image;
01364
01365
01366
01367
01368 (void) SyncImageSettings(image_info,*image);
01369 flop_image=FlopImage(*image,exception);
01370 if (flop_image == (Image *) NULL)
01371 break;
01372 *image=DestroyImage(*image);
01373 *image=flop_image;
01374 break;
01375 }
01376 if (LocaleCompare("floodfill",option+1) == 0)
01377 {
01378 MagickPixelPacket
01379 target;
01380
01381
01382
01383
01384 (void) SyncImageSettings(image_info,*image);
01385 (void) ParsePageGeometry(*image,argv[i+1],&geometry);
01386 (void) QueryMagickColor(argv[i+2],&target,exception);
01387 (void) FloodfillPaintImage(*image,channel,draw_info,&target,
01388 geometry.x,geometry.y,*option == '-' ? MagickFalse : MagickTrue);
01389 InheritException(exception,&(*image)->exception);
01390 break;
01391 }
01392 if (LocaleCompare("font",option+1) == 0)
01393 {
01394 if (*option == '+')
01395 {
01396 if (draw_info->font != (char *) NULL)
01397 draw_info->font=DestroyString(draw_info->font);
01398 break;
01399 }
01400 (void) CloneString(&draw_info->font,argv[i+1]);
01401 break;
01402 }
01403 if (LocaleCompare("format",option+1) == 0)
01404 {
01405 format=argv[i+1];
01406 break;
01407 }
01408 if (LocaleCompare("frame",option+1) == 0)
01409 {
01410 FrameInfo
01411 frame_info;
01412
01413 Image
01414 *frame_image;
01415
01416
01417
01418
01419 (void) SyncImageSettings(image_info,*image);
01420 flags=ParsePageGeometry(*image,argv[i+1],&geometry);
01421 frame_info.width=geometry.width;
01422 frame_info.height=geometry.height;
01423 if ((flags & HeightValue) == 0)
01424 frame_info.height=geometry.width;
01425 frame_info.outer_bevel=geometry.x;
01426 frame_info.inner_bevel=geometry.y;
01427 frame_info.x=(long) frame_info.width;
01428 frame_info.y=(long) frame_info.height;
01429 frame_info.width=(*image)->columns+2*frame_info.width;
01430 frame_info.height=(*image)->rows+2*frame_info.height;
01431 frame_image=FrameImage(*image,&frame_info,exception);
01432 if (frame_image == (Image *) NULL)
01433 break;
01434 *image=DestroyImage(*image);
01435 *image=frame_image;
01436 break;
01437 }
01438 break;
01439 }
01440 case 'g':
01441 {
01442 if (LocaleCompare("gamma",option+1) == 0)
01443 {
01444
01445
01446
01447 (void) SyncImageSettings(image_info,*image);
01448 if (*option == '+')
01449 (*image)->gamma=atof(argv[i+1]);
01450 else
01451 {
01452 if (strchr(argv[i+1],',') != (char *) NULL)
01453 (void) GammaImage(*image,argv[i+1]);
01454 else
01455 (void) GammaImageChannel(*image,channel,atof(argv[i+1]));
01456 InheritException(exception,&(*image)->exception);
01457 }
01458 break;
01459 }
01460 if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
01461 (LocaleCompare("gaussian",option+1) == 0))
01462 {
01463 Image
01464 *gaussian_image;
01465
01466
01467
01468
01469 (void) SyncImageSettings(image_info,*image);
01470 flags=ParseGeometry(argv[i+1],&geometry_info);
01471 if ((flags & SigmaValue) == 0)
01472 geometry_info.sigma=1.0;
01473 gaussian_image=GaussianBlurImageChannel(*image,channel,
01474 geometry_info.rho,geometry_info.sigma,exception);
01475 if (gaussian_image == (Image *) NULL)
01476 break;
01477 *image=DestroyImage(*image);
01478 *image=gaussian_image;
01479 break;
01480 }
01481 if (LocaleCompare("geometry",option+1) == 0)
01482 {
01483 (void) SyncImageSettings(image_info,*image);
01484 if (*option == '+')
01485 {
01486 if ((*image)->geometry != (char *) NULL)
01487 (*image)->geometry=DestroyString((*image)->geometry);
01488 break;
01489 }
01490 (void) CloneString(&(*image)->geometry,argv[i+1]);
01491 flags=ParseSizeGeometry(*image,argv[i+1],&geometry);
01492 if (((flags & XValue) == 0) && ((flags & YValue) == 0))
01493 {
01494 Image
01495 *zoom_image;
01496
01497
01498
01499
01500 zoom_image=ZoomImage(*image,geometry.width,geometry.height,
01501 exception);
01502 if (zoom_image == (Image *) NULL)
01503 break;
01504 *image=DestroyImage(*image);
01505 *image=zoom_image;
01506 }
01507 break;
01508 }
01509 if (LocaleCompare("gravity",option+1) == 0)
01510 {
01511 if (*option == '+')
01512 {
01513 draw_info->gravity=UndefinedGravity;
01514 break;
01515 }
01516 draw_info->gravity=(GravityType) ParseMagickOption(
01517 MagickGravityOptions,MagickFalse,argv[i+1]);
01518 break;
01519 }
01520 break;
01521 }
01522 case 'h':
01523 {
01524 if (LocaleCompare("highlight-color",option+1) == 0)
01525 {
01526 (void) SetImageArtifact(*image,option+1,argv[i+1]);
01527 break;
01528 }
01529 break;
01530 }
01531