]> granicus.if.org Git - imagemagick/blob - MagickWand/identify.c
(no commit message)
[imagemagick] / MagickWand / identify.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %           IIIII  DDDD   EEEEE  N   N  TTTTT  IIIII  FFFFF  Y   Y            %
7 %             I    D   D  E      NN  N    T      I    F       Y Y             %
8 %             I    D   D  EEE    N N N    T      I    FFF      Y              %
9 %             I    D   D  E      N  NN    T      I    F        Y              %
10 %           IIIII  DDDD   EEEEE  N   N    T    IIIII  F        Y              %
11 %                                                                             %
12 %                                                                             %
13 %               Identify an Image Format and Characteristics.                 %
14 %                                                                             %
15 %                           Software Design                                   %
16 %                             John Cristy                                     %
17 %                            September 1994                                   %
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 %  The identify program describes the format and characteristics of one or more
37 %  image files. It also reports if an image is incomplete or corrupt. The
38 %  information returned includes the image number, the file name, the width and
39 %  height of the image, whether the image is colormapped or not, the number of
40 %  colors in the image, the number of bytes in the image, the format of the
41 %  image (JPEG, PNM, etc.), and finally the number of seconds it took to read
42 %  and process the image. Many more attributes are available with the verbose
43 %  option.
44 %
45 */
46 \f
47 /*
48   Include declarations.
49 */
50 #include "MagickWand/studio.h"
51 #include "MagickWand/MagickWand.h"
52 #include "MagickWand/mogrify-private.h"
53 #include "MagickCore/string-private.h"
54 \f
55 /*
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %                                                                             %
58 %                                                                             %
59 %                                                                             %
60 +   I d e n t i f y I m a g e C o m m a n d                                   %
61 %                                                                             %
62 %                                                                             %
63 %                                                                             %
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 %
66 %  IdentifyImageCommand() describes the format and characteristics of one or
67 %  more image files. It will also report if an image is incomplete or corrupt.
68 %  The information displayed includes the scene number, the file name, the
69 %  width and height of the image, whether the image is colormapped or not,
70 %  the number of colors in the image, the number of bytes in the image, the
71 %  format of the image (JPEG, PNM, etc.), and finally the number of seconds
72 %  it took to read and process the image.
73 %
74 %  The format of the IdentifyImageCommand method is:
75 %
76 %      MagickBooleanType IdentifyImageCommand(ImageInfo *image_info,int argc,
77 %        char **argv,char **metadata,ExceptionInfo *exception)
78 %
79 %  A description of each parameter follows:
80 %
81 %    o image_info: the image info.
82 %
83 %    o argc: the number of elements in the argument vector.
84 %
85 %    o argv: A text array containing the command line arguments.
86 %
87 %    o metadata: any metadata is returned here.
88 %
89 %    o exception: return any errors or warnings in this structure.
90 %
91 */
92
93 static MagickBooleanType IdentifyUsage(void)
94 {
95   const char
96     **p;
97
98   static const char
99     *miscellaneous[]=
100     {
101       "-debug events        display copious debugging information",
102       "-help                print program options",
103       "-list type           print a list of supported option arguments",
104       "-log format          format of debugging information",
105       "-version             print version information",
106       (char *) NULL
107     },
108     *operators[]=
109     {
110       "-negate              replace every pixel with its complementary color ",
111       (char *) NULL
112     },
113     *settings[]=
114     {
115       "-alpha option        on, activate, off, deactivate, set, opaque, copy",
116       "                     transparent, extract, background, or shape",
117       "-antialias           remove pixel-aliasing",
118       "-authenticate password",
119       "                     decipher image with this password",
120       "-channel type        apply option to select image channels",
121       "-colorspace type     alternate image colorspace",
122       "-crop geometry       cut out a rectangular region of the image",
123       "-define format:option",
124       "                     define one or more image format options",
125       "-density geometry    horizontal and vertical density of the image",
126       "-depth value         image depth",
127       "-endian type         endianness (MSB or LSB) of the image",
128       "-extract geometry    extract area from image",
129       "-features distance   analyze image features (e.g. contrast, correlation)",
130       "-format \"string\"     output formatted image characteristics",
131       "-fuzz distance       colors within this distance are considered equal",
132       "-gamma value         of gamma correction",
133       "-interlace type      type of image interlacing scheme",
134       "-interpolate method  pixel color interpolation method",
135       "-limit type value    pixel cache resource limit",
136       "-mask filename       associate a mask with the image",
137       "-monitor             monitor progress",
138       "-ping                efficiently determine image attributes",
139       "-quiet               suppress all warning messages",
140       "-regard-warnings     pay attention to warning messages",
141       "-respect-parentheses settings remain in effect until parenthesis boundary",
142       "-sampling-factor geometry",
143       "                     horizontal and vertical sampling factor",
144       "-seed value          seed a new sequence of pseudo-random numbers",
145       "-set attribute value set an image attribute",
146       "-size geometry       width and height of image",
147       "-strip               strip image of all profiles and comments",
148       "-unique              display the number of unique colors in the image",
149       "-units type          the units of image resolution",
150       "-verbose             print detailed information about the image",
151       "-virtual-pixel method",
152       "                     virtual pixel access method",
153       (char *) NULL
154     };
155
156   (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
157   (void) printf("Copyright: %s\n",GetMagickCopyright());
158   (void) printf("Features: %s\n\n",GetMagickFeatures());
159   (void) printf("Usage: %s [options ...] file [ [options ...] "
160     "file ... ]\n",GetClientName());
161   (void) printf("\nImage Settings:\n");
162   for (p=settings; *p != (char *) NULL; p++)
163     (void) printf("  %s\n",*p);
164   (void) printf("\nImage Operators:\n");
165   for (p=operators; *p != (char *) NULL; p++)
166     (void) printf("  %s\n",*p);
167   (void) printf("\nMiscellaneous Options:\n");
168   for (p=miscellaneous; *p != (char *) NULL; p++)
169     (void) printf("  %s\n",*p);
170   (void) printf(
171     "\nBy default, the image format of 'file' is determined by its magic\n");
172   (void) printf(
173     "number.  To specify a particular image format, precede the filename\n");
174   (void) printf(
175     "with an image format name and a colon (i.e. ps:image) or specify the\n");
176   (void) printf(
177     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
178   (void) printf("'-' for standard input or output.\n");
179   return(MagickFalse);
180 }
181
182 WandExport MagickBooleanType IdentifyImageCommand(ImageInfo *image_info,
183   int argc,char **argv,char **metadata,ExceptionInfo *exception)
184 {
185 #define DestroyIdentify() \
186 { \
187   DestroyImageStack(); \
188   for (i=0; i < (ssize_t) argc; i++) \
189     argv[i]=DestroyString(argv[i]); \
190   argv=(char **) RelinquishMagickMemory(argv); \
191 }
192 #define ThrowIdentifyException(asperity,tag,option) \
193 { \
194   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"'%s'", \
195     option); \
196   DestroyIdentify(); \
197   return(MagickFalse); \
198 }
199 #define ThrowIdentifyInvalidArgumentException(option,argument) \
200 { \
201   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
202     "InvalidArgument","'%s': %s",option,argument); \
203   DestroyIdentify(); \
204   return(MagickFalse); \
205 }
206
207   const char
208     *format,
209     *option;
210
211   Image
212     *image;
213
214   ImageStack
215     image_stack[MaxImageStackDepth+1];
216
217   MagickBooleanType
218     fire,
219     pend,
220     respect_parenthesis;
221
222   MagickStatusType
223     status;
224
225   register ssize_t
226     i;
227
228   size_t
229     count;
230
231   ssize_t
232     j,
233     k;
234
235   /*
236     Set defaults.
237   */
238   assert(image_info != (ImageInfo *) NULL);
239   assert(image_info->signature == MagickSignature);
240   if (image_info->debug != MagickFalse)
241     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
242   assert(exception != (ExceptionInfo *) NULL);
243   if (argc == 2)
244     {
245       option=argv[1];
246       if ((LocaleCompare("version",option+1) == 0) ||
247           (LocaleCompare("-version",option+1) == 0))
248         {
249           (void) FormatLocaleFile(stdout,"Version: %s\n",
250             GetMagickVersion((size_t *) NULL));
251           (void) FormatLocaleFile(stdout,"Copyright: %s\n",
252             GetMagickCopyright());
253           (void) FormatLocaleFile(stdout,"Features: %s\n\n",
254             GetMagickFeatures());
255           return(MagickFalse);
256         }
257     }
258   if (argc < 2)
259     return(IdentifyUsage());
260   count=0;
261   format=NULL;
262   j=1;
263   k=0;
264   NewImageStack();
265   option=(char *) NULL;
266   pend=MagickFalse;
267   respect_parenthesis=MagickFalse;
268   status=MagickTrue;
269   /*
270     Identify an image.
271   */
272   ReadCommandlLine(argc,&argv);
273   status=ExpandFilenames(&argc,&argv);
274   if (status == MagickFalse)
275     ThrowIdentifyException(ResourceLimitError,"MemoryAllocationFailed",
276       GetExceptionMessage(errno));
277   image_info->ping=MagickTrue;
278   for (i=1; i < (ssize_t) argc; i++)
279   {
280     option=argv[i];
281     if (LocaleCompare(option,"(") == 0)
282       {
283         FireImageStack(MagickFalse,MagickTrue,pend);
284         if (k == MaxImageStackDepth)
285           ThrowIdentifyException(OptionError,"ParenthesisNestedTooDeeply",
286             option);
287         PushImageStack();
288         continue;
289       }
290     if (LocaleCompare(option,")") == 0)
291       {
292         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
293         if (k == 0)
294           ThrowIdentifyException(OptionError,"UnableToParseExpression",option);
295         PopImageStack();
296         continue;
297       }
298     if (IsCommandOption(option) == MagickFalse)
299       {
300         char
301           *filename;
302
303         Image
304           *images;
305
306         ImageInfo
307           *identify_info;
308
309         /*
310           Read input image.
311         */
312         FireImageStack(MagickFalse,MagickFalse,pend);
313         identify_info=CloneImageInfo(image_info);
314         identify_info->verbose=MagickFalse;
315         filename=argv[i];
316         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
317           filename=argv[++i];
318         if (identify_info->ping != MagickFalse)
319           images=PingImages(identify_info,filename,exception);
320         else
321           images=ReadImages(identify_info,filename,exception);
322         identify_info=DestroyImageInfo(identify_info);
323         status&=(images != (Image *) NULL) &&
324           (exception->severity < ErrorException);
325         if (images == (Image *) NULL)
326           continue;
327         AppendImageStack(images);
328         FinalizeImageSettings(image_info,image,MagickFalse);
329         for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
330         {
331           if (image->scene == 0)
332             image->scene=count++;
333           if (format == (char *) NULL)
334             {
335               (void) IdentifyImage(image,stdout,image_info->verbose,exception);
336               continue;
337             }
338           if (metadata != (char **) NULL)
339             {
340               char
341                 *text;
342
343               text=InterpretImageProperties(image_info,image,format,exception);
344               if (text == (char *) NULL)
345                 ThrowIdentifyException(ResourceLimitError,
346                   "MemoryAllocationFailed",GetExceptionMessage(errno));
347               (void) ConcatenateString(&(*metadata),text);
348               text=DestroyString(text);
349               if (LocaleCompare(format,"%n") == 0)
350                 break;
351             }
352         }
353         RemoveAllImageStack();
354         continue;
355       }
356     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
357     switch (*(option+1))
358     {
359       case 'a':
360       {
361         if (LocaleCompare("alpha",option+1) == 0)
362           {
363             ssize_t
364               type;
365
366             if (*option == '+')
367               break;
368             i++;
369             if (i == (ssize_t) argc)
370               ThrowIdentifyException(OptionError,"MissingArgument",option);
371             type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,
372               argv[i]);
373             if (type < 0)
374               ThrowIdentifyException(OptionError,
375                 "UnrecognizedAlphaChannelOption",argv[i]);
376             break;
377           }
378         if (LocaleCompare("antialias",option+1) == 0)
379           break;
380         if (LocaleCompare("authenticate",option+1) == 0)
381           {
382             if (*option == '+')
383               break;
384             i++;
385             if (i == (ssize_t) (argc-1))
386               ThrowIdentifyException(OptionError,"MissingArgument",option);
387             break;
388           }
389         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
390       }
391       case 'c':
392       {
393         if (LocaleCompare("cache",option+1) == 0)
394           {
395             if (*option == '+')
396               break;
397             i++;
398             if (i == (ssize_t) argc)
399               ThrowIdentifyException(OptionError,"MissingArgument",option);
400             if (IsGeometry(argv[i]) == MagickFalse)
401               ThrowIdentifyInvalidArgumentException(option,argv[i]);
402             break;
403           }
404         if (LocaleCompare("channel",option+1) == 0)
405           {
406             ssize_t
407               channel;
408
409             if (*option == '+')
410               break;
411             i++;
412             if (i == (ssize_t) (argc-1))
413               ThrowIdentifyException(OptionError,"MissingArgument",option);
414             channel=ParseChannelOption(argv[i]);
415             if (channel < 0)
416               ThrowIdentifyException(OptionError,"UnrecognizedChannelType",
417                 argv[i]);
418             break;
419           }
420         if (LocaleCompare("colorspace",option+1) == 0)
421           {
422             ssize_t
423               colorspace;
424
425             if (*option == '+')
426               break;
427             i++;
428             if (i == (ssize_t) (argc-1))
429               ThrowIdentifyException(OptionError,"MissingArgument",option);
430             colorspace=ParseCommandOption(MagickColorspaceOptions,
431               MagickFalse,argv[i]);
432             if (colorspace < 0)
433               ThrowIdentifyException(OptionError,"UnrecognizedColorspace",
434                 argv[i]);
435             break;
436           }
437         if (LocaleCompare("crop",option+1) == 0)
438           {
439             if (*option == '+')
440               break;
441             i++;
442             if (i == (ssize_t) (argc-1))
443               ThrowIdentifyException(OptionError,"MissingArgument",option);
444             if (IsGeometry(argv[i]) == MagickFalse)
445               ThrowIdentifyInvalidArgumentException(option,argv[i]);
446             image_info->ping=MagickFalse;
447             break;
448           }
449         if (LocaleCompare("concurrent",option+1) == 0)
450           break;
451         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
452       }
453       case 'd':
454       {
455         if (LocaleCompare("debug",option+1) == 0)
456           {
457             ssize_t
458               event;
459
460             if (*option == '+')
461               break;
462             i++;
463             if (i == (ssize_t) argc)
464               ThrowIdentifyException(OptionError,"MissingArgument",option);
465             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
466             if (event < 0)
467               ThrowIdentifyException(OptionError,"UnrecognizedEventType",
468                 argv[i]);
469             (void) SetLogEventMask(argv[i]);
470             break;
471           }
472         if (LocaleCompare("define",option+1) == 0)
473           {
474             i++;
475             if (i == (ssize_t) argc)
476               ThrowIdentifyException(OptionError,"MissingArgument",option);
477             if (*option == '+')
478               {
479                 const char
480                   *define;
481
482                 define=GetImageOption(image_info,argv[i]);
483                 if (define == (const char *) NULL)
484                   ThrowIdentifyException(OptionError,"NoSuchOption",argv[i]);
485                 break;
486               }
487             break;
488           }
489         if (LocaleCompare("density",option+1) == 0)
490           {
491             if (*option == '+')
492               break;
493             i++;
494             if (i == (ssize_t) argc)
495               ThrowIdentifyException(OptionError,"MissingArgument",option);
496             if (IsGeometry(argv[i]) == MagickFalse)
497               ThrowIdentifyInvalidArgumentException(option,argv[i]);
498             break;
499           }
500         if (LocaleCompare("depth",option+1) == 0)
501           {
502             if (*option == '+')
503               break;
504             i++;
505             if (i == (ssize_t) argc)
506               ThrowIdentifyException(OptionError,"MissingArgument",option);
507             if (IsGeometry(argv[i]) == MagickFalse)
508               ThrowIdentifyInvalidArgumentException(option,argv[i]);
509             break;
510           }
511         if (LocaleCompare("duration",option+1) == 0)
512           {
513             if (*option == '+')
514               break;
515             i++;
516             if (i == (ssize_t) (argc-1))
517               ThrowIdentifyException(OptionError,"MissingArgument",option);
518             if (IsGeometry(argv[i]) == MagickFalse)
519               ThrowIdentifyInvalidArgumentException(option,argv[i]);
520             break;
521           }
522         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
523       }
524       case '3':
525       {
526         if (LocaleCompare("endian",option+1) == 0)
527           {
528             ssize_t
529               endian;
530
531             if (*option == '+')
532               break;
533             i++;
534             if (i == (ssize_t) (argc-1))
535               ThrowIdentifyException(OptionError,"MissingArgument",option);
536             endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
537               argv[i]);
538             if (endian < 0)
539               ThrowIdentifyException(OptionError,"UnrecognizedEndianType",
540                 argv[i]);
541             break;
542           }
543         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
544       }
545       case 'f':
546       {
547         if (LocaleCompare("features",option+1) == 0)
548           {
549             if (*option == '+')
550               break;
551             i++;
552             if (i == (ssize_t) (argc-1))
553               ThrowIdentifyException(OptionError,"MissingArgument",option);
554             if (IsGeometry(argv[i]) == MagickFalse)
555               ThrowIdentifyInvalidArgumentException(option,argv[i]);
556             break;
557           }
558         if (LocaleCompare("format",option+1) == 0)
559           {
560             format=(char *) NULL;
561             if (*option == '+')
562               break;
563             i++;
564             if (i == (ssize_t) argc)
565               ThrowIdentifyException(OptionError,"MissingArgument",option);
566             format=argv[i];
567             break;
568           }
569         if (LocaleCompare("fuzz",option+1) == 0)
570           {
571             if (*option == '+')
572               break;
573             i++;
574             if (i == (ssize_t) (argc-1))
575               ThrowIdentifyException(OptionError,"MissingArgument",option);
576             if (IsGeometry(argv[i]) == MagickFalse)
577               ThrowIdentifyInvalidArgumentException(option,argv[i]);
578             break;
579           }
580         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
581       }
582       case 'g':
583       {
584         if (LocaleCompare("gamma",option+1) == 0)
585           {
586             i++;
587             if (i == (ssize_t) (argc-1))
588               ThrowIdentifyException(OptionError,"MissingArgument",option);
589             if (IsGeometry(argv[i]) == MagickFalse)
590               ThrowIdentifyInvalidArgumentException(option,argv[i]);
591             break;
592           }
593         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
594       }
595       case 'h':
596       {
597         if ((LocaleCompare("help",option+1) == 0) ||
598             (LocaleCompare("-help",option+1) == 0))
599           return(IdentifyUsage());
600         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
601       }
602       case 'i':
603       {
604         if (LocaleCompare("interlace",option+1) == 0)
605           {
606             ssize_t
607               interlace;
608
609             if (*option == '+')
610               break;
611             i++;
612             if (i == (ssize_t) argc)
613               ThrowIdentifyException(OptionError,"MissingArgument",option);
614             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
615               argv[i]);
616             if (interlace < 0)
617               ThrowIdentifyException(OptionError,
618                 "UnrecognizedInterlaceType",argv[i]);
619             break;
620           }
621         if (LocaleCompare("interpolate",option+1) == 0)
622           {
623             ssize_t
624               interpolate;
625
626             if (*option == '+')
627               break;
628             i++;
629             if (i == (ssize_t) argc)
630               ThrowIdentifyException(OptionError,"MissingArgument",option);
631             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
632               argv[i]);
633             if (interpolate < 0)
634               ThrowIdentifyException(OptionError,
635                 "UnrecognizedInterpolateMethod",argv[i]);
636             break;
637           }
638         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
639       }
640       case 'l':
641       {
642         if (LocaleCompare("limit",option+1) == 0)
643           {
644             char
645               *p;
646
647             double
648               value;
649
650             ssize_t
651               resource;
652
653             if (*option == '+')
654               break;
655             i++;
656             if (i == (ssize_t) argc)
657               ThrowIdentifyException(OptionError,"MissingArgument",option);
658             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
659               argv[i]);
660             if (resource < 0)
661               ThrowIdentifyException(OptionError,"UnrecognizedResourceType",
662                 argv[i]);
663             i++;
664             if (i == (ssize_t) argc)
665               ThrowIdentifyException(OptionError,"MissingArgument",option);
666             value=StringToDouble(argv[i],&p);
667             (void) value;
668             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
669               ThrowIdentifyInvalidArgumentException(option,argv[i]);
670             break;
671           }
672         if (LocaleCompare("list",option+1) == 0)
673           {
674             ssize_t
675               list;
676
677             if (*option == '+')
678               break;
679             i++;
680             if (i == (ssize_t) argc)
681               ThrowIdentifyException(OptionError,"MissingArgument",option);
682             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
683             if (list < 0)
684               ThrowIdentifyException(OptionError,"UnrecognizedListType",
685                 argv[i]);
686             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
687               argv+j,exception);
688             DestroyIdentify();
689             return(status != 0 ? MagickFalse : MagickTrue);
690           }
691         if (LocaleCompare("log",option+1) == 0)
692           {
693             if (*option == '+')
694               break;
695             i++;
696             if ((i == (ssize_t) argc) ||
697                 (strchr(argv[i],'%') == (char *) NULL))
698               ThrowIdentifyException(OptionError,"MissingArgument",option);
699             break;
700           }
701         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
702       }
703       case 'm':
704       {
705         if (LocaleCompare("mask",option+1) == 0)
706           {
707             if (*option == '+')
708               break;
709             i++;
710             if (i == (ssize_t) (argc-1))
711               ThrowIdentifyException(OptionError,"MissingArgument",option);
712             break;
713           }
714         if (LocaleCompare("matte",option+1) == 0)
715           break;
716         if (LocaleCompare("monitor",option+1) == 0)
717           break;
718         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
719       }
720       case 'n':
721       {
722         if (LocaleCompare("negate",option+1) == 0)
723           break;
724         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
725       }
726       case 'p':
727       {
728         if (LocaleCompare("ping",option+1) == 0)
729           break;
730         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
731       }
732       case 'q':
733       {
734         if (LocaleCompare("quiet",option+1) == 0)
735           break;
736         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
737       }
738       case 'r':
739       {
740         if (LocaleCompare("regard-warnings",option+1) == 0)
741           break;
742         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
743           {
744             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
745             break;
746           }
747         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
748       }
749       case 's':
750       {
751         if (LocaleCompare("sampling-factor",option+1) == 0)
752           {
753             if (*option == '+')
754               break;
755             i++;
756             if (i == (ssize_t) argc)
757               ThrowIdentifyException(OptionError,"MissingArgument",option);
758             if (IsGeometry(argv[i]) == MagickFalse)
759               ThrowIdentifyInvalidArgumentException(option,argv[i]);
760             break;
761           }
762         if (LocaleCompare("seed",option+1) == 0)
763           {
764             if (*option == '+')
765               break;
766             i++;
767             if (i == (ssize_t) (argc-1))
768               ThrowIdentifyException(OptionError,"MissingArgument",option);
769             if (IsGeometry(argv[i]) == MagickFalse)
770               ThrowIdentifyInvalidArgumentException(option,argv[i]);
771             break;
772           }
773         if (LocaleCompare("set",option+1) == 0)
774           {
775             i++;
776             if (i == (ssize_t) argc)
777               ThrowIdentifyException(OptionError,"MissingArgument",option);
778             if (*option == '+')
779               break;
780             i++;
781             if (i == (ssize_t) argc)
782               ThrowIdentifyException(OptionError,"MissingArgument",option);
783             break;
784           }
785         if (LocaleCompare("size",option+1) == 0)
786           {
787             if (*option == '+')
788               break;
789             i++;
790             if (i == (ssize_t) argc)
791               ThrowIdentifyException(OptionError,"MissingArgument",option);
792             if (IsGeometry(argv[i]) == MagickFalse)
793               ThrowIdentifyInvalidArgumentException(option,argv[i]);
794             break;
795           }
796         if (LocaleCompare("strip",option+1) == 0)
797           break;
798         if (LocaleCompare("support",option+1) == 0)
799           {
800             if (*option == '+')
801               break;
802             i++;
803             if (i == (ssize_t) argc)
804               ThrowIdentifyException(OptionError,"MissingArgument",option);
805             if (IsGeometry(argv[i]) == MagickFalse)
806               ThrowIdentifyInvalidArgumentException(option,argv[i]);
807             break;
808           }
809         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
810       }
811       case 'u':
812       {
813         if (LocaleCompare("unique",option+1) == 0)
814           break;
815         if (LocaleCompare("units",option+1) == 0)
816           {
817             ssize_t
818               units;
819
820             if (*option == '+')
821               break;
822             i++;
823             if (i == (ssize_t) (argc-1))
824               ThrowIdentifyException(OptionError,"MissingArgument",option);
825             units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
826               argv[i]);
827             if (units < 0)
828               ThrowIdentifyException(OptionError,"UnrecognizedUnitsType",
829                 argv[i]);
830             break;
831           }
832         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
833       }
834       case 'v':
835       {
836         if (LocaleCompare("verbose",option+1) == 0)
837           break;
838         if (LocaleCompare("virtual-pixel",option+1) == 0)
839           {
840             ssize_t
841               method;
842
843             if (*option == '+')
844               break;
845             i++;
846             if (i == (ssize_t) (argc-1))
847               ThrowIdentifyException(OptionError,"MissingArgument",option);
848             method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
849               argv[i]);
850             if (method < 0)
851               ThrowIdentifyException(OptionError,
852                 "UnrecognizedVirtualPixelMethod",argv[i]);
853             break;
854           }
855         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
856       }
857       case '?':
858         break;
859       default:
860         ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
861     }
862     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
863       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
864     if (fire != MagickFalse)
865       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
866   }
867   if (k != 0)
868     ThrowIdentifyException(OptionError,"UnbalancedParenthesis",argv[i]);
869   if (i != (ssize_t) argc)
870     ThrowIdentifyException(OptionError,"MissingAnImageFilename",argv[i]);
871   DestroyIdentify();
872   return(status != 0 ? MagickTrue : MagickFalse);
873 }