blob: 9a72da6c71541f5b776cc91d8779195167084621 [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 }
anthony5f78bca2012-10-05 06:51:00 +0000296 /* if no per-image artifact - look for a global option instead */
297 if ( (image->image_info != (ImageInfo *)NULL) &&
298 (image->image_info->options != (void *) NULL) )
299 p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
300 image->image_info->options,artifact);
cristy3ed852e2009-09-05 21:47:34 +0000301 return(p);
302}
303
304/*
305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306% %
307% %
308% %
309% G e t N e x t I m a g e A r t i f a c t %
310% %
311% %
312% %
313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314%
315% GetNextImageArtifact() gets the next image artifact value.
316%
317% The format of the GetNextImageArtifact method is:
318%
319% char *GetNextImageArtifact(const Image *image)
320%
321% A description of each parameter follows:
322%
323% o image: the image.
324%
325*/
326MagickExport char *GetNextImageArtifact(const Image *image)
327{
328 assert(image != (Image *) NULL);
329 assert(image->signature == MagickSignature);
330 if (image->debug != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
332 image->filename);
333 if (image->artifacts == (void *) NULL)
334 return((char *) NULL);
335 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->artifacts));
336}
337
338/*
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340% %
341% %
342% %
343% R e m o v e I m a g e A r t i f a c t %
344% %
345% %
346% %
347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348%
349% RemoveImageArtifact() removes an artifact from the image and returns its
350% value.
351%
anthony5f78bca2012-10-05 06:51:00 +0000352% In this case the ConstantString() value returned should be freed by the
353% caller when finished.
354%
cristy3ed852e2009-09-05 21:47:34 +0000355% The format of the RemoveImageArtifact method is:
356%
357% char *RemoveImageArtifact(Image *image,const char *artifact)
358%
359% A description of each parameter follows:
360%
361% o image: the image.
362%
363% o artifact: the image artifact.
364%
365*/
366MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
367{
368 char
369 *value;
370
371 assert(image != (Image *) NULL);
372 assert(image->signature == MagickSignature);
373 if (image->debug != MagickFalse)
374 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
375 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%
anthony5f78bca2012-10-05 06:51:00 +0000398% Alternatively you can use GetImageArtifact() with a NULL artifact field to
399% reset the iterator and return the first artifact.
400%
cristy3ed852e2009-09-05 21:47:34 +0000401% 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 == MagickSignature);
414 if (image->debug != MagickFalse)
415 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
416 image->filename);
417 if (image->artifacts == (void *) NULL)
418 return;
419 ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
420}
421
422/*
423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424% %
425% %
426% %
427% S e t I m a g e A r t i f a c t %
428% %
429% %
430% %
431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432%
anthony5f78bca2012-10-05 06:51:00 +0000433% SetImageArtifact() associates makes a copy of the given string value
434% and inserts it into the artifact tree of the given image.
cristy3ed852e2009-09-05 21:47:34 +0000435%
436% The format of the SetImageArtifact method is:
437%
438% MagickBooleanType SetImageArtifact(Image *image,const char *artifact,
439% const char *value)
440%
441% A description of each parameter follows:
442%
443% o image: the image.
444%
445% o artifact: the image artifact.
446%
447% o values: the image artifact values.
448%
449*/
450MagickExport MagickBooleanType SetImageArtifact(Image *image,
451 const char *artifact,const char *value)
452{
453 MagickBooleanType
454 status;
455
456 assert(image != (Image *) NULL);
457 assert(image->signature == MagickSignature);
458 if (image->debug != MagickFalse)
459 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
460 image->filename);
anthonyd181ea02011-10-12 07:44:13 +0000461
anthony5f78bca2012-10-05 06:51:00 +0000462 /* Create tree if needed - specify how key,values are to be freed */
cristy3ed852e2009-09-05 21:47:34 +0000463 if (image->artifacts == (void *) NULL)
464 image->artifacts=NewSplayTree(CompareSplayTreeString,
465 RelinquishMagickMemory,RelinquishMagickMemory);
anthony7bb7aee2012-05-15 00:09:16 +0000466
467 /* Delete artifact if NULL -- empty string values are valid! */
468 if (value == (const char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000469 return(DeleteImageArtifact(image,artifact));
anthony7bb7aee2012-05-15 00:09:16 +0000470
471 /* add artifact to splay-tree */
cristy3ed852e2009-09-05 21:47:34 +0000472 status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
473 ConstantString(artifact),ConstantString(value));
474 return(status);
475}