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