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