mogrify.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %              M   M   OOO   GGGGG  RRRR   IIIII  FFFFF  Y   Y                %
00007 %              MM MM  O   O  G      R   R    I    F       Y Y                 %
00008 %              M M M  O   O  G GGG  RRRR     I    FFF      Y                  %
00009 %              M   M  O   O  G   G  R R      I    F        Y                  %
00010 %              M   M   OOO   GGGG   R  R   IIIII  F        Y                  %
00011 %                                                                             %
00012 %                                                                             %
00013 %                         MagickWand Module Methods                           %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                March 2000                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "wand/studio.h"
00044 #include "wand/MagickWand.h"
00045 #include "wand/mogrify-private.h"
00046 
00047 /*
00048   Define declarations.
00049 */
00050 #define UndefinedCompressionQuality  0UL
00051 
00052 /*
00053   Constant declaration.
00054 */
00055 static const char
00056   *BackgroundColor = "#fff",  /* white */
00057   *BorderColor = "#dfdfdf",  /* gray */
00058   *MatteColor = "#bdbdbd";  /* gray */
00059 
00060 /*
00061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00062 %                                                                             %
00063 %                                                                             %
00064 %                                                                             %
00065 +     M o g r i f y I m a g e                                                 %
00066 %                                                                             %
00067 %                                                                             %
00068 %                                                                             %
00069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00070 %
00071 %  MogrifyImage() applies image processing options to an image as prescribed
00072 %  by command line options.
00073 %
00074 %  The format of the MogrifyImage method is:
00075 %
00076 %      MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
00077 %        const char **argv,Image **image)
00078 %
00079 %  A description of each parameter follows:
00080 %
00081 %    o image_info: the image info..
00082 %
00083 %    o argc: Specifies a pointer to an integer describing the number of
00084 %      elements in the argument vector.
00085 %
00086 %    o argv: Specifies a pointer to a text array containing the command line
00087 %      arguments.
00088 %
00089 %    o image: the image.
00090 %
00091 %    o exception: return any errors or warnings in this structure.
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   /* Limit Channel according to image - and add up number of color channel */
00204   channels=channel;
00205   if ( image->colorspace != CMYKColorspace )
00206     channels = (ChannelType) (channels & ~IndexChannel);  /* remove index channels from count */
00207   if ( image->matte == MagickFalse )
00208     channels = (ChannelType) (channels & ~OpacityChannel);  /* remove matte/alpha channels from count */
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   /* Read string, to determine number of arguments needed */
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;  /* color argument */
00230     }
00231     else {
00232       x++;   /* floating point argument */
00233     }
00234   }
00235   error=MagickTrue;
00236   if ( color_from_image ) {
00237     /* just the control points are being given */
00238     error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
00239     number_arguments=(x/2)*(2+number_colors);
00240   }
00241   else {
00242     /* control points and color values */
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   /* Allocate and fill in the floating point arguments */
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     /* X coordinate */
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     /* Y coordinate */
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     /* color values for this control point */
00289 #if 0
00290     if ( (color_from_image ) {
00291       /* get color from image */
00292       /* HOW??? */
00293     }
00294     else
00295 #endif
00296     {
00297       /* color name or function given in string argument */
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         /* Color string given */
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         /* the color name/function/value was not found - error */
00317         break;
00318 #else
00319         /* Colors given as a set of floating point values - experimental */
00320         /* NB: token contains the first floating point value to use! */
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] = ','; /* used this token - get another */
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] = ','; /* used this token - get another */
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] = ','; /* used this token - get another */
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] = ','; /* used this token - get another */
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] = ','; /* used this token - get another */
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   /* Call the Interpolation function with the parsed arguments */
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     Initialize method variables.
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,&region_geometry);
00437   region_image=NewImageList();
00438   /*
00439     Transmogrify the image.
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               Adaptive blur image.
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               Adaptive resize image.
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               Adaptive sharpen image.
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               Affine matrix.
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               Annotate image.
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               Black threshold image.
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               Gaussian blur image.
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               Surround image with a border of solid color.
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               Charcoal image.
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               Chop the image.
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                   Remove a mask.
00793                 */
00794                 (void) SetImageMask(*image,(Image *) NULL);
00795                 InheritException(exception,&(*image)->exception);
00796                 break;
00797               }
00798             /*
00799               Set the image mask.
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               Colorize the image.
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               Reduce the number of colors in the image.
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               Contrast stretch image.
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               Convolve image.
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               Cycle an image colormap.
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               Decipher pixels.
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               Set image density.
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               Straighten the image.
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               Reduce the speckles within an image.
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               Distort image.
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               Draw image.
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               Enhance edges in the image.
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               Gaussian embossen image.
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               Encipher pixels.
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               Enhance image.
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               Equalize image.
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               Set the image extent.
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               Flip image scanlines.
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               Flop image scanlines.
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               Floodfill image.
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               Surround image with an ornamental border.
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               Gamma image.
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               Gaussian blur image.
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                   Resize image.
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