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