1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % CCCC OOO N N JJJJJ U U RRRR EEEEE % 7 % C O O NN N J U U R R E % 8 % C O O N N N J U U RRRR EEE % 9 % C O O N NN J J U U R R E % 10 % CCCC OOO N N JJJ UUU R R EEEEE % 11 % % 12 % % 13 % Interpret Magick Scripting Language. % 14 % % 15 % Software Design % 16 % Cristy % 17 % December 2001 % 18 % % 19 % % 20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % http://www.imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % The conjure program gives you the ability to perform custom image processing 37 % tasks from a script written in the Magick Scripting Language (MSL). MSL is 38 % XML-based and consists of action statements with attributes. Actions include 39 % reading an image, processing an image, getting attributes from an image, 40 % writing an image, and more. An attribute is a key/value pair that modifies 41 % the behavior of an action. 42 % 43 */ 44 45 /* 47 Include declarations. 48 */ 49 #include "MagickWand/studio.h" 50 #include "MagickWand/MagickWand.h" 51 #include "MagickWand/mogrify-private.h" 52 53 /* 55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 % % 57 % % 58 % % 59 + C o n j u r e I m a g e C o m m a n d % 60 % % 61 % % 62 % % 63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 % 65 % ConjureImageCommand() 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 ConjureImageCommand method is: 74 % 75 % MagickBooleanType ConjureImageCommand(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 ConjureUsage(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 *settings[]= 108 { 109 "-monitor monitor progress", 110 "-quiet suppress all warning messages", 111 "-regard-warnings pay attention to warning messages", 112 "-seed value seed a new sequence of pseudo-random numbers", 113 "-verbose print detailed information about the image", 114 (char *) NULL 115 }; 116 117 ListMagickVersion(stdout); 118 (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n", 119 GetClientName()); 120 (void) printf("\nImage Settings:\n"); 121 for (p=settings; *p != (char *) NULL; p++) 122 (void) printf(" %s\n",*p); 123 (void) printf("\nMiscellaneous Options:\n"); 124 for (p=miscellaneous; *p != (char *) NULL; p++) 125 (void) printf(" %s\n",*p); 126 (void) printf("\nIn addition, define any key value pairs required by " 127 "your script. For\nexample,\n\n"); 128 (void) printf(" conjure -size 100x100 -color blue -foo bar script.msl\n"); 129 return(MagickFalse); 130 } 131 132 WandExport MagickBooleanType ConjureImageCommand(ImageInfo *image_info, 133 int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception) 134 { 135 #define DestroyConjure() \ 136 { \ 137 image=DestroyImageList(image); \ 138 for (i=0; i < (ssize_t) argc; i++) \ 139 argv[i]=DestroyString(argv[i]); \ 140 argv=(char **) RelinquishMagickMemory(argv); \ 141 } 142 #define ThrowConjureException(asperity,tag,option) \ 143 { \ 144 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ 145 option); \ 146 DestroyConjure(); \ 147 return(MagickFalse); \ 148 } 149 #define ThrowConjureInvalidArgumentException(option,argument) \ 150 { \ 151 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ 152 "InvalidArgument","'%s': %s",option,argument); \ 153 DestroyConjure(); \ 154 return(MagickFalse); \ 155 } 156 157 char 158 filename[MagickPathExtent], 159 *option; 160 161 Image 162 *image; 163 164 MagickStatusType 165 status; 166 167 register ssize_t 168 i; 169 170 ssize_t 171 number_images; 172 173 /* 174 Set defaults. 175 */ 176 assert(image_info != (ImageInfo *) NULL); 177 assert(image_info->signature == MagickCoreSignature); 178 if (image_info->debug != MagickFalse) 179 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 180 assert(exception != (ExceptionInfo *) NULL); 181 if (argc < 2) 182 return(ConjureUsage()); 183 image=NewImageList(); 184 number_images=0; 185 option=(char *) NULL; 186 /* 187 Conjure an image. 188 */ 189 ReadCommandlLine(argc,&argv); 190 status=ExpandFilenames(&argc,&argv); 191 if (status == MagickFalse) 192 ThrowConjureException(ResourceLimitError,"MemoryAllocationFailed", 193 GetExceptionMessage(errno)); 194 for (i=1; i < (ssize_t) argc; i++) 195 { 196 option=argv[i]; 197 if (IsCommandOption(option) != MagickFalse) 198 { 199 if (LocaleCompare("concurrent",option+1) == 0) 200 break; 201 if (LocaleCompare("debug",option+1) == 0) 202 { 203 ssize_t 204 event; 205 206 if (*option == '+') 207 break; 208 i++; 209 if (i == (ssize_t) argc) 210 ThrowConjureException(OptionError,"MissingArgument",option); 211 event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]); 212 if (event < 0) 213 ThrowConjureException(OptionError,"UnrecognizedEventType", 214 argv[i]); 215 (void) SetLogEventMask(argv[i]); 216 continue; 217 } 218 if (LocaleCompare("duration",option+1) == 0) 219 { 220 if (*option == '+') 221 break; 222 i++; 223 if (i == (ssize_t) argc) 224 ThrowConjureException(OptionError,"MissingArgument",option); 225 if (IsGeometry(argv[i]) == MagickFalse) 226 ThrowConjureInvalidArgumentException(option,argv[i]); 227 continue; 228 } 229 if ((LocaleCompare("help",option+1) == 0) || 230 (LocaleCompare("-help",option+1) == 0)) 231 { 232 if (*option == '-') 233 return(ConjureUsage()); 234 continue; 235 } 236 if (LocaleCompare("log",option+1) == 0) 237 { 238 if (*option == '-') 239 { 240 i++; 241 if (i == (ssize_t) argc) 242 ThrowConjureException(OptionError,"MissingLogFormat",option); 243 (void) SetLogFormat(argv[i]); 244 } 245 continue; 246 } 247 if (LocaleCompare("monitor",option+1) == 0) 248 continue; 249 if (LocaleCompare("quiet",option+1) == 0) 250 continue; 251 if (LocaleCompare("regard-warnings",option+1) == 0) 252 break; 253 if (LocaleCompare("seed",option+1) == 0) 254 { 255 if (*option == '+') 256 break; 257 i++; 258 if (i == (ssize_t) argc) 259 ThrowConjureException(OptionError,"MissingArgument",option); 260 if (IsGeometry(argv[i]) == MagickFalse) 261 ThrowConjureInvalidArgumentException(option,argv[i]); 262 break; 263 } 264 if (LocaleCompare("verbose",option+1) == 0) 265 { 266 image_info->verbose=(*option == '-') ? MagickTrue : MagickFalse; 267 continue; 268 } 269 if ((LocaleCompare("version",option+1) == 0) || 270 (LocaleCompare("-version",option+1) == 0)) 271 { 272 ListMagickVersion(stdout); 273 return(MagickTrue); 274 } 275 /* 276 Persist key/value pair. 277 */ 278 (void) DeleteImageOption(image_info,option+1); 279 status=SetImageOption(image_info,option+1,argv[i+1]); 280 if (status == MagickFalse) 281 ThrowConjureException(ImageError,"UnableToPersistKey",option); 282 i++; 283 continue; 284 } 285 /* 286 Interpret MSL script. 287 */ 288 (void) DeleteImageOption(image_info,"filename"); 289 status=SetImageOption(image_info,"filename",argv[i]); 290 if (status == MagickFalse) 291 ThrowConjureException(ImageError,"UnableToPersistKey",argv[i]); 292 (void) FormatLocaleString(filename,MagickPathExtent,"msl:%s",argv[i]); 293 image=ReadImages(image_info,filename,exception); 294 CatchException(exception); 295 if (image != (Image *) NULL) 296 image=DestroyImageList(image); 297 status=image != (Image *) NULL ? MagickTrue : MagickFalse; 298 number_images++; 299 } 300 if (i != (ssize_t) argc) 301 ThrowConjureException(OptionError,"MissingAnImageFilename",argv[i]); 302 if (number_images == 0) 303 ThrowConjureException(OptionError,"MissingAnImageFilename",argv[argc-1]); 304 if (image != (Image *) NULL) 305 image=DestroyImageList(image); 306 for (i=0; i < (ssize_t) argc; i++) 307 argv[i]=DestroyString(argv[i]); 308 argv=(char **) RelinquishMagickMemory(argv); 309 return(status != 0 ? MagickTrue : MagickFalse); 310 } 311