/src/imagemagick/MagickCore/artifact.c
Line | Count | Source |
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/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 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 | 266k | { |
109 | 266k | return((void *) ((CloneKeyFunc) ConstantString)((const char *) key)); |
110 | 266k | } |
111 | | |
112 | | static inline void *CloneArtifactValue(void *value) |
113 | 266k | { |
114 | 266k | return((void *) ((CloneValueFunc) ConstantString)((const char *) value)); |
115 | 266k | } |
116 | | |
117 | | MagickExport MagickBooleanType CloneImageArtifacts(Image *image, |
118 | | const Image *clone_image) |
119 | 545k | { |
120 | 545k | assert(image != (Image *) NULL); |
121 | 545k | assert(image->signature == MagickCoreSignature); |
122 | 545k | assert(clone_image != (const Image *) NULL); |
123 | 545k | assert(clone_image->signature == MagickCoreSignature); |
124 | 545k | if (IsEventLogging() != MagickFalse) |
125 | 0 | { |
126 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
127 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
128 | 0 | clone_image->filename); |
129 | 0 | } |
130 | 545k | if (clone_image->artifacts != (void *) NULL) |
131 | 236k | { |
132 | 236k | if (image->artifacts != (void *) NULL) |
133 | 0 | DestroyImageArtifacts(image); |
134 | 236k | image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts, |
135 | 236k | CloneArtifactKey,CloneArtifactValue); |
136 | 236k | } |
137 | 545k | return(MagickTrue); |
138 | 545k | } |
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 | 0 | { |
170 | 0 | char |
171 | 0 | key[MagickPathExtent], |
172 | 0 | value[MagickPathExtent]; |
173 | |
|
174 | 0 | char |
175 | 0 | *p; |
176 | |
|
177 | 0 | assert(image != (Image *) NULL); |
178 | 0 | assert(artifact != (const char *) NULL); |
179 | 0 | (void) CopyMagickString(key,artifact,MagickPathExtent-1); |
180 | 0 | for (p=key; *p != '\0'; p++) |
181 | 0 | if (*p == '=') |
182 | 0 | break; |
183 | 0 | *value='\0'; |
184 | 0 | if (*p == '=') |
185 | 0 | (void) CopyMagickString(value,p+1,MagickPathExtent); |
186 | 0 | *p='\0'; |
187 | 0 | return(SetImageArtifact(image,key,value)); |
188 | 0 | } |
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 | 100k | { |
217 | 100k | assert(image != (Image *) NULL); |
218 | 100k | assert(image->signature == MagickCoreSignature); |
219 | 100k | if (IsEventLogging() != MagickFalse) |
220 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
221 | 100k | if (image->artifacts == (void *) NULL) |
222 | 81.7k | return(MagickFalse); |
223 | 19.1k | return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact)); |
224 | 100k | } |
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 | 3.60M | { |
251 | 3.60M | assert(image != (Image *) NULL); |
252 | 3.60M | assert(image->signature == MagickCoreSignature); |
253 | 3.60M | if (IsEventLogging() != MagickFalse) |
254 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
255 | 3.60M | if (image->artifacts != (void *) NULL) |
256 | 467k | image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *) |
257 | 467k | image->artifacts); |
258 | 3.60M | } |
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 | 1.96M | { |
292 | 1.96M | const char |
293 | 1.96M | *p; |
294 | | |
295 | 1.96M | assert(image != (Image *) NULL); |
296 | 1.96M | assert(image->signature == MagickCoreSignature); |
297 | 1.96M | if (IsEventLogging() != MagickFalse) |
298 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
299 | 1.96M | p=(const char *) NULL; |
300 | 1.96M | if (image->artifacts != (void *) NULL) |
301 | 1.07M | { |
302 | 1.07M | if (artifact == (const char *) NULL) |
303 | 0 | return((const char *) GetRootValueFromSplayTree((SplayTreeInfo *) |
304 | 0 | image->artifacts)); |
305 | 1.07M | p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts, |
306 | 1.07M | artifact); |
307 | 1.07M | if (p != (const char *) NULL) |
308 | 138k | return(p); |
309 | 1.07M | } |
310 | 1.82M | if ((image->image_info != (ImageInfo *) NULL) && |
311 | 1.74M | (image->image_info->options != (void *) NULL)) |
312 | 0 | p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) |
313 | 0 | image->image_info->options,artifact); |
314 | 1.82M | return(p); |
315 | 1.96M | } |
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 | 69 | { |
341 | 69 | assert(image != (Image *) NULL); |
342 | 69 | assert(image->signature == MagickCoreSignature); |
343 | 69 | if (IsEventLogging() != MagickFalse) |
344 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
345 | 69 | if (image->artifacts == (void *) NULL) |
346 | 10 | return((const char *) NULL); |
347 | 59 | return((const char *) GetNextKeyInSplayTree( |
348 | 59 | (SplayTreeInfo *) image->artifacts)); |
349 | 69 | } |
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 | 0 | { |
381 | 0 | char |
382 | 0 | *value; |
383 | |
|
384 | 0 | assert(image != (Image *) NULL); |
385 | 0 | assert(image->signature == MagickCoreSignature); |
386 | 0 | if (IsEventLogging() != MagickFalse) |
387 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
388 | 0 | if (image->artifacts == (void *) NULL) |
389 | 0 | return((char *) NULL); |
390 | 0 | value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts, |
391 | 0 | artifact); |
392 | 0 | return(value); |
393 | 0 | } |
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 | 45 | { |
424 | 45 | assert(image != (Image *) NULL); |
425 | 45 | assert(image->signature == MagickCoreSignature); |
426 | 45 | if (IsEventLogging() != MagickFalse) |
427 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
428 | 45 | if (image->artifacts == (void *) NULL) |
429 | 10 | return; |
430 | 35 | ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts); |
431 | 35 | } |
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 | 340k | { |
467 | 340k | MagickBooleanType |
468 | 340k | status; |
469 | | |
470 | 340k | assert(image != (Image *) NULL); |
471 | 340k | assert(image->signature == MagickCoreSignature); |
472 | 340k | if (IsEventLogging() != MagickFalse) |
473 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
474 | | /* |
475 | | Create tree if needed - specify how key,values are to be freed. |
476 | | */ |
477 | 340k | if (image->artifacts == (void *) NULL) |
478 | 230k | image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, |
479 | 230k | RelinquishMagickMemory); |
480 | | /* |
481 | | Delete artifact if NULL -- empty string values are valid!, |
482 | | */ |
483 | 340k | if (value == (const char *) NULL) |
484 | 0 | return(DeleteImageArtifact(image,artifact)); |
485 | | /* |
486 | | Add artifact to splay-tree. |
487 | | */ |
488 | 340k | status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts, |
489 | 340k | ConstantString(artifact),ConstantString(value)); |
490 | 340k | return(status); |
491 | 340k | } |