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