• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                 IIIII  M   M  PPPP    OOO   RRRR   TTTTT                    %
7 %                   I    MM MM  P   P  O   O  R   R    T                      %
8 %                   I    M M M  PPPP   O   O  RRRR     T                      %
9 %                   I    M   M  P      O   O  R R      T                      %
10 %                 IIIII  M   M  P       OOO   R  R     T                      %
11 %                                                                             %
12 %                                                                             %
13 %                       Import Image from X11 Screen                          %
14 %                                                                             %
15 %                           Software Design                                   %
16 %                                Cristy                                       %
17 %                              July 1992                                      %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    https://imagemagick.org/script/license.php                               %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %  Use the import program to capture some or all of an X server screen and
37 %  save the image to a file.
38 %
39 */
40 
41 /*
42   Include declarations.
43 */
44 #include "MagickWand/studio.h"
45 #include "MagickWand/MagickWand.h"
46 #include "MagickWand/mogrify-private.h"
47 #include "MagickCore/string-private.h"
48 #include "MagickCore/image-private.h"
49 #include "MagickCore/xwindow-private.h"
50 
51 /*
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 %                                                                             %
54 %                                                                             %
55 %                                                                             %
56 +   I m p o r t I m a g e C o m m a n d                                       %
57 %                                                                             %
58 %                                                                             %
59 %                                                                             %
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61 %
62 %  ImportImageCommand() reads an image from any visible window on an X server
63 %  and outputs it as an image file. You can capture a single window, the
64 %  entire screen, or any rectangular portion of the screen.  You can use the
65 %  display utility for redisplay, printing, editing, formatting, archiving,
66 %  image processing, etc. of the captured image.
67 %
68 %  The target window can be specified by id, name, or may be selected by
69 %  clicking the mouse in the desired window. If you press a button and then
70 %  drag, a rectangle will form which expands and contracts as the mouse moves.
71 %  To save the portion of the screen defined by the rectangle, just release
72 %  the button. The keyboard bell is rung once at the beginning of the screen
73 %  capture and twice when it completes.
74 %
75 %  The format of the ImportImageCommand method is:
76 %
77 %      MagickBooleanType ImportImageCommand(ImageInfo *image_info,int argc,
78 %        char **argv,char **metadata,ExceptionInfo *exception)
79 %
80 %  A description of each parameter follows:
81 %
82 %    o image_info: the image info.
83 %
84 %    o argc: the number of elements in the argument vector.
85 %
86 %    o argv: A text array containing the command line arguments.
87 %
88 %    o metadata: any metadata is returned here.
89 %
90 %    o exception: return any errors or warnings in this structure.
91 %
92 */
93 
ImportUsage(void)94 static MagickBooleanType ImportUsage(void)
95 {
96   const char
97     **p;
98 
99   static const char
100     *miscellaneous[]=
101     {
102       "-debug events        display copious debugging information",
103       "-help                print program options",
104       "-list type           print a list of supported option arguments",
105       "-log format          format of debugging information",
106       "-version             print version information",
107       (char *) NULL
108     },
109     *operators[]=
110     {
111       "-annotate geometry text",
112       "                     annotate the image with text",
113       "-colors value        preferred number of colors in the image",
114       "-crop geometry       preferred size and location of the cropped image",
115       "-encipher filename   convert plain pixels to cipher pixels",
116       "-geometry geometry   preferred size or location of the image",
117       "-help                print program options",
118       "-monochrome          transform image to black and white",
119       "-negate              replace every pixel with its complementary color ",
120       "-quantize colorspace reduce colors in this colorspace",
121       "-resize geometry     resize the image",
122       "-rotate degrees      apply Paeth rotation to the image",
123       "-strip               strip image of all profiles and comments",
124       "-thumbnail geometry  create a thumbnail of the image",
125       "-transparent color   make this color transparent within the image",
126       "-trim                trim image edges",
127       "-type type           image type",
128       (char *) NULL
129     },
130     *settings[]=
131     {
132       "-adjoin              join images into a single multi-image file",
133       "-border              include window border in the output image",
134       "-channel type        apply option to select image channels",
135       "-colorspace type     alternate image colorspace",
136       "-comment string      annotate image with comment",
137       "-compress type       type of pixel compression when writing the image",
138       "-define format:option",
139       "                     define one or more image format options",
140       "-density geometry    horizontal and vertical density of the image",
141       "-depth value         image depth",
142       "-descend             obtain image by descending window hierarchy",
143       "-display server      X server to contact",
144       "-dispose method      layer disposal method",
145       "-dither method       apply error diffusion to image",
146       "-delay value         display the next image after pausing",
147       "-encipher filename   convert plain pixels to cipher pixels",
148       "-endian type         endianness (MSB or LSB) of the image",
149       "-encoding type       text encoding type",
150       "-filter type         use this filter when resizing an image",
151       "-format \"string\"     output formatted image characteristics",
152       "-frame               include window manager frame",
153       "-gravity direction   which direction to gravitate towards",
154       "-identify            identify the format and characteristics of the image",
155       "-interlace type      None, Line, Plane, or Partition",
156       "-interpolate method  pixel color interpolation method",
157       "-label string        assign a label to an image",
158       "-limit type value    Area, Disk, Map, or Memory resource limit",
159       "-monitor             monitor progress",
160       "-page geometry       size and location of an image canvas",
161       "-pause seconds       seconds delay between snapshots",
162       "-pointsize value     font point size",
163       "-quality value       JPEG/MIFF/PNG compression level",
164       "-quiet               suppress all warning messages",
165       "-regard-warnings     pay attention to warning messages",
166       "-repage geometry     size and location of an image canvas",
167       "-respect-parentheses settings remain in effect until parenthesis boundary",
168       "-sampling-factor geometry",
169       "                     horizontal and vertical sampling factor",
170       "-scene value         image scene number",
171       "-screen              select image from root window",
172       "-seed value          seed a new sequence of pseudo-random numbers",
173       "-set property value  set an image property",
174       "-silent              operate silently, i.e. don't ring any bells ",
175       "-snaps value         number of screen snapshots",
176       "-support factor      resize support: > 1.0 is blurry, < 1.0 is sharp",
177       "-synchronize         synchronize image to storage device",
178       "-taint               declare the image as modified",
179       "-transparent-color color",
180       "                     transparent color",
181       "-treedepth value     color tree depth",
182       "-verbose             print detailed information about the image",
183       "-virtual-pixel method",
184       "                     Constant, Edge, Mirror, or Tile",
185       "-window id           select window with this id or name",
186       "                     root selects whole screen",
187       (char *) NULL
188     };
189 
190   ListMagickVersion(stdout);
191   (void) printf("Usage: %s [options ...] [ file ]\n",
192     GetClientName());
193   (void) printf("\nImage Settings:\n");
194   for (p=settings; *p != (char *) NULL; p++)
195     (void) printf("  %s\n",*p);
196   (void) printf("\nImage Operators:\n");
197   for (p=operators; *p != (char *) NULL; p++)
198     (void) printf("  %s\n",*p);
199   (void) printf("\nMiscellaneous Options:\n");
200   for (p=miscellaneous; *p != (char *) NULL; p++)
201     (void) printf("  %s\n",*p);
202   (void) printf(
203   "\nBy default, 'file' is written in the MIFF image format.  To\n");
204   (void) printf(
205     "specify a particular image format, precede the filename with an image\n");
206   (void) printf(
207     "format name and a colon (i.e. ps:image) or specify the image type as\n");
208   (void) printf(
209     "the filename suffix (i.e. image.ps).  Specify 'file' as '-' for\n");
210   (void) printf("standard input or output.\n");
211   return(MagickFalse);
212 }
213 
ImportImageCommand(ImageInfo * image_info,int argc,char ** argv,char ** wand_unused (metadata),ExceptionInfo * exception)214 WandExport MagickBooleanType ImportImageCommand(ImageInfo *image_info,
215   int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
216 {
217 #if defined(MAGICKCORE_X11_DELEGATE)
218 #define DestroyImport() \
219 { \
220   XDestroyResourceInfo(&resource_info); \
221   if (display != (Display *) NULL) \
222     { \
223       XCloseDisplay(display); \
224       display=(Display *) NULL; \
225     } \
226   DestroyImageStack(); \
227   if (target_window != (char *) NULL) \
228     target_window=DestroyString(target_window); \
229   for (i=0; i < (ssize_t) argc; i++) \
230     argv[i]=DestroyString(argv[i]); \
231   argv=(char **) RelinquishMagickMemory(argv); \
232 }
233 #define ThrowImportException(asperity,tag,option) \
234 { \
235   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
236      option); \
237   DestroyImport(); \
238   return(MagickFalse); \
239 }
240 #define ThrowImportInvalidArgumentException(option,argument) \
241 { \
242   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
243     "InvalidArgument","'%s': %s",option,argument); \
244   DestroyImport(); \
245   return(MagickFalse); \
246 }
247 
248   char
249     *filename,
250     *option,
251     *resource_value,
252     *server_name,
253     *target_window;
254 
255   Display
256     *display;
257 
258   Image
259     *image;
260 
261   ImageStack
262     image_stack[MaxImageStackDepth+1];
263 
264   MagickBooleanType
265     fire,
266     pend,
267     respect_parenthesis;
268 
269   MagickStatusType
270     status;
271 
272   QuantizeInfo
273     *quantize_info;
274 
275   register ssize_t
276     i;
277 
278   ssize_t
279     j,
280     k,
281     snapshots;
282 
283   XImportInfo
284     ximage_info;
285 
286   XResourceInfo
287     resource_info;
288 
289   XrmDatabase
290     resource_database;
291 
292   /*
293     Set defaults.
294   */
295   assert(image_info != (ImageInfo *) NULL);
296   assert(image_info->signature == MagickCoreSignature);
297   if (image_info->debug != MagickFalse)
298     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
299   assert(exception != (ExceptionInfo *) NULL);
300   if (argc == 2)
301     {
302       option=argv[1];
303       if ((LocaleCompare("version",option+1) == 0) ||
304           (LocaleCompare("-version",option+1) == 0))
305         {
306           ListMagickVersion(stdout);
307           return(MagickTrue);
308         }
309     }
310   display=(Display *) NULL;
311   j=1;
312   k=0;
313   NewImageStack();
314   option=(char *) NULL;
315   pend=MagickFalse;
316   resource_database=(XrmDatabase) NULL;
317   respect_parenthesis=MagickFalse;
318   (void) memset(&resource_info,0,sizeof(resource_info));
319   server_name=(char *) NULL;
320   status=MagickTrue;
321   SetNotifyHandlers;
322   target_window=(char *) NULL;
323   /*
324     Check for server name specified on the command line.
325   */
326   ReadCommandlLine(argc,&argv);
327   status=ExpandFilenames(&argc,&argv);
328   if (status == MagickFalse)
329     ThrowImportException(ResourceLimitError,"MemoryAllocationFailed",
330       GetExceptionMessage(errno));
331   for (i=1; i < (ssize_t) argc; i++)
332   {
333     /*
334       Check command line for server name.
335     */
336     option=argv[i];
337     if (IsCommandOption(option) == MagickFalse)
338       continue;
339     if (LocaleCompare("display",option+1) == 0)
340       {
341         /*
342           User specified server name.
343         */
344         i++;
345         if (i == (ssize_t) argc)
346           ThrowImportException(OptionError,"MissingArgument",option);
347         server_name=argv[i];
348       }
349     if ((LocaleCompare("help",option+1) == 0) ||
350         (LocaleCompare("-help",option+1) == 0))
351       return(ImportUsage());
352   }
353   /*
354     Get user defaults from X resource database.
355   */
356   display=XOpenDisplay(server_name);
357   if (display == (Display *) NULL)
358     ThrowImportException(XServerError,"UnableToOpenXServer",
359       XDisplayName(server_name));
360   (void) XSetErrorHandler(XError);
361   resource_database=XGetResourceDatabase(display,GetClientName());
362   XGetImportInfo(&ximage_info);
363   XGetResourceInfo(image_info,resource_database,GetClientName(),
364     &resource_info);
365   quantize_info=resource_info.quantize_info;
366   resource_value=XGetResourceInstance(resource_database,GetClientName(),
367     "border","False");
368   ximage_info.borders=IsStringTrue(resource_value);
369   resource_value=XGetResourceInstance(resource_database,GetClientName(),
370     "delay","0");
371   resource_info.delay=(unsigned int) StringToUnsignedLong(resource_value);
372   image_info->density=XGetResourceInstance(resource_database,GetClientName(),
373     "density",(char *) NULL);
374   resource_value=XGetResourceInstance(resource_database,GetClientName(),
375     "descend","False");
376   ximage_info.descend=IsStringTrue(resource_value);
377   resource_value=XGetResourceInstance(resource_database,GetClientName(),
378     "frame","False");
379   ximage_info.frame=IsStringTrue(resource_value);
380   resource_value=XGetResourceInstance(resource_database,GetClientName(),
381     "interlace","none");
382   image_info->interlace=UndefinedInterlace;
383   if (LocaleCompare("None",resource_value) == 0)
384     image_info->interlace=NoInterlace;
385   if (LocaleCompare("Line",resource_value) == 0)
386     image_info->interlace=LineInterlace;
387   if (LocaleCompare("Plane",resource_value) == 0)
388     image_info->interlace=PlaneInterlace;
389   if (LocaleCompare("Partition",resource_value) == 0)
390     image_info->interlace=PartitionInterlace;
391   if (image_info->interlace == UndefinedInterlace)
392     ThrowImportException(OptionError,"Unrecognized interlace type",
393       resource_value);
394   image_info->page=XGetResourceInstance(resource_database,GetClientName(),
395     "pageGeometry",(char *) NULL);
396   resource_value=XGetResourceInstance(resource_database,GetClientName(),
397     "pause","0");
398   resource_info.pause=(unsigned int) StringToUnsignedLong(resource_value);
399   resource_value=XGetResourceInstance(resource_database,GetClientName(),
400     "quality","85");
401   image_info->quality=StringToUnsignedLong(resource_value);
402   resource_value=XGetResourceInstance(resource_database,GetClientName(),
403     "screen","False");
404   ximage_info.screen=IsStringTrue(resource_value);
405   resource_value=XGetResourceInstance(resource_database,GetClientName(),
406     "silent","False");
407   ximage_info.silent=IsStringTrue(resource_value);
408   resource_value=XGetResourceInstance(resource_database,GetClientName(),
409     "verbose","False");
410   image_info->verbose=IsStringTrue(resource_value);
411   resource_value=XGetResourceInstance(resource_database,GetClientName(),
412     "dither","True");
413   quantize_info->dither_method=IsStringTrue(resource_value) != MagickFalse ?
414     RiemersmaDitherMethod : NoDitherMethod;
415   snapshots=1;
416   status=MagickTrue;
417   filename=(char *) NULL;
418   /*
419     Check command syntax.
420   */
421   for (i=1; i < (ssize_t) argc; i++)
422   {
423     option=argv[i];
424     if (LocaleCompare(option,"(") == 0)
425       {
426         FireImageStack(MagickFalse,MagickTrue,pend);
427         if (k == MaxImageStackDepth)
428           ThrowImportException(OptionError,"ParenthesisNestedTooDeeply",
429             option);
430         PushImageStack();
431         continue;
432       }
433     if (LocaleCompare(option,")") == 0)
434       {
435         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
436         if (k == 0)
437           ThrowImportException(OptionError,"UnableToParseExpression",option);
438         PopImageStack();
439         continue;
440       }
441     if (IsCommandOption(option) == MagickFalse)
442       {
443         Image
444           *images;
445 
446         size_t
447           scene;
448 
449         /*
450           Read image from X server.
451         */
452         FireImageStack(MagickFalse,MagickFalse,pend);
453         filename=argv[i];
454         if (target_window != (char *) NULL)
455           (void) CopyMagickString(image_info->filename,target_window,
456             MagickPathExtent);
457         for (scene=0; scene < (size_t) MagickMax(snapshots,1); scene++)
458         {
459           MagickDelay(1000*resource_info.pause);
460           images=XImportImage(image_info,&ximage_info,exception);
461           status&=(images != (Image *) NULL) &&
462             (exception->severity < ErrorException);
463           if (images == (Image *) NULL)
464             continue;
465           (void) CopyMagickString(images->filename,filename,MagickPathExtent);
466           (void) CopyMagickString(images->magick,"PS",MagickPathExtent);
467           images->scene=scene;
468           AppendImageStack(images);
469         }
470         continue;
471       }
472     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
473     switch(*(option+1))
474     {
475       case 'a':
476       {
477         if (LocaleCompare("adjoin",option+1) == 0)
478           break;
479         if (LocaleCompare("annotate",option+1) == 0)
480           {
481             if (*option == '+')
482               break;
483             i++;
484             if (i == (ssize_t) argc)
485               ThrowImportException(OptionError,"MissingArgument",option);
486             if (IsGeometry(argv[i]) == MagickFalse)
487               ThrowImportInvalidArgumentException(option,argv[i]);
488             if (i == (ssize_t) argc)
489               ThrowImportException(OptionError,"MissingArgument",option);
490             i++;
491             break;
492           }
493         ThrowImportException(OptionError,"UnrecognizedOption",option);
494       }
495       case 'b':
496       {
497         if (LocaleCompare("border",option+1) == 0)
498           {
499             (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
500             ximage_info.borders=(*option == '-') ? MagickTrue : MagickFalse;
501             break;
502           }
503         if (LocaleCompare("bordercolor",option+1) == 0)
504           {
505             if (*option == '+')
506               break;
507             i++;
508             if (i == (ssize_t) argc)
509               ThrowImportException(OptionError,"MissingArgument",option);
510             break;
511           }
512         ThrowImportException(OptionError,"UnrecognizedOption",option);
513       }
514       case 'c':
515       {
516         if (LocaleCompare("cache",option+1) == 0)
517           {
518             if (*option == '+')
519               break;
520             i++;
521             if (i == (ssize_t) argc)
522               ThrowImportException(OptionError,"MissingArgument",option);
523             if (IsGeometry(argv[i]) == MagickFalse)
524               ThrowImportInvalidArgumentException(option,argv[i]);
525             break;
526           }
527         if (LocaleCompare("channel",option+1) == 0)
528           {
529             ssize_t
530               channel;
531 
532             if (*option == '+')
533               break;
534             i++;
535             if (i == (ssize_t) argc)
536               ThrowImportException(OptionError,"MissingArgument",option);
537             channel=ParseChannelOption(argv[i]);
538             if (channel < 0)
539               ThrowImportException(OptionError,"UnrecognizedChannelType",
540                 argv[i]);
541             break;
542           }
543         if (LocaleCompare("colors",option+1) == 0)
544           {
545             quantize_info->number_colors=0;
546             if (*option == '+')
547               break;
548             i++;
549             if (i == (ssize_t) argc)
550               ThrowImportException(OptionError,"MissingArgument",option);
551             if (IsGeometry(argv[i]) == MagickFalse)
552               ThrowImportInvalidArgumentException(option,argv[i]);
553             quantize_info->number_colors=StringToUnsignedLong(argv[i]);
554             break;
555           }
556         if (LocaleCompare("colorspace",option+1) == 0)
557           {
558             ssize_t
559               colorspace;
560 
561             if (*option == '+')
562               break;
563             i++;
564             if (i == (ssize_t) argc)
565               ThrowImportException(OptionError,"MissingArgument",option);
566             colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
567               argv[i]);
568             if (colorspace < 0)
569               ThrowImportException(OptionError,"UnrecognizedColorspace",
570                 argv[i]);
571             break;
572           }
573         if (LocaleCompare("comment",option+1) == 0)
574           {
575             if (*option == '+')
576               break;
577             i++;
578             if (i == (ssize_t) argc)
579               ThrowImportException(OptionError,"MissingArgument",option);
580             status=SetImageOption(image_info,"comment",argv[i]);
581             if (status == MagickFalse)
582               ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
583             break;
584           }
585         if (LocaleCompare("compress",option+1) == 0)
586           {
587             ssize_t
588               compress;
589 
590             if (*option == '+')
591               break;
592             i++;
593             if (i == (ssize_t) argc)
594               ThrowImportException(OptionError,"MissingArgument",option);
595             compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
596               argv[i]);
597             if (compress < 0)
598               ThrowImportException(OptionError,"UnrecognizedImageCompression",
599                 argv[i]);
600             break;
601           }
602         if (LocaleCompare("concurrent",option+1) == 0)
603           break;
604         if (LocaleCompare("crop",option+1) == 0)
605           {
606             if (*option == '+')
607               break;
608             i++;
609             if (i == (ssize_t) argc)
610               ThrowImportException(OptionError,"MissingArgument",option);
611             if (IsGeometry(argv[i]) == MagickFalse)
612               ThrowImportInvalidArgumentException(option,argv[i]);
613             break;
614           }
615         ThrowImportException(OptionError,"UnrecognizedOption",option);
616       }
617       case 'd':
618       {
619         if (LocaleCompare("debug",option+1) == 0)
620           {
621             ssize_t
622               event;
623 
624             if (*option == '+')
625               break;
626             i++;
627             if (i == (ssize_t) argc)
628               ThrowImportException(OptionError,"MissingArgument",option);
629             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
630             if (event < 0)
631               ThrowImportException(OptionError,"UnrecognizedEventType",argv[i]);
632             (void) SetLogEventMask(argv[i]);
633             break;
634           }
635         if (LocaleCompare("define",option+1) == 0)
636           {
637             i++;
638             if (i == (ssize_t) argc)
639               ThrowImportException(OptionError,"MissingArgument",option);
640             if (*option == '+')
641               {
642                 const char
643                   *define;
644 
645                 define=GetImageOption(image_info,argv[i]);
646                 if (define == (char *) NULL)
647                   ThrowImportException(OptionError,"NoSuchOption",argv[i]);
648                 break;
649               }
650             break;
651           }
652         if (LocaleCompare("delay",option+1) == 0)
653           {
654             if (*option == '+')
655               break;
656             i++;
657             if (i == (ssize_t) argc)
658               ThrowImportException(OptionError,"MissingArgument",option);
659             if (IsGeometry(argv[i]) == MagickFalse)
660               ThrowImportInvalidArgumentException(option,argv[i]);
661             status=SetImageOption(image_info,"delay",argv[i]);
662             if (status == MagickFalse)
663               ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
664             break;
665           }
666         if (LocaleCompare("density",option+1) == 0)
667           {
668             if (*option == '+')
669               break;
670             i++;
671             if (i == (ssize_t) argc)
672               ThrowImportException(OptionError,"MissingArgument",option);
673             if (IsGeometry(argv[i]) == MagickFalse)
674               ThrowImportInvalidArgumentException(option,argv[i]);
675             break;
676           }
677         if (LocaleCompare("depth",option+1) == 0)
678           {
679             if (*option == '+')
680               break;
681             i++;
682             if (i == (ssize_t) argc)
683               ThrowImportException(OptionError,"MissingArgument",option);
684             if (IsGeometry(argv[i]) == MagickFalse)
685               ThrowImportInvalidArgumentException(option,argv[i]);
686             break;
687           }
688         if (LocaleCompare("descend",option+1) == 0)
689           {
690             ximage_info.descend=(*option == '-') ? MagickTrue : MagickFalse;
691             break;
692           }
693         if (LocaleCompare("display",option+1) == 0)
694           {
695             if (*option == '+')
696               break;
697             i++;
698             if (i == (ssize_t) argc)
699               ThrowImportException(OptionError,"MissingArgument",option);
700             break;
701           }
702         if (LocaleCompare("dispose",option+1) == 0)
703           {
704             ssize_t
705               dispose;
706 
707             if (*option == '+')
708               break;
709             i++;
710             if (i == (ssize_t) argc)
711               ThrowImportException(OptionError,"MissingArgument",option);
712             dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
713             if (dispose < 0)
714               ThrowImportException(OptionError,"UnrecognizedDisposeMethod",
715                 argv[i]);
716             break;
717           }
718         if (LocaleCompare("dither",option+1) == 0)
719           {
720             ssize_t
721               method;
722 
723             quantize_info->dither_method=NoDitherMethod;
724             if (*option == '+')
725               break;
726             i++;
727             if (i == (ssize_t) argc)
728               ThrowImportException(OptionError,"MissingArgument",option);
729             method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
730             if (method < 0)
731               ThrowImportException(OptionError,"UnrecognizedDitherMethod",
732                 argv[i]);
733             quantize_info->dither_method=(DitherMethod) method;
734             break;
735           }
736         if (LocaleCompare("duration",option+1) == 0)
737           {
738             if (*option == '+')
739               break;
740             i++;
741             if (i == (ssize_t) argc)
742               ThrowImportException(OptionError,"MissingArgument",option);
743             if (IsGeometry(argv[i]) == MagickFalse)
744               ThrowImportInvalidArgumentException(option,argv[i]);
745             break;
746           }
747         ThrowImportException(OptionError,"UnrecognizedOption",option);
748       }
749       case 'e':
750       {
751         if (LocaleCompare("encipher",option+1) == 0)
752           {
753             if (*option == '+')
754               break;
755             i++;
756             if (i == (ssize_t) argc)
757               ThrowImportException(OptionError,"MissingArgument",option);
758             break;
759           }
760         if (LocaleCompare("encoding",option+1) == 0)
761           {
762             if (*option == '+')
763               break;
764             i++;
765             if (i == (ssize_t) argc)
766               ThrowImportException(OptionError,"MissingArgument",option);
767             break;
768           }
769         if (LocaleCompare("endian",option+1) == 0)
770           {
771             ssize_t
772               endian;
773 
774             if (*option == '+')
775               break;
776             i++;
777             if (i == (ssize_t) argc)
778               ThrowImportException(OptionError,"MissingArgument",option);
779             endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
780               argv[i]);
781             if (endian < 0)
782               ThrowImportException(OptionError,"UnrecognizedEndianType",
783                 argv[i]);
784             break;
785           }
786         ThrowImportException(OptionError,"UnrecognizedOption",option);
787       }
788       case 'f':
789       {
790         if (LocaleCompare("filter",option+1) == 0)
791           {
792             ssize_t
793               filter;
794 
795             if (*option == '+')
796               break;
797             i++;
798             if (i == (ssize_t) argc)
799               ThrowImportException(OptionError,"MissingArgument",option);
800             filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
801             if (filter < 0)
802               ThrowImportException(OptionError,"UnrecognizedImageFilter",
803                 argv[i]);
804             break;
805           }
806         if (LocaleCompare("frame",option+1) == 0)
807           {
808             (void) CopyMagickString(argv[i]+1,"sans0",MagickPathExtent);
809             ximage_info.frame=(*option == '-') ? MagickTrue : MagickFalse;
810             break;
811           }
812         if (LocaleCompare("format",option+1) == 0)
813           {
814             if (*option == '+')
815               break;
816             i++;
817             if (i == (ssize_t) argc)
818               ThrowImportException(OptionError,"MissingArgument",option);
819             break;
820           }
821         ThrowImportException(OptionError,"UnrecognizedOption",option);
822       }
823       case 'g':
824       {
825         if (LocaleCompare("geometry",option+1) == 0)
826           {
827             if (*option == '+')
828               break;
829             i++;
830             if (i == (ssize_t) argc)
831               ThrowImportException(OptionError,"MissingArgument",option);
832             if (IsGeometry(argv[i]) == MagickFalse)
833               ThrowImportInvalidArgumentException(option,argv[i]);
834             break;
835           }
836         if (LocaleCompare("gravity",option+1) == 0)
837           {
838             ssize_t
839               gravity;
840 
841             if (*option == '+')
842               break;
843             i++;
844             if (i == (ssize_t) argc)
845               ThrowImportException(OptionError,"MissingArgument",option);
846             gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,argv[i]);
847             if (gravity < 0)
848               ThrowImportException(OptionError,"UnrecognizedGravityType",
849                 argv[i]);
850             break;
851           }
852         ThrowImportException(OptionError,"UnrecognizedOption",option);
853       }
854       case 'h':
855       {
856         if (LocaleCompare("help",option+1) == 0)
857           break;
858         ThrowImportException(OptionError,"UnrecognizedOption",option);
859       }
860       case 'i':
861       {
862         if (LocaleCompare("identify",option+1) == 0)
863           break;
864         if (LocaleCompare("interlace",option+1) == 0)
865           {
866             ssize_t
867               interlace;
868 
869             if (*option == '+')
870               break;
871             i++;
872             if (i == (ssize_t) argc)
873               ThrowImportException(OptionError,"MissingArgument",option);
874             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
875               argv[i]);
876             if (interlace < 0)
877               ThrowImportException(OptionError,"UnrecognizedInterlaceType",
878                 argv[i]);
879             break;
880           }
881         if (LocaleCompare("interpolate",option+1) == 0)
882           {
883             ssize_t
884               interpolate;
885 
886             if (*option == '+')
887               break;
888             i++;
889             if (i == (ssize_t) argc)
890               ThrowImportException(OptionError,"MissingArgument",option);
891             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
892               argv[i]);
893             if (interpolate < 0)
894               ThrowImportException(OptionError,"UnrecognizedInterpolateMethod",
895                 argv[i]);
896             break;
897           }
898         ThrowImportException(OptionError,"UnrecognizedOption",option);
899       }
900       case 'l':
901       {
902         if (LocaleCompare("label",option+1) == 0)
903           {
904             if (*option == '+')
905               break;
906             i++;
907             if (i == (ssize_t) argc)
908               ThrowImportException(OptionError,"MissingArgument",option);
909             status=SetImageOption(image_info,"label",argv[i]);
910             if (status == MagickFalse)
911               ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
912             break;
913           }
914         if (LocaleCompare("limit",option+1) == 0)
915           {
916             char
917               *p;
918 
919             double
920               value;
921 
922             ssize_t
923               resource;
924 
925             if (*option == '+')
926               break;
927             i++;
928             if (i == (ssize_t) argc)
929               ThrowImportException(OptionError,"MissingArgument",option);
930             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
931               argv[i]);
932             if (resource < 0)
933               ThrowImportException(OptionError,"UnrecognizedResourceType",
934                 argv[i]);
935             i++;
936             if (i == (ssize_t) argc)
937               ThrowImportException(OptionError,"MissingArgument",option);
938             value=StringToDouble(argv[i],&p);
939             (void) value;
940             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
941               ThrowImportInvalidArgumentException(option,argv[i]);
942             break;
943           }
944         if (LocaleCompare("list",option+1) == 0)
945           {
946             ssize_t
947               list;
948 
949             if (*option == '+')
950               break;
951             i++;
952             if (i == (ssize_t) argc)
953               ThrowImportException(OptionError,"MissingArgument",option);
954             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
955             if (list < 0)
956               ThrowImportException(OptionError,"UnrecognizedListType",argv[i]);
957             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
958               argv+j,exception);
959             DestroyImport();
960             return(status == 0 ? MagickFalse : MagickTrue);
961           }
962         if (LocaleCompare("log",option+1) == 0)
963           {
964             if (*option == '+')
965               break;
966             i++;
967             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
968               ThrowImportException(OptionError,"MissingArgument",option);
969             break;
970           }
971         ThrowImportException(OptionError,"UnrecognizedOption",option);
972       }
973       case 'm':
974       {
975         if (LocaleCompare("monitor",option+1) == 0)
976           break;
977         if (LocaleCompare("monochrome",option+1) == 0)
978           {
979             if (*option == '+')
980               break;
981             quantize_info->number_colors=2;
982             quantize_info->colorspace=GRAYColorspace;
983             break;
984           }
985         ThrowImportException(OptionError,"UnrecognizedOption",option);
986       }
987       case 'n':
988       {
989         if (LocaleCompare("negate",option+1) == 0)
990           break;
991         ThrowImportException(OptionError,"UnrecognizedOption",option);
992       }
993       case 'p':
994       {
995         if (LocaleCompare("page",option+1) == 0)
996           {
997             if (*option == '+')
998               break;
999             i++;
1000             if (i == (ssize_t) argc)
1001               ThrowImportException(OptionError,"MissingArgument",option);
1002             status=SetImageOption(image_info,"page",argv[i]);
1003             if (status == MagickFalse)
1004               ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
1005             break;
1006           }
1007         if (LocaleCompare("pause",option+1) == 0)
1008           {
1009             resource_info.pause=0;
1010             if (*option == '+')
1011               break;
1012             i++;
1013             if (i == (ssize_t) argc)
1014               ThrowImportException(OptionError,"MissingArgument",option);
1015             if (IsGeometry(argv[i]) == MagickFalse)
1016               ThrowImportInvalidArgumentException(option,argv[i]);
1017             resource_info.pause=(unsigned int) StringToUnsignedLong(argv[i]);
1018             break;
1019           }
1020         if (LocaleCompare("ping",option+1) == 0)
1021           break;  /* deprecated option */
1022         if (LocaleCompare("pointsize",option+1) == 0)
1023           {
1024             if (*option == '+')
1025               break;
1026             i++;
1027             if (i == (ssize_t) argc)
1028               ThrowImportException(OptionError,"MissingArgument",option);
1029             if (IsGeometry(argv[i]) == MagickFalse)
1030               ThrowImportInvalidArgumentException(option,argv[i]);
1031             break;
1032           }
1033         ThrowImportException(OptionError,"UnrecognizedOption",option);
1034       }
1035       case 'q':
1036       {
1037         if (LocaleCompare("quality",option+1) == 0)
1038           {
1039             if (*option == '+')
1040               break;
1041             i++;
1042             if (i == (ssize_t) argc)
1043               ThrowImportException(OptionError,"MissingArgument",option);
1044             if (IsGeometry(argv[i]) == MagickFalse)
1045               ThrowImportInvalidArgumentException(option,argv[i]);
1046             break;
1047           }
1048         if (LocaleCompare("quantize",option+1) == 0)
1049           {
1050             ssize_t
1051               colorspace;
1052 
1053             if (*option == '+')
1054               break;
1055             i++;
1056             if (i == (ssize_t) argc)
1057               ThrowImportException(OptionError,"MissingArgument",option);
1058             colorspace=ParseCommandOption(MagickColorspaceOptions,
1059               MagickFalse,argv[i]);
1060             if (colorspace < 0)
1061               ThrowImportException(OptionError,"UnrecognizedColorspace",
1062                 argv[i]);
1063             break;
1064           }
1065         if (LocaleCompare("quiet",option+1) == 0)
1066           break;
1067         ThrowImportException(OptionError,"UnrecognizedOption",option);
1068       }
1069       case 'r':
1070       {
1071         if (LocaleCompare("regard-warnings",option+1) == 0)
1072           break;
1073         if (LocaleCompare("repage",option+1) == 0)
1074           {
1075             if (*option == '+')
1076               break;
1077             i++;
1078             if (i == (ssize_t) argc)
1079               ThrowImportException(OptionError,"MissingArgument",option);
1080             if (IsGeometry(argv[i]) == MagickFalse)
1081               ThrowImportInvalidArgumentException(option,argv[i]);
1082             break;
1083           }
1084         if (LocaleCompare("resize",option+1) == 0)
1085           {
1086             if (*option == '+')
1087               break;
1088             i++;
1089             if (i == (ssize_t) argc)
1090               ThrowImportException(OptionError,"MissingArgument",option);
1091             if (IsGeometry(argv[i]) == MagickFalse)
1092               ThrowImportInvalidArgumentException(option,argv[i]);
1093             break;
1094           }
1095         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1096           {
1097             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1098             break;
1099           }
1100         if (LocaleCompare("rotate",option+1) == 0)
1101           {
1102             i++;
1103             if (i == (ssize_t) argc)
1104               ThrowImportException(OptionError,"MissingArgument",option);
1105             if (IsGeometry(argv[i]) == MagickFalse)
1106               ThrowImportInvalidArgumentException(option,argv[i]);
1107             break;
1108           }
1109         ThrowImportException(OptionError,"UnrecognizedOption",option);
1110       }
1111       case 's':
1112       {
1113         if (LocaleCompare("sampling-factor",option+1) == 0)
1114           {
1115             if (*option == '+')
1116               break;
1117             i++;
1118             if (i == (ssize_t) argc)
1119               ThrowImportException(OptionError,"MissingArgument",option);
1120             if (IsGeometry(argv[i]) == MagickFalse)
1121               ThrowImportInvalidArgumentException(option,argv[i]);
1122             break;
1123           }
1124         if (LocaleCompare("scene",option+1) == 0)
1125           {
1126             if (*option == '+')
1127               break;
1128             i++;
1129             if (i == (ssize_t) argc)
1130               ThrowImportException(OptionError,"MissingArgument",option);
1131             if (IsGeometry(argv[i]) == MagickFalse)
1132               ThrowImportInvalidArgumentException(option,argv[i]);
1133             break;
1134           }
1135         if (LocaleCompare("set",option+1) == 0)
1136           {
1137             i++;
1138             if (i == (ssize_t) argc)
1139               ThrowImportException(OptionError,"MissingArgument",option);
1140             if (*option == '+')
1141               break;
1142             i++;
1143             if (i == (ssize_t) argc)
1144               ThrowImportException(OptionError,"MissingArgument",option);
1145             break;
1146           }
1147         if (LocaleCompare("screen",option+1) == 0)
1148           {
1149             ximage_info.screen=(*option == '-') ? MagickTrue : MagickFalse;
1150             break;
1151           }
1152         if (LocaleCompare("seed",option+1) == 0)
1153           {
1154             if (*option == '+')
1155               break;
1156             i++;
1157             if (i == (ssize_t) argc)
1158               ThrowImportException(OptionError,"MissingArgument",option);
1159             if (IsGeometry(argv[i]) == MagickFalse)
1160               ThrowImportInvalidArgumentException(option,argv[i]);
1161             break;
1162           }
1163         if (LocaleCompare("silent",option+1) == 0)
1164           {
1165             ximage_info.silent=(*option == '-') ? MagickTrue : MagickFalse;
1166             break;
1167           }
1168         if (LocaleCompare("snaps",option+1) == 0)
1169           {
1170             (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1171             i++;
1172             if (i == (ssize_t) argc)
1173               ThrowImportException(OptionError,"MissingArgument",option);
1174             if (IsGeometry(argv[i]) == MagickFalse)
1175               ThrowImportInvalidArgumentException(option,argv[i]);
1176             snapshots=(ssize_t) StringToLong(argv[i]);
1177             break;
1178           }
1179         if (LocaleCompare("strip",option+1) == 0)
1180           break;
1181         if (LocaleCompare("support",option+1) == 0)
1182           {
1183             i++;  /* deprecated */
1184             break;
1185           }
1186         if (LocaleCompare("synchronize",option+1) == 0)
1187           break;
1188         ThrowImportException(OptionError,"UnrecognizedOption",option);
1189       }
1190       case 't':
1191       {
1192         if (LocaleCompare("taint",option+1) == 0)
1193           break;
1194         if (LocaleCompare("thumbnail",option+1) == 0)
1195           {
1196             if (*option == '+')
1197               break;
1198             i++;
1199             if (i == (ssize_t) argc)
1200               ThrowImportException(OptionError,"MissingArgument",option);
1201             if (IsGeometry(argv[i]) == MagickFalse)
1202               ThrowImportInvalidArgumentException(option,argv[i]);
1203             break;
1204           }
1205         if (LocaleCompare("transparent",option+1) == 0)
1206           {
1207             i++;
1208             if (i == (ssize_t) argc)
1209               ThrowImportException(OptionError,"MissingArgument",option);
1210             break;
1211           }
1212         if (LocaleCompare("transparent-color",option+1) == 0)
1213           {
1214             if (*option == '+')
1215               break;
1216             i++;
1217             if (i == (ssize_t) argc)
1218               ThrowImportException(OptionError,"MissingArgument",option);
1219             break;
1220           }
1221         if (LocaleCompare("treedepth",option+1) == 0)
1222           {
1223             quantize_info->tree_depth=0;
1224             if (*option == '+')
1225               break;
1226             i++;
1227             if (i == (ssize_t) argc)
1228               ThrowImportException(OptionError,"MissingArgument",option);
1229             if (IsGeometry(argv[i]) == MagickFalse)
1230               ThrowImportInvalidArgumentException(option,argv[i]);
1231             quantize_info->tree_depth=StringToUnsignedLong(argv[i]);
1232             break;
1233           }
1234         if (LocaleCompare("trim",option+1) == 0)
1235           break;
1236         if (LocaleCompare("type",option+1) == 0)
1237           {
1238             ssize_t
1239               type;
1240 
1241             if (*option == '+')
1242               break;
1243             i++;
1244             if (i == (ssize_t) argc)
1245               ThrowImportException(OptionError,"MissingArgument",option);
1246             type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1247             if (type < 0)
1248               ThrowImportException(OptionError,"UnrecognizedImageType",argv[i]);
1249             break;
1250           }
1251         ThrowImportException(OptionError,"UnrecognizedOption",option);
1252       }
1253       case 'w':
1254       {
1255         i++;
1256         if (i == (ssize_t) argc)
1257           ThrowImportException(OptionError,"MissingArgument",option);
1258         (void) CloneString(&target_window,argv[i]);
1259         break;
1260       }
1261       case 'v':
1262       {
1263         if (LocaleCompare("verbose",option+1) == 0)
1264           break;
1265         if ((LocaleCompare("version",option+1) == 0) ||
1266             (LocaleCompare("-version",option+1) == 0))
1267           {
1268             ListMagickVersion(stdout);
1269             break;
1270           }
1271         ThrowImportException(OptionError,"UnrecognizedOption",option);
1272       }
1273       case '?':
1274         break;
1275       default:
1276         ThrowImportException(OptionError,"UnrecognizedOption",option);
1277     }
1278     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1279       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
1280     if (fire != MagickFalse)
1281       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1282   }
1283   if (k != 0)
1284     ThrowImportException(OptionError,"UnbalancedParenthesis",argv[i]);
1285   if (i-- != (ssize_t) argc)
1286     ThrowImportException(OptionError,"MissingAnImageFilename",argv[i]);
1287   if (image == (Image *) NULL)
1288     ThrowImportException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1289   FinalizeImageSettings(image_info,image,MagickTrue);
1290   status&=WriteImages(image_info,image,filename,exception);
1291   DestroyImport();
1292   return(status != 0 ? MagickTrue : MagickFalse);
1293 #else
1294   wand_unreferenced(argc);
1295   wand_unreferenced(argv);
1296   wand_unreferenced(metadata);
1297   (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
1298     "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image_info->filename);
1299   return(ImportUsage());
1300 #endif
1301 }
1302