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