/src/imagemagick/MagickCore/artifact.c
Line | Count | Source (jump to first uncovered line) |
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 | | MagickExport MagickBooleanType CloneImageArtifacts(Image *image, |
103 | | const Image *clone_image) |
104 | 597k | { |
105 | 597k | assert(image != (Image *) NULL); |
106 | 597k | assert(image->signature == MagickCoreSignature); |
107 | 597k | assert(clone_image != (const Image *) NULL); |
108 | 597k | assert(clone_image->signature == MagickCoreSignature); |
109 | 597k | if (IsEventLogging() != MagickFalse) |
110 | 0 | { |
111 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
112 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
113 | 0 | clone_image->filename); |
114 | 0 | } |
115 | 597k | if (clone_image->artifacts != (void *) NULL) |
116 | 242k | { |
117 | 242k | if (image->artifacts != (void *) NULL) |
118 | 0 | DestroyImageArtifacts(image); |
119 | 242k | image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts, |
120 | 242k | (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString); |
121 | 242k | } |
122 | 597k | return(MagickTrue); |
123 | 597k | } |
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 equivalent 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 | 0 | { |
155 | 0 | char |
156 | 0 | key[MagickPathExtent], |
157 | 0 | value[MagickPathExtent]; |
158 | |
|
159 | 0 | char |
160 | 0 | *p; |
161 | |
|
162 | 0 | assert(image != (Image *) NULL); |
163 | 0 | assert(artifact != (const char *) NULL); |
164 | 0 | (void) CopyMagickString(key,artifact,MagickPathExtent-1); |
165 | 0 | for (p=key; *p != '\0'; p++) |
166 | 0 | if (*p == '=') |
167 | 0 | break; |
168 | 0 | *value='\0'; |
169 | 0 | if (*p == '=') |
170 | 0 | (void) CopyMagickString(value,p+1,MagickPathExtent); |
171 | 0 | *p='\0'; |
172 | 0 | return(SetImageArtifact(image,key,value)); |
173 | 0 | } |
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 | 100k | { |
202 | 100k | assert(image != (Image *) NULL); |
203 | 100k | assert(image->signature == MagickCoreSignature); |
204 | 100k | if (IsEventLogging() != MagickFalse) |
205 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
206 | 100k | if (image->artifacts == (void *) NULL) |
207 | 81.5k | return(MagickFalse); |
208 | 18.5k | return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact)); |
209 | 100k | } |
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 | 4.11M | { |
236 | 4.11M | assert(image != (Image *) NULL); |
237 | 4.11M | assert(image->signature == MagickCoreSignature); |
238 | 4.11M | if (IsEventLogging() != MagickFalse) |
239 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
240 | 4.11M | if (image->artifacts != (void *) NULL) |
241 | 466k | image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *) |
242 | 466k | image->artifacts); |
243 | 4.11M | } |
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 | 2.06M | { |
277 | 2.06M | const char |
278 | 2.06M | *p; |
279 | | |
280 | 2.06M | assert(image != (Image *) NULL); |
281 | 2.06M | assert(image->signature == MagickCoreSignature); |
282 | 2.06M | if (IsEventLogging() != MagickFalse) |
283 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
284 | 2.06M | p=(const char *) NULL; |
285 | 2.06M | if (image->artifacts != (void *) NULL) |
286 | 1.07M | { |
287 | 1.07M | if (artifact == (const char *) NULL) |
288 | 0 | return((const char *) GetRootValueFromSplayTree((SplayTreeInfo *) |
289 | 0 | image->artifacts)); |
290 | 1.07M | p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts, |
291 | 1.07M | artifact); |
292 | 1.07M | if (p != (const char *) NULL) |
293 | 135k | return(p); |
294 | 1.07M | } |
295 | 1.93M | if ((image->image_info != (ImageInfo *) NULL) && |
296 | 1.93M | (image->image_info->options != (void *) NULL)) |
297 | 0 | p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) |
298 | 0 | image->image_info->options,artifact); |
299 | 1.93M | return(p); |
300 | 2.06M | } |
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 | 78 | { |
326 | 78 | assert(image != (Image *) NULL); |
327 | 78 | assert(image->signature == MagickCoreSignature); |
328 | 78 | if (IsEventLogging() != MagickFalse) |
329 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
330 | 78 | if (image->artifacts == (void *) NULL) |
331 | 11 | return((const char *) NULL); |
332 | 67 | return((const char *) GetNextKeyInSplayTree( |
333 | 67 | (SplayTreeInfo *) image->artifacts)); |
334 | 78 | } |
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 | 0 | { |
366 | 0 | char |
367 | 0 | *value; |
368 | |
|
369 | 0 | assert(image != (Image *) NULL); |
370 | 0 | assert(image->signature == MagickCoreSignature); |
371 | 0 | if (IsEventLogging() != MagickFalse) |
372 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
373 | 0 | if (image->artifacts == (void *) NULL) |
374 | 0 | return((char *) NULL); |
375 | 0 | value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts, |
376 | 0 | artifact); |
377 | 0 | return(value); |
378 | 0 | } |
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 | 50 | { |
409 | 50 | assert(image != (Image *) NULL); |
410 | 50 | assert(image->signature == MagickCoreSignature); |
411 | 50 | if (IsEventLogging() != MagickFalse) |
412 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
413 | 50 | if (image->artifacts == (void *) NULL) |
414 | 11 | return; |
415 | 39 | ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts); |
416 | 39 | } |
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 | 332k | { |
452 | 332k | MagickBooleanType |
453 | 332k | status; |
454 | | |
455 | 332k | assert(image != (Image *) NULL); |
456 | 332k | assert(image->signature == MagickCoreSignature); |
457 | 332k | if (IsEventLogging() != MagickFalse) |
458 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
459 | | /* |
460 | | Create tree if needed - specify how key,values are to be freed. |
461 | | */ |
462 | 332k | if (image->artifacts == (void *) NULL) |
463 | 224k | image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, |
464 | 224k | RelinquishMagickMemory); |
465 | | /* |
466 | | Delete artifact if NULL -- empty string values are valid!, |
467 | | */ |
468 | 332k | if (value == (const char *) NULL) |
469 | 0 | return(DeleteImageArtifact(image,artifact)); |
470 | | /* |
471 | | Add artifact to splay-tree. |
472 | | */ |
473 | 332k | status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts, |
474 | 332k | ConstantString(artifact),ConstantString(value)); |
475 | 332k | return(status); |
476 | 332k | } |