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