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