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