blob: 9620dc36cbac7d4af27e2c2560b4168810bfb90e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
17% March 2000 %
18% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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*/
cristy4c08aed2011-07-01 19:47:50 +000043#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"
cristy3ed852e2009-09-05 21:47:34 +000074
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%
anthony5f78bca2012-10-05 06:51:00 +000086% CloneImageArtifacts() clones all image artifacts to another image.
87%
88% This will not delete any existing artifacts that may be present!
cristy3ed852e2009-09-05 21:47:34 +000089%
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%
anthony5f78bca2012-10-05 06:51:00 +000097% o image: the image, to recieve the cloned artifacts.
cristy3ed852e2009-09-05 21:47:34 +000098%
anthony5f78bca2012-10-05 06:51:00 +000099% o clone_image: the source image for artifacts to clone.
cristy3ed852e2009-09-05 21:47:34 +0000100%
101*/
102MagickExport MagickBooleanType CloneImageArtifacts(Image *image,
103 const Image *clone_image)
104{
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)
115 image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts,
116 (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString);
117 return(MagickTrue);
118}
119
120/*
121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122% %
123% %
124% %
125% D e f i n e I m a g e A r t i f a c t %
126% %
127% %
128% %
129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130%
anthony5f78bca2012-10-05 06:51:00 +0000131% DefineImageArtifact() associates an assignment string of the form
132% "key=value" with per-image artifact. It is equivelent to
133% SetImageArtifact().
cristy3ed852e2009-09-05 21:47:34 +0000134%
135% The format of the DefineImageArtifact method is:
136%
137% MagickBooleanType DefineImageArtifact(Image *image,
138% const char *artifact)
139%
140% A description of each parameter follows:
141%
142% o image: the image.
143%
144% o artifact: the image artifact.
145%
146*/
147MagickExport MagickBooleanType DefineImageArtifact(Image *image,
148 const char *artifact)
149{
150 char
151 key[MaxTextExtent],
152 value[MaxTextExtent];
153
154 register char
155 *p;
156
157 assert(image != (Image *) NULL);
158 assert(artifact != (const char *) NULL);
159 (void) CopyMagickString(key,artifact,MaxTextExtent-1);
160 for (p=key; *p != '\0'; p++)
161 if (*p == '=')
162 break;
163 *value='\0';
164 if (*p == '=')
165 (void) CopyMagickString(value,p+1,MaxTextExtent);
166 *p='\0';
167 return(SetImageArtifact(image,key,value));
168}
169
170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175% D e l e t e I m a g e A r t i f a c t %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% DeleteImageArtifact() deletes an image artifact.
182%
183% The format of the DeleteImageArtifact method is:
184%
185% MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact)
186%
187% A description of each parameter follows:
188%
189% o image: the image.
190%
191% o artifact: the image artifact.
192%
193*/
194MagickExport MagickBooleanType DeleteImageArtifact(Image *image,
195 const char *artifact)
196{
197 assert(image != (Image *) NULL);
198 assert(image->signature == MagickSignature);
199 if (image->debug != MagickFalse)
200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
201 image->filename);
202 if (image->artifacts == (void *) NULL)
203 return(MagickFalse);
204 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact));
205}
206
207/*
208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209% %
210% %
211% %
212% D e s t r o y I m a g e A r t i f a c t s %
213% %
214% %
215% %
216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217%
anthony5f78bca2012-10-05 06:51:00 +0000218% DestroyImageArtifacts() destroys all artifacts and associated memory
219% attached to the given image.
cristy3ed852e2009-09-05 21:47:34 +0000220%
anthony5f78bca2012-10-05 06:51:00 +0000221% The format of the DestroyImageArtifacts method is:
cristy3ed852e2009-09-05 21:47:34 +0000222%
223% void DestroyImageArtifacts(Image *image)
224%
225% A description of each parameter follows:
226%
227% o image: the image.
228%
229*/
230MagickExport void DestroyImageArtifacts(Image *image)
231{
232 assert(image != (Image *) NULL);
233 assert(image->signature == MagickSignature);
234 if (image->debug != MagickFalse)
235 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
236 image->filename);
237 if (image->artifacts != (void *) NULL)
238 image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *)
239 image->artifacts);
240}
241
242/*
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244% %
245% %
246% %
247% G e t I m a g e A r t i f a c t %
248% %
249% %
250% %
251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252%
253% GetImageArtifact() gets a value associated with an image artifact.
anthony5f78bca2012-10-05 06:51:00 +0000254% If the requested artifact is NULL return the first artifact, to
255% prepare to iterate over all artifacts.
cristy3ed852e2009-09-05 21:47:34 +0000256%
anthony5f78bca2012-10-05 06:51:00 +0000257% The returned string is a constant string in the tree and should NOT be
258% freed by the caller.
anthony580609e2010-05-12 02:27:05 +0000259%
cristy3ed852e2009-09-05 21:47:34 +0000260% The format of the GetImageArtifact method is:
261%
262% const char *GetImageArtifact(const Image *image,const char *key)
263%
264% A description of each parameter follows:
265%
266% o image: the image.
267%
268% o key: the key.
269%
270*/
271MagickExport const char *GetImageArtifact(const Image *image,
272 const char *artifact)
273{
274 register const char
275 *p;
276
277 assert(image != (Image *) NULL);
278 assert(image->signature == MagickSignature);
279 if (image->debug != MagickFalse)
280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
281 p=(const char *) NULL;
282 if (artifact == (const char *) NULL)
283 {
284 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
285 p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
286 image->artifacts);
287 return(p);
288 }
289 if (image->artifacts != (void *) NULL)
290 {
291 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
292 image->artifacts,artifact);
293 if (p != (const char *) NULL)
294 return(p);
295 }
anthony11d32022012-11-17 05:31:33 +0000296 /* Programmer notes....
297 CLI IMv7: if no per-image artifact - look for a global option instead
298 CLI IMv6: global options are copied into per-image artifacts
299 In all other cases, if image is not part of a image_info, image list this
300 pointer should be NULL.
301 */
302
anthony5f78bca2012-10-05 06:51:00 +0000303 if ( (image->image_info != (ImageInfo *)NULL) &&
304 (image->image_info->options != (void *) NULL) )
305 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
306 image->image_info->options,artifact);
cristy3ed852e2009-09-05 21:47:34 +0000307 return(p);
308}
309
310/*
311%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312% %
313% %
314% %
315% G e t N e x t I m a g e A r t i f a c t %
316% %
317% %
318% %
319%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320%
321% GetNextImageArtifact() gets the next image artifact value.
322%
323% The format of the GetNextImageArtifact method is:
324%
325% char *GetNextImageArtifact(const Image *image)
326%
327% A description of each parameter follows:
328%
329% o image: the image.
330%
331*/
332MagickExport char *GetNextImageArtifact(const Image *image)
333{
334 assert(image != (Image *) NULL);
335 assert(image->signature == MagickSignature);
336 if (image->debug != MagickFalse)
337 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
338 image->filename);
339 if (image->artifacts == (void *) NULL)
340 return((char *) NULL);
341 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->artifacts));
342}
343
344/*
345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346% %
347% %
348% %
349% R e m o v e I m a g e A r t i f a c t %
350% %
351% %
352% %
353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354%
355% RemoveImageArtifact() removes an artifact from the image and returns its
356% value.
357%
anthony5f78bca2012-10-05 06:51:00 +0000358% In this case the ConstantString() value returned should be freed by the
359% caller when finished.
360%
cristy3ed852e2009-09-05 21:47:34 +0000361% The format of the RemoveImageArtifact method is:
362%
363% char *RemoveImageArtifact(Image *image,const char *artifact)
364%
365% A description of each parameter follows:
366%
367% o image: the image.
368%
369% o artifact: the image artifact.
370%
371*/
372MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
373{
374 char
375 *value;
376
377 assert(image != (Image *) NULL);
378 assert(image->signature == MagickSignature);
379 if (image->debug != MagickFalse)
380 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
381 image->filename);
382 if (image->artifacts == (void *) NULL)
383 return((char *) NULL);
384 value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts,
385 artifact);
386 return(value);
387}
388
389/*
390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391% %
392% %
393% %
394% 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 %
395% %
396% %
397% %
398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399%
400% ResetImageArtifactIterator() resets the image artifact iterator. Use it
401% in conjunction with GetNextImageArtifact() to iterate over all the values
402% associated with an image artifact.
403%
anthony5f78bca2012-10-05 06:51:00 +0000404% Alternatively you can use GetImageArtifact() with a NULL artifact field to
405% reset the iterator and return the first artifact.
406%
cristy3ed852e2009-09-05 21:47:34 +0000407% The format of the ResetImageArtifactIterator method is:
408%
409% ResetImageArtifactIterator(Image *image)
410%
411% A description of each parameter follows:
412%
413% o image: the image.
414%
415*/
416MagickExport void ResetImageArtifactIterator(const Image *image)
417{
418 assert(image != (Image *) NULL);
419 assert(image->signature == MagickSignature);
420 if (image->debug != MagickFalse)
421 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
422 image->filename);
423 if (image->artifacts == (void *) NULL)
424 return;
425 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
426}
427
428/*
429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430% %
431% %
432% %
433% S e t I m a g e A r t i f a c t %
434% %
435% %
436% %
437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438%
anthony5f78bca2012-10-05 06:51:00 +0000439% SetImageArtifact() associates makes a copy of the given string value
440% and inserts it into the artifact tree of the given image.
cristy3ed852e2009-09-05 21:47:34 +0000441%
442% The format of the SetImageArtifact method is:
443%
444% MagickBooleanType SetImageArtifact(Image *image,const char *artifact,
445% const char *value)
446%
447% A description of each parameter follows:
448%
449% o image: the image.
450%
451% o artifact: the image artifact.
452%
453% o values: the image artifact values.
454%
455*/
456MagickExport MagickBooleanType SetImageArtifact(Image *image,
457 const char *artifact,const char *value)
458{
459 MagickBooleanType
460 status;
461
462 assert(image != (Image *) NULL);
463 assert(image->signature == MagickSignature);
464 if (image->debug != MagickFalse)
465 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
466 image->filename);
anthonyd181ea02011-10-12 07:44:13 +0000467
anthony5f78bca2012-10-05 06:51:00 +0000468 /* Create tree if needed - specify how key,values are to be freed */
cristy3ed852e2009-09-05 21:47:34 +0000469 if (image->artifacts == (void *) NULL)
470 image->artifacts=NewSplayTree(CompareSplayTreeString,
471 RelinquishMagickMemory,RelinquishMagickMemory);
anthony7bb7aee2012-05-15 00:09:16 +0000472
473 /* Delete artifact if NULL -- empty string values are valid! */
474 if (value == (const char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000475 return(DeleteImageArtifact(image,artifact));
anthony7bb7aee2012-05-15 00:09:16 +0000476
477 /* add artifact to splay-tree */
cristy3ed852e2009-09-05 21:47:34 +0000478 status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
479 ConstantString(artifact),ConstantString(value));
480 return(status);
481}