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