| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % AAA RRRR TTTTT IIIII FFFFF AAA CCCC TTTTT % |
| % A A R R T I F A A C T % |
| % AAAAA RRRRR T I FFF AAAAA C T % |
| % A A R R T I F A A C T % |
| % A A R R T IIIII F A A CCCCC T % |
| % % |
| % % |
| % MagickCore Artifact Methods % |
| % % |
| % Software Design % |
| % Cristy % |
| % March 2000 % |
| % % |
| % % |
| % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % |
| % dedicated to making software imaging solutions freely available. % |
| % % |
| % You may not use this file except in compliance with the License. You may % |
| % obtain a copy of the License at % |
| % % |
| % https://imagemagick.org/script/license.php % |
| % % |
| % Unless required by applicable law or agreed to in writing, software % |
| % distributed under the License is distributed on an "AS IS" BASIS, % |
| % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
| % See the License for the specific language governing permissions and % |
| % limitations under the License. % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % |
| % |
| */ |
| |
| /* |
| Include declarations. |
| */ |
| #include "MagickCore/studio.h" |
| #include "MagickCore/artifact.h" |
| #include "MagickCore/cache.h" |
| #include "MagickCore/color.h" |
| #include "MagickCore/compare.h" |
| #include "MagickCore/constitute.h" |
| #include "MagickCore/draw.h" |
| #include "MagickCore/effect.h" |
| #include "MagickCore/exception.h" |
| #include "MagickCore/exception-private.h" |
| #include "MagickCore/fx.h" |
| #include "MagickCore/fx-private.h" |
| #include "MagickCore/gem.h" |
| #include "MagickCore/geometry.h" |
| #include "MagickCore/image.h" |
| #include "MagickCore/layer.h" |
| #include "MagickCore/list.h" |
| #include "MagickCore/memory_.h" |
| #include "MagickCore/monitor.h" |
| #include "MagickCore/montage.h" |
| #include "MagickCore/option.h" |
| #include "MagickCore/profile.h" |
| #include "MagickCore/quantum.h" |
| #include "MagickCore/resource_.h" |
| #include "MagickCore/splay-tree.h" |
| #include "MagickCore/signature-private.h" |
| #include "MagickCore/statistic.h" |
| #include "MagickCore/string_.h" |
| #include "MagickCore/token.h" |
| #include "MagickCore/utility.h" |
| #include "MagickCore/xml-tree.h" |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % C l o n e I m a g e A r t i f a c t s % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % CloneImageArtifacts() clones all image artifacts to another image. |
| % |
| % This will not delete any existing artifacts that may be present! |
| % |
| % The format of the CloneImageArtifacts method is: |
| % |
| % MagickBooleanType CloneImageArtifacts(Image *image, |
| % const Image *clone_image) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image, to recieve the cloned artifacts. |
| % |
| % o clone_image: the source image for artifacts to clone. |
| % |
| */ |
| MagickExport MagickBooleanType CloneImageArtifacts(Image *image, |
| const Image *clone_image) |
| { |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| assert(clone_image != (const Image *) NULL); |
| assert(clone_image->signature == MagickCoreSignature); |
| if (clone_image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
| clone_image->filename); |
| if (clone_image->artifacts != (void *) NULL) |
| { |
| if (image->artifacts != (void *) NULL) |
| DestroyImageArtifacts(image); |
| image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts, |
| (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString); |
| } |
| return(MagickTrue); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % D e f i n e I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % DefineImageArtifact() associates an assignment string of the form |
| % "key=value" with per-image artifact. It is equivelent to |
| % SetImageArtifact(). |
| % |
| % The format of the DefineImageArtifact method is: |
| % |
| % MagickBooleanType DefineImageArtifact(Image *image, |
| % const char *artifact) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o artifact: the image artifact. |
| % |
| */ |
| MagickExport MagickBooleanType DefineImageArtifact(Image *image, |
| const char *artifact) |
| { |
| char |
| key[MagickPathExtent], |
| value[MagickPathExtent]; |
| |
| char |
| *p; |
| |
| assert(image != (Image *) NULL); |
| assert(artifact != (const char *) NULL); |
| (void) CopyMagickString(key,artifact,MagickPathExtent-1); |
| for (p=key; *p != '\0'; p++) |
| if (*p == '=') |
| break; |
| *value='\0'; |
| if (*p == '=') |
| (void) CopyMagickString(value,p+1,MagickPathExtent); |
| *p='\0'; |
| return(SetImageArtifact(image,key,value)); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % D e l e t e I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % DeleteImageArtifact() deletes an image artifact. |
| % |
| % The format of the DeleteImageArtifact method is: |
| % |
| % MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o artifact: the image artifact. |
| % |
| */ |
| MagickExport MagickBooleanType DeleteImageArtifact(Image *image, |
| const char *artifact) |
| { |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| if (image->artifacts == (void *) NULL) |
| return(MagickFalse); |
| return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact)); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % D e s t r o y I m a g e A r t i f a c t s % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % DestroyImageArtifacts() destroys all artifacts and associated memory |
| % attached to the given image. |
| % |
| % The format of the DestroyImageArtifacts method is: |
| % |
| % void DestroyImageArtifacts(Image *image) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| */ |
| MagickExport void DestroyImageArtifacts(Image *image) |
| { |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| if (image->artifacts != (void *) NULL) |
| image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *) |
| image->artifacts); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % G e t I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % GetImageArtifact() gets a value associated with an image artifact. |
| % If the requested artifact is NULL return the first artifact, to |
| % prepare to iterate over all artifacts. |
| % |
| % The returned string is a constant string in the tree and should NOT be |
| % freed by the caller. |
| % |
| % The format of the GetImageArtifact method is: |
| % |
| % const char *GetImageArtifact(const Image *image,const char *key) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o key: the key. |
| % |
| */ |
| MagickExport const char *GetImageArtifact(const Image *image, |
| const char *artifact) |
| { |
| const char |
| *p; |
| |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| p=(const char *) NULL; |
| if (image->artifacts != (void *) NULL) |
| { |
| if (artifact == (const char *) NULL) |
| return((const char *) GetRootValueFromSplayTree((SplayTreeInfo *) |
| image->artifacts)); |
| p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts, |
| artifact); |
| if (p != (const char *) NULL) |
| return(p); |
| } |
| if ((image->image_info != (ImageInfo *) NULL) && |
| (image->image_info->options != (void *) NULL)) |
| p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) |
| image->image_info->options,artifact); |
| return(p); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % G e t N e x t I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % GetNextImageArtifact() gets the next image artifact value. |
| % |
| % The format of the GetNextImageArtifact method is: |
| % |
| % char *GetNextImageArtifact(const Image *image) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| */ |
| MagickExport const char *GetNextImageArtifact(const Image *image) |
| { |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| if (image->artifacts == (void *) NULL) |
| return((const char *) NULL); |
| return((const char *) GetNextKeyInSplayTree( |
| (SplayTreeInfo *) image->artifacts)); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % R e m o v e I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % RemoveImageArtifact() removes an artifact from the image and returns its |
| % value. |
| % |
| % In this case the ConstantString() value returned should be freed by the |
| % caller when finished. |
| % |
| % The format of the RemoveImageArtifact method is: |
| % |
| % char *RemoveImageArtifact(Image *image,const char *artifact) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o artifact: the image artifact. |
| % |
| */ |
| MagickExport char *RemoveImageArtifact(Image *image,const char *artifact) |
| { |
| char |
| *value; |
| |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| if (image->artifacts == (void *) NULL) |
| return((char *) NULL); |
| value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts, |
| artifact); |
| return(value); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % 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 % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % ResetImageArtifactIterator() resets the image artifact iterator. Use it |
| % in conjunction with GetNextImageArtifact() to iterate over all the values |
| % associated with an image artifact. |
| % |
| % Alternatively you can use GetImageArtifact() with a NULL artifact field to |
| % reset the iterator and return the first artifact. |
| % |
| % The format of the ResetImageArtifactIterator method is: |
| % |
| % ResetImageArtifactIterator(Image *image) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| */ |
| MagickExport void ResetImageArtifactIterator(const Image *image) |
| { |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| if (image->artifacts == (void *) NULL) |
| return; |
| ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts); |
| } |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % S e t I m a g e A r t i f a c t % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % SetImageArtifact() sets a key-value pair in the image artifact namespace. |
| % Artifacts differ from properties. Properties are public and are generally |
| % exported to an external image format if the format supports it. Artifacts |
| % are private and are utilized by the internal ImageMagick API to modify the |
| % behavior of certain algorithms. |
| % |
| % The format of the SetImageArtifact method is: |
| % |
| % MagickBooleanType SetImageArtifact(Image *image,const char *artifact, |
| % const char *value) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o artifact: the image artifact key. |
| % |
| % o value: the image artifact value. |
| % |
| */ |
| MagickExport MagickBooleanType SetImageArtifact(Image *image, |
| const char *artifact,const char *value) |
| { |
| MagickBooleanType |
| status; |
| |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickCoreSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| /* |
| Create tree if needed - specify how key,values are to be freed. |
| */ |
| if (image->artifacts == (void *) NULL) |
| image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, |
| RelinquishMagickMemory); |
| /* |
| Delete artifact if NULL -- empty string values are valid!, |
| */ |
| if (value == (const char *) NULL) |
| return(DeleteImageArtifact(image,artifact)); |
| /* |
| Add artifact to splay-tree. |
| */ |
| status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts, |
| ConstantString(artifact),ConstantString(value)); |
| return(status); |
| } |