MagickCore  7.1.0
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 @ 2000 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 recieve the cloned artifacts.
98 %
99 % o clone_image: the source image for artifacts to clone.
100 %
101 */
102 MagickExport 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 equivelent 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 */
152 MagickExport 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 */
199 MagickExport 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 */
234 MagickExport 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 */
274 MagickExport 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 */
324 MagickExport 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 */
364 MagickExport 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 */
407 MagickExport 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 */
449 MagickExport 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 }
Definition: image.h:152