root / ImageMagick / trunk / wand / import.c

Revision 12706, 44.7 kB (checked in by cristy, 2 days ago)
Line 
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-2008 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%  Import is an X Window System window dumping utility.  Import allows X
37%  users to store window images in a specially formatted dump file.  This
38%  file can then be read by the Display utility for redisplay, printing,
39%  editing, formatting, archiving, image processing, etc.  The target
40%  window can be specified by id or name or be selected by clicking the
41%  mouse in the desired window.  The keyboard bell is rung once at the
42%  beginning of the dump and twice when the dump is completed.
43%
44%
45*/
46
47/*
48  Include declarations.
49*/
50#include "wand/studio.h"
51#include "wand/MagickWand.h"
52#include "wand/mogrify-private.h"
53#include "magick/xwindow-private.h"
54
55/*
56%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57%                                                                             %
58%                                                                             %
59%                                                                             %
60+   I m p o r t I m a g e C o m m a n d                                       %
61%                                                                             %
62%                                                                             %
63%                                                                             %
64%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65%
66%  ImportImageCommand() reads an image from any visible window on an X server
67%  and outputs it as an image file. You can capture a single window, the
68%  entire screen, or any rectangular portion of the screen.  You can use the
69%  display utility for redisplay, printing, editing, formatting, archiving,
70%  image processing, etc. of the captured image.</dd>
71%
72%  The target window can be specified by id, name, or may be selected by
73%  clicking the mouse in the desired window. If you press a button and then
74%  drag, a rectangle will form which expands and contracts as the mouse moves.
75%  To save the portion of the screen defined by the rectangle, just release
76%  the button. The keyboard bell is rung once at the beginning of the screen
77%  capture and twice when it completes.
78%
79%  The format of the ImportImageCommand method is:
80%
81%      MagickBooleanType ImportImageCommand(ImageInfo *image_info,int argc,
82%        char **argv,char **metadata,ExceptionInfo *exception)
83%
84%  A description of each parameter follows:
85%
86%    o image_info: the image info.
87%
88%    o argc: the number of elements in the argument vector.
89%
90%    o argv: A text array containing the command line arguments.
91%
92%    o metadata: any metadata is returned here.
93%
94%    o exception: Return any errors or warnings in this structure.
95%
96*/
97
98static void ImportUsage(void)
99{
100  const char
101    **p;
102
103  static const char
104    *miscellaneous[]=
105    {
106      "-debug events        display copious debugging information",
107      "-help                print program options",
108      "-list type           print a list of supported option arguments",
109      "-log format          format of debugging information",
110      "-version             print version information",
111      (char *) NULL
112    },
113    *operators[]=
114    {
115      "-annotate geometry text",
116      "                     annotate the image with text",
117      "-border              include image borders in the output image",
118      "-colors value        preferred number of colors in the image",
119      "-crop geometry       preferred size and location of the cropped image",
120      "-encipher filename   convert plain pixels to cipher pixels",
121      "-geometry geometry   perferred size or location of the image",
122      "-help                print program options",
123      "-monochrome          transform image to black and white",
124      "-negate              replace every pixel with its complementary color ",
125      "-repage geometry     size and location of an image canvas",
126      "-quantize colorspace reduce colors in this colorspace",
127      "-resize geometry     resize the image",
128      "-rotate degrees      apply Paeth rotation to the image",
129      "-strip               strip image of all profiles and comments",
130      "-thumbnail geometry  create a thumbnail of the image",
131      "-transparent color   make this color transparent within the image",
132      "-trim                trim image edges",
133      "-type type           image type",
134      (char *) NULL
135    },
136    *settings[]=
137    {
138      "-adjoin              join images into a single multi-image file",
139      "-channel type        apply option to select image channels",
140      "-colorspace type     alternate image colorspace",
141      "-comment string      annotate image with comment",
142      "-compress type       type of pixel compression when writing the image",
143      "-define format:option",
144      "                     define one or more image format options",
145      "-density geometry    horizontal and vertical density of the image",
146      "-depth value         image depth",
147      "-descend             obtain image by descending window hierarchy",
148      "-display server      X server to contact",
149      "-dispose method      layer disposal method",
150      "-dither method       apply error diffusion to image",
151      "-delay value         display the next image after pausing",
152      "-encipher filename   convert plain pixels to cipher pixels",
153      "-endian type         endianness (MSB or LSB) of the image",
154      "-encoding type       text encoding type",
155      "-filter type         use this filter when resizing an image",
156      "-format \"string\"     output formatted image characteristics",
157      "-frame               include window manager frame",
158      "-gravity direction   which direction to gravitate towards",
159      "-identify            identify the format and characteristics of the image",
160      "-interlace type      None, Line, Plane, or Partition",
161      "-interpolate method  pixel color interpolation method",
162      "-label string        assign a label to an image",
163      "-limit type value    Area, Disk, Map, or Memory resource limit",
164      "-monitor             monitor progress",
165      "-page geometry       size and location of an image canvas",
166      "-pause value         seconds delay between snapshots",
167      "-pointsize value     font point size",
168      "-quality value       JPEG/MIFF/PNG compression level",
169      "-quiet               suppress all warning messages",
170      "-regard-warnings     pay attention to warning messages",
171      "-respect-parenthesis settings remain in effect until parenthesis boundary",
172      "-sampling-factor geometry",
173      "                     horizontal and vertical sampling factor",
174      "-scene value         image scene number",
175      "-screen              select image from root window",
176      "-seed value          seed a new sequence of pseudo-random numbers",
177      "-set property value  set an image property",
178      "-silent              operate silently, i.e. don't ring any bells ",
179      "-snaps value         number of screen snapshots",
180      "-transparent-color color",
181      "                     transparent color",
182      "-treedepth value     color tree depth",
183      "-verbose             print detailed information about the image",
184      "-virtual-pixel method",
185      "                     Constant, Edge, Mirror, or Tile",
186      "-window id           select window with this id or name",
187      (char *) NULL
188    };
189
190  (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
191  (void) printf("Copyright: %s\n\n",GetMagickCopyright());
192  (void) printf("Usage: %s [options ...] [ file ]\n",
193    GetClientName());
194  (void) printf("\nImage Settings:\n");
195  for (p=settings; *p != (char *) NULL; p++)
196    (void) printf("  %s\n",*p);
197  (void) printf("\nImage Operators:\n");
198  for (p=operators; *p != (char *) NULL; p++)
199    (void) printf("  %s\n",*p);
200  (void) printf("\nMiscellaneous Options:\n");
201  for (p=miscellaneous; *p != (char *) NULL; p++)
202    (void) printf("  %s\n",*p);
203  (void) printf(
204  "\nBy default, 'file' is written in the MIFF image format.  To\n");
205  (void) printf(
206    "specify a particular image format, precede the filename with an image\n");
207  (void) printf(
208    "format name and a colon (i.e. ps:image) or specify the image type as\n");
209  (void) printf(
210    "the filename suffix (i.e. image.ps).  Specify 'file' as '-' for\n");
211  (void) printf("standard input or output.\n");
212  exit(0);
213}
214
215static inline long MagickMax(const long x,const long y)
216{
217  if (x > y)
218    return(x);
219  return(y);
220}
221
222WandExport MagickBooleanType ImportImageCommand(ImageInfo *image_info,
223  int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
224{
225#if defined(MAGICKCORE_X11_DELEGATE)
226#define DestroyImport() \
227{ \
228  XDestroyResourceInfo(&resource_info); \
229  if (display != (Display *) NULL) \
230    { \
231      XCloseDisplay(display); \
232      display=(Display *) NULL; \
233    } \
234  DestroyImageStack(); \
235  for (i=0; i < (long) 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",argument,option); \
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  long
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 long
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((unsigned long *) NULL));
313          (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
314          return(MagickFalse);
315        }
316    }
317  display=(Display *) NULL;
318  j=1;
319  k=0;
320  NewImageStack();
321  option=(char *) NULL;
322  pend=MagickFalse;
323  resource_database=(XrmDatabase) NULL;
324  (void) ResetMagickMemory(&resource_info,0,sizeof(resource_info));
325  server_name=(char *) NULL;
326  status=MagickTrue;
327  SetNotifyHandlers;
328  /*
329    Check for server name specified on the command line.
330  */
331  ReadCommandlLine(argc,&argv);
332  status=ExpandFilenames(&argc,&argv);
333  if (status == MagickFalse)
334    ThrowImportException(ResourceLimitError,"MemoryAllocationFailed",
335      strerror(errno));
336  for (i=1; i < (long) argc; i++)
337  {
338    /*
339      Check command line for server name.
340    */
341    option=argv[i];
342    if (IsMagickOption(option) == MagickFalse)
343      continue;
344    if (LocaleCompare("display",option+1) == 0)
345      {
346        /*
347          User specified server name.
348        */
349        i++;
350        if (i == (long) 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      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) atoi(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) atol(resource_value);
404  resource_value=XGetResourceInstance(resource_database,GetClientName(),
405    "quality","85");
406  image_info->quality=(unsigned long) atol(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  target_window=(char *) NULL;
423  /*
424    Check command syntax.
425  */
426  for (i=1; i < (long) argc; i++)
427  {
428    option=argv[i];
429    if (LocaleCompare(option,"(") == 0)
430      {
431        FireImageStack(MagickFalse,MagickTrue,pend);
432        if (k == MaxImageStackDepth)
433          ThrowImportException(OptionError,"ParenthesisNestedTooDeeply",
434            option);
435        PushImageStack();
436        continue;
437      }
438    if (LocaleCompare(option,")") == 0)
439      {
440        FireImageStack(MagickFalse,MagickTrue,MagickTrue);
441        if (k == 0)
442          ThrowImportException(OptionError,"UnableToParseExpression",option);
443        PopImageStack();
444        continue;
445      }
446    if (IsMagickOption(option) == MagickFalse)
447      {
448        Image
449          *images;
450
451        unsigned long
452          scene;
453
454        /*
455          Read image from X server.
456        */
457        FireImageStack(MagickFalse,MagickFalse,pend);
458        filename=argv[i];
459        if (target_window != (char *) NULL)
460          (void) CopyMagickString(image_info->filename,target_window,
461            MaxTextExtent);
462        for (scene=0; scene < (unsigned long) MagickMax(snapshots,1); scene++)
463        {
464          (void) sleep(resource_info.pause);
465          images=XImportImage(image_info,&ximage_info);
466          status&=(images != (Image *) NULL) &&
467            (exception->severity < ErrorException);
468          if (images == (Image *) NULL)
469            continue;
470          (void) CopyMagickString(images->filename,filename,MaxTextExtent);
471          (void) CopyMagickString(images->magick,"PS",MaxTextExtent);
472          images->scene=scene;
473          AppendImageStack(images);
474          FireImageStack(MagickFalse,MagickFalse,MagickTrue);
475        }
476        continue;
477      }
478    pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
479    switch(*(option+1))
480    {
481      case 'a':
482      {
483        if (LocaleCompare("adjoin",option+1) == 0)
484          break;
485        if (LocaleCompare("annotate",option+1) == 0)
486          {
487            if (*option == '+')
488              break;
489            i++;
490            if (i == (long) (argc-1))
491              ThrowImportException(OptionError,"MissingArgument",option);
492            if (IsGeometry(argv[i]) == MagickFalse)
493              ThrowImportInvalidArgumentException(option,argv[i]);
494            if (i == (long) (argc-1))
495              ThrowImportException(OptionError,"MissingArgument",option);
496            i++;
497            break;
498          }
499        ThrowImportException(OptionError,"UnrecognizedOption",option);
500      }
501      case 'b':
502      {
503        if (LocaleCompare("border",option+1) == 0)
504          {
505            ximage_info.borders=(*option == '-') ? MagickTrue : MagickFalse;
506            (void) CopyMagickString(argv[i]+1,"sans0",MaxTextExtent);
507            break;
508          }
509        if (LocaleCompare("bordercolor",option+1) == 0)
510          {
511            if (*option == '+')
512              break;
513            i++;
514            if (i == (long) argc)
515              ThrowImportException(OptionError,"MissingArgument",option);
516            break;
517          }
518        ThrowImportException(OptionError,"UnrecognizedOption",option);
519      }
520      case 'c':
521      {
522        if (LocaleCompare("cache",option+1) == 0)
523          {
524            if (*option == '+')
525              break;
526            i++;
527            if (i == (long) argc)
528              ThrowImportException(OptionError,"MissingArgument",option);
529            if (IsGeometry(argv[i]) == MagickFalse)
530              ThrowImportInvalidArgumentException(option,argv[i]);
531            break;
532          }
533        if (LocaleCompare("channel",option+1) == 0)
534          {
535            long
536              channel;
537
538            if (*option == '+')
539              break;
540            i++;
541            if (i == (long) (argc-1))
542              ThrowImportException(OptionError,"MissingArgument",option);
543            channel=ParseChannelOption(argv[i]);
544            if (channel < 0)
545              ThrowImportException(OptionError,"UnrecognizedChannelType",
546                argv[i]);
547            break;
548          }
549        if (LocaleCompare("colors",option+1) == 0)
550          {
551            quantize_info->number_colors=0;
552            if (*option == '+')
553              break;
554            i++;
555            if (i == (long) argc)
556              ThrowImportException(OptionError,"MissingArgument",option);
557            if (IsGeometry(argv[i]) == MagickFalse)
558              ThrowImportInvalidArgumentException(option,argv[i]);
559            quantize_info->number_colors=(unsigned long) atol(argv[i]);
560            break;
561          }
562        if (LocaleCompare("colorspace",option+1) == 0)
563          {
564            long
565              colorspace;
566
567            if (*option == '+')
568              break;
569            i++;
570            if (i == (long) argc)
571              ThrowImportException(OptionError,"MissingArgument",option);
572            colorspace=ParseMagickOption(MagickColorspaceOptions,MagickFalse,
573              argv[i]);
574            if (colorspace < 0)
575              ThrowImportException(OptionError,"UnrecognizedColorspace",
576                argv[i]);
577            break;
578          }
579        if (LocaleCompare("comment",option+1) == 0)
580          {
581            if (*option == '+')
582              break;
583            i++;
584            if (i == (long) argc)
585              ThrowImportException(OptionError,"MissingArgument",option);
586            status=SetImageOption(image_info,"comment",argv[i]);
587            if (status == MagickFalse)
588              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
589            break;
590          }
591        if (LocaleCompare("compress",option+1) == 0)
592          {
593            long
594              compress;
595
596            if (*option == '+')
597              break;
598            i++;
599            if (i == (long) argc)
600              ThrowImportException(OptionError,"MissingArgument",option);
601            compress=ParseMagickOption(MagickCompressOptions,MagickFalse,
602              argv[i]);
603            if (compress < 0)
604              ThrowImportException(OptionError,"UnrecognizedImageCompression",
605                argv[i]);
606            break;
607          }
608        if (LocaleCompare("crop",option+1) == 0)
609          {
610            if (*option == '+')
611              break;
612            i++;
613            if (i == (long) 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            long
626              event;
627
628            if (*option == '+')
629              break;
630            i++;
631            if (i == (long) 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 == (long) 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 == (long) 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 == (long) 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 == (long) 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 == (long) argc)
703              ThrowImportException(OptionError,"MissingArgument",option);
704            break;
705          }
706        if (LocaleCompare("dispose",option+1) == 0)
707          {
708            long
709              dispose;
710
711            if (*option == '+')
712              break;
713            i++;
714            if (i == (long) 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            long
725              method;
726
727            quantize_info->dither=MagickFalse;
728            if (*option == '+')
729              break;
730            i++;
731            if (i == (long) 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        ThrowImportException(OptionError,"UnrecognizedOption",option);
742      }
743      case 'e':
744      {
745        if (LocaleCompare("encipher",option+1) == 0)
746          {
747            if (*option == '+')
748              break;
749            i++;
750            if (i == (long) (argc-1))
751              ThrowImportException(OptionError,"MissingArgument",option);
752            break;
753          }
754        if (LocaleCompare("encoding",option+1) == 0)
755          {
756            if (*option == '+')
757              break;
758            i++;
759            if (i == (long) argc)
760              ThrowImportException(OptionError,"MissingArgument",option);
761            break;
762          }
763        if (LocaleCompare("endian",option+1) == 0)
764          {
765            long
766              endian;
767
768            if (*option == '+')
769              break;
770            i++;
771            if (i == (long) argc)
772              ThrowImportException(OptionError,"MissingArgument",option);
773            endian=ParseMagickOption(MagickEndianOptions,MagickFalse,
774              argv[i]);
775            if (endian < 0)
776              ThrowImportException(OptionError,"UnrecognizedEndianType",
777                argv[i]);
778            break;
779          }
780        ThrowImportException(OptionError,"UnrecognizedOption",option);
781      }
782      case 'f':
783      {
784        if (LocaleCompare("filter",option+1) == 0)
785          {
786            long
787              filter;
788
789            if (*option == '+')
790              break;
791            i++;
792            if (i == (long) (argc-1))
793              ThrowImportException(OptionError,"MissingArgument",option);
794            filter=ParseMagickOption(MagickFilterOptions,MagickFalse,argv[i]);
795            if (filter < 0)
796              ThrowImportException(OptionError,"UnrecognizedImageFilter",
797                argv[i]);
798            break;
799          }
800        if (LocaleCompare("frame",option+1) == 0)
801          {
802            ximage_info.frame=(*option == '-') ? MagickTrue : MagickFalse;
803            (void) CopyMagickString(argv[i]+1,"sans0",MaxTextExtent);
804            break;
805          }
806        if (LocaleCompare("format",option+1) == 0)
807          {
808            if (*option == '+')
809              break;
810            i++;
811            if (i == (long) (argc-1))
812              ThrowImportException(OptionError,"MissingArgument",option);
813            break;
814          }
815        ThrowImportException(OptionError,"UnrecognizedOption",option);
816      }
817      case 'g':
818      {
819        if (LocaleCompare("geometry",option+1) == 0)
820          {
821            if (*option == '+')
822              break;
823            i++;
824            if (i == (long) argc)
825              ThrowImportException(OptionError,"MissingArgument",option);
826            if (IsGeometry(argv[i]) == MagickFalse)
827              ThrowImportInvalidArgumentException(option,argv[i]);
828            break;
829          }
830        if (LocaleCompare("gravity",option+1) == 0)
831          {
832            long
833              gravity;
834
835            if (*option == '+')
836              break;
837            i++;
838            if (i == (long) argc)
839              ThrowImportException(OptionError,"MissingArgument",option);
840            gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,argv[i]);
841            if (gravity < 0)
842              ThrowImportException(OptionError,"UnrecognizedGravityType",
843                argv[i]);
844            break;
845          }
846        ThrowImportException(OptionError,"UnrecognizedOption",option);
847      }
848      case 'h':
849      {
850        if (LocaleCompare("help",option+1) == 0)
851          break;
852        ThrowImportException(OptionError,"UnrecognizedOption",option);
853      }
854      case 'i':
855      {
856        if (LocaleCompare("identify",option+1) == 0)
857          break;
858        if (LocaleCompare("interlace",option+1) == 0)
859          {
860            long
861              interlace;
862
863            if (*option == '+')
864              break;
865            i++;
866            if (i == (long) argc)
867              ThrowImportException(OptionError,"MissingArgument",option);
868            interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
869              argv[i]);
870            if (interlace < 0)
871              ThrowImportException(OptionError,"UnrecognizedInterlaceType",
872                argv[i]);
873            break;
874          }
875        if (LocaleCompare("interpolate",option+1) == 0)
876          {
877            long
878              interpolate;
879
880            if (*option == '+')
881              break;
882            i++;
883            if (i == (long) argc)
884              ThrowImportException(OptionError,"MissingArgument",option);
885            interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
886              argv[i]);
887            if (interpolate < 0)
888              ThrowImportException(OptionError,"UnrecognizedInterpolateMethod",
889                argv[i]);
890            break;
891          }
892        ThrowImportException(OptionError,"UnrecognizedOption",option);
893      }
894      case 'l':
895      {
896        if (LocaleCompare("label",option+1) == 0)
897          {
898            if (*option == '+')
899              break;
900            i++;
901            if (i == (long) argc)
902              ThrowImportException(OptionError,"MissingArgument",option);
903            status=SetImageOption(image_info,"label",argv[i]);
904            if (status == MagickFalse)
905              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
906            break;
907          }
908        if (LocaleCompare("limit",option+1) == 0)
909          {
910            char
911              *p;
912
913            long
914              resource;
915
916            if (*option == '+')
917              break;
918            i++;
919            if (i == (long) argc)
920              ThrowImportException(OptionError,"MissingArgument",option);
921            resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
922              argv[i]);
923            if (resource < 0)
924              ThrowImportException(OptionError,"UnrecognizedResourceType",
925                argv[i]);
926            i++;
927            if (i == (long) argc)
928              ThrowImportException(OptionError,"MissingArgument",option);
929            (void) strtod(argv[i],&p);
930            if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
931              ThrowImportInvalidArgumentException(option,argv[i]);
932            break;
933          }
934        if (LocaleCompare("log",option+1) == 0)
935          {
936            if (*option == '+')
937              break;
938            i++;
939            if ((i == (long) argc) || (strchr(argv[i],'%') == (char *) NULL))
940              ThrowImportException(OptionError,"MissingArgument",option);
941            break;
942          }
943        ThrowImportException(OptionError,"UnrecognizedOption",option);