]> granicus.if.org Git - imagemagick/blob - wand/import.c
(no commit message)
[imagemagick] / wand / 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-2010 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 "wand/studio.h"
45 #include "wand/MagickWand.h"
46 #include "wand/mogrify-private.h"
47 #include "magick/xwindow-private.h"
48 #include "magick/string-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.</dd>
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       "-border              include image borders in the output image",
113       "-colors value        preferred number of colors in the image",
114       "-crop geometry       preferred size and location of the cropped image",
115       "-encipher filename   convert plain pixels to cipher pixels",
116       "-geometry geometry   preferred size or location of the image",
117       "-help                print program options",
118       "-monochrome          transform image to black and white",
119       "-negate              replace every pixel with its complementary color ",
120       "-repage geometry     size and location of an image canvas",
121       "-quantize colorspace reduce colors in this colorspace",
122       "-resize geometry     resize the image",
123       "-rotate degrees      apply Paeth rotation to the image",
124       "-strip               strip image of all profiles and comments",
125       "-thumbnail geometry  create a thumbnail of the image",
126       "-transparent color   make this color transparent within the image",
127       "-trim                trim image edges",
128       "-type type           image type",
129       (char *) NULL
130     },
131     *settings[]=
132     {
133       "-adjoin              join images into a single multi-image file",
134       "-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       "-transparent-color color",
176       "                     transparent color",
177       "-treedepth value     color tree depth",
178       "-verbose             print detailed information about the image",
179       "-virtual-pixel method",
180       "                     Constant, Edge, Mirror, or Tile",
181       "-window id           select window with this id or name",
182       (char *) NULL
183     };
184
185   (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
186   (void) printf("Copyright: %s\n",GetMagickCopyright());
187   (void) printf("Features: %s\n\n",GetMagickFeatures());
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 long MagickMax(const long x,const long 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 < (long) 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   long
269     j,
270     k,
271     snapshots;
272
273   MagickBooleanType
274     fire,
275     pend;
276
277   MagickStatusType
278     status;
279
280   QuantizeInfo
281     *quantize_info;
282
283   register long
284     i;
285
286   XImportInfo
287     ximage_info;
288
289   XResourceInfo
290     resource_info;
291
292   XrmDatabase
293     resource_database;
294
295   /*
296     Set defaults.
297   */
298   assert(image_info != (ImageInfo *) NULL);
299   assert(image_info->signature == MagickSignature);
300   if (image_info->debug != MagickFalse)
301     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
302   assert(exception != (ExceptionInfo *) NULL);
303   if (argc == 2)
304     {
305       option=argv[1];
306       if ((LocaleCompare("version",option+1) == 0) ||
307           (LocaleCompare("-version",option+1) == 0))
308         {
309           (void) fprintf(stdout,"Version: %s\n",
310             GetMagickVersion((unsigned long *) NULL));
311           (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
312           (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
313           return(MagickFalse);
314         }
315     }
316   display=(Display *) NULL;
317   j=1;
318   k=0;
319   NewImageStack();
320   option=(char *) NULL;
321   pend=MagickFalse;
322   resource_database=(XrmDatabase) NULL;
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 < (long) 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 == (long) 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=IsMagickTrue(resource_value);
372   resource_value=XGetResourceInstance(resource_database,GetClientName(),
373     "delay","0");
374   resource_info.delay=(unsigned int) StringToLong(resource_value);
375   image_info->density=XGetResourceInstance(resource_database,GetClientName(),
376     "density",(char *) NULL);
377   resource_value=XGetResourceInstance(resource_database,GetClientName(),
378     "descend","True");
379   ximage_info.descend=IsMagickTrue(resource_value);
380   resource_value=XGetResourceInstance(resource_database,GetClientName(),
381     "frame","False");
382   ximage_info.frame=IsMagickTrue(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) StringToLong(resource_value);
402   resource_value=XGetResourceInstance(resource_database,GetClientName(),
403     "quality","85");
404   image_info->quality=(unsigned long) StringToLong(resource_value);
405   resource_value=XGetResourceInstance(resource_database,GetClientName(),
406     "screen","False");
407   ximage_info.screen=IsMagickTrue(resource_value);
408   resource_value=XGetResourceInstance(resource_database,GetClientName(),
409     "silent","False");
410   ximage_info.silent=IsMagickTrue(resource_value);
411   resource_value=XGetResourceInstance(resource_database,GetClientName(),
412     "verbose","False");
413   image_info->verbose=IsMagickTrue(resource_value);
414   resource_value=XGetResourceInstance(resource_database,GetClientName(),
415     "dither","True");
416   quantize_info->dither=IsMagickTrue(resource_value);
417   snapshots=1;
418   status=MagickTrue;
419   filename=(char *) NULL;
420   /*
421     Check command syntax.
422   */
423   for (i=1; i < (long) 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 (IsMagickOption(option) == MagickFalse)
444       {
445         Image
446           *images;
447
448         unsigned long
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 < (unsigned long) MagickMax(snapshots,1); scene++)
460         {
461           (void) sleep(resource_info.pause);
462           images=XImportImage(image_info,&ximage_info);
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 == (long) (argc-1))
487               ThrowImportException(OptionError,"MissingArgument",option);
488             if (IsGeometry(argv[i]) == MagickFalse)
489               ThrowImportInvalidArgumentException(option,argv[i]);
490             if (i == (long) (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 == (long) 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 == (long) 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             long
532               channel;
533
534             if (*option == '+')
535               break;
536             i++;
537             if (i == (long) (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 == (long) argc)
552               ThrowImportException(OptionError,"MissingArgument",option);
553             if (IsGeometry(argv[i]) == MagickFalse)
554               ThrowImportInvalidArgumentException(option,argv[i]);
555             quantize_info->number_colors=(unsigned long) StringToLong(argv[i]);
556             break;
557           }
558         if (LocaleCompare("colorspace",option+1) == 0)
559           {
560             long
561               colorspace;
562
563             if (*option == '+')
564               break;
565             i++;
566             if (i == (long) argc)
567               ThrowImportException(OptionError,"MissingArgument",option);
568             colorspace=ParseMagickOption(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 == (long) 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             long
590               compress;
591
592             if (*option == '+')
593               break;
594             i++;
595             if (i == (long) argc)
596               ThrowImportException(OptionError,"MissingArgument",option);
597             compress=ParseMagickOption(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 == (long) 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             long
624               event;
625
626             if (*option == '+')
627               break;
628             i++;
629             if (i == (long) argc)
630               ThrowImportException(OptionError,"MissingArgument",option);
631             event=ParseMagickOption(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 == (long) 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 == (long) 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 == (long) 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 == (long) 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 == (long) argc)
701               ThrowImportException(OptionError,"MissingArgument",option);
702             break;
703           }
704         if (LocaleCompare("dispose",option+1) == 0)
705           {
706             long
707               dispose;
708
709             if (*option == '+')
710               break;
711             i++;
712             if (i == (long) argc)
713               ThrowImportException(OptionError,"MissingArgument",option);
714             dispose=ParseMagickOption(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             long
723               method;
724
725             quantize_info->dither=MagickFalse;
726             if (*option == '+')
727               break;
728             i++;
729             if (i == (long) argc)
730               ThrowImportException(OptionError,"MissingArgument",option);
731             method=ParseMagickOption(MagickDitherOptions,MagickFalse,argv[i]);
732             if (method < 0)
733               ThrowImportException(OptionError,"UnrecognizedDitherMethod",
734                 argv[i]);
735             quantize_info->dither=MagickTrue;
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 == (long) (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 == (long) (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 == (long) argc)
769               ThrowImportException(OptionError,"MissingArgument",option);
770             break;
771           }
772         if (LocaleCompare("endian",option+1) == 0)
773           {
774             long
775               endian;
776
777             if (*option == '+')
778               break;
779             i++;
780             if (i == (long) argc)
781               ThrowImportException(OptionError,"MissingArgument",option);
782             endian=ParseMagickOption(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             long
796               filter;
797
798             if (*option == '+')
799               break;
800             i++;
801             if (i == (long) (argc-1))
802               ThrowImportException(OptionError,"MissingArgument",option);
803             filter=ParseMagickOption(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 == (long) (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 == (long) 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             long
842               gravity;
843
844             if (*option == '+')
845               break;
846             i++;
847             if (i == (long) argc)
848               ThrowImportException(OptionError,"MissingArgument",option);
849             gravity=ParseMagickOption(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             long
870               interlace;
871
872             if (*option == '+')
873               break;
874             i++;
875             if (i == (long) argc)
876               ThrowImportException(OptionError,"MissingArgument",option);
877             interlace=ParseMagickOption(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             long
887               interpolate;
888
889             if (*option == '+')
890               break;
891             i++;
892             if (i == (long) argc)
893               ThrowImportException(OptionError,"MissingArgument",option);
894             interpolate=ParseMagickOption(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 == (long) 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             long
926               resource;
927
928             if (*option == '+')
929               break;
930             i++;
931             if (i == (long) argc)
932               ThrowImportException(OptionError,"MissingArgument",option);
933             resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
934               argv[i]);
935             if (resource < 0)
936               ThrowImportException(OptionError,"UnrecognizedResourceType",
937                 argv[i]);
938             i++;
939             if (i == (long) argc)
940               ThrowImportException(OptionError,"MissingArgument",option);
941             value=strtod(argv[i],&p);
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             long
949               list;
950
951             if (*option == '+')
952               break;
953             i++;
954             if (i == (long) argc)
955               ThrowImportException(OptionError,"MissingArgument",option);
956             list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
957             if (list < 0)
958               ThrowImportException(OptionError,"UnrecognizedListType",argv[i]);
959             (void) MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
960               argv+j,exception);
961             DestroyImport();
962             return(MagickTrue);
963           }
964         if (LocaleCompare("log",option+1) == 0)
965           {
966             if (*option == '+')
967               break;
968             i++;
969             if ((i == (long) 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 == (long) 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 == (long) argc)
1016               ThrowImportException(OptionError,"MissingArgument",option);
1017             if (IsGeometry(argv[i]) == MagickFalse)
1018               ThrowImportInvalidArgumentException(option,argv[i]);
1019             resource_info.pause=(unsigned int) StringToLong(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 == (long) 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 == (long) 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             long
1053               colorspace;
1054
1055             if (*option == '+')
1056               break;
1057             i++;
1058             if (i == (long) (argc-1))
1059               ThrowImportException(OptionError,"MissingArgument",option);
1060             colorspace=ParseMagickOption(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 == (long) (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 == (long) 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 == (long) 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 == (long) 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 == (long) 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 == (long) argc)
1141               ThrowImportException(OptionError,"MissingArgument",option);
1142             if (*option == '+')
1143               break;
1144             i++;
1145             if (i == (long) 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 == (long) (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 == (long) argc)
1175               ThrowImportException(OptionError,"MissingArgument",option);
1176             if (IsGeometry(argv[i]) == MagickFalse)
1177               ThrowImportInvalidArgumentException(option,argv[i]);
1178             snapshots=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         ThrowImportException(OptionError,"UnrecognizedOption",option);
1189       }
1190       case 't':
1191       {
1192         if (LocaleCompare("thumnail",option+1) == 0)
1193           {
1194             if (*option == '+')
1195               break;
1196             i++;
1197             if (i == (long) argc)
1198               ThrowImportException(OptionError,"MissingArgument",option);
1199             if (IsGeometry(argv[i]) == MagickFalse)
1200               ThrowImportInvalidArgumentException(option,argv[i]);
1201             break;
1202           }
1203         if (LocaleCompare("transparent",option+1) == 0)
1204           {
1205             i++;
1206             if (i == (long) argc)
1207               ThrowImportException(OptionError,"MissingArgument",option);
1208             break;
1209           }
1210         if (LocaleCompare("transparent-color",option+1) == 0)
1211           {
1212             if (*option == '+')
1213               break;
1214             i++;
1215             if (i == (long) (argc-1))
1216               ThrowImportException(OptionError,"MissingArgument",option);
1217             break;
1218           }
1219         if (LocaleCompare("treedepth",option+1) == 0)
1220           {
1221             quantize_info->tree_depth=0;
1222             if (*option == '+')
1223               break;
1224             i++;
1225             if (i == (long) argc)
1226               ThrowImportException(OptionError,"MissingArgument",option);
1227             if (IsGeometry(argv[i]) == MagickFalse)
1228               ThrowImportInvalidArgumentException(option,argv[i]);
1229             quantize_info->tree_depth=(unsigned long) StringToLong(argv[i]);
1230             break;
1231           }
1232         if (LocaleCompare("trim",option+1) == 0)
1233           break;
1234         if (LocaleCompare("type",option+1) == 0)
1235           {
1236             long
1237               type;
1238
1239             if (*option == '+')
1240               break;
1241             i++;
1242             if (i == (long) argc)
1243               ThrowImportException(OptionError,"MissingArgument",option);
1244             type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]);
1245             if (type < 0)
1246               ThrowImportException(OptionError,"UnrecognizedImageType",argv[i]);
1247             break;
1248           }
1249         ThrowImportException(OptionError,"UnrecognizedOption",option);
1250       }
1251       case 'w':
1252       {
1253         i++;
1254         if (i == (long) argc)
1255           ThrowImportException(OptionError,"MissingArgument",option);
1256         (void) CloneString(&target_window,argv[i]);
1257         break;
1258       }
1259       case 'v':
1260       {
1261         if (LocaleCompare("verbose",option+1) == 0)
1262           break;
1263         if ((LocaleCompare("version",option+1) == 0) ||
1264             (LocaleCompare("-version",option+1) == 0))
1265           {
1266             (void) fprintf(stdout,"Version: %s\n",
1267               GetMagickVersion((unsigned long *) NULL));
1268             (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
1269             (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
1270             break;
1271           }
1272         ThrowImportException(OptionError,"UnrecognizedOption",option);
1273       }
1274       case '?':
1275         break;
1276       default:
1277         ThrowImportException(OptionError,"UnrecognizedOption",option);
1278     }
1279     fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ?
1280       MagickFalse : MagickTrue;
1281     if (fire != MagickFalse)
1282       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1283   }
1284   if (k != 0)
1285     ThrowImportException(OptionError,"UnbalancedParenthesis",argv[i]);
1286   if (i-- != argc)
1287     ThrowImportException(OptionError,"MissingAnImageFilename",argv[i]);
1288   if (image == (Image *) NULL)
1289     ThrowImportException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1290   FinalizeImageSettings(image_info,image,MagickTrue);
1291   status&=WriteImages(image_info,image,filename,exception);
1292   DestroyImport();
1293   return(status != 0 ? MagickTrue : MagickFalse);
1294 #else
1295   (void) argc;
1296   (void) argv;
1297   (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
1298     "DelegateLibrarySupportNotBuiltIn","`%s' (X11)",image_info->filename);
1299   return(ImportUsage());
1300 #endif
1301 }