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