Home | History | Annotate | Download | only in MagickCore
      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-2016 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 %    http://www.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 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/artifact.h"
     46 #include "MagickCore/cache.h"
     47 #include "MagickCore/color.h"
     48 #include "MagickCore/compare.h"
     49 #include "MagickCore/constitute.h"
     50 #include "MagickCore/draw.h"
     51 #include "MagickCore/effect.h"
     52 #include "MagickCore/exception.h"
     53 #include "MagickCore/exception-private.h"
     54 #include "MagickCore/fx.h"
     55 #include "MagickCore/fx-private.h"
     56 #include "MagickCore/gem.h"
     57 #include "MagickCore/geometry.h"
     58 #include "MagickCore/image.h"
     59 #include "MagickCore/layer.h"
     60 #include "MagickCore/list.h"
     61 #include "MagickCore/memory_.h"
     62 #include "MagickCore/monitor.h"
     63 #include "MagickCore/montage.h"
     64 #include "MagickCore/option.h"
     65 #include "MagickCore/profile.h"
     66 #include "MagickCore/quantum.h"
     67 #include "MagickCore/resource_.h"
     68 #include "MagickCore/splay-tree.h"
     69 #include "MagickCore/signature-private.h"
     70 #include "MagickCore/statistic.h"
     71 #include "MagickCore/string_.h"
     72 #include "MagickCore/token.h"
     73 #include "MagickCore/utility.h"
     74 #include "MagickCore/xml-tree.h"
     75 
     76 /*
     78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     79 %                                                                             %
     80 %                                                                             %
     81 %                                                                             %
     82 %   C l o n e I m a g e A r t i f a c t s                                     %
     83 %                                                                             %
     84 %                                                                             %
     85 %                                                                             %
     86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     87 %
     88 %  CloneImageArtifacts() clones all image artifacts to another image.
     89 %
     90 %  This will not delete any existing artifacts that may be present!
     91 %
     92 %  The format of the CloneImageArtifacts method is:
     93 %
     94 %      MagickBooleanType CloneImageArtifacts(Image *image,
     95 %        const Image *clone_image)
     96 %
     97 %  A description of each parameter follows:
     98 %
     99 %    o image: the image, to recieve the cloned artifacts.
    100 %
    101 %    o clone_image: the source image for artifacts to clone.
    102 %
    103 */
    104 MagickExport MagickBooleanType CloneImageArtifacts(Image *image,
    105   const Image *clone_image)
    106 {
    107   assert(image != (Image *) NULL);
    108   assert(image->signature == MagickCoreSignature);
    109   if (image->debug != MagickFalse)
    110     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    111   assert(clone_image != (const Image *) NULL);
    112   assert(clone_image->signature == MagickCoreSignature);
    113   if (clone_image->debug != MagickFalse)
    114     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    115       clone_image->filename);
    116   if (clone_image->artifacts != (void *) NULL)
    117     {
    118       if (image->artifacts != (void *) NULL)
    119         DestroyImageArtifacts(image);
    120       image->artifacts=CloneSplayTree((SplayTreeInfo *) clone_image->artifacts,
    121         (void *(*)(void *)) ConstantString,(void *(*)(void *)) ConstantString);
    122     }
    123   return(MagickTrue);
    124 }
    125 
    126 /*
    128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    129 %                                                                             %
    130 %                                                                             %
    131 %                                                                             %
    132 %   D e f i n e I m a g e A r t i f a c t                                     %
    133 %                                                                             %
    134 %                                                                             %
    135 %                                                                             %
    136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    137 %
    138 %  DefineImageArtifact() associates an assignment string of the form
    139 %  "key=value" with per-image artifact. It is equivelent to
    140 %  SetImageArtifact().
    141 %
    142 %  The format of the DefineImageArtifact method is:
    143 %
    144 %      MagickBooleanType DefineImageArtifact(Image *image,
    145 %        const char *artifact)
    146 %
    147 %  A description of each parameter follows:
    148 %
    149 %    o image: the image.
    150 %
    151 %    o artifact: the image artifact.
    152 %
    153 */
    154 MagickExport MagickBooleanType DefineImageArtifact(Image *image,
    155   const char *artifact)
    156 {
    157   char
    158     key[MagickPathExtent],
    159     value[MagickPathExtent];
    160 
    161   register char
    162     *p;
    163 
    164   assert(image != (Image *) NULL);
    165   assert(artifact != (const char *) NULL);
    166   (void) CopyMagickString(key,artifact,MagickPathExtent-1);
    167   for (p=key; *p != '\0'; p++)
    168     if (*p == '=')
    169       break;
    170   *value='\0';
    171   if (*p == '=')
    172     (void) CopyMagickString(value,p+1,MagickPathExtent);
    173   *p='\0';
    174   return(SetImageArtifact(image,key,value));
    175 }
    176 
    177 /*
    179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    180 %                                                                             %
    181 %                                                                             %
    182 %                                                                             %
    183 %   D e l e t e I m a g e A r t i f a c t                                     %
    184 %                                                                             %
    185 %                                                                             %
    186 %                                                                             %
    187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    188 %
    189 %  DeleteImageArtifact() deletes an image artifact.
    190 %
    191 %  The format of the DeleteImageArtifact method is:
    192 %
    193 %      MagickBooleanType DeleteImageArtifact(Image *image,const char *artifact)
    194 %
    195 %  A description of each parameter follows:
    196 %
    197 %    o image: the image.
    198 %
    199 %    o artifact: the image artifact.
    200 %
    201 */
    202 MagickExport MagickBooleanType DeleteImageArtifact(Image *image,
    203   const char *artifact)
    204 {
    205   assert(image != (Image *) NULL);
    206   assert(image->signature == MagickCoreSignature);
    207   if (image->debug != MagickFalse)
    208     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    209   if (image->artifacts == (void *) NULL)
    210     return(MagickFalse);
    211   return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->artifacts,artifact));
    212 }
    213 
    214 /*
    216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    217 %                                                                             %
    218 %                                                                             %
    219 %                                                                             %
    220 %   D e s t r o y I m a g e A r t i f a c t s                                 %
    221 %                                                                             %
    222 %                                                                             %
    223 %                                                                             %
    224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    225 %
    226 %  DestroyImageArtifacts() destroys all artifacts and associated memory
    227 %  attached to the given image.
    228 %
    229 %  The format of the DestroyImageArtifacts method is:
    230 %
    231 %      void DestroyImageArtifacts(Image *image)
    232 %
    233 %  A description of each parameter follows:
    234 %
    235 %    o image: the image.
    236 %
    237 */
    238 MagickExport void DestroyImageArtifacts(Image *image)
    239 {
    240   assert(image != (Image *) NULL);
    241   assert(image->signature == MagickCoreSignature);
    242   if (image->debug != MagickFalse)
    243     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    244   if (image->artifacts != (void *) NULL)
    245     image->artifacts=(void *) DestroySplayTree((SplayTreeInfo *)
    246       image->artifacts);
    247 }
    248 
    249 /*
    251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    252 %                                                                             %
    253 %                                                                             %
    254 %                                                                             %
    255 %   G e t I m a g e A r t i f a c t                                           %
    256 %                                                                             %
    257 %                                                                             %
    258 %                                                                             %
    259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    260 %
    261 %  GetImageArtifact() gets a value associated with an image artifact.
    262 %  If the requested artifact is NULL return the first artifact, to
    263 %  prepare to iterate over all artifacts.
    264 %
    265 %  The returned string is a constant string in the tree and should NOT be
    266 %  freed by the caller.
    267 %
    268 %  The format of the GetImageArtifact method is:
    269 %
    270 %      const char *GetImageArtifact(const Image *image,const char *key)
    271 %
    272 %  A description of each parameter follows:
    273 %
    274 %    o image: the image.
    275 %
    276 %    o key: the key.
    277 %
    278 */
    279 MagickExport const char *GetImageArtifact(const Image *image,
    280   const char *artifact)
    281 {
    282   register const char
    283     *p;
    284 
    285   assert(image != (Image *) NULL);
    286   assert(image->signature == MagickCoreSignature);
    287   if (image->debug != MagickFalse)
    288     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    289   p=(const char *) NULL;
    290   if (artifact == (const char *) NULL)
    291     {
    292       ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
    293       p=(const char *) GetNextValueInSplayTree((SplayTreeInfo *)
    294         image->artifacts);
    295       return(p);
    296     }
    297   if (image->artifacts != (void *) NULL)
    298     {
    299       p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts,
    300         artifact);
    301       if (p != (const char *) NULL)
    302         return(p);
    303     }
    304   if ((image->image_info != (ImageInfo *) NULL) &&
    305       (image->image_info->options != (void *) NULL))
    306     p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
    307       image->image_info->options,artifact);
    308   return(p);
    309 }
    310 
    311 /*
    313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    314 %                                                                             %
    315 %                                                                             %
    316 %                                                                             %
    317 %   G e t N e x t I m a g e A r t i f a c t                                   %
    318 %                                                                             %
    319 %                                                                             %
    320 %                                                                             %
    321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    322 %
    323 %  GetNextImageArtifact() gets the next image artifact value.
    324 %
    325 %  The format of the GetNextImageArtifact method is:
    326 %
    327 %      char *GetNextImageArtifact(const Image *image)
    328 %
    329 %  A description of each parameter follows:
    330 %
    331 %    o image: the image.
    332 %
    333 */
    334 MagickExport const char *GetNextImageArtifact(const Image *image)
    335 {
    336   assert(image != (Image *) NULL);
    337   assert(image->signature == MagickCoreSignature);
    338   if (image->debug != MagickFalse)
    339     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    340   if (image->artifacts == (void *) NULL)
    341     return((const char *) NULL);
    342   return((const char *) GetNextKeyInSplayTree(
    343    (SplayTreeInfo *) image->artifacts));
    344 }
    345 
    346 /*
    348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    349 %                                                                             %
    350 %                                                                             %
    351 %                                                                             %
    352 %   R e m o v e I m a g e A r t i f a c t                                     %
    353 %                                                                             %
    354 %                                                                             %
    355 %                                                                             %
    356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    357 %
    358 %  RemoveImageArtifact() removes an artifact from the image and returns its
    359 %  value.
    360 %
    361 %  In this case the ConstantString() value returned should be freed by the
    362 %  caller when finished.
    363 %
    364 %  The format of the RemoveImageArtifact method is:
    365 %
    366 %      char *RemoveImageArtifact(Image *image,const char *artifact)
    367 %
    368 %  A description of each parameter follows:
    369 %
    370 %    o image: the image.
    371 %
    372 %    o artifact: the image artifact.
    373 %
    374 */
    375 MagickExport char *RemoveImageArtifact(Image *image,const char *artifact)
    376 {
    377   char
    378     *value;
    379 
    380   assert(image != (Image *) NULL);
    381   assert(image->signature == MagickCoreSignature);
    382   if (image->debug != MagickFalse)
    383     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    384   if (image->artifacts == (void *) NULL)
    385     return((char *) NULL);
    386   value=(char *) RemoveNodeFromSplayTree((SplayTreeInfo *) image->artifacts,
    387     artifact);
    388   return(value);
    389 }
    390 
    391 /*
    393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    394 %                                                                             %
    395 %                                                                             %
    396 %                                                                             %
    397 %   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                       %
    398 %                                                                             %
    399 %                                                                             %
    400 %                                                                             %
    401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    402 %
    403 %  ResetImageArtifactIterator() resets the image artifact iterator.  Use it
    404 %  in conjunction with GetNextImageArtifact() to iterate over all the values
    405 %  associated with an image artifact.
    406 %
    407 %  Alternatively you can use GetImageArtifact() with a NULL artifact field to
    408 %  reset the iterator and return the first artifact.
    409 %
    410 %  The format of the ResetImageArtifactIterator method is:
    411 %
    412 %      ResetImageArtifactIterator(Image *image)
    413 %
    414 %  A description of each parameter follows:
    415 %
    416 %    o image: the image.
    417 %
    418 */
    419 MagickExport void ResetImageArtifactIterator(const Image *image)
    420 {
    421   assert(image != (Image *) NULL);
    422   assert(image->signature == MagickCoreSignature);
    423   if (image->debug != MagickFalse)
    424     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    425   if (image->artifacts == (void *) NULL)
    426     return;
    427   ResetSplayTreeIterator((SplayTreeInfo *) image->artifacts);
    428 }
    429 
    430 /*
    432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    433 %                                                                             %
    434 %                                                                             %
    435 %                                                                             %
    436 %   S e t I m a g e A r t i f a c t                                           %
    437 %                                                                             %
    438 %                                                                             %
    439 %                                                                             %
    440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    441 %
    442 %  SetImageArtifact() associates makes a copy of the given string arguments
    443 %  and inserts it into the artifact tree of the given image.
    444 %
    445 %  The format of the SetImageArtifact method is:
    446 %
    447 %      MagickBooleanType SetImageArtifact(Image *image,const char *artifact,
    448 %        const char *value)
    449 %
    450 %  A description of each parameter follows:
    451 %
    452 %    o image: the image.
    453 %
    454 %    o artifact: the image artifact key.
    455 %
    456 %    o value: the image artifact value.
    457 %
    458 */
    459 MagickExport MagickBooleanType SetImageArtifact(Image *image,
    460   const char *artifact,const char *value)
    461 {
    462   MagickBooleanType
    463     status;
    464 
    465   assert(image != (Image *) NULL);
    466   assert(image->signature == MagickCoreSignature);
    467   if (image->debug != MagickFalse)
    468     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    469   /*
    470     Create tree if needed - specify how key,values are to be freed.
    471   */
    472   if (image->artifacts == (void *) NULL)
    473     image->artifacts=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
    474       RelinquishMagickMemory);
    475   /*
    476     Delete artifact if NULL --  empty string values are valid!,
    477   */
    478   if (value == (const char *) NULL)
    479     return(DeleteImageArtifact(image,artifact));
    480   /*
    481     Add artifact to splay-tree.
    482   */
    483   status=AddValueToSplayTree((SplayTreeInfo *) image->artifacts,
    484     ConstantString(artifact),ConstantString(value));
    485   return(status);
    486 }
    487