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