2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % MagickCore Artifact Methods %
20 % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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"
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 % C l o n e I m a g e A r t i f a c t s %
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % CloneImageArtifacts() clones all image artifacts to another image.
88 % This will not delete any existing artifacts that may be present!
90 % The format of the CloneImageArtifacts method is:
92 % MagickBooleanType CloneImageArtifacts(Image *image,
93 % const Image *clone_image)
95 % A description of each parameter follows:
97 % o image: the image, to recieve the cloned artifacts.
99 % o clone_image: the source image for artifacts to clone.
102 MagickExport MagickBooleanType CloneImageArtifacts(Image *image,
103 const Image *clone_image)
105 assert(image != (Image *) NULL);
106 assert(image->signature == MagickSignature);
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 == MagickSignature);
111 if (clone_image->debug != MagickFalse)
112 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
113 clone_image->filename);
114 if (clone_image->artifacts != (void *) NULL)
116 if (image->artifacts != (void *) NULL)
117 DestroyImageArtifacts(image);
118 image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts,
119 (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString);
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 % D e f i n e I m a g e A r t i f a c t %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % DefineImageArtifact() associates an assignment string of the form
136 % "key=value" with per-image artifact. It is equivelent to
137 % SetImageArtifact().
139 % The format of the DefineImageArtifact method is:
141 % MagickBooleanType DefineImageArtifact(Image *image,
142 % const char *artifact)
144 % A description of each parameter follows:
146 % o image: the image.
148 % o artifact: the image artifact.
151 MagickExport MagickBooleanType DefineImageArtifact(Image *image,
152 const char *artifact)
156 value[MaxTextExtent];
161 assert(image != (Image *) NULL);
162 assert(artifact != (const char *) NULL);
163 (void) CopyMagickString(key,artifact,MaxTextExtent-1);
164 for (p=key; *p != '\0'; p++)
169 (void) CopyMagickString(value,p+1,MaxTextExtent);
171 return(SetImageArtifact(image,key,value));
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 % D e l e t e I m a g e A r t i f a c t %
183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 % DeleteImageArtifact() deletes an image artifact.
187 % The format of the DeleteImageArtifact method is:
189 % MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact)
191 % A description of each parameter follows:
193 % o image: the image.
195 % o artifact: the image artifact.
198 MagickExport MagickBooleanType DeleteImageArtifact(Image *image,
199 const char *artifact)
201 assert(image != (Image *) NULL);
202 assert(image->signature == MagickSignature);
203 if (image->debug != MagickFalse)
204 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
205 if (image->artifacts == (void *) NULL)
207 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact));
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215 % D e s t r o y I m a g e A r t i f a c t s %
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 % DestroyImageArtifacts() destroys all artifacts and associated memory
222 % attached to the given image.
224 % The format of the DestroyImageArtifacts method is:
226 % void DestroyImageArtifacts(Image *image)
228 % A description of each parameter follows:
230 % o image: the image.
233 MagickExport void DestroyImageArtifacts(Image *image)
235 assert(image != (Image *) NULL);
236 assert(image->signature == MagickSignature);
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 *)
245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % G e t I m a g e A r t i f a c t %
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
259 % The returned string is a constant string in the tree and should NOT be
260 % freed by the caller.
262 % The format of the GetImageArtifact method is:
264 % const char *GetImageArtifact(const Image *image,const char *key)
266 % A description of each parameter follows:
268 % o image: the image.
273 MagickExport const char *GetImageArtifact(const Image *image,
274 const char *artifact)
279 assert(image != (Image *) NULL);
280 assert(image->signature == MagickSignature);
281 if (image->debug != MagickFalse)
282 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
283 p=(const char *) NULL;
284 if (artifact == (const char *) NULL)
286 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
287 p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
291 if (image->artifacts != (void *) NULL)
293 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts,
295 if (p != (const char *) NULL)
301 CLI IMv7: if no per-image artifact - look for a global option instead CLI
302 IMv6: global options are copied into per-image artifacts In all other
303 cases, if image is not part of an image_info image list this pointer
304 should be NULL, an no global image options are available.
306 if ((image->image_info != (ImageInfo *)NULL) &&
307 (image->image_info->options != (void *) NULL))
309 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
310 image->image_info->options,artifact);
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % G e t N e x t I m a g e A r t i f a c t %
324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 % GetNextImageArtifact() gets the next image artifact value.
328 % The format of the GetNextImageArtifact method is:
330 % char *GetNextImageArtifact(const Image *image)
332 % A description of each parameter follows:
334 % o image: the image.
337 MagickExport char *GetNextImageArtifact(const Image *image)
339 assert(image != (Image *) NULL);
340 assert(image->signature == MagickSignature);
341 if (image->debug != MagickFalse)
342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
343 if (image->artifacts == (void *) NULL)
344 return((char *) NULL);
345 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->artifacts));
349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 % R e m o v e I m a g e A r t i f a c t %
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359 % RemoveImageArtifact() removes an artifact from the image and returns its
362 % In this case the ConstantString() value returned should be freed by the
363 % caller when finished.
365 % The format of the RemoveImageArtifact method is:
367 % char *RemoveImageArtifact(Image *image,const char *artifact)
369 % A description of each parameter follows:
371 % o image: the image.
373 % o artifact: the image artifact.
376 MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
381 assert(image != (Image *) NULL);
382 assert(image->signature == MagickSignature);
383 if (image->debug != MagickFalse)
384 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
385 if (image->artifacts == (void *) NULL)
386 return((char *) NULL);
387 value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts,
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
407 % Alternatively you can use GetImageArtifact() with a NULL artifact field to
408 % reset the iterator and return the first artifact.
410 % The format of the ResetImageArtifactIterator method is:
412 % ResetImageArtifactIterator(Image *image)
414 % A description of each parameter follows:
416 % o image: the image.
419 MagickExport void ResetImageArtifactIterator(const Image *image)
421 assert(image != (Image *) NULL);
422 assert(image->signature == MagickSignature);
423 if (image->debug != MagickFalse)
424 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
425 if (image->artifacts == (void *) NULL)
427 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % S e t I m a g e A r t i f a c t %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 % SetImageArtifact() associates makes a copy of the given string arguments
442 % and inserts it into the artifact tree of the given image.
444 % The format of the SetImageArtifact method is:
446 % MagickBooleanType SetImageArtifact(Image *image,const char *artifact,
449 % A description of each parameter follows:
451 % o image: the image.
453 % o artifact: the image artifact key.
455 % o value: the image artifact value.
458 MagickExport MagickBooleanType SetImageArtifact(Image *image,
459 const char *artifact,const char *value)
464 assert(image != (Image *) NULL);
465 assert(image->signature == MagickSignature);
466 if (image->debug != MagickFalse)
467 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
469 Create tree if needed - specify how key,values are to be freed.
471 if (image->artifacts == (void *) NULL)
472 image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
473 RelinquishMagickMemory);
475 Delete artifact if NULL -- empty string values are valid!,
477 if (value == (const char *) NULL)
478 return(DeleteImageArtifact(image,artifact));
480 Add artifact to splay-tree.
482 status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
483 ConstantString(artifact),ConstantString(value));