root / ImageMagick / trunk / wand / animate.c

Revision 11956, 49.3 kB (checked in by cristy, 10 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                AAA   N   N  IIIII  M   M   AAA   TTTTT  EEEEE               %
7%               A   A  NN  N    I    MM MM  A   A    T    E                   %
8%               AAAAA  N N N    I    M M M  AAAAA    T    EEE                 %
9%               A   A  N  NN    I    M   M  A   A    T    E                   %
10%               A   A  N   N  IIIII  M   M  A   A    T    EEEEE               %
11%                                                                             %
12%                                                                             %
13%              Methods to Interactively Animate an Image Sequence             %
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%
37*/
38
39/*
40  Include declarations.
41*/
42#include "wand/studio.h"
43#include "wand/MagickWand.h"
44#include "wand/mogrify-private.h"
45#include "magick/animate-private.h"
46
47/*
48%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49%                                                                             %
50%                                                                             %
51%                                                                             %
52+   A n i m a t e I m a g e C o m m a n d                                     %
53%                                                                             %
54%                                                                             %
55%                                                                             %
56%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57%
58%  AnimateImageCommand() displays a sequence of images on any workstation
59%  display running an X server. Animate first determines the hardware
60%  capabilities of the workstation. If the number of unique colors in an image
61%  is less than or equal to the number the workstation can support, the image
62%  is displayed in an X window. Otherwise the number of colors in the image is
63%  first reduced to match the color resolution of the workstation before it is
64%  displayed.
65%
66%  This means that a continuous-tone 24 bits/pixel image can display on a 8
67%  bit pseudo-color device or monochrome device. In most instances the reduced
68%  color image closely resembles the original. Alternatively, a monochrome or
69%  pseudo-color image sequence can display on a continuous-tone 24 bits/pixels
70%  device.
71%
72%  The format of the AnimateImageCommand method is:
73%
74%      MagickBooleanType AnimateImageCommand(ImageInfo *image_info,int argc,
75%        char **argv,char **metadata,ExceptionInfo *exception)
76%
77%  A description of each parameter follows:
78%
79%    o image_info: the image info.
80%
81%    o argc: the number of elements in the argument vector.
82%
83%    o argv: A text array containing the command line arguments.
84%
85%    o metadata: any metadata is returned here.
86%
87%    o exception: Return any errors or warnings in this structure.
88%
89*/
90
91static void AnimateUsage(void)
92{
93  const char
94    **p;
95
96  static const char
97    *buttons[]=
98    {
99      "Press any button to map or unmap the Command widget",
100      (char *) NULL
101    },
102    *miscellaneous[]=
103    {
104      "-debug events        display copious debugging information",
105      "-help                print program options",
106      "-list type           print a list of supported option arguments",
107      "-log format          format of debugging information",
108      "-version             print version information",
109      (char *) NULL
110    },
111    *operators[]=
112    {
113      "-colors value        preferred number of colors in the image",
114      "-crop geometry       preferred size and location of the cropped image",
115      "-extract geometry    extract area from image",
116      "-monochrome          transform image to black and white",
117      "-repage geometry     size and location of an image canvas (operator)",
118      "-resample geometry   change the resolution of an image",
119      "-resize geometry     resize the image",
120      "-rotate degrees      apply Paeth rotation to the image",
121      "-strip               strip image of all profiles and comments",
122      "-trim                trim image edges",
123      (char *) NULL
124    },
125    *settings[]=
126    {
127      "-alpha option        activate, deactivate, reset, or set the alpha channel",
128      "-authenticate password",
129      "                     decipher image with this password",
130      "-backdrop            display image centered on a backdrop",
131      "-channel type        apply option to select image channels",
132      "-colormap type       Shared or Private",
133      "-colorspace type     alternate image colorspace",
134      "-decipher filename   convert cipher pixels to plain pixels",
135      "-define format:option",
136      "                     define one or more image format options",
137      "-delay value         display the next image after pausing",
138      "-density geometry    horizontal and vertical density of the image",
139      "-depth value         image depth",
140      "-display server      display image to this X server",
141      "-dispose method      layer disposal method",
142      "-dither method       apply error diffusion to image",
143      "-filter type         use this filter when resizing an image",
144      "-format \"string\"     output formatted image characteristics",
145      "-gamma value         level of gamma correction",
146      "-geometry geometry   preferred size and location of the Image window",
147      "-identify            identify the format and characteristics of the image",
148      "-immutable           displayed image cannot be modified",
149      "-interlace type      type of image interlacing scheme",
150      "-interpolate method  pixel color interpolation method",
151      "-limit type value    pixel cache resource limit",
152      "-loop iterations     loop images then exit",
153      "-map type            display image using this Standard Colormap",
154      "-monitor             monitor progress",
155      "-pause               seconds to pause before reanimating",
156      "-page geometry       size and location of an image canvas (setting)",
157      "-quantize colorspace reduce colors in this colorspace",
158      "-quiet               suppress all warning messages",
159      "-regard-warnings     pay attention to warning messages",
160      "-remote command      execute a command in an remote display process",
161      "-respect-parenthesis settings remain in effect until parenthesis boundary",
162      "-sampling-factor geometry",
163      "                     horizontal and vertical sampling factor",
164      "-scenes range        image scene range",
165      "-seed value          seed a new sequence of pseudo-random numbers",
166      "-set attribute value set an image attribute",
167      "-size geometry       width and height of image",
168      "-transparent-color color",
169      "                     transparent color",
170      "-treedepth value     color tree depth",
171      "-verbose             print detailed information about the image",
172      "-visual type         display image using this visual type",
173      "-virtual-pixel method",
174      "                     virtual pixel access method",
175      "-window id           display image to background of this window",
176      (char *) NULL
177    },
178    *sequence_operators[]=
179    {
180      "-coalesce            merge a sequence of images",
181      "-flatten             flatten a sequence of images",
182      (char *) NULL
183    };
184
185  (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
186  (void) printf("Copyright: %s\n\n",GetMagickCopyright());
187  (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n",
188    GetClientName());
189  (void) printf("\nImage Settings:\n");
190  for (p=settings; *p != (char *) NULL; p++)
191    (void) printf("  %s\n",*p);
192  (void) printf("\nImage Operators:\n");
193  for (p=operators; *p != (char *) NULL; p++)
194    (void) printf("  %s\n",*p);
195  (void) printf("\nImage Sequence Operators:\n");
196  for (p=sequence_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    "\nIn addition to those listed above, you can specify these standard X\n");
203  (void) printf(
204    "resources as command line options:  -background, -bordercolor,\n");
205  (void) printf(
206    "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name,\n");
207  (void) printf("-mattecolor, -shared-memory, or -title.\n");
208  (void) printf(
209    "\nBy default, the image format of `file' is determined by its magic\n");
210  (void) printf(
211    "number.  To specify a particular image format, precede the filename\n");
212  (void) printf(
213    "with an image format name and a colon (i.e. ps:image) or specify the\n");
214  (void) printf(
215    "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
216  (void) printf("'-' for standard input or output.\n");
217  (void) printf("\nButtons: \n");
218  for (p=buttons; *p != (char *) NULL; p++)
219    (void) printf("  %s\n",*p);
220  exit(0);
221}
222
223WandExport MagickBooleanType AnimateImageCommand(ImageInfo *image_info,
224  int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
225{
226#if defined(MAGICKCORE_X11_DELEGATE)
227#define DestroyAnimate() \
228{ \
229  XDestroyResourceInfo(&resource_info); \
230  if (display != (Display *) NULL) \
231    { \
232      XCloseDisplay(display); \
233      display=(Display *) NULL; \
234    } \
235  XDestroyResourceInfo(&resource_info); \
236  DestroyImageStack(); \
237  for (i=0; i < (long) argc; i++) \
238    argv[i]=DestroyString(argv[i]); \
239  argv=(char **) RelinquishMagickMemory(argv); \
240}
241#define ThrowAnimateException(asperity,tag,option) \
242{ \
243  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
244    option); \
245  DestroyAnimate(); \
246  return(MagickFalse); \
247}
248#define ThrowAnimateInvalidArgumentException(option,argument) \
249{ \
250  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
251    "InvalidArgument","`%s': %s",argument,option); \
252  DestroyAnimate(); \
253  return(MagickFalse); \
254}
255
256  char
257    *resource_value,
258    *server_name;
259
260  const char
261    *option;
262
263  Display
264    *display;
265
266  Image
267    *image;
268
269  ImageStack
270    image_stack[MaxImageStackDepth+1];
271
272  long
273    first_scene,
274    j,
275    k,
276    last_scene,
277    scene;
278
279  MagickBooleanType
280    fire,
281    pend;
282
283  MagickStatusType
284    status;
285
286  QuantizeInfo
287    *quantize_info;
288
289  register long
290    i;
291
292  XResourceInfo
293    resource_info;
294
295  XrmDatabase
296    resource_database;
297
298  /*
299    Set defaults.
300  */
301  assert(image_info != (ImageInfo *) NULL);
302  assert(image_info->signature == MagickSignature);
303  if (image_info->debug != MagickFalse)
304    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
305  assert(exception != (ExceptionInfo *) NULL);
306  if (argc == 2)
307    {
308      option=argv[1];
309      if ((LocaleCompare("version",option+1) == 0) ||
310          (LocaleCompare("-version",option+1) == 0))
311        {
312          (void) fprintf(stdout,"Version: %s\n",
313            GetMagickVersion((unsigned long *) NULL));
314          (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
315          return(MagickFalse);
316        }
317    }
318  status=MagickTrue;
319  SetNotifyHandlers;
320  display=(Display *) NULL;
321  first_scene=0;
322  j=1;
323  k=0;
324  last_scene=0;
325  NewImageStack();
326  option=(char *) NULL;
327  pend=MagickFalse;
328  resource_database=(XrmDatabase) NULL;
329  (void) ResetMagickMemory(&resource_info,0,sizeof(XResourceInfo));
330  server_name=(char *) NULL;
331  status=MagickTrue;
332  /*
333    Check for server name specified on the command line.
334  */
335  ReadCommandlLine(argc,&argv);
336  status=ExpandFilenames(&argc,&argv);
337  if (status == MagickFalse)
338    ThrowAnimateException(ResourceLimitError,"MemoryAllocationFailed",
339      image_info->filename);
340  for (i=1; i < (long) argc; i++)
341  {
342    /*
343      Check command line for server name.
344    */
345    option=argv[i];
346    if (IsMagickOption(option) == MagickFalse)
347      continue;
348    if (LocaleCompare("display",option+1) == 0)
349      {
350        /*
351          User specified server name.
352        */
353        i++;
354        if (i == (long) argc)
355          ThrowAnimateException(OptionError,"MissingArgument",option);
356        server_name=argv[i];
357      }
358    if ((LocaleCompare("help",option+1) == 0) ||
359        (LocaleCompare("-help",option+1) == 0))
360      AnimateUsage();
361  }
362  /*
363    Get user defaults from X resource database.
364  */
365  display=XOpenDisplay(server_name);
366  if (display == (Display *) NULL)
367    ThrowAnimateException(XServerError,"UnableToOpenXServer",
368      XDisplayName(server_name));
369  (void) XSetErrorHandler(XError);
370  resource_database=XGetResourceDatabase(display,GetClientName());
371  XGetResourceInfo(image_info,resource_database,GetClientName(),
372    &resource_info);
373  quantize_info=resource_info.quantize_info;
374  image_info->density=XGetResourceInstance(resource_database,GetClientName(),
375    "density",(char *) NULL);
376  if (image_info->density == (char *) NULL)
377    image_info->density=XGetScreenDensity(display);
378  resource_value=XGetResourceInstance(resource_database,GetClientName(),
379    "interlace","none");
380  image_info->interlace=(InterlaceType)
381    ParseMagickOption(MagickInterlaceOptions,MagickFalse,resource_value);
382  resource_value=XGetResourceInstance(resource_database,GetClientName(),
383    "verbose","False");
384  image_info->verbose=IsMagickTrue(resource_value);
385  resource_value=XGetResourceInstance(resource_database,GetClientName(),
386    "dither","True");
387  quantize_info->dither=IsMagickTrue(resource_value);
388  /*
389    Parse command line.
390  */
391  for (i=1; i <= (long) argc; i++)
392  {
393    if (i < (long) argc)
394      option=argv[i];
395    else
396      if (image != (Image *) NULL)
397        break;
398      else
399        if (isatty(STDIN_FILENO) != MagickFalse)
400          option="logo:";
401        else
402          {
403            int
404              c;
405
406            c=getc(stdin);
407            if (c == EOF)
408              option="logo:";
409            else
410              {
411                c=ungetc(c,stdin);
412                option="-";
413              }
414          }
415    if (LocaleCompare(option,"(") == 0)
416      {
417        FireImageStack(MagickFalse,MagickTrue,pend);
418        if (k == MaxImageStackDepth)
419          ThrowAnimateException(OptionError,"ParenthesisNestedTooDeeply",
420            option);
421        PushImageStack();
422        continue;
423      }
424    if (LocaleCompare(option,")") == 0)
425      {
426        FireImageStack(MagickFalse,MagickTrue,MagickTrue);
427        if (k == 0)
428          ThrowAnimateException(OptionError,"UnableToParseExpression",option);
429        PopImageStack();
430        continue;
431      }
432    if (IsMagickOption(option) == MagickFalse)
433      {
434        /*
435          Option is a file name.
436        */
437        FireImageStack(MagickFalse,MagickTrue,pend);
438        for (scene=first_scene; scene <= last_scene ; scene++)
439        {
440          const char
441            *filename;
442
443          Image
444            *images;
445
446          /*
447            Read image.
448          */
449          filename=option;
450          if ((LocaleCompare(filename,"--") == 0) && (i < (argc-1)))
451            {
452              option=argv[++i];
453              filename=option;
454            }
455          (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
456          if (first_scene != last_scene)
457            {
458              char
459                filename[MaxTextExtent];
460
461              /*
462                Form filename for multi-part images.
463              */
464              (void) InterpretImageFilename(filename,MaxTextExtent,
465                image_info->filename,(int) scene);
466              if (LocaleCompare(filename,image_info->filename) == 0)
467                (void) FormatMagickString(filename,MaxTextExtent,"%s[%lu]",
468                  image_info->filename,scene);
469              (void) CopyMagickString(image_info->filename,filename,
470                MaxTextExtent);
471            }
472          images=ReadImage(image_info,exception);
473          status&=(images != (Image *) NULL) &&
474            (exception->severity < ErrorException);
475          if (images == (Image *) NULL)
476            continue;
477          AppendImageStack(images);
478          FireImageStack(MagickFalse,MagickFalse,MagickTrue);
479        }
480        continue;
481      }
482    pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
483    switch (*(option+1))
484    {
485      case 'a':
486      {
487        if (LocaleCompare("alpha",option+1) == 0)
488          {
489            long
490              type;
491
492            if (*option == '+')
493              break;
494            i++;
495            if (i == (long) argc)
496              ThrowAnimateException(OptionError,"MissingArgument",option);
497            type=ParseMagickOption(MagickAlphaOptions,MagickFalse,argv[i]);
498            if (type < 0)
499              ThrowAnimateException(OptionError,"UnrecognizedAlphaChannelType",
500                argv[i]);
501            break;
502          }
503        if (LocaleCompare("authenticate",option+1) == 0)
504          {
505            if (*option == '+')
506              break;
507            i++;
508            if (i == (long) argc)
509              ThrowAnimateException(OptionError,"MissingArgument",option);
510            break;
511          }
512        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
513      }
514      case 'b':
515      {
516        if (LocaleCompare("backdrop",option+1) == 0)
517          {
518            resource_info.backdrop=(*option == '-') ? MagickTrue : MagickFalse;
519            break;
520          }
521        if (LocaleCompare("background",option+1) == 0)
522          {
523            if (*option == '+')
524              break;
525            i++;
526            if (i == (long) argc)
527              ThrowAnimateException(OptionError,"MissingArgument",option);
528            resource_info.background_color=argv[i];
529            break;
530          }
531        if (LocaleCompare("bordercolor",option+1) == 0)
532          {
533            if (*option == '+')
534              break;
535            i++;
536            if (i == (long) argc)
537              ThrowAnimateException(OptionError,"MissingArgument",option);
538            resource_info.border_color=argv[i];
539            break;
540          }
541        if (LocaleCompare("borderwidth",option+1) == 0)
542          {
543            resource_info.border_width=0;
544            if (*option == '+')
545              break;
546            i++;
547            if ((i == (long) argc) || (IsGeometry(argv[i]) == MagickFalse))
548              ThrowAnimateException(OptionError,"MissingArgument",option);
549            resource_info.border_width=(unsigned int) atoi(argv[i]);
550            break;
551          }
552        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
553      }
554      case 'c':
555      {
556        if (LocaleCompare("cache",option+1) == 0)
557          {
558            if (*option == '+')
559              break;
560            i++;
561            if (i == (long) argc)
562              ThrowAnimateException(OptionError,"MissingArgument",option);
563            if (IsGeometry(argv[i]) == MagickFalse)
564              ThrowAnimateInvalidArgumentException(option,argv[i]);
565            break;
566          }
567        if (LocaleCompare("channel",option+1) == 0)
568          {
569            long
570              channel;
571
572            if (*option == '+')
573              break;
574            i++;
575            if (i == (long) (argc-1))
576              ThrowAnimateException(OptionError,"MissingArgument",option);
577            channel=ParseChannelOption(argv[i]);
578            if (channel < 0)
579              ThrowAnimateException(OptionError,"UnrecognizedChannelType",
580                argv[i]);
581            break;
582          }
583        if (LocaleCompare("clone",option+1) == 0)
584          {
585            Image
586              *clone_images;
587
588            clone_images=image;
589            if (k != 0)
590              clone_images=image_stack[k-1].image;
591            if (clone_images == (Image *) NULL)
592              ThrowAnimateException(ImageError,"ImageSequenceRequired",option);
593            if (*option == '+')
594              clone_images=CloneImages(clone_images,"-1",exception);
595            else
596              {
597                i++;
598                if (i == (long) (argc-1))
599                  ThrowAnimateException(OptionError,"MissingArgument",option);
600                if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
601                  ThrowAnimateInvalidArgumentException(option,argv[i]);
602                clone_images=CloneImages(clone_images,argv[i],exception);
603              }
604            if (clone_images == (Image *) NULL)
605              ThrowAnimateException(OptionError,"NoSuchImage",option);
606            FireImageStack(MagickFalse,MagickTrue,MagickTrue);
607            AppendImageStack(clone_images);
608            break;
609          }
610        if (LocaleCompare("coalesce",option+1) == 0)
611          break;
612        if (LocaleCompare("colormap",option+1) == 0)
613          {
614            resource_info.colormap=PrivateColormap;
615            if (*option == '+')
616              break;
617            i++;
618            if (i == (long) argc)
619              ThrowAnimateException(OptionError,"MissingArgument",option);
620            resource_info.colormap=UndefinedColormap;
621            if (LocaleCompare("private",argv[i]) == 0)
622              resource_info.colormap=PrivateColormap;
623            if (LocaleCompare("shared",argv[i]) == 0)
624              resource_info.colormap=SharedColormap;
625            if (resource_info.colormap == UndefinedColormap)
626              ThrowAnimateException(OptionError,"UnrecognizedColormapType",
627                argv[i]);
628            break;
629          }
630        if (LocaleCompare("colors",option+1) == 0)
631          {
632            quantize_info->number_colors=0;
633            if (*option == '+')
634              break;
635            i++;
636            if (i == (long) argc)
637              ThrowAnimateException(OptionError,"MissingArgument",option);
638            if (IsGeometry(argv[i]) == MagickFalse)
639              ThrowAnimateInvalidArgumentException(option,argv[i]);
640            quantize_info->number_colors=(unsigned long) atol(argv[i]);
641            break;
642          }
643        if (LocaleCompare("colorspace",option+1) == 0)
644          {
645            long
646              colorspace;
647
648            if (*option == '+')
649              break;
650            i++;
651            if (i == (long) argc)
652              ThrowAnimateException(OptionError,"MissingArgument",option);
653            colorspace=ParseMagickOption(MagickColorspaceOptions,
654              MagickFalse,argv[i]);
655            if (colorspace < 0)
656              ThrowAnimateException(OptionError,"UnrecognizedColorspace",
657                argv[i]);
658            break;
659          }
660        if (LocaleCompare("crop",option+1) == 0)
661          {
662            if (*option == '+')
663              break;
664            i++;
665            if (i == (long) argc)
666              ThrowAnimateException(OptionError,"MissingArgument",option);
667            if (IsGeometry(argv[i]) == MagickFalse)
668              ThrowAnimateInvalidArgumentException(option,argv[i]);
669            break;
670          }
671        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
672      }
673      case 'd':
674      {
675        if (LocaleCompare("debug",option+1) == 0)
676          {
677            long
678              event;
679
680            if (*option == '+')
681              break;
682            i++;
683            if (i == (long) argc)
684              ThrowAnimateException(OptionError,"MissingArgument",option);
685            event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]);
686            if (event < 0)
687              ThrowAnimateException(OptionError,"UnrecognizedEventType",
688                argv[i]);
689            (void) SetLogEventMask(argv[i]);
690            break;
691          }
692        if (LocaleCompare("decipher",option+1) == 0)
693          {
694            if (*option == '+')
695              break;
696            i++;
697            if (i == (long) (argc-1))
698              ThrowAnimateException(OptionError,"MissingArgument",option);
699            break;
700          }
701        if (LocaleCompare("define",option+1) == 0)
702          {
703            i++;
704            if (i == (long) argc)
705              ThrowAnimateException(OptionError,"MissingArgument",option);
706            if (*option == '+')
707              {
708                const char
709                  *define;
710
711                define=GetImageOption(image_info,argv[i]);
712                if (define == (const char *) NULL)
713                  ThrowAnimateException(OptionError,"NoSuchOption",argv[i]);
714                break;
715              }
716            break;
717          }
718        if (LocaleCompare("delay",option+1) == 0)
719          {
720            if (*option == '+')
721              break;
722            i++;
723            if (i == (long) argc)
724              ThrowAnimateException(OptionError,"MissingArgument",option);
725            if (IsGeometry(argv[i]) == MagickFalse)
726              ThrowAnimateInvalidArgumentException(option,argv[i]);
727            break;
728          }
729        if (LocaleCompare("density",option+1) == 0)
730          {
731            if (*option == '+')
732              break;
733            i++;
734            if (i == (long) argc)
735              ThrowAnimateException(OptionError,"MissingArgument",option);
736            if (IsGeometry(argv[i]) == MagickFalse)
737              ThrowAnimateInvalidArgumentException(option,argv[i]);
738            break;
739          }
740        if (LocaleCompare("depth",option+1) == 0)
741          {
742            if (*option == '+')
743              break;
744            i++;
745            if (i == (long) argc)
746              ThrowAnimateException(OptionError,"MissingArgument",option);
747            if (IsGeometry(argv[i]) == MagickFalse)
748              ThrowAnimateInvalidArgumentException(option,argv[i]);
749            break;
750          }
751        if (LocaleCompare("display",option+1) == 0)
752          {
753            if (*option == '+')
754              break;
755            i++;
756            if (i == (long) argc)
757              ThrowAnimateException(OptionError,"MissingArgument",option);
758            break;
759          }
760        if (LocaleCompare("dispose",option+1) == 0)
761          {
762            long
763              dispose;
764
765            if (*option == '+')
766              break;
767            i++;
768            if (i == (long) argc)
769              ThrowAnimateException(OptionError,"MissingArgument",option);
770            dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,argv[i]);
771            if (dispose < 0)
772              ThrowAnimateException(OptionError,"UnrecognizedDisposeMethod",
773                argv[i]);
774            break;
775          }
776        if (LocaleCompare("dither",option+1) == 0)
777          {
778            long
779              method;
780
781            quantize_info->dither=MagickFalse;
782            if (*option == '+')
783              break;
784            i++;
785            if (i == (long) argc)
786              ThrowAnimateException(OptionError,"MissingArgument",option);
787            method=ParseMagickOption(MagickDitherOptions,MagickFalse,argv[i]);
788            if (method < 0)
789              ThrowAnimateException(OptionError,"UnrecognizedDitherMethod",
790                argv[i]);
791            quantize_info->dither=MagickTrue;
792            quantize_info->dither_method=(DitherMethod) method;
793            break;
794          }
795        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
796      }
797      case 'e':
798      {
799        if (LocaleCompare("extract",option+1) == 0)
800          {
801            if (*option == '+')
802              break;
803            i++;
804            if (i == (long) argc)
805              ThrowAnimateException(OptionError,"MissingArgument",option);
806            if (IsGeometry(argv[i]) == MagickFalse)
807              ThrowAnimateInvalidArgumentException(option,argv[i]);
808            break;
809          }
810        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
811      }
812      case 'f':
813      {
814        if (LocaleCompare("filter",option+1) == 0)
815          {
816            long
817              filter;
818
819            if (*option == '+')
820              break;
821            i++;
822            if (i == (long) (argc-1))
823              ThrowAnimateException(OptionError,"MissingArgument",option);
824            filter=ParseMagickOption(MagickFilterOptions,MagickFalse,argv[i]);
825            if (filter < 0)
826              ThrowAnimateException(OptionError,"UnrecognizedImageFilter",
827                argv[i]);
828            break;
829          }
830        if (LocaleCompare("flatten",option+1) == 0)
831          break;
832        if (LocaleCompare("font",option+1) == 0)
833          {
834            if (*option == '+')
835              break;
836            i++;
837            if (i == (long) argc)
838              ThrowAnimateException(OptionError,"MissingArgument",option);
839            resource_info.font=XGetResourceClass(resource_database,
840              GetClientName(),"font",argv[i]);
841            break;
842          }
843        if (LocaleCompare("foreground",option+1) == 0)
844          {
845            if (*option == '+')
846              break;
847            i++;
848            if (i == (long) argc)
849              ThrowAnimateException(OptionError,"MissingArgument",option);
850            resource_info.foreground_color=argv[i];
851            break;
852          }
853        if (LocaleCompare("format",option+1) == 0)
854          {
855            if (*option == '+')
856              break;
857            i++;
858            if (i == (long) (argc-1))
859              ThrowAnimateException(OptionError,"MissingArgument",option);
860            break;
861          }
862        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
863      }
864      case 'g':
865      {
866        if (LocaleCompare("gamma",option+1) == 0)
867          {
868            i++;
869            if (i == (long) argc)
870              ThrowAnimateException(OptionError,"MissingArgument",option);
871            if (IsGeometry(argv[i]) == MagickFalse)
872              ThrowAnimateInvalidArgumentException(option,argv[i]);
873            break;
874          }
875        if (LocaleCompare("geometry",option+1) == 0)
876          {
877            resource_info.image_geometry=(char *) NULL;
878            if (*option == '+')
879              break;
880            i++;
881            if (i == (long) argc)
882              ThrowAnimateException(OptionError,"MissingArgument",option);
883            if (IsGeometry(argv[i]) == MagickFalse)
884              ThrowAnimateInvalidArgumentException(option,argv[i]);
885            resource_info.image_geometry=ConstantString(argv[i]);
886            break;
887          }
888        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
889      }
890      case 'h':
891      {
892        if ((LocaleCompare("help",option+1) == 0) ||
893            (LocaleCompare("-help",option+1) == 0))
894          break;
895        ThrowAnimateException(OptionError,"UnrecognizedOption",option);
896      }
897      case 'i':
898      {
899        if (LocaleCompare("iconGeometry",option+1) == 0)
900          {
901            resource_info.icon_geometry=(char *) NULL;
902            if (*option == '+')
903              break;
904            i++;
905            if (i == (long) argc)
906              ThrowAnimateException(OptionError,"MissingArgument",option);
907            if (IsGeometry(argv[i]) == MagickFalse)
908              ThrowAnimateInvalidArgumentException(option,argv[i]);
909            resource_info.icon_geometry=argv[i];
910            break;
911          }
912        if (LocaleCompare("iconic",option+1) == 0)
913          {
914            resource_info.iconic=(*option == '-') ? MagickTrue : MagickFalse;
915            break;
916          }
917        if (LocaleCompare("identify",option+1) == 0)
918          break;
919        if (LocaleCompare("immutable",option+1) == 0)
920          {
921            resource_info.immutable=(*option == '-') ? MagickTrue : MagickFalse;
922            break;
923          }
924        if (LocaleCompare("interlace",option+1) == 0)
925          {
926            long
927              interlace;
928
929            if (*option == '+')
930              break;
931            i++;
932            if (i == (long) argc)
933              ThrowAnimateException(OptionError,"MissingArgument",option);
934            interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
935              argv[i]);
936            if (interlace < 0)
937              ThrowAnimateException(OptionError,"UnrecognizedInterlaceType",
938                argv[i]);
939            break;
940          }
941        if (LocaleCompare("interpolate",option+1) == 0)
942          {
943            long
944              interpolate;
945
946            if (*option == '+')
947              break;
948            i++;
949            if (i == (long) argc)
950              ThrowAnimateException(OptionError,"MissingArgument",option);
951            interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
952              argv[i]);
953            if (interpolate < 0)