MagickCore 7.1.2
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
artifact.c
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 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% https://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 receive the cloned artifacts.
98%
99% o clone_image: the source image for artifacts to clone.
100%
101*/
102
103typedef char
104 *(*CloneKeyFunc)(const char *),
105 *(*CloneValueFunc)(const char *);
106
107static inline void *CloneArtifactKey(void *key)
108{
109 return((void *) ((CloneKeyFunc) ConstantString)((const char *) key));
110}
111
112static inline void *CloneArtifactValue(void *value)
113{
114 return((void *) ((CloneValueFunc) ConstantString)((const char *) value));
115}
116
117MagickExport MagickBooleanType CloneImageArtifacts(Image *image,
118 const Image *clone_image)
119{
120 assert(image != (Image *) NULL);
121 assert(image->signature == MagickCoreSignature);
122 assert(clone_image != (const Image *) NULL);
123 assert(clone_image->signature == MagickCoreSignature);
124 if (IsEventLogging() != MagickFalse)
125 {
126 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
127 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
128 clone_image->filename);
129 }
130 if (clone_image->artifacts != (void *) NULL)
131 {
132 if (image->artifacts != (void *) NULL)
133 DestroyImageArtifacts(image);
134 image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts,
135 CloneArtifactKey,CloneArtifactValue);
136 }
137 return(MagickTrue);
138}
139
140/*
141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142% %
143% %
144% %
145% D e f i n e I m a g e A r t i f a c t %
146% %
147% %
148% %
149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150%
151% DefineImageArtifact() associates an assignment string of the form
152% "key=value" with per-image artifact. It is equivalent to
153% SetImageArtifact().
154%
155% The format of the DefineImageArtifact method is:
156%
157% MagickBooleanType DefineImageArtifact(Image *image,
158% const char *artifact)
159%
160% A description of each parameter follows:
161%
162% o image: the image.
163%
164% o artifact: the image artifact.
165%
166*/
167MagickExport MagickBooleanType DefineImageArtifact(Image *image,
168 const char *artifact)
169{
170 char
171 key[MagickPathExtent],
172 value[MagickPathExtent];
173
174 char
175 *p;
176
177 assert(image != (Image *) NULL);
178 assert(artifact != (const char *) NULL);
179 (void) CopyMagickString(key,artifact,MagickPathExtent-1);
180 for (p=key; *p != '\0'; p++)
181 if (*p == '=')
182 break;
183 *value='\0';
184 if (*p == '=')
185 (void) CopyMagickString(value,p+1,MagickPathExtent);
186 *p='\0';
187 return(SetImageArtifact(image,key,value));
188}
189
190/*
191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192% %
193% %
194% %
195% D e l e t e I m a g e A r t i f a c t %
196% %
197% %
198% %
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200%
201% DeleteImageArtifact() deletes an image artifact.
202%
203% The format of the DeleteImageArtifact method is:
204%
205% MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact)
206%
207% A description of each parameter follows:
208%
209% o image: the image.
210%
211% o artifact: the image artifact.
212%
213*/
214MagickExport MagickBooleanType DeleteImageArtifact(Image *image,
215 const char *artifact)
216{
217 assert(image != (Image *) NULL);
218 assert(image->signature == MagickCoreSignature);
219 if (IsEventLogging() != MagickFalse)
220 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
221 if (image->artifacts == (void *) NULL)
222 return(MagickFalse);
223 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact));
224}
225
226/*
227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228% %
229% %
230% %
231% D e s t r o y I m a g e A r t i f a c t s %
232% %
233% %
234% %
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236%
237% DestroyImageArtifacts() destroys all artifacts and associated memory
238% attached to the given image.
239%
240% The format of the DestroyImageArtifacts method is:
241%
242% void DestroyImageArtifacts(Image *image)
243%
244% A description of each parameter follows:
245%
246% o image: the image.
247%
248*/
249MagickExport void DestroyImageArtifacts(Image *image)
250{
251 assert(image != (Image *) NULL);
252 assert(image->signature == MagickCoreSignature);
253 if (IsEventLogging() != MagickFalse)
254 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
255 if (image->artifacts != (void *) NULL)
256 image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *)
257 image->artifacts);
258}
259
260/*
261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262% %
263% %
264% %
265% G e t I m a g e A r t i f a c t %
266% %
267% %
268% %
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270%
271% GetImageArtifact() gets a value associated with an image artifact.
272% If the requested artifact is NULL return the first artifact, to
273% prepare to iterate over all artifacts.
274%
275% The returned string is a constant string in the tree and should NOT be
276% freed by the caller.
277%
278% The format of the GetImageArtifact method is:
279%
280% const char *GetImageArtifact(const Image *image,const char *key)
281%
282% A description of each parameter follows:
283%
284% o image: the image.
285%
286% o key: the key.
287%
288*/
289MagickExport const char *GetImageArtifact(const Image *image,
290 const char *artifact)
291{
292 const char
293 *p;
294
295 assert(image != (Image *) NULL);
296 assert(image->signature == MagickCoreSignature);
297 if (IsEventLogging() != MagickFalse)
298 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
299 p=(const char *) NULL;
300 if (image->artifacts != (void *) NULL)
301 {
302 if (artifact == (const char *) NULL)
303 return((const char *) GetRootValueFromSplayTree((SplayTreeInfo *)
304 image->artifacts));
305 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts,
306 artifact);
307 if (p != (const char *) NULL)
308 return(p);
309 }
310 if ((image->image_info != (ImageInfo *) NULL) &&
311 (image->image_info->options != (void *) NULL))
312 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
313 image->image_info->options,artifact);
314 return(p);
315}
316
317/*
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319% %
320% %
321% %
322% G e t N e x t I m a g e A r t i f a c t %
323% %
324% %
325% %
326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327%
328% GetNextImageArtifact() gets the next image artifact value.
329%
330% The format of the GetNextImageArtifact method is:
331%
332% char *GetNextImageArtifact(const Image *image)
333%
334% A description of each parameter follows:
335%
336% o image: the image.
337%
338*/
339MagickExport const char *GetNextImageArtifact(const Image *image)
340{
341 assert(image != (Image *) NULL);
342 assert(image->signature == MagickCoreSignature);
343 if (IsEventLogging() != MagickFalse)
344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
345 if (image->artifacts == (void *) NULL)
346 return((const char *) NULL);
347 return((const char *) GetNextKeyInSplayTree(
348 (SplayTreeInfo *) image->artifacts));
349}
350
351/*
352%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353% %
354% %
355% %
356% R e m o v e I m a g e A r t i f a c t %
357% %
358% %
359% %
360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361%
362% RemoveImageArtifact() removes an artifact from the image and returns its
363% value.
364%
365% In this case the ConstantString() value returned should be freed by the
366% caller when finished.
367%
368% The format of the RemoveImageArtifact method is:
369%
370% char *RemoveImageArtifact(Image *image,const char *artifact)
371%
372% A description of each parameter follows:
373%
374% o image: the image.
375%
376% o artifact: the image artifact.
377%
378*/
379MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
380{
381 char
382 *value;
383
384 assert(image != (Image *) NULL);
385 assert(image->signature == MagickCoreSignature);
386 if (IsEventLogging() != MagickFalse)
387 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
388 if (image->artifacts == (void *) NULL)
389 return((char *) NULL);
390 value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts,
391 artifact);
392 return(value);
393}
394
395/*
396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397% %
398% %
399% %
400% 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% %
402% %
403% %
404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405%
406% ResetImageArtifactIterator() resets the image artifact iterator. Use it
407% in conjunction with GetNextImageArtifact() to iterate over all the values
408% associated with an image artifact.
409%
410% Alternatively you can use GetImageArtifact() with a NULL artifact field to
411% reset the iterator and return the first artifact.
412%
413% The format of the ResetImageArtifactIterator method is:
414%
415% ResetImageArtifactIterator(Image *image)
416%
417% A description of each parameter follows:
418%
419% o image: the image.
420%
421*/
422MagickExport void ResetImageArtifactIterator(const Image *image)
423{
424 assert(image != (Image *) NULL);
425 assert(image->signature == MagickCoreSignature);
426 if (IsEventLogging() != MagickFalse)
427 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
428 if (image->artifacts == (void *) NULL)
429 return;
430 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
431}
432
433/*
434%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435% %
436% %
437% %
438% S e t I m a g e A r t i f a c t %
439% %
440% %
441% %
442%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443%
444% SetImageArtifact() sets a key-value pair in the image artifact namespace.
445% Artifacts differ from properties. Properties are public and are generally
446% exported to an external image format if the format supports it. Artifacts
447% are private and are utilized by the internal ImageMagick API to modify the
448% behavior of certain algorithms.
449%
450% The format of the SetImageArtifact method is:
451%
452% MagickBooleanType SetImageArtifact(Image *image,const char *artifact,
453% const char *value)
454%
455% A description of each parameter follows:
456%
457% o image: the image.
458%
459% o artifact: the image artifact key.
460%
461% o value: the image artifact value.
462%
463*/
464MagickExport MagickBooleanType SetImageArtifact(Image *image,
465 const char *artifact,const char *value)
466{
467 MagickBooleanType
468 status;
469
470 assert(image != (Image *) NULL);
471 assert(image->signature == MagickCoreSignature);
472 if (IsEventLogging() != MagickFalse)
473 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
474 /*
475 Create tree if needed - specify how key,values are to be freed.
476 */
477 if (image->artifacts == (void *) NULL)
478 image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
479 RelinquishMagickMemory);
480 /*
481 Delete artifact if NULL -- empty string values are valid!,
482 */
483 if (value == (const char *) NULL)
484 return(DeleteImageArtifact(image,artifact));
485 /*
486 Add artifact to splay-tree.
487 */
488 status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
489 ConstantString(artifact),ConstantString(value));
490 return(status);
491}