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