]> granicus.if.org Git - imagemagick/blob - MagickWand/stream.c
(no commit message)
[imagemagick] / MagickWand / stream.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                 SSSSS  TTTTT  RRRR   EEEEE   AAA   M   M                    %
7 %                 SS       T    R   R  E      A   A  MM MM                    %
8 %                  SSS     T    RRRR   EEE    AAAAA  M M M                    %
9 %                    SS    T    R R    E      A   A  M   M                    %
10 %                 SSSSS    T    R  R   EEEEE  A   A  M   M                    %
11 %                                                                             %
12 %                                                                             %
13 %                     Stream Image to a Raw Image Format                      %
14 %                                                                             %
15 %                           Software Design                                   %
16 %                             John Cristy                                     %
17 %                              July 1992                                      %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2013 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 %  Stream is a lightweight tool to stream one or more pixel components of the
37 %  image or portion of the image to your choice of storage formats. It writes
38 %  the pixel components as they are read from the input image a row at a time
39 %  making stream desirable when working with large images or when you require
40 %  raw pixel components.
41 %
42 */
43 \f
44 /*
45   Include declarations.
46 */
47 #include "MagickWand/studio.h"
48 #include "MagickWand/MagickWand.h"
49 #include "MagickWand/mogrify-private.h"
50 #include "MagickCore/stream-private.h"
51 #include "MagickCore/string-private.h"
52 \f
53 /*
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 %                                                                             %
56 %                                                                             %
57 %                                                                             %
58 %   S t r e a m I m a g e C o m m a n d                                       %
59 %                                                                             %
60 %                                                                             %
61 %                                                                             %
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 %
64 %  StreamImageCommand() is a lightweight method designed to extract pixels
65 %  from large image files to a raw format using a minimum of system resources.
66 %  The entire image or any regular portion of the image can be extracted.
67 %
68 %  The format of the StreamImageCommand method is:
69 %
70 %      MagickBooleanType StreamImageCommand(ImageInfo *image_info,int argc,
71 %        char **argv,char **metadata,ExceptionInfo *exception)
72 %
73 %  A description of each parameter follows:
74 %
75 %    o image_info: the image info.
76 %
77 %    o argc: the number of elements in the argument vector.
78 %
79 %    o argv: A text array containing the command line arguments.
80 %
81 %    o metadata: any metadata is returned here.
82 %
83 %    o exception: return any errors or warnings in this structure.
84 %
85 */
86
87 static MagickBooleanType StreamUsage(void)
88 {
89   const char
90     **p;
91
92   static const char
93     *miscellaneous[]=
94     {
95       "-debug events        display copious debugging information",
96       "-help                print program options",
97       "-list type           print a list of supported option arguments",
98       "-log format          format of debugging information",
99       "-version             print version information",
100       (char *) NULL
101     },
102     *settings[]=
103     {
104       "-authenticate password",
105       "                     decipher image with this password",
106       "-channel type        apply option to select image channels",
107       "-colorspace type     alternate image colorspace",
108       "-compress type       type of pixel compression when writing the image",
109       "-define format:option",
110       "                     define one or more image format options",
111       "-density geometry    horizontal and vertical density of the image",
112       "-depth value         image depth",
113       "-extract geometry    extract area from image",
114       "-identify            identify the format and characteristics of the image",
115       "-interlace type      type of image interlacing scheme",
116       "-interpolate method  pixel color interpolation method",
117       "-limit type value    pixel cache resource limit",
118       "-map components      one or more pixel components",
119       "-monitor             monitor progress",
120       "-quantize colorspace reduce colors in this colorspace",
121       "-quiet               suppress all warning messages",
122       "-regard-warnings     pay attention to warning messages",
123       "-respect-parentheses settings remain in effect until parenthesis boundary",
124       "-sampling-factor geometry",
125       "                     horizontal and vertical sampling factor",
126       "-seed value          seed a new sequence of pseudo-random numbers",
127       "-set attribute value set an image attribute",
128       "-size geometry       width and height of image",
129       "-storage-type type   pixel storage type",
130       "-synchronize         synchronize image to storage device",
131       "-taint               declare the image as modified",
132       "-transparent-color color",
133       "                     transparent color",
134       "-verbose             print detailed information about the image",
135       "-virtual-pixel method",
136       "                     virtual pixel access method",
137       (char *) NULL
138     };
139
140   (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
141   (void) printf("Copyright: %s\n",GetMagickCopyright());
142   (void) printf("Features: %s\n\n",GetMagickFeatures());
143   (void) printf("Usage: %s [options ...] input-image raw-image\n",
144     GetClientName());
145   (void) printf("\nImage Settings:\n");
146   for (p=settings; *p != (char *) NULL; p++)
147     (void) printf("  %s\n",*p);
148   (void) printf("\nMiscellaneous Options:\n");
149   for (p=miscellaneous; *p != (char *) NULL; p++)
150     (void) printf("  %s\n",*p);
151   (void) printf(
152     "\nBy default, the image format of 'file' is determined by its magic\n");
153   (void) printf(
154     "number.  To specify a particular image format, precede the filename\n");
155   (void) printf(
156     "with an image format name and a colon (i.e. ps:image) or specify the\n");
157   (void) printf(
158     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
159   (void) printf("'-' for standard input or output.\n");
160   return(MagickFalse);
161 }
162
163 WandExport MagickBooleanType StreamImageCommand(ImageInfo *image_info,
164   int argc,char **argv,char **metadata,ExceptionInfo *exception)
165 {
166 #define DestroyStream() \
167 { \
168   DestroyImageStack(); \
169   stream_info=DestroyStreamInfo(stream_info); \
170   for (i=0; i < (ssize_t) argc; i++) \
171     argv[i]=DestroyString(argv[i]); \
172   argv=(char **) RelinquishMagickMemory(argv); \
173 }
174 #define ThrowStreamException(asperity,tag,option) \
175 { \
176   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"'%s'", \
177     option); \
178   DestroyStream(); \
179   return(MagickFalse); \
180 }
181 #define ThrowStreamInvalidArgumentException(option,argument) \
182 { \
183   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
184     "InvalidArgument","'%s': %s",option,argument); \
185   DestroyStream(); \
186   return(MagickFalse); \
187 }
188
189   char
190     *filename,
191     *option;
192
193   const char
194     *format;
195
196   Image
197     *image;
198
199   ImageStack
200     image_stack[MaxImageStackDepth+1];
201
202   MagickBooleanType
203     fire,
204     pend,
205     respect_parenthesis;
206
207   MagickStatusType
208     status;
209
210   register ssize_t
211     i;
212
213   ssize_t
214     j,
215     k;
216
217   StreamInfo
218     *stream_info;
219
220   /*
221     Set defaults.
222   */
223   assert(image_info != (ImageInfo *) NULL);
224   assert(image_info->signature == MagickSignature);
225   if (image_info->debug != MagickFalse)
226     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
227   assert(exception != (ExceptionInfo *) NULL);
228   (void) metadata;
229   if (argc == 2)
230     {
231       option=argv[1];
232       if ((LocaleCompare("version",option+1) == 0) ||
233           (LocaleCompare("-version",option+1) == 0))
234         {
235           (void) FormatLocaleFile(stdout,"Version: %s\n",
236             GetMagickVersion((size_t *) NULL));
237           (void) FormatLocaleFile(stdout,"Copyright: %s\n",
238             GetMagickCopyright());
239           (void) FormatLocaleFile(stdout,"Features: %s\n\n",
240             GetMagickFeatures());
241           return(MagickFalse);
242         }
243     }
244   if (argc < 3)
245     return(StreamUsage());
246   format="%w,%h,%m";
247   (void) format;
248   j=1;
249   k=0;
250   NewImageStack();
251   option=(char *) NULL;
252   pend=MagickFalse;
253   respect_parenthesis=MagickFalse;
254   stream_info=AcquireStreamInfo(image_info,exception);
255   status=MagickTrue;
256   /*
257     Stream an image.
258   */
259   ReadCommandlLine(argc,&argv);
260   status=ExpandFilenames(&argc,&argv);
261   if (status == MagickFalse)
262     ThrowStreamException(ResourceLimitError,"MemoryAllocationFailed",
263       GetExceptionMessage(errno));
264   status=OpenStream(image_info,stream_info,argv[argc-1],exception);
265   if (status == MagickFalse)
266     {
267       DestroyStream();
268       return(MagickFalse);
269     }
270   for (i=1; i < (ssize_t) (argc-1); i++)
271   {
272     option=argv[i];
273     if (LocaleCompare(option,"(") == 0)
274       {
275         FireImageStack(MagickFalse,MagickTrue,pend);
276         if (k == MaxImageStackDepth)
277           ThrowStreamException(OptionError,"ParenthesisNestedTooDeeply",option);
278         PushImageStack();
279         continue;
280       }
281     if (LocaleCompare(option,")") == 0)
282       {
283         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
284         if (k == 0)
285           ThrowStreamException(OptionError,"UnableToParseExpression",option);
286         PopImageStack();
287         continue;
288       }
289     if (IsCommandOption(option) == MagickFalse)
290       {
291         Image
292           *images;
293
294         /*
295           Stream input image.
296         */
297         FireImageStack(MagickFalse,MagickFalse,pend);
298         filename=argv[i];
299         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
300           filename=argv[++i];
301         (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
302         images=StreamImage(image_info,stream_info,exception);
303         status&=(images != (Image *) NULL) &&
304           (exception->severity < ErrorException);
305         if (images == (Image *) NULL)
306           continue;
307         AppendImageStack(images);
308         continue;
309       }
310     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
311     switch (*(option+1))
312     {
313       case 'a':
314       {
315         if (LocaleCompare("authenticate",option+1) == 0)
316           {
317             if (*option == '+')
318               break;
319             i++;
320             if (i == (ssize_t) (argc-1))
321               ThrowStreamException(OptionError,"MissingArgument",option);
322             break;
323           }
324         ThrowStreamException(OptionError,"UnrecognizedOption",option)
325       }
326       case 'c':
327       {
328         if (LocaleCompare("cache",option+1) == 0)
329           {
330             if (*option == '+')
331               break;
332             i++;
333             if (i == (ssize_t) argc)
334               ThrowStreamException(OptionError,"MissingArgument",option);
335             if (IsGeometry(argv[i]) == MagickFalse)
336               ThrowStreamInvalidArgumentException(option,argv[i]);
337             break;
338           }
339         if (LocaleCompare("channel",option+1) == 0)
340           {
341             ssize_t
342               channel;
343
344             if (*option == '+')
345               break;
346             i++;
347             if (i == (ssize_t) (argc-1))
348               ThrowStreamException(OptionError,"MissingArgument",option);
349             channel=ParseChannelOption(argv[i]);
350             if (channel < 0)
351               ThrowStreamException(OptionError,"UnrecognizedChannelType",
352                 argv[i]);
353             break;
354           }
355         if (LocaleCompare("colorspace",option+1) == 0)
356           {
357             ssize_t
358               colorspace;
359
360             if (*option == '+')
361               break;
362             i++;
363             if (i == (ssize_t) (argc-1))
364               ThrowStreamException(OptionError,"MissingArgument",option);
365             colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
366               argv[i]);
367             if (colorspace < 0)
368               ThrowStreamException(OptionError,"UnrecognizedColorspace",
369                 argv[i]);
370             break;
371           }
372         if (LocaleCompare("compress",option+1) == 0)
373           {
374             ssize_t
375               compress;
376
377             if (*option == '+')
378               break;
379             i++;
380             if (i == (ssize_t) (argc-1))
381               ThrowStreamException(OptionError,"MissingArgument",option);
382             compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
383               argv[i]);
384             if (compress < 0)
385               ThrowStreamException(OptionError,"UnrecognizedImageCompression",
386                 argv[i]);
387             break;
388           }
389         if (LocaleCompare("concurrent",option+1) == 0)
390           break;
391         ThrowStreamException(OptionError,"UnrecognizedOption",option)
392       }
393       case 'd':
394       {
395         if (LocaleCompare("debug",option+1) == 0)
396           {
397             ssize_t
398               event;
399
400             if (*option == '+')
401               break;
402             i++;
403             if (i == (ssize_t) argc)
404               ThrowStreamException(OptionError,"MissingArgument",option);
405             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
406             if (event < 0)
407               ThrowStreamException(OptionError,"UnrecognizedEventType",argv[i]);
408             (void) SetLogEventMask(argv[i]);
409             break;
410           }
411         if (LocaleCompare("define",option+1) == 0)
412           {
413             i++;
414             if (i == (ssize_t) argc)
415               ThrowStreamException(OptionError,"MissingArgument",option);
416             if (*option == '+')
417               {
418                 const char
419                   *define;
420
421                 define=GetImageOption(image_info,argv[i]);
422                 if (define == (const char *) NULL)
423                   ThrowStreamException(OptionError,"NoSuchOption",argv[i]);
424                 break;
425               }
426             break;
427           }
428         if (LocaleCompare("density",option+1) == 0)
429           {
430             if (*option == '+')
431               break;
432             i++;
433             if (i == (ssize_t) argc)
434               ThrowStreamException(OptionError,"MissingArgument",option);
435             if (IsGeometry(argv[i]) == MagickFalse)
436               ThrowStreamInvalidArgumentException(option,argv[i]);
437             break;
438           }
439         if (LocaleCompare("depth",option+1) == 0)
440           {
441             if (*option == '+')
442               break;
443             i++;
444             if (i == (ssize_t) argc)
445               ThrowStreamException(OptionError,"MissingArgument",option);
446             if (IsGeometry(argv[i]) == MagickFalse)
447               ThrowStreamInvalidArgumentException(option,argv[i]);
448             break;
449           }
450         if (LocaleCompare("duration",option+1) == 0)
451           {
452             if (*option == '+')
453               break;
454             i++;
455             if (i == (ssize_t) (argc-1))
456               ThrowStreamException(OptionError,"MissingArgument",option);
457             if (IsGeometry(argv[i]) == MagickFalse)
458               ThrowStreamInvalidArgumentException(option,argv[i]);
459             break;
460           }
461         ThrowStreamException(OptionError,"UnrecognizedOption",option)
462       }
463       case 'e':
464       {
465         if (LocaleCompare("extract",option+1) == 0)
466           {
467             if (*option == '+')
468               break;
469             i++;
470             if (i == (ssize_t) (argc-1))
471               ThrowStreamException(OptionError,"MissingArgument",option);
472             if (IsGeometry(argv[i]) == MagickFalse)
473               ThrowStreamInvalidArgumentException(option,argv[i]);
474             break;
475           }
476         ThrowStreamException(OptionError,"UnrecognizedOption",option)
477       }
478       case 'h':
479       {
480         if ((LocaleCompare("help",option+1) == 0) ||
481             (LocaleCompare("-help",option+1) == 0))
482           return(StreamUsage());
483         ThrowStreamException(OptionError,"UnrecognizedOption",option)
484       }
485       case 'i':
486       {
487         if (LocaleCompare("identify",option+1) == 0)
488           break;
489         if (LocaleCompare("interlace",option+1) == 0)
490           {
491             ssize_t
492               interlace;
493
494             if (*option == '+')
495               break;
496             i++;
497             if (i == (ssize_t) argc)
498               ThrowStreamException(OptionError,"MissingArgument",option);
499             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
500               argv[i]);
501             if (interlace < 0)
502               ThrowStreamException(OptionError,"UnrecognizedInterlaceType",
503                 argv[i]);
504             break;
505           }
506         if (LocaleCompare("interpolate",option+1) == 0)
507           {
508             ssize_t
509               interpolate;
510
511             if (*option == '+')
512               break;
513             i++;
514             if (i == (ssize_t) argc)
515               ThrowStreamException(OptionError,"MissingArgument",option);
516             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
517               argv[i]);
518             if (interpolate < 0)
519               ThrowStreamException(OptionError,"UnrecognizedInterpolateMethod",
520                 argv[i]);
521             break;
522           }
523         ThrowStreamException(OptionError,"UnrecognizedOption",option)
524       }
525       case 'l':
526       {
527         if (LocaleCompare("limit",option+1) == 0)
528           {
529             char
530               *p;
531
532             double
533               value;
534
535             ssize_t
536               resource;
537
538             if (*option == '+')
539               break;
540             i++;
541             if (i == (ssize_t) argc)
542               ThrowStreamException(OptionError,"MissingArgument",option);
543             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
544               argv[i]);
545             if (resource < 0)
546               ThrowStreamException(OptionError,"UnrecognizedResourceType",
547                 argv[i]);
548             i++;
549             if (i == (ssize_t) argc)
550               ThrowStreamException(OptionError,"MissingArgument",option);
551             value=StringToDouble(argv[i],&p);
552             (void) value;
553             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
554               ThrowStreamInvalidArgumentException(option,argv[i]);
555             break;
556           }
557         if (LocaleCompare("list",option+1) == 0)
558           {
559             ssize_t
560               list;
561
562             if (*option == '+')
563               break;
564             i++;
565             if (i == (ssize_t) argc)
566               ThrowStreamException(OptionError,"MissingArgument",option);
567             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
568             if (list < 0)
569               ThrowStreamException(OptionError,"UnrecognizedListType",argv[i]);
570             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
571               argv+j,exception);
572             DestroyStream();
573             return(status != 0 ? MagickFalse : MagickTrue);
574           }
575         if (LocaleCompare("log",option+1) == 0)
576           {
577             if (*option == '+')
578               break;
579             i++;
580             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
581               ThrowStreamException(OptionError,"MissingArgument",option);
582             break;
583           }
584         ThrowStreamException(OptionError,"UnrecognizedOption",option)
585       }
586       case 'm':
587       {
588         if (LocaleCompare("map",option+1) == 0)
589           {
590             (void) CopyMagickString(argv[i]+1,"san",MaxTextExtent);
591             if (*option == '+')
592               break;
593             i++;
594             SetStreamInfoMap(stream_info,argv[i]);
595             break;
596           }
597         if (LocaleCompare("monitor",option+1) == 0)
598           break;
599         ThrowStreamException(OptionError,"UnrecognizedOption",option)
600       }
601       case 'q':
602       {
603         if (LocaleCompare("quantize",option+1) == 0)
604           {
605             ssize_t
606               colorspace;
607
608             if (*option == '+')
609               break;
610             i++;
611             if (i == (ssize_t) (argc-1))
612               ThrowStreamException(OptionError,"MissingArgument",option);
613             colorspace=ParseCommandOption(MagickColorspaceOptions,
614               MagickFalse,argv[i]);
615             if (colorspace < 0)
616               ThrowStreamException(OptionError,"UnrecognizedColorspace",
617                 argv[i]);
618             break;
619           }
620         if (LocaleCompare("quiet",option+1) == 0)
621           break;
622         ThrowStreamException(OptionError,"UnrecognizedOption",option)
623       }
624       case 'r':
625       {
626         if (LocaleCompare("regard-warnings",option+1) == 0)
627           break;
628         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
629           {
630             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
631             break;
632           }
633         ThrowStreamException(OptionError,"UnrecognizedOption",option)
634       }
635       case 's':
636       {
637         if (LocaleCompare("sampling-factor",option+1) == 0)
638           {
639             if (*option == '+')
640               break;
641             i++;
642             if (i == (ssize_t) argc)
643               ThrowStreamException(OptionError,"MissingArgument",option);
644             if (IsGeometry(argv[i]) == MagickFalse)
645               ThrowStreamInvalidArgumentException(option,argv[i]);
646             break;
647           }
648         if (LocaleCompare("seed",option+1) == 0)
649           {
650             if (*option == '+')
651               break;
652             i++;
653             if (i == (ssize_t) (argc-1))
654               ThrowStreamException(OptionError,"MissingArgument",option);
655             if (IsGeometry(argv[i]) == MagickFalse)
656               ThrowStreamInvalidArgumentException(option,argv[i]);
657             break;
658           }
659         if (LocaleCompare("set",option+1) == 0)
660           {
661             i++;
662             if (i == (ssize_t) argc)
663               ThrowStreamException(OptionError,"MissingArgument",option);
664             if (*option == '+')
665               break;
666             i++;
667             if (i == (ssize_t) argc)
668               ThrowStreamException(OptionError,"MissingArgument",option);
669             break;
670           }
671         if (LocaleCompare("size",option+1) == 0)
672           {
673             if (*option == '+')
674               break;
675             i++;
676             if (i == (ssize_t) argc)
677               ThrowStreamException(OptionError,"MissingArgument",option);
678             if (IsGeometry(argv[i]) == MagickFalse)
679               ThrowStreamInvalidArgumentException(option,argv[i]);
680             break;
681           }
682         if (LocaleCompare("storage-type",option+1) == 0)
683           {
684             ssize_t
685               type;
686
687             if (*option == '+')
688               break;
689             i++;
690             if (i == (ssize_t) (argc-1))
691               ThrowStreamException(OptionError,"MissingArgument",option);
692             type=ParseCommandOption(MagickStorageOptions,MagickFalse,argv[i]);
693             if (type < 0)
694               ThrowStreamException(OptionError,"UnrecognizedStorageType",
695                 argv[i]);
696             SetStreamInfoStorageType(stream_info,(StorageType) type);
697             break;
698           }
699         if (LocaleCompare("synchronize",option+1) == 0)
700           break;
701         ThrowStreamException(OptionError,"UnrecognizedOption",option)
702       }
703       case 't':
704       {
705         if (LocaleCompare("taint",option+1) == 0)
706           break;
707         if (LocaleCompare("transparent-color",option+1) == 0)
708           {
709             if (*option == '+')
710               break;
711             i++;
712             if (i == (ssize_t) (argc-1))
713               ThrowStreamException(OptionError,"MissingArgument",option);
714             break;
715           }
716         ThrowStreamException(OptionError,"UnrecognizedOption",option)
717       }
718       case 'v':
719       {
720         if (LocaleCompare("verbose",option+1) == 0)
721           break;
722         if ((LocaleCompare("version",option+1) == 0) ||
723             (LocaleCompare("-version",option+1) == 0))
724           {
725             (void) FormatLocaleFile(stdout,"Version: %s\n",
726               GetMagickVersion((size_t *) NULL));
727             (void) FormatLocaleFile(stdout,"Copyright: %s\n",
728               GetMagickCopyright());
729             (void) FormatLocaleFile(stdout,"Features: %s\n\n",
730               GetMagickFeatures());
731             break;
732           }
733         if (LocaleCompare("virtual-pixel",option+1) == 0)
734           {
735             ssize_t
736               method;
737
738             if (*option == '+')
739               break;
740             i++;
741             if (i == (ssize_t) (argc-1))
742               ThrowStreamException(OptionError,"MissingArgument",option);
743             method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
744               argv[i]);
745             if (method < 0)
746               ThrowStreamException(OptionError,
747                 "UnrecognizedVirtualPixelMethod",argv[i]);
748             break;
749           }
750         ThrowStreamException(OptionError,"UnrecognizedOption",option)
751       }
752       case '?':
753         break;
754       default:
755         ThrowStreamException(OptionError,"UnrecognizedOption",option)
756     }
757     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
758       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
759     if (fire != MagickFalse)
760       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
761   }
762   if (k != 0)
763     ThrowStreamException(OptionError,"UnbalancedParenthesis",argv[i]);
764   if (i-- != (ssize_t) (argc-1))
765     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
766   if (image == (Image *) NULL)
767     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
768   FinalizeImageSettings(image_info,image,MagickTrue);
769   if (image == (Image *) NULL)
770     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
771   DestroyStream();
772   return(status != 0 ? MagickTrue : MagickFalse);
773 }