1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % AAA RRRR TTTTT IIIII FFFFF AAA CCCC TTTTT % 7 % A A R R T I F A A C T % 8 % AAAAA RRRRR T I FFF AAAAA C T % 9 % A A R R T I F A A C T % 10 % A A R R T IIIII F A A CCCCC T % 11 % % 12 % % 13 % MagickCore Artifact Methods % 14 % % 15 % Software Design % 16 % Cristy % 17 % March 2000 % 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 % 37 % 38 */ 39 40 /* 42 Include declarations. 43 */ 44 #include "MagickCore/studio.h" 45 #include "MagickCore/artifact.h" 46 #include "MagickCore/cache.h" 47 #include "MagickCore/color.h" 48 #include "MagickCore/compare.h" 49 #include "MagickCore/constitute.h" 50 #include "MagickCore/draw.h" 51 #include "MagickCore/effect.h" 52 #include "MagickCore/exception.h" 53 #include "MagickCore/exception-private.h" 54 #include "MagickCore/fx.h" 55 #include "MagickCore/fx-private.h" 56 #include "MagickCore/gem.h" 57 #include "MagickCore/geometry.h" 58 #include "MagickCore/image.h" 59 #include "MagickCore/layer.h" 60 #include "MagickCore/list.h" 61 #include "MagickCore/memory_.h" 62 #include "MagickCore/monitor.h" 63 #include "MagickCore/montage.h" 64 #include "MagickCore/option.h" 65 #include "MagickCore/profile.h" 66 #include "MagickCore/quantum.h" 67 #include "MagickCore/resource_.h" 68 #include "MagickCore/splay-tree.h" 69 #include "MagickCore/signature-private.h" 70 #include "MagickCore/statistic.h" 71 #include "MagickCore/string_.h" 72 #include "MagickCore/token.h" 73 #include "MagickCore/utility.h" 74 #include "MagickCore/xml-tree.h" 75 76 /* 78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 % % 80 % % 81 % % 82 % C l o n e I m a g e A r t i f a c t s % 83 % % 84 % % 85 % % 86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 87 % 88 % CloneImageArtifacts() clones all image artifacts to another image. 89 % 90 % This will not delete any existing artifacts that may be present! 91 % 92 % The format of the CloneImageArtifacts method is: 93 % 94 % MagickBooleanType CloneImageArtifacts(Image *image, 95 % const Image *clone_image) 96 % 97 % A description of each parameter follows: 98 % 99 % o image: the image, to recieve the cloned artifacts. 100 % 101 % o clone_image: the source image for artifacts to clone. 102 % 103 */ 104 MagickExport MagickBooleanType CloneImageArtifacts(Image *image, 105 const Image *clone_image) 106 { 107 assert(image != (Image *) NULL); 108 assert(image->signature == MagickCoreSignature); 109 if (image->debug != MagickFalse) 110 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 111 assert(clone_image != (const Image *) NULL); 112 assert(clone_image->signature == MagickCoreSignature); 113 if (clone_image->debug != MagickFalse) 114 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 115 clone_image->filename); 116 if (clone_image->artifacts != (void *) NULL) 117 { 118 if (image->artifacts != (void *) NULL) 119 DestroyImageArtifacts(image); 120 image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts, 121 (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString); 122 } 123 return(MagickTrue); 124 } 125 126 /* 128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 129 % % 130 % % 131 % % 132 % D e f i n e I m a g e A r t i f a c t % 133 % % 134 % % 135 % % 136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137 % 138 % DefineImageArtifact() associates an assignment string of the form 139 % "key=value" with per-image artifact. It is equivelent to 140 % SetImageArtifact(). 141 % 142 % The format of the DefineImageArtifact method is: 143 % 144 % MagickBooleanType DefineImageArtifact(Image *image, 145 % const char *artifact) 146 % 147 % A description of each parameter follows: 148 % 149 % o image: the image. 150 % 151 % o artifact: the image artifact. 152 % 153 */ 154 MagickExport MagickBooleanType DefineImageArtifact(Image *image, 155 const char *artifact) 156 { 157 char 158 key[MagickPathExtent], 159 value[MagickPathExtent]; 160 161 register char 162 *p; 163 164 assert(image != (Image *) NULL); 165 assert(artifact != (const char *) NULL); 166 (void) CopyMagickString(key,artifact,MagickPathExtent-1); 167 for (p=key; *p != '\0'; p++) 168 if (*p == '=') 169 break; 170 *value='\0'; 171 if (*p == '=') 172 (void) CopyMagickString(value,p+1,MagickPathExtent); 173 *p='\0'; 174 return(SetImageArtifact(image,key,value)); 175 } 176 177 /* 179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 180 % % 181 % % 182 % % 183 % D e l e t e I m a g e A r t i f a c t % 184 % % 185 % % 186 % % 187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 188 % 189 % DeleteImageArtifact() deletes an image artifact. 190 % 191 % The format of the DeleteImageArtifact method is: 192 % 193 % MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact) 194 % 195 % A description of each parameter follows: 196 % 197 % o image: the image. 198 % 199 % o artifact: the image artifact. 200 % 201 */ 202 MagickExport MagickBooleanType DeleteImageArtifact(Image *image, 203 const char *artifact) 204 { 205 assert(image != (Image *) NULL); 206 assert(image->signature == MagickCoreSignature); 207 if (image->debug != MagickFalse) 208 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 209 if (image->artifacts == (void *) NULL) 210 return(MagickFalse); 211 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact)); 212 } 213 214 /* 216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 217 % % 218 % % 219 % % 220 % D e s t r o y I m a g e A r t i f a c t s % 221 % % 222 % % 223 % % 224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 225 % 226 % DestroyImageArtifacts() destroys all artifacts and associated memory 227 % attached to the given image. 228 % 229 % The format of the DestroyImageArtifacts method is: 230 % 231 % void DestroyImageArtifacts(Image *image) 232 % 233 % A description of each parameter follows: 234 % 235 % o image: the image. 236 % 237 */ 238 MagickExport void DestroyImageArtifacts(Image *image) 239 { 240 assert(image != (Image *) NULL); 241 assert(image->signature == MagickCoreSignature); 242 if (image->debug != MagickFalse) 243 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 244 if (image->artifacts != (void *) NULL) 245 image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *) 246 image->artifacts); 247 } 248 249 /* 251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 252 % % 253 % % 254 % % 255 % G e t I m a g e A r t i f a c t % 256 % % 257 % % 258 % % 259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 260 % 261 % GetImageArtifact() gets a value associated with an image artifact. 262 % If the requested artifact is NULL return the first artifact, to 263 % prepare to iterate over all artifacts. 264 % 265 % The returned string is a constant string in the tree and should NOT be 266 % freed by the caller. 267 % 268 % The format of the GetImageArtifact method is: 269 % 270 % const char *GetImageArtifact(const Image *image,const char *key) 271 % 272 % A description of each parameter follows: 273 % 274 % o image: the image. 275 % 276 % o key: the key. 277 % 278 */ 279 MagickExport const char *GetImageArtifact(const Image *image, 280 const char *artifact) 281 { 282 register const char 283 *p; 284 285 assert(image != (Image *) NULL); 286 assert(image->signature == MagickCoreSignature); 287 if (image->debug != MagickFalse) 288 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 289 p=(const char *) NULL; 290 if (artifact == (const char *) NULL) 291 { 292 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts); 293 p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *) 294 image->artifacts); 295 return(p); 296 } 297 if (image->artifacts != (void *) NULL) 298 { 299 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts, 300 artifact); 301 if (p != (const char *) NULL) 302 return(p); 303 } 304 if ((image->image_info != (ImageInfo *) NULL) && 305 (image->image_info->options != (void *) NULL)) 306 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) 307 image->image_info->options,artifact); 308 return(p); 309 } 310 311 /* 313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 314 % % 315 % % 316 % % 317 % G e t N e x t I m a g e A r t i f a c t % 318 % % 319 % % 320 % % 321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 322 % 323 % GetNextImageArtifact() gets the next image artifact value. 324 % 325 % The format of the GetNextImageArtifact method is: 326 % 327 % char *GetNextImageArtifact(const Image *image) 328 % 329 % A description of each parameter follows: 330 % 331 % o image: the image. 332 % 333 */ 334 MagickExport const char *GetNextImageArtifact(const Image *image) 335 { 336 assert(image != (Image *) NULL); 337 assert(image->signature == MagickCoreSignature); 338 if (image->debug != MagickFalse) 339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 340 if (image->artifacts == (void *) NULL) 341 return((const char *) NULL); 342 return((const char *) GetNextKeyInSplayTree( 343 (SplayTreeInfo *) image->artifacts)); 344 } 345 346 /* 348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 349 % % 350 % % 351 % % 352 % R e m o v e I m a g e A r t i f a c t % 353 % % 354 % % 355 % % 356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 357 % 358 % RemoveImageArtifact() removes an artifact from the image and returns its 359 % value. 360 % 361 % In this case the ConstantString() value returned should be freed by the 362 % caller when finished. 363 % 364 % The format of the RemoveImageArtifact method is: 365 % 366 % char *RemoveImageArtifact(Image *image,const char *artifact) 367 % 368 % A description of each parameter follows: 369 % 370 % o image: the image. 371 % 372 % o artifact: the image artifact. 373 % 374 */ 375 MagickExport char *RemoveImageArtifact(Image *image,const char *artifact) 376 { 377 char 378 *value; 379 380 assert(image != (Image *) NULL); 381 assert(image->signature == MagickCoreSignature); 382 if (image->debug != MagickFalse) 383 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 384 if (image->artifacts == (void *) NULL) 385 return((char *) NULL); 386 value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts, 387 artifact); 388 return(value); 389 } 390 391 /* 393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 394 % % 395 % % 396 % % 397 % R e s e t I m a g e A r t i f a c t I t e r a t o r % 398 % % 399 % % 400 % % 401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 402 % 403 % ResetImageArtifactIterator() resets the image artifact iterator. Use it 404 % in conjunction with GetNextImageArtifact() to iterate over all the values 405 % associated with an image artifact. 406 % 407 % Alternatively you can use GetImageArtifact() with a NULL artifact field to 408 % reset the iterator and return the first artifact. 409 % 410 % The format of the ResetImageArtifactIterator method is: 411 % 412 % ResetImageArtifactIterator(Image *image) 413 % 414 % A description of each parameter follows: 415 % 416 % o image: the image. 417 % 418 */ 419 MagickExport void ResetImageArtifactIterator(const Image *image) 420 { 421 assert(image != (Image *) NULL); 422 assert(image->signature == MagickCoreSignature); 423 if (image->debug != MagickFalse) 424 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 425 if (image->artifacts == (void *) NULL) 426 return; 427 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts); 428 } 429 430 /* 432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 433 % % 434 % % 435 % % 436 % S e t I m a g e A r t i f a c t % 437 % % 438 % % 439 % % 440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 441 % 442 % SetImageArtifact() associates makes a copy of the given string arguments 443 % and inserts it into the artifact tree of the given image. 444 % 445 % The format of the SetImageArtifact method is: 446 % 447 % MagickBooleanType SetImageArtifact(Image *image,const char *artifact, 448 % const char *value) 449 % 450 % A description of each parameter follows: 451 % 452 % o image: the image. 453 % 454 % o artifact: the image artifact key. 455 % 456 % o value: the image artifact value. 457 % 458 */ 459 MagickExport MagickBooleanType SetImageArtifact(Image *image, 460 const char *artifact,const char *value) 461 { 462 MagickBooleanType 463 status; 464 465 assert(image != (Image *) NULL); 466 assert(image->signature == MagickCoreSignature); 467 if (image->debug != MagickFalse) 468 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 469 /* 470 Create tree if needed - specify how key,values are to be freed. 471 */ 472 if (image->artifacts == (void *) NULL) 473 image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, 474 RelinquishMagickMemory); 475 /* 476 Delete artifact if NULL -- empty string values are valid!, 477 */ 478 if (value == (const char *) NULL) 479 return(DeleteImageArtifact(image,artifact)); 480 /* 481 Add artifact to splay-tree. 482 */ 483 status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts, 484 ConstantString(artifact),ConstantString(value)); 485 return(status); 486 } 487