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-2016 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      "-channel mask        set the image channel mask",
111      "-grayscale method    convert image to grayscale",
112      "-negate              replace every pixel with its complementary color ",
113      (char *) NULL
114    },
115    *settings[]=
116    {
117      "-alpha option        on, activate, off, deactivate, set, opaque, copy",
118      "                     transparent, extract, background, or shape",
119      "-antialias           remove pixel-aliasing",
120      "-authenticate password",
121      "                     decipher image with this password",
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      "-matte               store matte channel if the image has one",
141      "-moments             report image moments",
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      "-read-mask filename  associate a read mask with the image",
147      "-regard-warnings     pay attention to warning messages",
148      "-respect-parentheses settings remain in effect until parenthesis boundary",
149      "-sampling-factor geometry",
150      "                     horizontal and vertical sampling factor",
151      "-seed value          seed a new sequence of pseudo-random numbers",
152      "-set attribute value set an image attribute",
153      "-size geometry       width and height of image",
154      "-strip               strip image of all profiles and comments",
155      "-unique              display the number of unique colors in the image",
156      "-units type          the units of image resolution",
157      "-verbose             print detailed information about the image",
158      "-virtual-pixel method",
159      "                     virtual pixel access method",
160      (char *) NULL
161    };
162
163  ListMagickVersion(stdout);
164  (void) printf("Usage: %s [options ...] file [ [options ...] "
165    "file ... ]\n",GetClientName());
166  (void) printf("\nImage Settings:\n");
167  for (p=settings; *p != (char *) NULL; p++)
168    (void) printf("  %s\n",*p);
169  (void) printf("\nImage Operators:\n");
170  for (p=operators; *p != (char *) NULL; p++)
171    (void) printf("  %s\n",*p);
172  (void) printf("\nMiscellaneous Options:\n");
173  for (p=miscellaneous; *p != (char *) NULL; p++)
174    (void) printf("  %s\n",*p);
175  (void) printf(
176    "\nBy default, the image format of 'file' is determined by its magic\n");
177  (void) printf(
178    "number.  To specify a particular image format, precede the filename\n");
179  (void) printf(
180    "with an image format name and a colon (i.e. ps:image) or specify the\n");
181  (void) printf(
182    "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
183  (void) printf("'-' for standard input or output.\n");
184  return(MagickFalse);
185}
186
187WandExport MagickBooleanType IdentifyImageCommand(ImageInfo *image_info,
188  int argc,char **argv,char **metadata,ExceptionInfo *exception)
189{
190#define DestroyIdentify() \
191{ \
192  DestroyImageStack(); \
193  for (i=0; i < (ssize_t) argc; i++) \
194    argv[i]=DestroyString(argv[i]); \
195  argv=(char **) RelinquishMagickMemory(argv); \
196}
197#define ThrowIdentifyException(asperity,tag,option) \
198{ \
199  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
200    option); \
201  DestroyIdentify(); \
202  return(MagickFalse); \
203}
204#define ThrowIdentifyInvalidArgumentException(option,argument) \
205{ \
206  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
207    "InvalidArgument","'%s': %s",option,argument); \
208  DestroyIdentify(); \
209  return(MagickFalse); \
210}
211
212  const char
213    *format,
214    *option;
215
216  Image
217    *image;
218
219  ImageStack
220    image_stack[MaxImageStackDepth+1];
221
222  MagickBooleanType
223    fire,
224    pend,
225    respect_parenthesis;
226
227  MagickStatusType
228    status;
229
230  register ssize_t
231    i;
232
233  size_t
234    count;
235
236  ssize_t
237    j,
238    k;
239
240  /*
241    Set defaults.
242  */
243  assert(image_info != (ImageInfo *) NULL);
244  assert(image_info->signature == MagickCoreSignature);
245  if (image_info->debug != MagickFalse)
246    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
247  assert(exception != (ExceptionInfo *) NULL);
248  if (argc == 2)
249    {
250      option=argv[1];
251      if ((LocaleCompare("version",option+1) == 0) ||
252          (LocaleCompare("-version",option+1) == 0))
253        {
254          ListMagickVersion(stdout);
255          return(MagickTrue);
256        }
257    }
258  if (argc < 2)
259    return(IdentifyUsage());
260  count=0;
261  format=NULL;
262  j=1;
263  k=0;
264  NewImageStack();
265  option=(char *) NULL;
266  pend=MagickFalse;
267  respect_parenthesis=MagickFalse;
268  status=MagickTrue;
269  /*
270    Identify an image.
271  */
272  ReadCommandlLine(argc,&argv);
273  status=ExpandFilenames(&argc,&argv);
274  if (status == MagickFalse)
275    ThrowIdentifyException(ResourceLimitError,"MemoryAllocationFailed",
276      GetExceptionMessage(errno));
277  image_info->ping=MagickTrue;
278  for (i=1; i < (ssize_t) argc; i++)
279  {
280    option=argv[i];
281    if (LocaleCompare(option,"(") == 0)
282      {
283        FireImageStack(MagickFalse,MagickTrue,pend);
284        if (k == MaxImageStackDepth)
285          ThrowIdentifyException(OptionError,"ParenthesisNestedTooDeeply",
286            option);
287        PushImageStack();
288        continue;
289      }
290    if (LocaleCompare(option,")") == 0)
291      {
292        FireImageStack(MagickFalse,MagickTrue,MagickTrue);
293        if (k == 0)
294          ThrowIdentifyException(OptionError,"UnableToParseExpression",option);
295        PopImageStack();
296        continue;
297      }
298    if (IsCommandOption(option) == MagickFalse)
299      {
300        char
301          *filename;
302
303        Image
304          *images;
305
306        ImageInfo
307          *identify_info;
308
309        /*
310          Read input image.
311        */
312        FireImageStack(MagickFalse,MagickFalse,pend);
313        identify_info=CloneImageInfo(image_info);
314        identify_info->verbose=MagickFalse;
315        filename=argv[i];
316        if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
317          filename=argv[++i];
318        if (identify_info->ping != MagickFalse)
319          images=PingImages(identify_info,filename,exception);
320        else
321          images=ReadImages(identify_info,filename,exception);
322        identify_info=DestroyImageInfo(identify_info);
323        status&=(images != (Image *) NULL) &&
324          (exception->severity < ErrorException);
325        if (images == (Image *) NULL)
326          continue;
327        AppendImageStack(images);
328        FinalizeImageSettings(image_info,image,MagickFalse);
329        count=0;
330        for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
331        {
332          if (image->scene == 0)
333            image->scene=count++;
334          if (format == (char *) NULL)
335            {
336              (void) IdentifyImage(image,stdout,image_info->verbose,exception);
337              continue;
338            }
339          if (metadata != (char **) NULL)
340            {
341              char
342                *text;
343
344              text=InterpretImageProperties(image_info,image,format,exception);
345              if (text == (char *) NULL)
346                ThrowIdentifyException(ResourceLimitError,
347                  "MemoryAllocationFailed",GetExceptionMessage(errno));
348              (void) ConcatenateString(&(*metadata),text);
349              text=DestroyString(text);
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)
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)
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)
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)
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)
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)
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],15) == 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)
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)
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)
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)
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)
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)
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)
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 ? MagickTrue : MagickFalse);
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)
758              ThrowIdentifyException(OptionError,"MissingArgument",option);
759            break;
760          }
761        if (LocaleCompare("matte",option+1) == 0)
762          break;
763        if (LocaleCompare("moments",option+1) == 0)
764          break;
765        if (LocaleCompare("monitor",option+1) == 0)
766          break;
767        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
768      }
769      case 'n':
770      {
771        if (LocaleCompare("negate",option+1) == 0)
772          break;
773        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
774      }
775      case 'p':
776      {
777        if (LocaleCompare("ping",option+1) == 0)
778          break;
779        if (LocaleCompare("precision",option+1) == 0)
780          {
781            if (*option == '+')
782              break;
783            i++;
784            if (i == (ssize_t) argc)
785              ThrowIdentifyException(OptionError,"MissingArgument",option);
786            if (IsGeometry(argv[i]) == MagickFalse)
787              ThrowIdentifyInvalidArgumentException(option,argv[i]);
788            break;
789          }
790        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
791      }
792      case 'q':
793      {
794        if (LocaleCompare("quiet",option+1) == 0)
795          break;
796        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
797      }
798      case 'r':
799      {
800        if (LocaleCompare("regard-warnings",option+1) == 0)
801          break;
802        if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
803          {
804            respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
805            break;
806          }
807        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
808      }
809      case 's':
810      {
811        if (LocaleCompare("sampling-factor",option+1) == 0)
812          {
813            if (*option == '+')
814              break;
815            i++;
816            if (i == (ssize_t) argc)
817              ThrowIdentifyException(OptionError,"MissingArgument",option);
818            if (IsGeometry(argv[i]) == MagickFalse)
819              ThrowIdentifyInvalidArgumentException(option,argv[i]);
820            break;
821          }
822        if (LocaleCompare("seed",option+1) == 0)
823          {
824            if (*option == '+')
825              break;
826            i++;
827            if (i == (ssize_t) argc)
828              ThrowIdentifyException(OptionError,"MissingArgument",option);
829            if (IsGeometry(argv[i]) == MagickFalse)
830              ThrowIdentifyInvalidArgumentException(option,argv[i]);
831            break;
832          }
833        if (LocaleCompare("set",option+1) == 0)
834          {
835            i++;
836            if (i == (ssize_t) argc)
837              ThrowIdentifyException(OptionError,"MissingArgument",option);
838            if (*option == '+')
839              break;
840            i++;
841            if (i == (ssize_t) argc)
842              ThrowIdentifyException(OptionError,"MissingArgument",option);
843            break;
844          }
845        if (LocaleCompare("size",option+1) == 0)
846          {
847            if (*option == '+')
848              break;
849            i++;
850            if (i == (ssize_t) argc)
851              ThrowIdentifyException(OptionError,"MissingArgument",option);
852            if (IsGeometry(argv[i]) == MagickFalse)
853              ThrowIdentifyInvalidArgumentException(option,argv[i]);
854            break;
855          }
856        if (LocaleCompare("strip",option+1) == 0)
857          break;
858        if (LocaleCompare("support",option+1) == 0)
859          {
860            if (*option == '+')
861              break;
862            i++;
863            if (i == (ssize_t) argc)
864              ThrowIdentifyException(OptionError,"MissingArgument",option);
865            if (IsGeometry(argv[i]) == MagickFalse)
866              ThrowIdentifyInvalidArgumentException(option,argv[i]);
867            break;
868          }
869        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
870      }
871      case 'u':
872      {
873        if (LocaleCompare("unique",option+1) == 0)
874          break;
875        if (LocaleCompare("units",option+1) == 0)
876          {
877            ssize_t
878              units;
879
880            if (*option == '+')
881              break;
882            i++;
883            if (i == (ssize_t) argc)
884              ThrowIdentifyException(OptionError,"MissingArgument",option);
885            units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
886              argv[i]);
887            if (units < 0)
888              ThrowIdentifyException(OptionError,"UnrecognizedUnitsType",
889                argv[i]);
890            break;
891          }
892        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
893      }
894      case 'v':
895      {
896        if (LocaleCompare("verbose",option+1) == 0)
897          break;
898        if (LocaleCompare("virtual-pixel",option+1) == 0)
899          {
900            ssize_t
901              method;
902
903            if (*option == '+')
904              break;
905            i++;
906            if (i == (ssize_t) argc)
907              ThrowIdentifyException(OptionError,"MissingArgument",option);
908            method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
909              argv[i]);
910            if (method < 0)
911              ThrowIdentifyException(OptionError,
912                "UnrecognizedVirtualPixelMethod",argv[i]);
913            break;
914          }
915        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
916      }
917      case '?':
918        break;
919      default:
920        ThrowIdentifyException(OptionError,"UnrecognizedOption",option)
921    }
922    fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
923      FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
924    if (fire != MagickFalse)
925      FireImageStack(MagickFalse,MagickTrue,MagickTrue);
926  }
927  if (k != 0)
928    ThrowIdentifyException(OptionError,"UnbalancedParenthesis",argv[i]);
929  if (i != (ssize_t) argc)
930    ThrowIdentifyException(OptionError,"MissingAnImageFilename",argv[i]);
931  DestroyIdentify();
932  return(status != 0 ? MagickTrue : MagickFalse);
933}
934