]> granicus.if.org Git - imagemagick/blob - wand/stream.c
162e4befd211385fd3ef84f8690d6ac93fa0b848
[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) fprintf(stdout,"Version: %s\n",
235             GetMagickVersion((size_t *) NULL));
236           (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
237           (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
238           return(MagickFalse);
239         }
240     }
241   if (argc < 3)
242     return(StreamUsage());
243   format="%w,%h,%m";
244   (void) format;
245   j=1;
246   k=0;
247   NewImageStack();
248   option=(char *) NULL;
249   pend=MagickFalse;
250   respect_parenthesis=MagickFalse;
251   stream_info=AcquireStreamInfo(image_info);
252   status=MagickTrue;
253   /*
254     Stream an image.
255   */
256   ReadCommandlLine(argc,&argv);
257   status=ExpandFilenames(&argc,&argv);
258   if (status == MagickFalse)
259     ThrowStreamException(ResourceLimitError,"MemoryAllocationFailed",
260       GetExceptionMessage(errno));
261   status=OpenStream(image_info,stream_info,argv[argc-1],exception);
262   if (status == MagickFalse)
263     {
264       DestroyStream();
265       return(MagickFalse);
266     }
267   for (i=1; i < (ssize_t) (argc-1); i++)
268   {
269     option=argv[i];
270     if (LocaleCompare(option,"(") == 0)
271       {
272         FireImageStack(MagickFalse,MagickTrue,pend);
273         if (k == MaxImageStackDepth)
274           ThrowStreamException(OptionError,"ParenthesisNestedTooDeeply",option);
275         PushImageStack();
276         continue;
277       }
278     if (LocaleCompare(option,")") == 0)
279       {
280         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
281         if (k == 0)
282           ThrowStreamException(OptionError,"UnableToParseExpression",option);
283         PopImageStack();
284         continue;
285       }
286     if (IsMagickOption(option) == MagickFalse)
287       {
288         Image
289           *images;
290
291         /*
292           Stream input image.
293         */
294         FireImageStack(MagickFalse,MagickFalse,pend);
295         filename=argv[i];
296         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
297           filename=argv[++i];
298         (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
299         images=StreamImage(image_info,stream_info,exception);
300         status&=(images != (Image *) NULL) &&
301           (exception->severity < ErrorException);
302         if (images == (Image *) NULL)
303           continue;
304         AppendImageStack(images);
305         continue;
306       }
307     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
308     switch (*(option+1))
309     {
310       case 'a':
311       {
312         if (LocaleCompare("authenticate",option+1) == 0)
313           {
314             if (*option == '+')
315               break;
316             i++;
317             if (i == (ssize_t) (argc-1))
318               ThrowStreamException(OptionError,"MissingArgument",option);
319             break;
320           }
321         ThrowStreamException(OptionError,"UnrecognizedOption",option)
322       }
323       case 'c':
324       {
325         if (LocaleCompare("cache",option+1) == 0)
326           {
327             if (*option == '+')
328               break;
329             i++;
330             if (i == (ssize_t) argc)
331               ThrowStreamException(OptionError,"MissingArgument",option);
332             if (IsGeometry(argv[i]) == MagickFalse)
333               ThrowStreamInvalidArgumentException(option,argv[i]);
334             break;
335           }
336         if (LocaleCompare("channel",option+1) == 0)
337           {
338             ssize_t
339               channel;
340
341             if (*option == '+')
342               break;
343             i++;
344             if (i == (ssize_t) (argc-1))
345               ThrowStreamException(OptionError,"MissingArgument",option);
346             channel=ParseChannelOption(argv[i]);
347             if (channel < 0)
348               ThrowStreamException(OptionError,"UnrecognizedChannelType",
349                 argv[i]);
350             break;
351           }
352         if (LocaleCompare("colorspace",option+1) == 0)
353           {
354             ssize_t
355               colorspace;
356
357             if (*option == '+')
358               break;
359             i++;
360             if (i == (ssize_t) (argc-1))
361               ThrowStreamException(OptionError,"MissingArgument",option);
362             colorspace=ParseMagickOption(MagickColorspaceOptions,MagickFalse,
363               argv[i]);
364             if (colorspace < 0)
365               ThrowStreamException(OptionError,"UnrecognizedColorspace",
366                 argv[i]);
367             break;
368           }
369         if (LocaleCompare("compress",option+1) == 0)
370           {
371             ssize_t
372               compress;
373
374             if (*option == '+')
375               break;
376             i++;
377             if (i == (ssize_t) (argc-1))
378               ThrowStreamException(OptionError,"MissingArgument",option);
379             compress=ParseMagickOption(MagickCompressOptions,MagickFalse,
380               argv[i]);
381             if (compress < 0)
382               ThrowStreamException(OptionError,"UnrecognizedImageCompression",
383                 argv[i]);
384             break;
385           }
386         if (LocaleCompare("concurrent",option+1) == 0)
387           break;
388         ThrowStreamException(OptionError,"UnrecognizedOption",option)
389       }
390       case 'd':
391       {
392         if (LocaleCompare("debug",option+1) == 0)
393           {
394             ssize_t
395               event;
396
397             if (*option == '+')
398               break;
399             i++;
400             if (i == (ssize_t) argc)
401               ThrowStreamException(OptionError,"MissingArgument",option);
402             event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]);
403             if (event < 0)
404               ThrowStreamException(OptionError,"UnrecognizedEventType",argv[i]);
405             (void) SetLogEventMask(argv[i]);
406             break;
407           }
408         if (LocaleCompare("define",option+1) == 0)
409           {
410             i++;
411             if (i == (ssize_t) argc)
412               ThrowStreamException(OptionError,"MissingArgument",option);
413             if (*option == '+')
414               {
415                 const char
416                   *define;
417
418                 define=GetImageOption(image_info,argv[i]);
419                 if (define == (const char *) NULL)
420                   ThrowStreamException(OptionError,"NoSuchOption",argv[i]);
421                 break;
422               }
423             break;
424           }
425         if (LocaleCompare("density",option+1) == 0)
426           {
427             if (*option == '+')
428               break;
429             i++;
430             if (i == (ssize_t) argc)
431               ThrowStreamException(OptionError,"MissingArgument",option);
432             if (IsGeometry(argv[i]) == MagickFalse)
433               ThrowStreamInvalidArgumentException(option,argv[i]);
434             break;
435           }
436         if (LocaleCompare("depth",option+1) == 0)
437           {
438             if (*option == '+')
439               break;
440             i++;
441             if (i == (ssize_t) argc)
442               ThrowStreamException(OptionError,"MissingArgument",option);
443             if (IsGeometry(argv[i]) == MagickFalse)
444               ThrowStreamInvalidArgumentException(option,argv[i]);
445             break;
446           }
447         if (LocaleCompare("duration",option+1) == 0)
448           {
449             if (*option == '+')
450               break;
451             i++;
452             if (i == (ssize_t) (argc-1))
453               ThrowStreamException(OptionError,"MissingArgument",option);
454             if (IsGeometry(argv[i]) == MagickFalse)
455               ThrowStreamInvalidArgumentException(option,argv[i]);
456             break;
457           }
458         ThrowStreamException(OptionError,"UnrecognizedOption",option)
459       }
460       case 'e':
461       {
462         if (LocaleCompare("extract",option+1) == 0)
463           {
464             if (*option == '+')
465               break;
466             i++;
467             if (i == (ssize_t) (argc-1))
468               ThrowStreamException(OptionError,"MissingArgument",option);
469             if (IsGeometry(argv[i]) == MagickFalse)
470               ThrowStreamInvalidArgumentException(option,argv[i]);
471             break;
472           }
473         ThrowStreamException(OptionError,"UnrecognizedOption",option)
474       }
475       case 'h':
476       {
477         if ((LocaleCompare("help",option+1) == 0) ||
478             (LocaleCompare("-help",option+1) == 0))
479           return(StreamUsage());
480         ThrowStreamException(OptionError,"UnrecognizedOption",option)
481       }
482       case 'i':
483       {
484         if (LocaleCompare("identify",option+1) == 0)
485           break;
486         if (LocaleCompare("interlace",option+1) == 0)
487           {
488             ssize_t
489               interlace;
490
491             if (*option == '+')
492               break;
493             i++;
494             if (i == (ssize_t) argc)
495               ThrowStreamException(OptionError,"MissingArgument",option);
496             interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
497               argv[i]);
498             if (interlace < 0)
499               ThrowStreamException(OptionError,"UnrecognizedInterlaceType",
500                 argv[i]);
501             break;
502           }
503         if (LocaleCompare("interpolate",option+1) == 0)
504           {
505             ssize_t
506               interpolate;
507
508             if (*option == '+')
509               break;
510             i++;
511             if (i == (ssize_t) argc)
512               ThrowStreamException(OptionError,"MissingArgument",option);
513             interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
514               argv[i]);
515             if (interpolate < 0)
516               ThrowStreamException(OptionError,"UnrecognizedInterpolateMethod",
517                 argv[i]);
518             break;
519           }
520         ThrowStreamException(OptionError,"UnrecognizedOption",option)
521       }
522       case 'l':
523       {
524         if (LocaleCompare("limit",option+1) == 0)
525           {
526             char
527               *p;
528
529             double
530               value;
531
532             ssize_t
533               resource;
534
535             if (*option == '+')
536               break;
537             i++;
538             if (i == (ssize_t) argc)
539               ThrowStreamException(OptionError,"MissingArgument",option);
540             resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
541               argv[i]);
542             if (resource < 0)
543               ThrowStreamException(OptionError,"UnrecognizedResourceType",
544                 argv[i]);
545             i++;
546             if (i == (ssize_t) argc)
547               ThrowStreamException(OptionError,"MissingArgument",option);
548             value=strtod(argv[i],&p);
549             (void) value;
550             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
551               ThrowStreamInvalidArgumentException(option,argv[i]);
552             break;
553           }
554         if (LocaleCompare("list",option+1) == 0)
555           {
556             ssize_t
557               list;
558
559             if (*option == '+')
560               break;
561             i++;
562             if (i == (ssize_t) argc)
563               ThrowStreamException(OptionError,"MissingArgument",option);
564             list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
565             if (list < 0)
566               ThrowStreamException(OptionError,"UnrecognizedListType",argv[i]);
567             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
568               argv+j,exception);
569             DestroyStream();
570             return(status != 0 ? MagickFalse : MagickTrue);
571           }
572         if (LocaleCompare("log",option+1) == 0)
573           {
574             if (*option == '+')
575               break;
576             i++;
577             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
578               ThrowStreamException(OptionError,"MissingArgument",option);
579             break;
580           }
581         ThrowStreamException(OptionError,"UnrecognizedOption",option)
582       }
583       case 'm':
584       {
585         if (LocaleCompare("map",option+1) == 0)
586           {
587             (void) CopyMagickString(argv[i]+1,"san",MaxTextExtent);
588             if (*option == '+')
589               break;
590             i++;
591             SetStreamInfoMap(stream_info,argv[i]);
592             break;
593           }
594         if (LocaleCompare("monitor",option+1) == 0)
595           break;
596         ThrowStreamException(OptionError,"UnrecognizedOption",option)
597       }
598       case 'q':
599       {
600         if (LocaleCompare("quantize",option+1) == 0)
601           {
602             ssize_t
603               colorspace;
604
605             if (*option == '+')
606               break;
607             i++;
608             if (i == (ssize_t) (argc-1))
609               ThrowStreamException(OptionError,"MissingArgument",option);
610             colorspace=ParseMagickOption(MagickColorspaceOptions,
611               MagickFalse,argv[i]);
612             if (colorspace < 0)
613               ThrowStreamException(OptionError,"UnrecognizedColorspace",
614                 argv[i]);
615             break;
616           }
617         if (LocaleCompare("quiet",option+1) == 0)
618           break;
619         ThrowStreamException(OptionError,"UnrecognizedOption",option)
620       }
621       case 'r':
622       {
623         if (LocaleCompare("regard-warnings",option+1) == 0)
624           break;
625         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
626           {
627             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
628             break;
629           }
630         ThrowStreamException(OptionError,"UnrecognizedOption",option)
631       }
632       case 's':
633       {
634         if (LocaleCompare("sampling-factor",option+1) == 0)
635           {
636             if (*option == '+')
637               break;
638             i++;
639             if (i == (ssize_t) argc)
640               ThrowStreamException(OptionError,"MissingArgument",option);
641             if (IsGeometry(argv[i]) == MagickFalse)
642               ThrowStreamInvalidArgumentException(option,argv[i]);
643             break;
644           }
645         if (LocaleCompare("seed",option+1) == 0)
646           {
647             if (*option == '+')
648               break;
649             i++;
650             if (i == (ssize_t) (argc-1))
651               ThrowStreamException(OptionError,"MissingArgument",option);
652             if (IsGeometry(argv[i]) == MagickFalse)
653               ThrowStreamInvalidArgumentException(option,argv[i]);
654             break;
655           }
656         if (LocaleCompare("set",option+1) == 0)
657           {
658             i++;
659             if (i == (ssize_t) argc)
660               ThrowStreamException(OptionError,"MissingArgument",option);
661             if (*option == '+')
662               break;
663             i++;
664             if (i == (ssize_t) argc)
665               ThrowStreamException(OptionError,"MissingArgument",option);
666             break;
667           }
668         if (LocaleCompare("size",option+1) == 0)
669           {
670             if (*option == '+')
671               break;
672             i++;
673             if (i == (ssize_t) argc)
674               ThrowStreamException(OptionError,"MissingArgument",option);
675             if (IsGeometry(argv[i]) == MagickFalse)
676               ThrowStreamInvalidArgumentException(option,argv[i]);
677             break;
678           }
679         if (LocaleCompare("storage-type",option+1) == 0)
680           {
681             ssize_t
682               type;
683
684             if (*option == '+')
685               break;
686             i++;
687             if (i == (ssize_t) (argc-1))
688               ThrowStreamException(OptionError,"MissingArgument",option);
689             type=ParseMagickOption(MagickStorageOptions,MagickFalse,argv[i]);
690             if (type < 0)
691               ThrowStreamException(OptionError,"UnrecognizedStorageType",
692                 argv[i]);
693             SetStreamInfoStorageType(stream_info,(StorageType) type);
694             break;
695           }
696         if (LocaleCompare("synchronize",option+1) == 0)
697           break;
698         ThrowStreamException(OptionError,"UnrecognizedOption",option)
699       }
700       case 't':
701       {
702         if (LocaleCompare("taint",option+1) == 0)
703           break;
704         if (LocaleCompare("transparent-color",option+1) == 0)
705           {
706             if (*option == '+')
707               break;
708             i++;
709             if (i == (ssize_t) (argc-1))
710               ThrowStreamException(OptionError,"MissingArgument",option);
711             break;
712           }
713         ThrowStreamException(OptionError,"UnrecognizedOption",option)
714       }
715       case 'v':
716       {
717         if (LocaleCompare("verbose",option+1) == 0)
718           break;
719         if ((LocaleCompare("version",option+1) == 0) ||
720             (LocaleCompare("-version",option+1) == 0))
721           {
722             (void) fprintf(stdout,"Version: %s\n",
723               GetMagickVersion((size_t *) NULL));
724             (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
725             (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
726             break;
727           }
728         if (LocaleCompare("virtual-pixel",option+1) == 0)
729           {
730             ssize_t
731               method;
732
733             if (*option == '+')
734               break;
735             i++;
736             if (i == (ssize_t) (argc-1))
737               ThrowStreamException(OptionError,"MissingArgument",option);
738             method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
739               argv[i]);
740             if (method < 0)
741               ThrowStreamException(OptionError,
742                 "UnrecognizedVirtualPixelMethod",argv[i]);
743             break;
744           }
745         ThrowStreamException(OptionError,"UnrecognizedOption",option)
746       }
747       case '?':
748         break;
749       default:
750         ThrowStreamException(OptionError,"UnrecognizedOption",option)
751     }
752     fire=(ParseMagickOption(MagickCommandOptions,MagickFalse,option)
753             &FireOption) == 0 ?  MagickFalse : MagickTrue;
754     if (fire != MagickFalse)
755       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
756   }
757   if (k != 0)
758     ThrowStreamException(OptionError,"UnbalancedParenthesis",argv[i]);
759   if (i-- != (ssize_t) (argc-1))
760     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
761   if (image == (Image *) NULL)
762     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
763   FinalizeImageSettings(image_info,image,MagickTrue);
764   if (image == (Image *) NULL)
765     ThrowStreamException(OptionError,"MissingAnImageFilename",argv[i]);
766   DestroyStream();
767   return(status != 0 ? MagickTrue : MagickFalse);
768 }