MagickCore  6.9.13-46
Convert, Edit, Or Compose Bitmap Images
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/license/ %
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 "magick/studio.h"
44 #include "magick/artifact.h"
45 #include "magick/cache.h"
46 #include "magick/color.h"
47 #include "magick/compare.h"
48 #include "magick/constitute.h"
49 #include "magick/draw.h"
50 #include "magick/effect.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/fx.h"
54 #include "magick/fx-private.h"
55 #include "magick/gem.h"
56 #include "magick/geometry.h"
57 #include "magick/image.h"
58 #include "magick/layer.h"
59 #include "magick/list.h"
60 #include "magick/memory_.h"
61 #include "magick/monitor.h"
62 #include "magick/montage.h"
63 #include "magick/option.h"
64 #include "magick/profile.h"
65 #include "magick/quantum.h"
66 #include "magick/resource_.h"
67 #include "magick/splay-tree.h"
68 #include "magick/signature-private.h"
69 #include "magick/statistic.h"
70 #include "magick/string_.h"
71 #include "magick/token.h"
72 #include "magick/utility.h"
73 #include "magick/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 one or more image artifacts.
87 %
88 % The format of the CloneImageArtifacts method is:
89 %
90 % MagickBooleanType CloneImageArtifacts(Image *image,
91 % const Image *clone_image)
92 %
93 % A description of each parameter follows:
94 %
95 % o image: the image.
96 %
97 % o clone_image: the clone image.
98 %
99 */
100 
101 typedef char
102  *(*CloneKeyFunc)(const char *),
103  *(*CloneValueFunc)(const char *);
104 
105 static inline void *CloneArtifactKey(void *key)
106 {
107  return((void *) ((CloneKeyFunc) ConstantString)((const char *) key));
108 }
109 
110 static inline void *CloneArtifactValue(void *value)
111 {
112  return((void *) ((CloneValueFunc) ConstantString)((const char *) value));
113 }
114 
115 MagickExport MagickBooleanType CloneImageArtifacts(Image *image,
116  const Image *clone_image)
117 {
118  assert(image != (Image *) NULL);
119  assert(image->signature == MagickCoreSignature);
120  assert(clone_image != (const Image *) NULL);
121  assert(clone_image->signature == MagickCoreSignature);
122  if (IsEventLogging() != MagickFalse)
123  {
124  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
125  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
126  clone_image->filename);
127  }
128  if (clone_image->artifacts != (void *) NULL)
129  {
130  if (image->artifacts != (void *) NULL)
131  DestroyImageArtifacts(image);
132  image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts,
133  CloneArtifactKey,CloneArtifactValue);
134  }
135  return(MagickTrue);
136 }
137 
138 /*
139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 % %
141 % %
142 % %
143 % D e f i n e I m a g e A r t i f a c t %
144 % %
145 % %
146 % %
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148 %
149 % DefineImageArtifact() associates a key/value pair with an image artifact.
150 %
151 % The format of the DefineImageArtifact method is:
152 %
153 % MagickBooleanType DefineImageArtifact(Image *image,
154 % const char *artifact)
155 %
156 % A description of each parameter follows:
157 %
158 % o image: the image.
159 %
160 % o artifact: the image artifact.
161 %
162 */
163 MagickExport MagickBooleanType DefineImageArtifact(Image *image,
164  const char *artifact)
165 {
166  char
167  key[MaxTextExtent],
168  value[MaxTextExtent];
169 
170  char
171  *p;
172 
173  assert(image != (Image *) NULL);
174  assert(artifact != (const char *) NULL);
175  (void) CopyMagickString(key,artifact,MaxTextExtent-1);
176  for (p=key; *p != '\0'; p++)
177  if (*p == '=')
178  break;
179  *value='\0';
180  if (*p == '=')
181  (void) CopyMagickString(value,p+1,MaxTextExtent);
182  *p='\0';
183  return(SetImageArtifact(image,key,value));
184 }
185 
186 /*
187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188 % %
189 % %
190 % %
191 % D e l e t e I m a g e A r t i f a c t %
192 % %
193 % %
194 % %
195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196 %
197 % DeleteImageArtifact() deletes an image artifact.
198 %
199 % The format of the DeleteImageArtifact method is:
200 %
201 % MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact)
202 %
203 % A description of each parameter follows:
204 %
205 % o image: the image.
206 %
207 % o artifact: the image artifact.
208 %
209 */
210 MagickExport MagickBooleanType DeleteImageArtifact(Image *image,
211  const char *artifact)
212 {
213  assert(image != (Image *) NULL);
214  assert(image->signature == MagickCoreSignature);
215  if (IsEventLogging() != MagickFalse)
216  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
217  if (image->artifacts == (void *) NULL)
218  return(MagickFalse);
219  return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact));
220 }
221 
222 /*
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 % %
225 % %
226 % %
227 % D e s t r o y I m a g e A r t i f a c t s %
228 % %
229 % %
230 % %
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232 %
233 % DestroyImageArtifacts() releases memory associated with image artifact
234 % values.
235 %
236 % The format of the DestroyDefines method is:
237 %
238 % void DestroyImageArtifacts(Image *image)
239 %
240 % A description of each parameter follows:
241 %
242 % o image: the image.
243 %
244 */
245 MagickExport void DestroyImageArtifacts(Image *image)
246 {
247  assert(image != (Image *) NULL);
248  assert(image->signature == MagickCoreSignature);
249  if (IsEventLogging() != MagickFalse)
250  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
251  if (image->artifacts != (void *) NULL)
252  image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *)
253  image->artifacts);
254 }
255 
256 /*
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 % %
259 % %
260 % %
261 % G e t I m a g e A r t i f a c t %
262 % %
263 % %
264 % %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 %
267 % GetImageArtifact() gets a value associated with an image artifact.
268 %
269 % Note, the artifact is a constant. Do not attempt to free it.
270 %
271 % The format of the GetImageArtifact method is:
272 %
273 % const char *GetImageArtifact(const Image *image,const char *key)
274 %
275 % A description of each parameter follows:
276 %
277 % o image: the image.
278 %
279 % o key: the key.
280 %
281 */
282 MagickExport const char *GetImageArtifact(const Image *image,
283  const char *artifact)
284 {
285  const char
286  *p;
287 
288  assert(image != (Image *) NULL);
289  assert(image->signature == MagickCoreSignature);
290  if (IsEventLogging() != MagickFalse)
291  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
292  p=(const char *) NULL;
293  if (artifact == (const char *) NULL)
294  {
295  ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
296  p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
297  image->artifacts);
298  return(p);
299  }
300  if (image->artifacts != (void *) NULL)
301  {
302  p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts,
303  artifact);
304  if (p != (const char *) NULL)
305  return(p);
306  }
307  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 */
332 MagickExport char *GetNextImageArtifact(const Image *image)
333 {
334  assert(image != (Image *) NULL);
335  assert(image->signature == MagickCoreSignature);
336  if (IsEventLogging() != MagickFalse)
337  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
338  if (image->artifacts == (void *) NULL)
339  return((char *) NULL);
340  return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->artifacts));
341 }
342 
343 /*
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 % %
346 % %
347 % %
348 % R e m o v e I m a g e A r t i f a c t %
349 % %
350 % %
351 % %
352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 %
354 % RemoveImageArtifact() removes an artifact from the image and returns its
355 % value.
356 %
357 % The format of the RemoveImageArtifact method is:
358 %
359 % char *RemoveImageArtifact(Image *image,const char *artifact)
360 %
361 % A description of each parameter follows:
362 %
363 % o image: the image.
364 %
365 % o artifact: the image artifact.
366 %
367 */
368 MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
369 {
370  char
371  *value;
372 
373  assert(image != (Image *) NULL);
374  assert(image->signature == MagickCoreSignature);
375  if (IsEventLogging() != MagickFalse)
376  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
377  if (image->artifacts == (void *) NULL)
378  return((char *) NULL);
379  value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts,
380  artifact);
381  return(value);
382 }
383 
384 /*
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 % %
387 % %
388 % %
389 % 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 %
390 % %
391 % %
392 % %
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 %
395 % ResetImageArtifactIterator() resets the image artifact iterator. Use it
396 % in conjunction with GetNextImageArtifact() to iterate over all the values
397 % associated with an image artifact.
398 %
399 % The format of the ResetImageArtifactIterator method is:
400 %
401 % ResetImageArtifactIterator(Image *image)
402 %
403 % A description of each parameter follows:
404 %
405 % o image: the image.
406 %
407 */
408 MagickExport void ResetImageArtifactIterator(const Image *image)
409 {
410  assert(image != (Image *) NULL);
411  assert(image->signature == MagickCoreSignature);
412  if (IsEventLogging() != MagickFalse)
413  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
414  if (image->artifacts == (void *) NULL)
415  return;
416  ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
417 }
418 
419 /*
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421 % %
422 % %
423 % %
424 % S e t I m a g e A r t i f a c t %
425 % %
426 % %
427 % %
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
429 %
430 % SetImageArtifact() sets a key-value pair in the image artifact namespace.
431 % Artifacts differ from properties. Properties are public and are generally
432 % exported to an external image format if the format supports it. Artifacts
433 % are private and are utilized by the internal ImageMagick API to modify the
434 % behavior of certain algorithms.
435 %
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 key.
446 %
447 % o value: the image artifact value.
448 %
449 */
450 MagickExport 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 == MagickCoreSignature);
458  if (IsEventLogging() != MagickFalse)
459  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
460  /*
461  Create tree if needed.
462  */
463  if (image->artifacts == (void *) NULL)
464  image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
465  RelinquishMagickMemory);
466  /*
467  Delete artifact if NULL -- empty string values are valid!
468  */
469  if (value == (const char *) NULL)
470  return(DeleteImageArtifact(image,artifact));
471  /*
472  Add artifact to tree.
473  */
474  status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
475  ConstantString(artifact),ConstantString(value));
476  return(status);
477 }
Definition: image.h:133