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