MagickCore  7.1.2-29
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 "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 
103 typedef char
104  *(*CloneKeyFunc)(const char *),
105  *(*CloneValueFunc)(const char *);
106 
107 static inline void *CloneArtifactKey(void *key)
108 {
109  return((void *) ((CloneKeyFunc) ConstantString)((const char *) key));
110 }
111 
112 static inline void *CloneArtifactValue(void *value)
113 {
114  return((void *) ((CloneValueFunc) ConstantString)((const char *) value));
115 }
116 
117 MagickExport 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 */
167 MagickExport 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 */
214 MagickExport 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 */
249 MagickExport 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 */
289 MagickExport 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 */
339 MagickExport 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 */
379 MagickExport 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 */
422 MagickExport 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 */
464 MagickExport 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 }
Definition: image.h:132