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