/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % CCCC OOO N N JJJJJ U U RRRR EEEEE % % C O O NN N J U U R R E % % C O O N N N J U U RRRR EEE % % C O O N NN J J U U R R E % % CCCC OOO N N JJJ UUU R R EEEEE % % % % % % Interpret Magick Scripting Language. % % % % Software Design % % Cristy % % December 2001 % % % % % % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % % obtain a copy of the License at % % % % https://imagemagick.org/script/license.php % % % % Unless required by applicable law or agreed to in writing, software % % distributed under the License is distributed on an "AS IS" BASIS, % % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % % See the License for the specific language governing permissions and % % limitations under the License. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The conjure program gives you the ability to perform custom image processing % tasks from a script written in the Magick Scripting Language (MSL). MSL is % XML-based and consists of action statements with attributes. Actions include % reading an image, processing an image, getting attributes from an image, % writing an image, and more. An attribute is a key/value pair that modifies % the behavior of an action. % */ /* Include declarations. */ #include "MagickWand/studio.h" #include "MagickWand/MagickWand.h" #include "MagickWand/mogrify-private.h" /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + C o n j u r e I m a g e C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ConjureImageCommand() describes the format and characteristics of one or % more image files. It will also report if an image is incomplete or corrupt. % The information displayed includes the scene number, the file name, the % width and height of the image, whether the image is colormapped or not, % the number of colors in the image, the number of bytes in the image, the % format of the image (JPEG, PNM, etc.), and finally the number of seconds % it took to read and process the image. % % The format of the ConjureImageCommand method is: % % MagickBooleanType ConjureImageCommand(ImageInfo *image_info,int argc, % char **argv,char **metadata,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o argc: the number of elements in the argument vector. % % o argv: A text array containing the command line arguments. % % o metadata: any metadata is returned here. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType ConjureUsage(void) { static const char miscellaneous[] = " -debug events display copious debugging information\n" " -help print program options\n" " -list type print a list of supported option arguments\n" " -log format format of debugging information\n" " -version print version information", settings[] = " -monitor monitor progress\n" " -quiet suppress all warning messages\n" " -regard-warnings pay attention to warning messages\n" " -seed value seed a new sequence of pseudo-random numbers\n" " -verbose print detailed information about the image"; ListMagickVersion(stdout); (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n", GetClientName()); (void) printf("\nImage Settings:\n"); (void) puts(settings); (void) printf("\nMiscellaneous Options:\n"); (void) puts(miscellaneous); (void) printf("\nIn addition, define any key value pairs required by " "your script. For\nexample,\n\n"); (void) printf(" conjure -size 100x100 -color blue -foo bar script.msl\n"); return(MagickTrue); } WandExport MagickBooleanType ConjureImageCommand(ImageInfo *image_info, int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception) { #define DestroyConjure() \ { \ image=DestroyImageList(image); \ for (i=0; i < (ssize_t) argc; i++) \ argv[i]=DestroyString(argv[i]); \ argv=(char **) RelinquishMagickMemory(argv); \ } #define ThrowConjureException(asperity,tag,option) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ option); \ DestroyConjure(); \ return(MagickFalse); \ } #define ThrowConjureInvalidArgumentException(option,argument) \ { \ (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ "InvalidArgument","'%s': %s",option,argument); \ DestroyConjure(); \ return(MagickFalse); \ } char filename[MagickPathExtent], *option; Image *image; MagickStatusType status; ssize_t i; ssize_t number_images; wand_unreferenced(metadata); /* Set defaults. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(exception != (ExceptionInfo *) NULL); if (argc < 2) return(ConjureUsage()); image=NewImageList(); number_images=0; option=(char *) NULL; /* Conjure an image. */ ReadCommandlLine(argc,&argv); status=ExpandFilenames(&argc,&argv); if (status == MagickFalse) ThrowConjureException(ResourceLimitError,"MemoryAllocationFailed", GetExceptionMessage(errno)); for (i=1; i < (ssize_t) argc; i++) { option=argv[i]; if (IsCommandOption(option) != MagickFalse) { if (LocaleCompare("concurrent",option+1) == 0) break; if (LocaleCompare("debug",option+1) == 0) { ssize_t event; if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingArgument",option); event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]); if (event < 0) ThrowConjureException(OptionError,"UnrecognizedEventType", argv[i]); (void) SetLogEventMask(argv[i]); continue; } if (LocaleCompare("duration",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowConjureInvalidArgumentException(option,argv[i]); continue; } if ((LocaleCompare("help",option+1) == 0) || (LocaleCompare("-help",option+1) == 0)) { if (*option == '-') { DestroyConjure(); return(ConjureUsage()); } continue; } if (LocaleCompare("log",option+1) == 0) { if (*option == '-') { i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingLogFormat",option); (void) SetLogFormat(argv[i]); } continue; } if (LocaleCompare("monitor",option+1) == 0) continue; if (LocaleCompare("quiet",option+1) == 0) continue; if (LocaleCompare("regard-warnings",option+1) == 0) break; if (LocaleCompare("seed",option+1) == 0) { if (*option == '+') break; i++; if (i == (ssize_t) argc) ThrowConjureException(OptionError,"MissingArgument",option); if (IsGeometry(argv[i]) == MagickFalse) ThrowConjureInvalidArgumentException(option,argv[i]); break; } if (LocaleCompare("verbose",option+1) == 0) { image_info->verbose=(*option == '-') ? MagickTrue : MagickFalse; continue; } if ((LocaleCompare("version",option+1) == 0) || (LocaleCompare("-version",option+1) == 0)) { ListMagickVersion(stdout); return(MagickTrue); } /* Persist key/value pair. */ (void) DeleteImageOption(image_info,option+1); status=SetImageOption(image_info,option+1,argv[i+1]); if (status == MagickFalse) ThrowConjureException(ImageError,"UnableToPersistKey",option); i++; continue; } /* Interpret MSL script. */ (void) DeleteImageOption(image_info,"filename"); status=SetImageOption(image_info,"filename",argv[i]); if (status == MagickFalse) ThrowConjureException(ImageError,"UnableToPersistKey",argv[i]); (void) FormatLocaleString(filename,MagickPathExtent,"%s",argv[i]); image=ReadImages(image_info,filename,exception); CatchException(exception); if (image != (Image *) NULL) image=DestroyImageList(image); status=image != (Image *) NULL ? MagickTrue : MagickFalse; number_images++; } if (i != (ssize_t) argc) ThrowConjureException(OptionError,"MissingAnImageFilename",argv[i]); if (number_images == 0) ThrowConjureException(OptionError,"MissingAnImageFilename",argv[argc-1]); if (image != (Image *) NULL) image=DestroyImageList(image); for (i=0; i < (ssize_t) argc; i++) argv[i]=DestroyString(argv[i]); argv=(char **) RelinquishMagickMemory(argv); return(status != 0 ? MagickTrue : MagickFalse); }