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