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