blob: 2304da2a583e58d8a262e1cae4dc299ea70a571e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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-2009 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 animate program to animate an image sequence on any X server.
37%
38*/
39
40/*
41 Include declarations.
42*/
43#include "wand/studio.h"
44#include "wand/MagickWand.h"
45#include "wand/mogrify-private.h"
46#include "magick/animate-private.h"
47
48/*
49%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50% %
51% %
52% %
53+ A n i m a t e I m a g e C o m m a n d %
54% %
55% %
56% %
57%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58%
59% AnimateImageCommand() displays a sequence of images on any workstation
60% display running an X server. Animate first determines the hardware
61% capabilities of the workstation. If the number of unique colors in an image
62% is less than or equal to the number the workstation can support, the image
63% is displayed in an X window. Otherwise the number of colors in the image is
64% first reduced to match the color resolution of the workstation before it is
65% displayed.
66%
67% This means that a continuous-tone 24 bits/pixel image can display on a 8
68% bit pseudo-color device or monochrome device. In most instances the reduced
69% color image closely resembles the original. Alternatively, a monochrome or
70% pseudo-color image sequence can display on a continuous-tone 24 bits/pixels
71% device.
72%
73% The format of the AnimateImageCommand method is:
74%
75% MagickBooleanType AnimateImageCommand(ImageInfo *image_info,int argc,
76% char **argv,char **metadata,ExceptionInfo *exception)
77%
78% A description of each parameter follows:
79%
80% o image_info: the image info.
81%
82% o argc: the number of elements in the argument vector.
83%
84% o argv: A text array containing the command line arguments.
85%
86% o metadata: any metadata is returned here.
87%
88% o exception: return any errors or warnings in this structure.
89%
90*/
91
92static MagickBooleanType AnimateUsage(void)
93{
94 const char
95 **p;
96
97 static const char
98 *buttons[]=
99 {
100 "Press any button to map or unmap the Command widget",
101 (char *) NULL
102 },
103 *miscellaneous[]=
104 {
105 "-debug events display copious debugging information",
106 "-help print program options",
107 "-list type print a list of supported option arguments",
108 "-log format format of debugging information",
109 "-version print version information",
110 (char *) NULL
111 },
112 *operators[]=
113 {
114 "-colors value preferred number of colors in the image",
115 "-crop geometry preferred size and location of the cropped image",
116 "-extract geometry extract area from image",
117 "-monochrome transform image to black and white",
118 "-repage geometry size and location of an image canvas (operator)",
119 "-resample geometry change the resolution of an image",
120 "-resize geometry resize the image",
121 "-rotate degrees apply Paeth rotation to the image",
122 "-strip strip image of all profiles and comments",
123 "-trim trim image edges",
124 (char *) NULL
125 },
126 *settings[]=
127 {
128 "-alpha option on, activate, off, deactivate, set, opaque, copy",
129 " transparent, extract, background, or shape",
130 "-authenticate password",
131 " decipher image with this password",
132 "-backdrop display image centered on a backdrop",
133 "-channel type apply option to select image channels",
134 "-colormap type Shared or Private",
135 "-colorspace type alternate image colorspace",
136 "-decipher filename convert cipher pixels to plain pixels",
137 "-define format:option",
138 " define one or more image format options",
139 "-delay value display the next image after pausing",
140 "-density geometry horizontal and vertical density of the image",
141 "-depth value image depth",
142 "-display server display image to this X server",
143 "-dispose method layer disposal method",
144 "-dither method apply error diffusion to image",
145 "-filter type use this filter when resizing an image",
146 "-format \"string\" output formatted image characteristics",
147 "-gamma value level of gamma correction",
148 "-geometry geometry preferred size and location of the Image window",
149 "-gravity type horizontal and vertical backdrop placement",
150 "-identify identify the format and characteristics of the image",
151 "-immutable displayed image cannot be modified",
152 "-interlace type type of image interlacing scheme",
153 "-interpolate method pixel color interpolation method",
154 "-limit type value pixel cache resource limit",
155 "-loop iterations loop images then exit",
156 "-map type display image using this Standard Colormap",
157 "-monitor monitor progress",
158 "-pause seconds to pause before reanimating",
159 "-page geometry size and location of an image canvas (setting)",
160 "-quantize colorspace reduce colors in this colorspace",
161 "-quiet suppress all warning messages",
162 "-regard-warnings pay attention to warning messages",
163 "-remote command execute a command in an remote display process",
164 "-respect-parentheses settings remain in effect until parenthesis boundary",
165 "-sampling-factor geometry",
166 " horizontal and vertical sampling factor",
167 "-seed value seed a new sequence of pseudo-random numbers",
168 "-set attribute value set an image attribute",
169 "-size geometry width and height of image",
170 "-transparent-color color",
171 " transparent color",
172 "-treedepth value color tree depth",
173 "-verbose print detailed information about the image",
174 "-visual type display image using this visual type",
175 "-virtual-pixel method",
176 " virtual pixel access method",
177 "-window id display image to background of this window",
178 (char *) NULL
179 },
180 *sequence_operators[]=
181 {
182 "-coalesce merge a sequence of images",
183 "-flatten flatten a sequence of images",
184 (char *) NULL
185 };
186
187 (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
188 (void) printf("Copyright: %s\n\n",GetMagickCopyright());
189 (void) printf("Usage: %s [options ...] file [ [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("\nImage Sequence Operators:\n");
198 for (p=sequence_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 "\nIn addition to those listed above, you can specify these standard X\n");
205 (void) printf(
206 "resources as command line options: -background, -bordercolor,\n");
207 (void) printf(
208 "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name,\n");
209 (void) printf("-mattecolor, -shared-memory, or -title.\n");
210 (void) printf(
211 "\nBy default, the image format of `file' is determined by its magic\n");
212 (void) printf(
213 "number. To specify a particular image format, precede the filename\n");
214 (void) printf(
215 "with an image format name and a colon (i.e. ps:image) or specify the\n");
216 (void) printf(
217 "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
218 (void) printf("'-' for standard input or output.\n");
219 (void) printf("\nButtons: \n");
220 for (p=buttons; *p != (char *) NULL; p++)
221 (void) printf(" %s\n",*p);
222 return(MagickFalse);
223}
224
225WandExport MagickBooleanType AnimateImageCommand(ImageInfo *image_info,
226 int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
227{
228#if defined(MAGICKCORE_X11_DELEGATE)
229#define DestroyAnimate() \
230{ \
231 XDestroyResourceInfo(&resource_info); \
232 if (display != (Display *) NULL) \
233 { \
234 XCloseDisplay(display); \
235 display=(Display *) NULL; \
236 } \
237 XDestroyResourceInfo(&resource_info); \
238 DestroyImageStack(); \
239 for (i=0; i < (long) argc; i++) \
240 argv[i]=DestroyString(argv[i]); \
241 argv=(char **) RelinquishMagickMemory(argv); \
242}
243#define ThrowAnimateException(asperity,tag,option) \
244{ \
245 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
246 option); \
247 DestroyAnimate(); \
248 return(MagickFalse); \
249}
250#define ThrowAnimateInvalidArgumentException(option,argument) \
251{ \
252 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
253 "InvalidArgument","`%s': %s",option,argument); \
254 DestroyAnimate(); \
255 return(MagickFalse); \
256}
257
258 char
259 *resource_value,
260 *server_name;
261
262 const char
263 *option;
264
265 Display
266 *display;
267
268 Image
269 *image;
270
271 ImageStack
272 image_stack[MaxImageStackDepth+1];
273
274 long
275 j,
276 k;
277
278 MagickBooleanType
279 fire,
280 pend;
281
282 MagickStatusType
283 status;
284
285 QuantizeInfo
286 *quantize_info;
287
288 register long
289 i;
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 status=MagickTrue;
318 SetNotifyHandlers;
319 display=(Display *) NULL;
320 j=1;
321 k=0;
322 NewImageStack();
323 option=(char *) NULL;
324 pend=MagickFalse;
325 resource_database=(XrmDatabase) NULL;
326 (void) ResetMagickMemory(&resource_info,0,sizeof(XResourceInfo));
327 server_name=(char *) NULL;
328 status=MagickTrue;
329 /*
330 Check for server name specified on the command line.
331 */
332 ReadCommandlLine(argc,&argv);
333 status=ExpandFilenames(&argc,&argv);
334 if (status == MagickFalse)
335 ThrowAnimateException(ResourceLimitError,"MemoryAllocationFailed",
336 image_info->filename);
337 for (i=1; i < (long) argc; i++)
338 {
339 /*
340 Check command line for server name.
341 */
342 option=argv[i];
343 if (LocaleCompare("display",option+1) == 0)
344 {
345 /*
346 User specified server name.
347 */
348 i++;
349 if (i == (long) argc)
350 ThrowAnimateException(OptionError,"MissingArgument",option);
351 server_name=argv[i];
352 }
353 if ((LocaleCompare("help",option+1) == 0) ||
354 (LocaleCompare("-help",option+1) == 0))
355 return(AnimateUsage());
356 }
357 /*
358 Get user defaults from X resource database.
359 */
360 display=XOpenDisplay(server_name);
361 if (display == (Display *) NULL)
362 ThrowAnimateException(XServerError,"UnableToOpenXServer",
363 XDisplayName(server_name));
364 (void) XSetErrorHandler(XError);
365 resource_database=XGetResourceDatabase(display,GetClientName());
366 XGetResourceInfo(image_info,resource_database,GetClientName(),
367 &resource_info);
368 quantize_info=resource_info.quantize_info;
369 image_info->density=XGetResourceInstance(resource_database,GetClientName(),
370 "density",(char *) NULL);
371 if (image_info->density == (char *) NULL)
372 image_info->density=XGetScreenDensity(display);
373 resource_value=XGetResourceInstance(resource_database,GetClientName(),
374 "interlace","none");
375 image_info->interlace=(InterlaceType)
376 ParseMagickOption(MagickInterlaceOptions,MagickFalse,resource_value);
377 resource_value=XGetResourceInstance(resource_database,GetClientName(),
378 "verbose","False");
379 image_info->verbose=IsMagickTrue(resource_value);
380 resource_value=XGetResourceInstance(resource_database,GetClientName(),
381 "dither","True");
382 quantize_info->dither=IsMagickTrue(resource_value);
383 /*
384 Parse command line.
385 */
386 for (i=1; i <= (long) argc; i++)
387 {
388 if (i < (long) argc)
389 option=argv[i];
390 else
391 if (image != (Image *) NULL)
392 break;
393 else
394 if (isatty(STDIN_FILENO) != MagickFalse)
395 option="logo:";
396 else
397 {
398 int
399 c;
400
401 c=getc(stdin);
402 if (c == EOF)
403 option="logo:";
404 else
405 {
406 c=ungetc(c,stdin);
407 option="-";
408 }
409 }
410 if (LocaleCompare(option,"(") == 0)
411 {
412 FireImageStack(MagickFalse,MagickTrue,pend);
413 if (k == MaxImageStackDepth)
414 ThrowAnimateException(OptionError,"ParenthesisNestedTooDeeply",
415 option);
416 PushImageStack();
417 continue;
418 }
419 if (LocaleCompare(option,")") == 0)
420 {
421 FireImageStack(MagickFalse,MagickTrue,MagickTrue);
422 if (k == 0)
423 ThrowAnimateException(OptionError,"UnableToParseExpression",option);
424 PopImageStack();
425 continue;
426 }
427 if (IsMagickOption(option) == MagickFalse)
428 {
429 const char
430 *filename;
431
432 Image
433 *images;
434
435 /*
436 Read input image.
437 */
438 FireImageStack(MagickFalse,MagickFalse,pend);
439 filename=option;
440 if ((LocaleCompare(filename,"--") == 0) && (i < (argc-1)))
441 {
442 option=argv[++i];
443 filename=option;
444 }
445 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
446 if (image_info->ping != MagickFalse)
447 images=PingImages(image_info,exception);
448 else
449 images=ReadImages(image_info,exception);
450 status&=(images != (Image *) NULL) &&
451 (exception->severity < ErrorException);
452 if (images == (Image *) NULL)
453 continue;
454 AppendImageStack(images);
455 continue;
456 }
457 pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
458 switch (*(option+1))
459 {
460 case 'a':
461 {
462 if (LocaleCompare("alpha",option+1) == 0)
463 {
464 long
465 type;
466
467 if (*option == '+')
468 break;
469 i++;
470 if (i == (long) argc)
471 ThrowAnimateException(OptionError,"MissingArgument",option);
472 type=ParseMagickOption(MagickAlphaOptions,MagickFalse,argv[i]);
473 if (type < 0)
474 ThrowAnimateException(OptionError,"UnrecognizedAlphaChannelType",
475 argv[i]);
476 break;
477 }
478 if (LocaleCompare("authenticate",option+1) == 0)
479 {
480 if (*option == '+')
481 break;
482 i++;
483 if (i == (long) argc)
484 ThrowAnimateException(OptionError,"MissingArgument",option);
485 break;
486 }
487 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
488 }
489 case 'b':
490 {
491 if (LocaleCompare("backdrop",option+1) == 0)
492 {
493 resource_info.backdrop=(*option == '-') ? MagickTrue : MagickFalse;
494 break;
495 }
496 if (LocaleCompare("background",option+1) == 0)
497 {
498 if (*option == '+')
499 break;
500 i++;
501 if (i == (long) argc)
502 ThrowAnimateException(OptionError,"MissingArgument",option);
503 resource_info.background_color=argv[i];
504 break;
505 }
506 if (LocaleCompare("bordercolor",option+1) == 0)
507 {
508 if (*option == '+')
509 break;
510 i++;
511 if (i == (long) argc)
512 ThrowAnimateException(OptionError,"MissingArgument",option);
513 resource_info.border_color=argv[i];
514 break;
515 }
516 if (LocaleCompare("borderwidth",option+1) == 0)
517 {
518 resource_info.border_width=0;
519 if (*option == '+')
520 break;
521 i++;
522 if ((i == (long) argc) || (IsGeometry(argv[i]) == MagickFalse))
523 ThrowAnimateException(OptionError,"MissingArgument",option);
524 resource_info.border_width=(unsigned int) atoi(argv[i]);
525 break;
526 }
527 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
528 }
529 case 'c':
530 {
531 if (LocaleCompare("cache",option+1) == 0)
532 {
533 if (*option == '+')
534 break;
535 i++;
536 if (i == (long) argc)
537 ThrowAnimateException(OptionError,"MissingArgument",option);
538 if (IsGeometry(argv[i]) == MagickFalse)
539 ThrowAnimateInvalidArgumentException(option,argv[i]);
540 break;
541 }
542 if (LocaleCompare("channel",option+1) == 0)
543 {
544 long
545 channel;
546
547 if (*option == '+')
548 break;
549 i++;
550 if (i == (long) (argc-1))
551 ThrowAnimateException(OptionError,"MissingArgument",option);
552 channel=ParseChannelOption(argv[i]);
553 if (channel < 0)
554 ThrowAnimateException(OptionError,"UnrecognizedChannelType",
555 argv[i]);
556 break;
557 }
558 if (LocaleCompare("clone",option+1) == 0)
559 {
560 Image
561 *clone_images;
562
563 clone_images=image;
564 if (k != 0)
565 clone_images=image_stack[k-1].image;
566 if (clone_images == (Image *) NULL)
567 ThrowAnimateException(ImageError,"ImageSequenceRequired",option);
568 FireImageStack(MagickFalse,MagickTrue,MagickTrue);
569 if (*option == '+')
570 clone_images=CloneImages(clone_images,"-1",exception);
571 else
572 {
573 i++;
574 if (i == (long) (argc-1))
575 ThrowAnimateException(OptionError,"MissingArgument",option);
576 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
577 ThrowAnimateInvalidArgumentException(option,argv[i]);
578 clone_images=CloneImages(clone_images,argv[i],exception);
579 }
580 if (clone_images == (Image *) NULL)
581 ThrowAnimateException(OptionError,"NoSuchImage",option);
582 AppendImageStack(clone_images);
583 break;
584 }
585 if (LocaleCompare("coalesce",option+1) == 0)
586 break;
587 if (LocaleCompare("colormap",option+1) == 0)
588 {
589 resource_info.colormap=PrivateColormap;
590 if (*option == '+')
591 break;
592 i++;
593 if (i == (long) argc)
594 ThrowAnimateException(OptionError,"MissingArgument",option);
595 resource_info.colormap=UndefinedColormap;
596 if (LocaleCompare("private",argv[i]) == 0)
597 resource_info.colormap=PrivateColormap;
598 if (LocaleCompare("shared",argv[i]) == 0)
599 resource_info.colormap=SharedColormap;
600 if (resource_info.colormap == UndefinedColormap)
601 ThrowAnimateException(OptionError,"UnrecognizedColormapType",
602 argv[i]);
603 break;
604 }
605 if (LocaleCompare("colors",option+1) == 0)
606 {
607 quantize_info->number_colors=0;
608 if (*option == '+')
609 break;
610 i++;
611 if (i == (long) argc)
612 ThrowAnimateException(OptionError,"MissingArgument",option);
613 if (IsGeometry(argv[i]) == MagickFalse)
614 ThrowAnimateInvalidArgumentException(option,argv[i]);
615 quantize_info->number_colors=(unsigned long) atol(argv[i]);
616 break;
617 }
618 if (LocaleCompare("colorspace",option+1) == 0)
619 {
620 long
621 colorspace;
622
623 if (*option == '+')
624 break;
625 i++;
626 if (i == (long) argc)
627 ThrowAnimateException(OptionError,"MissingArgument",option);
628 colorspace=ParseMagickOption(MagickColorspaceOptions,
629 MagickFalse,argv[i]);
630 if (colorspace < 0)
631 ThrowAnimateException(OptionError,"UnrecognizedColorspace",
632 argv[i]);
633 break;
634 }
635 if (LocaleCompare("crop",option+1) == 0)
636 {
637 if (*option == '+')
638 break;
639 i++;
640 if (i == (long) argc)
641 ThrowAnimateException(OptionError,"MissingArgument",option);
642 if (IsGeometry(argv[i]) == MagickFalse)
643 ThrowAnimateInvalidArgumentException(option,argv[i]);
644 break;
645 }
646 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
647 }
648 case 'd':
649 {
650 if (LocaleCompare("debug",option+1) == 0)
651 {
652 long
653 event;
654
655 if (*option == '+')
656 break;
657 i++;
658 if (i == (long) argc)
659 ThrowAnimateException(OptionError,"MissingArgument",option);
660 event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]);
661 if (event < 0)
662 ThrowAnimateException(OptionError,"UnrecognizedEventType",
663 argv[i]);
664 (void) SetLogEventMask(argv[i]);
665 break;
666 }
667 if (LocaleCompare("decipher",option+1) == 0)
668 {
669 if (*option == '+')
670 break;
671 i++;
672 if (i == (long) (argc-1))
673 ThrowAnimateException(OptionError,"MissingArgument",option);
674 break;
675 }
676 if (LocaleCompare("define",option+1) == 0)
677 {
678 i++;
679 if (i == (long) argc)
680 ThrowAnimateException(OptionError,"MissingArgument",option);
681 if (*option == '+')
682 {
683 const char
684 *define;
685
686 define=GetImageOption(image_info,argv[i]);
687 if (define == (const char *) NULL)
688 ThrowAnimateException(OptionError,"NoSuchOption",argv[i]);
689 break;
690 }
691 break;
692 }
693 if (LocaleCompare("delay",option+1) == 0)
694 {
695 if (*option == '+')
696 break;
697 i++;
698 if (i == (long) argc)
699 ThrowAnimateException(OptionError,"MissingArgument",option);
700 if (IsGeometry(argv[i]) == MagickFalse)
701 ThrowAnimateInvalidArgumentException(option,argv[i]);
702 break;
703 }
704 if (LocaleCompare("density",option+1) == 0)
705 {
706 if (*option == '+')
707 break;
708 i++;
709 if (i == (long) argc)
710 ThrowAnimateException(OptionError,"MissingArgument",option);
711 if (IsGeometry(argv[i]) == MagickFalse)
712 ThrowAnimateInvalidArgumentException(option,argv[i]);
713 break;
714 }
715 if (LocaleCompare("depth",option+1) == 0)
716 {
717 if (*option == '+')
718 break;
719 i++;
720 if (i == (long) argc)
721 ThrowAnimateException(OptionError,"MissingArgument",option);
722 if (IsGeometry(argv[i]) == MagickFalse)
723 ThrowAnimateInvalidArgumentException(option,argv[i]);
724 break;
725 }
726 if (LocaleCompare("display",option+1) == 0)
727 {
728 if (*option == '+')
729 break;
730 i++;
731 if (i == (long) argc)
732 ThrowAnimateException(OptionError,"MissingArgument",option);
733 break;
734 }
735 if (LocaleCompare("dispose",option+1) == 0)
736 {
737 long
738 dispose;
739
740 if (*option == '+')
741 break;
742 i++;
743 if (i == (long) argc)
744 ThrowAnimateException(OptionError,"MissingArgument",option);
745 dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,argv[i]);
746 if (dispose < 0)
747 ThrowAnimateException(OptionError,"UnrecognizedDisposeMethod",
748 argv[i]);
749 break;
750 }
751 if (LocaleCompare("dither",option+1) == 0)
752 {
753 long
754 method;
755
756 quantize_info->dither=MagickFalse;
757 if (*option == '+')
758 break;
759 i++;
760 if (i == (long) argc)
761 ThrowAnimateException(OptionError,"MissingArgument",option);
762 method=ParseMagickOption(MagickDitherOptions,MagickFalse,argv[i]);
763 if (method < 0)
764 ThrowAnimateException(OptionError,"UnrecognizedDitherMethod",
765 argv[i]);
766 quantize_info->dither=MagickTrue;
767 quantize_info->dither_method=(DitherMethod) method;
768 break;
769 }
770 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
771 }
772 case 'e':
773 {
774 if (LocaleCompare("extract",option+1) == 0)
775 {
776 if (*option == '+')
777 break;
778 i++;
779 if (i == (long) argc)
780 ThrowAnimateException(OptionError,"MissingArgument",option);
781 if (IsGeometry(argv[i]) == MagickFalse)
782 ThrowAnimateInvalidArgumentException(option,argv[i]);
783 break;
784 }
785 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
786 }
787 case 'f':
788 {
789 if (LocaleCompare("filter",option+1) == 0)
790 {
791 long
792 filter;
793
794 if (*option == '+')
795 break;
796 i++;
797 if (i == (long) (argc-1))
798 ThrowAnimateException(OptionError,"MissingArgument",option);
799 filter=ParseMagickOption(MagickFilterOptions,MagickFalse,argv[i]);
800 if (filter < 0)
801 ThrowAnimateException(OptionError,"UnrecognizedImageFilter",
802 argv[i]);
803 break;
804 }
805 if (LocaleCompare("flatten",option+1) == 0)
806 break;
807 if (LocaleCompare("font",option+1) == 0)
808 {
809 if (*option == '+')
810 break;
811 i++;
812 if (i == (long) argc)
813 ThrowAnimateException(OptionError,"MissingArgument",option);
814 resource_info.font=XGetResourceClass(resource_database,
815 GetClientName(),"font",argv[i]);
816 break;
817 }
818 if (LocaleCompare("foreground",option+1) == 0)
819 {
820 if (*option == '+')
821 break;
822 i++;
823 if (i == (long) argc)
824 ThrowAnimateException(OptionError,"MissingArgument",option);
825 resource_info.foreground_color=argv[i];
826 break;
827 }
828 if (LocaleCompare("format",option+1) == 0)
829 {
830 if (*option == '+')
831 break;
832 i++;
833 if (i == (long) (argc-1))
834 ThrowAnimateException(OptionError,"MissingArgument",option);
835 break;
836 }
837 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
838 }
839 case 'g':
840 {
841 if (LocaleCompare("gamma",option+1) == 0)
842 {
843 i++;
844 if (i == (long) argc)
845 ThrowAnimateException(OptionError,"MissingArgument",option);
846 if (IsGeometry(argv[i]) == MagickFalse)
847 ThrowAnimateInvalidArgumentException(option,argv[i]);
848 break;
849 }
850 if (LocaleCompare("geometry",option+1) == 0)
851 {
852 resource_info.image_geometry=(char *) NULL;
853 if (*option == '+')
854 break;
855 i++;
856 if (i == (long) argc)
857 ThrowAnimateException(OptionError,"MissingArgument",option);
858 if (IsGeometry(argv[i]) == MagickFalse)
859 ThrowAnimateInvalidArgumentException(option,argv[i]);
860 resource_info.image_geometry=ConstantString(argv[i]);
861 break;
862 }
863 if (LocaleCompare("gravity",option+1) == 0)
864 {
865 long
866 gravity;
867
868 if (*option == '+')
869 break;
870 i++;
871 if (i == (long) (argc-1))
872 ThrowAnimateException(OptionError,"MissingArgument",option);
873 gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,
874 argv[i]);
875 if (gravity < 0)
876 ThrowAnimateException(OptionError,"UnrecognizedGravityType",
877 argv[i]);
878 break;
879 }
880 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
881 }
882 case 'h':
883 {
884 if ((LocaleCompare("help",option+1) == 0) ||
885 (LocaleCompare("-help",option+1) == 0))
886 break;
887 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
888 }
889 case 'i':
890 {
891 if (LocaleCompare("iconGeometry",option+1) == 0)
892 {
893 resource_info.icon_geometry=(char *) NULL;
894 if (*option == '+')
895 break;
896 i++;
897 if (i == (long) argc)
898 ThrowAnimateException(OptionError,"MissingArgument",option);
899 if (IsGeometry(argv[i]) == MagickFalse)
900 ThrowAnimateInvalidArgumentException(option,argv[i]);
901 resource_info.icon_geometry=argv[i];
902 break;
903 }
904 if (LocaleCompare("iconic",option+1) == 0)
905 {
906 resource_info.iconic=(*option == '-') ? MagickTrue : MagickFalse;
907 break;
908 }
909 if (LocaleCompare("identify",option+1) == 0)
910 break;
911 if (LocaleCompare("immutable",option+1) == 0)
912 {
913 resource_info.immutable=(*option == '-') ? MagickTrue : MagickFalse;
914 break;
915 }
916 if (LocaleCompare("interlace",option+1) == 0)
917 {
918 long
919 interlace;
920
921 if (*option == '+')
922 break;
923 i++;
924 if (i == (long) argc)
925 ThrowAnimateException(OptionError,"MissingArgument",option);
926 interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
927 argv[i]);
928 if (interlace < 0)
929 ThrowAnimateException(OptionError,"UnrecognizedInterlaceType",
930 argv[i]);
931 break;
932 }
933 if (LocaleCompare("interpolate",option+1) == 0)
934 {
935 long
936 interpolate;
937
938 if (*option == '+')
939 break;
940 i++;
941 if (i == (long) argc)
942 ThrowAnimateException(OptionError,"MissingArgument",option);
943 interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
944 argv[i]);
945 if (interpolate < 0)
946 ThrowAnimateException(OptionError,"UnrecognizedInterpolateMethod",
947 argv[i]);
948 break;
949 }
950 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
951 }
952 case 'l':
953 {
954 if (LocaleCompare("label",option+1) == 0)
955 {
956 if (*option == '+')
957 break;
958 i++;
959 if (i == (long) argc)
960 ThrowAnimateException(OptionError,"MissingArgument",option);
961 break;
962 }
963 if (LocaleCompare("limit",option+1) == 0)
964 {
965 char
966 *p;
967
968 double
969 value;
970
971 long
972 resource;
973
974 if (*option == '+')
975 break;
976 i++;
977 if (i == (long) argc)
978 ThrowAnimateException(OptionError,"MissingArgument",option);
979 resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
980 argv[i]);
981 if (resource < 0)
982 ThrowAnimateException(OptionError,"UnrecognizedResourceType",
983 argv[i]);
984 i++;
985 if (i == (long) argc)
986 ThrowAnimateException(OptionError,"MissingArgument",option);
987 value=strtod(argv[i],&p);
988 if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
989 ThrowAnimateInvalidArgumentException(option,argv[i]);
990 break;
991 }
992 if (LocaleCompare("list",option+1) == 0)
993 {
994 long
995 list;
996
997 if (*option == '+')
998 break;
999 i++;
1000 if (i == (long) argc)
1001 ThrowAnimateException(OptionError,"MissingArgument",option);
1002 list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
1003 if (list < 0)
1004 ThrowAnimateException(OptionError,"UnrecognizedListType",argv[i]);
1005 (void) MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1006 argv+j,exception);
1007 DestroyAnimate();
1008 return(MagickTrue);
1009 }
1010 if (LocaleCompare("log",option+1) == 0)
1011 {
1012 if (*option == '+')
1013 break;
1014 i++;
1015 if ((i == (long) argc) ||
1016 (strchr(argv[i],'%') == (char *) NULL))
1017 ThrowAnimateException(OptionError,"MissingArgument",option);
1018 break;
1019 }
1020 if (LocaleCompare("loop",option+1) == 0)
1021 {
1022 if (*option == '+')
1023 break;
1024 i++;
1025 if (i == (long) (argc-1))
1026 ThrowAnimateException(OptionError,"MissingArgument",option);
1027 if (IsGeometry(argv[i]) == MagickFalse)
1028 ThrowAnimateInvalidArgumentException(option,argv[i]);
1029 break;
1030 }
1031 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1032 }
1033 case 'm':
1034 {
1035 if (LocaleCompare("map",option+1) == 0)
1036 {
1037 resource_info.map_type=(char *) NULL;
1038 if (*option == '+')
1039 break;
1040 (void) CopyMagickString(argv[i]+1,"san",MaxTextExtent);
1041 i++;
1042 if (i == (long) argc)
1043 ThrowAnimateException(OptionError,"MissingArgument",option);
1044 resource_info.map_type=argv[i];
1045 break;
1046 }
1047 if (LocaleCompare("matte",option+1) == 0)
1048 break;
1049 if (LocaleCompare("mattecolor",option+1) == 0)
1050 {
1051 if (*option == '+')
1052 break;
1053 i++;
1054 if (i == (long) argc)
1055 ThrowAnimateException(OptionError,"MissingArgument",option);
1056 resource_info.matte_color=argv[i];
1057 break;
1058 }
1059 if (LocaleCompare("monitor",option+1) == 0)
1060 break;
1061 if (LocaleCompare("monochrome",option+1) == 0)
1062 {
1063 if (*option == '+')
1064 break;
1065 quantize_info->number_colors=2;
1066 quantize_info->colorspace=GRAYColorspace;
1067 break;
1068 }
1069 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1070 }
1071 case 'n':
1072 {
1073 if (LocaleCompare("name",option+1) == 0)
1074 {
1075 resource_info.name=(char *) NULL;
1076 if (*option == '+')
1077 break;
1078 i++;
1079 if (i == (long) argc)
1080 ThrowAnimateException(OptionError,"MissingArgument",option);
1081 resource_info.name=ConstantString(argv[i]);
1082 break;
1083 }
1084 if (LocaleCompare("noop",option+1) == 0)
1085 break;
1086 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1087 }
1088 case 'p':
1089 {
1090 if (LocaleCompare("pause",option+1) == 0)
1091 {
1092 resource_info.pause=0;
1093 if (*option == '+')
1094 break;
1095 i++;
1096 if (i == (long) argc)
1097 ThrowAnimateException(OptionError,"MissingArgument",option);
1098 if (IsGeometry(argv[i]) == MagickFalse)
1099 ThrowAnimateInvalidArgumentException(option,argv[i]);
1100 resource_info.pause=(unsigned int) atoi(argv[i]);
1101 break;
1102 }
1103 if (LocaleCompare("page",option+1) == 0)
1104 {
1105 if (*option == '+')
1106 break;
1107 i++;
1108 if (i == (long) argc)
1109 ThrowAnimateException(OptionError,"MissingArgument",option);
1110 break;
1111 }
1112 if (LocaleCompare("profile",option+1) == 0)
1113 {
1114 i++;
1115 if (i == (long) argc)
1116 ThrowAnimateException(OptionError,"MissingArgument",option);
1117 break;
1118 }
1119 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1120 }
1121 case 'q':
1122 {
1123 if (LocaleCompare("quantize",option+1) == 0)
1124 {
1125 long
1126 colorspace;
1127
1128 if (*option == '+')
1129 break;
1130 i++;
1131 if (i == (long) (argc-1))
1132 ThrowAnimateException(OptionError,"MissingArgument",option);
1133 colorspace=ParseMagickOption(MagickColorspaceOptions,
1134 MagickFalse,argv[i]);
1135 if (colorspace < 0)
1136 ThrowAnimateException(OptionError,"UnrecognizedColorspace",
1137 argv[i]);
1138 break;
1139 }
1140 if (LocaleCompare("quiet",option+1) == 0)
1141 break;
1142 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1143 }
1144 case 'r':
1145 {
1146 if (LocaleCompare("regard-warnings",option+1) == 0)
1147 break;
1148 if (LocaleCompare("remote",option+1) == 0)
1149 {
1150 i++;
1151 if (i == (long) argc)
1152 ThrowAnimateException(OptionError,"MissingArgument",option);
1153 if (XRemoteCommand(display,resource_info.window_id,argv[i]) != 0)
1154 return(MagickFalse);
1155 i--;
1156 break;
1157 }
1158 if (LocaleCompare("repage",option+1) == 0)
1159 {
1160 if (*option == '+')
1161 break;
1162 i++;
1163 if (i == (long) argc)
1164 ThrowAnimateException(OptionError,"MissingArgument",option);
1165 if (IsGeometry(argv[i]) == MagickFalse)
1166 ThrowAnimateInvalidArgumentException(option,argv[i]);
1167 break;
1168 }
1169 if (LocaleCompare("resample",option+1) == 0)
1170 {
1171 if (*option == '+')
1172 break;
1173 i++;
1174 if (i == (long) (argc-1))
1175 ThrowAnimateException(OptionError,"MissingArgument",option);
1176 if (IsGeometry(argv[i]) == MagickFalse)
1177 ThrowAnimateInvalidArgumentException(option,argv[i]);
1178 break;
1179 }
1180 if (LocaleCompare("resize",option+1) == 0)
1181 {
1182 if (*option == '+')
1183 break;
1184 i++;
1185 if (i == (long) argc)
1186 ThrowAnimateException(OptionError,"MissingArgument",option);
1187 if (IsGeometry(argv[i]) == MagickFalse)
1188 ThrowAnimateInvalidArgumentException(option,argv[i]);
1189 break;
1190 }
1191 if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1192 {
1193 respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1194 break;
1195 }
1196 if (LocaleCompare("rotate",option+1) == 0)
1197 {
1198 i++;
1199 if (i == (long) argc)
1200 ThrowAnimateException(OptionError,"MissingArgument",option);
1201 if (IsGeometry(argv[i]) == MagickFalse)
1202 ThrowAnimateInvalidArgumentException(option,argv[i]);
1203 break;
1204 }
1205 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1206 }
1207 case 's':
1208 {
1209 if (LocaleCompare("sampling-factor",option+1) == 0)
1210 {
1211 if (*option == '+')
1212 break;
1213 i++;
1214 if (i == (long) argc)
1215 ThrowAnimateException(OptionError,"MissingArgument",option);
1216 if (IsGeometry(argv[i]) == MagickFalse)
1217 ThrowAnimateInvalidArgumentException(option,argv[i]);
1218 break;
1219 }
1220 if (LocaleCompare("seed",option+1) == 0)
1221 {
1222 if (*option == '+')
1223 break;
1224 i++;
1225 if (i == (long) (argc-1))
1226 ThrowAnimateException(OptionError,"MissingArgument",option);
1227 if (IsGeometry(argv[i]) == MagickFalse)
1228 ThrowAnimateInvalidArgumentException(option,argv[i]);
1229 break;
1230 }
1231 if (LocaleCompare("scenes",option+1) == 0) /* deprecated */
1232 {
1233 if (*option == '+')
1234 break;
1235 i++;
1236 if (i == (long) argc)
1237 ThrowAnimateException(OptionError,"MissingArgument",option);
1238 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
1239 ThrowAnimateInvalidArgumentException(option,argv[i]);
1240 break;
1241 }
1242 if (LocaleCompare("set",option+1) == 0)
1243 {
1244 i++;
1245 if (i == (long) argc)
1246 ThrowAnimateException(OptionError,"MissingArgument",option);
1247 if (*option == '+')
1248 break;
1249 i++;
1250 if (i == (long) argc)
1251 ThrowAnimateException(OptionError,"MissingArgument",option);
1252 break;
1253 }
1254 if (LocaleCompare("shared-memory",option+1) == 0)
1255 {
1256 resource_info.use_shared_memory=(*option == '-') ? MagickTrue :
1257 MagickFalse;
1258 break;
1259 }
1260 if (LocaleCompare("size",option+1) == 0)
1261 {
1262 if (*option == '+')
1263 break;
1264 i++;
1265 if (i == (long) argc)
1266 ThrowAnimateException(OptionError,"MissingArgument",option);
1267 if (IsGeometry(argv[i]) == MagickFalse)
1268 ThrowAnimateInvalidArgumentException(option,argv[i]);
1269 break;
1270 }
1271 if (LocaleCompare("strip",option+1) == 0)
1272 break;
1273 if (LocaleCompare("support",option+1) == 0)
1274 {
1275 i++; /* deprecated */
1276 break;
1277 }
1278 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1279 }
1280 case 't':
1281 {
1282 if (LocaleCompare("text-font",option+1) == 0)
1283 {
1284 resource_info.text_font=(char *) NULL;
1285 if (*option == '+')
1286 break;
1287 i++;
1288 if (i == (long) argc)
1289 ThrowAnimateException(OptionError,"MissingArgument",option);
1290 resource_info.text_font=XGetResourceClass(resource_database,
1291 GetClientName(),"font",argv[i]);
1292 break;
1293 }
1294 if (LocaleCompare("thumbnail",option+1) == 0)
1295 {
1296 if (*option == '+')
1297 break;
1298 i++;
1299 if (i == (long) argc)
1300 ThrowAnimateException(OptionError,"MissingArgument",option);
1301 if (IsGeometry(argv[i]) == MagickFalse)
1302 ThrowAnimateInvalidArgumentException(option,argv[i]);
1303 break;
1304 }
1305 if (LocaleCompare("title",option+1) == 0)
1306 {
1307 resource_info.title=(char *) NULL;
1308 if (*option == '+')
1309 break;
1310 i++;
1311 if (i == (long) argc)
1312 ThrowAnimateException(OptionError,"MissingArgument",option);
1313 resource_info.title=argv[i];
1314 break;
1315 }
1316 if (LocaleCompare("transparent-color",option+1) == 0)
1317 {
1318 if (*option == '+')
1319 break;
1320 i++;
1321 if (i == (long) (argc-1))
1322 ThrowAnimateException(OptionError,"MissingArgument",option);
1323 break;
1324 }
1325 if (LocaleCompare("treedepth",option+1) == 0)
1326 {
1327 quantize_info->tree_depth=0;
1328 if (*option == '+')
1329 break;
1330 i++;
1331 if (i == (long) argc)
1332 ThrowAnimateException(OptionError,"MissingArgument",option);
1333 if (IsGeometry(argv[i]) == MagickFalse)
1334 ThrowAnimateInvalidArgumentException(option,argv[i]);
1335 quantize_info->tree_depth=(unsigned long) atol(argv[i]);
1336 break;
1337 }
1338 if (LocaleCompare("trim",option+1) == 0)
1339 break;
1340 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1341 }
1342 case 'v':
1343 {
1344 if (LocaleCompare("verbose",option+1) == 0)
1345 break;
1346 if ((LocaleCompare("version",option+1) == 0) ||
1347 (LocaleCompare("-version",option+1) == 0))
1348 {
1349 (void) fprintf(stdout,"Version: %s\n",
1350 GetMagickVersion((unsigned long *) NULL));
1351 (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
1352 break;
1353 }
1354 if (LocaleCompare("virtual-pixel",option+1) == 0)
1355 {
1356 long
1357 method;
1358
1359 if (*option == '+')
1360 break;
1361 i++;
1362 if (i == (long) argc)
1363 ThrowAnimateException(OptionError,"MissingArgument",option);
1364 method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
1365 argv[i]);
1366 if (method < 0)
1367 ThrowAnimateException(OptionError,
1368 "UnrecognizedVirtualPixelMethod",argv[i]);
1369 break;
1370 }
1371 if (LocaleCompare("visual",option+1) == 0)
1372 {
1373 resource_info.visual_type=(char *) NULL;
1374 if (*option == '+')
1375 break;
1376 i++;
1377 if (i == (long) argc)
1378 ThrowAnimateException(OptionError,"MissingArgument",option);
1379 resource_info.visual_type=argv[i];
1380 break;
1381 }
1382 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1383 }
1384 case 'w':
1385 {
1386 if (LocaleCompare("window",option+1) == 0)
1387 {
1388 resource_info.window_id=(char *) NULL;
1389 if (*option == '+')
1390 break;
1391 i++;
1392 if (i == (long) argc)
1393 ThrowAnimateException(OptionError,"MissingArgument",option);
1394 resource_info.window_id=argv[i];
1395 break;
1396 }
1397 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1398 }
1399 case '?':
1400 break;
1401 default:
1402 ThrowAnimateException(OptionError,"UnrecognizedOption",option);
1403 }
1404 fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ?
1405 MagickFalse : MagickTrue;
1406 if (fire != MagickFalse)
1407 FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1408 }
1409 if (k != 0)
1410 ThrowAnimateException(OptionError,"UnbalancedParenthesis",argv[i]);
1411 if (image == (Image *) NULL)
1412 ThrowAnimateException(OptionError,"MissingAnImageFilename",argv[argc-1])
1413 FinalizeImageSettings(image_info,image,MagickTrue);
1414 if (resource_info.window_id != (char *) NULL)
1415 {
1416 XAnimateBackgroundImage(display,&resource_info,image);
1417 status&=MagickTrue;
1418 }
1419 else
1420 {
1421 Image
1422 *animate_image;
1423
1424 /*
1425 Animate image to X server.
1426 */
1427 animate_image=XAnimateImages(display,&resource_info,argv,argc,image);
1428 status&=animate_image != (Image *) NULL;
1429 while (animate_image != (Image *) NULL)
1430 {
1431 image=animate_image;
1432 animate_image=XAnimateImages(display,&resource_info,argv,argc,image);
1433 if (animate_image != image)
1434 image=DestroyImageList(image);
1435 }
1436 }
1437 DestroyAnimate();
1438 return(status != 0 ? MagickTrue : MagickFalse);
1439#else
1440 (void) argc;
1441 (void) argv;
1442 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
1443 "DelegateLibrarySupportNotBuiltIn","`%s' (X11)",image_info->filename);
1444 return(AnimateUsage());
1445#endif
1446}