Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %           RRRR    EEEEE    GGG   IIIII  SSSSS  TTTTT  RRRR   Y   Y          %
      7 %           R   R   E       G        I    SS       T    R   R   Y Y           %
      8 %           RRRR    EEE     G GGG    I     SSS     T    RRRR     Y            %
      9 %           R R     E       G   G    I       SS    T    R R      Y            %
     10 %           R  R    EEEEE    GGG   IIIII  SSSSS    T    R  R     Y            %
     11 %                                                                             %
     12 %                                                                             %
     13 %                       MagickCore Registry Methods                           %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 March 2000                                  %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2019 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 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/exception.h"
     46 #include "MagickCore/exception-private.h"
     47 #include "MagickCore/image.h"
     48 #include "MagickCore/list.h"
     49 #include "MagickCore/memory_.h"
     50 #include "MagickCore/memory-private.h"
     51 #include "MagickCore/registry.h"
     52 #include "MagickCore/registry-private.h"
     53 #include "MagickCore/splay-tree.h"
     54 #include "MagickCore/string_.h"
     55 #include "MagickCore/utility.h"
     56 
     57 /*
     59   Typedef declarations.
     60 */
     61 typedef struct _RegistryInfo
     62 {
     63   RegistryType
     64     type;
     65 
     66   void
     67     *value;
     68 
     69   size_t
     70     signature;
     71 } RegistryInfo;
     72 
     73 /*
     75   Static declarations.
     76 */
     77 static SplayTreeInfo
     78   *registry = (SplayTreeInfo *) NULL;
     79 
     80 static SemaphoreInfo
     81   *registry_semaphore = (SemaphoreInfo *) NULL;
     82 
     83 /*
     85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     86 %                                                                             %
     87 %                                                                             %
     88 %                                                                             %
     89 %   D e f i n e I m a g e R e g i s t r y                                     %
     90 %                                                                             %
     91 %                                                                             %
     92 %                                                                             %
     93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     94 %
     95 %  DefineImageRegistry() associates a key/value pair with the image registry.
     96 %
     97 %  The format of the DefineImageRegistry method is:
     98 %
     99 %      MagickBooleanType DefineImageRegistry(const RegistryType type,
    100 %        const char *option,ExceptionInfo *exception)
    101 %
    102 %  A description of each parameter follows:
    103 %
    104 %    o type: the type.
    105 %
    106 %    o option: the option.
    107 %
    108 %    o exception: the exception.
    109 %
    110 */
    111 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
    112   const char *option,ExceptionInfo *exception)
    113 {
    114   char
    115     key[MagickPathExtent],
    116     value[MagickPathExtent];
    117 
    118   register char
    119     *p;
    120 
    121   assert(option != (const char *) NULL);
    122   (void) CopyMagickString(key,option,MagickPathExtent);
    123   for (p=key; *p != '\0'; p++)
    124     if (*p == '=')
    125       break;
    126   *value='\0';
    127   if (*p == '=')
    128     (void) CopyMagickString(value,p+1,MagickPathExtent);
    129   *p='\0';
    130   return(SetImageRegistry(type,key,value,exception));
    131 }
    132 
    133 /*
    135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    136 %                                                                             %
    137 %                                                                             %
    138 %                                                                             %
    139 %   D e l e t e I m a g e R e g i s t r y                                     %
    140 %                                                                             %
    141 %                                                                             %
    142 %                                                                             %
    143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    144 %
    145 %  DeleteImageRegistry() deletes a key from the image registry.
    146 %
    147 %  The format of the DeleteImageRegistry method is:
    148 %
    149 %      MagickBooleanType DeleteImageRegistry(const char *key)
    150 %
    151 %  A description of each parameter follows:
    152 %
    153 %    o key: the registry.
    154 %
    155 */
    156 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
    157 {
    158   if (IsEventLogging() != MagickFalse)
    159     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
    160   if (registry == (void *) NULL)
    161     return(MagickFalse);
    162   return(DeleteNodeFromSplayTree(registry,key));
    163 }
    164 
    165 /*
    167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    168 %                                                                             %
    169 %                                                                             %
    170 %                                                                             %
    171 %   G e t I m a g e R e g i s t r y                                           %
    172 %                                                                             %
    173 %                                                                             %
    174 %                                                                             %
    175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    176 %
    177 %  GetImageRegistry() returns a value associated with an image registry key.
    178 %
    179 %  The format of the GetImageRegistry method is:
    180 %
    181 %      void *GetImageRegistry(const RegistryType type,const char *key,
    182 %        ExceptionInfo *exception)
    183 %
    184 %  A description of each parameter follows:
    185 %
    186 %    o type: the type.
    187 %
    188 %    o key: the key.
    189 %
    190 %    o exception: the exception.
    191 %
    192 */
    193 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
    194   ExceptionInfo *exception)
    195 {
    196   void
    197     *value;
    198 
    199   RegistryInfo
    200     *registry_info;
    201 
    202   if (IsEventLogging() != MagickFalse)
    203     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
    204   if (registry == (void *) NULL)
    205     return((void *) NULL);
    206   registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
    207   if (registry_info == (void *) NULL)
    208     return((void *) NULL);
    209   value=(void *) NULL;
    210   switch (type)
    211   {
    212     case ImageRegistryType:
    213     {
    214       if (type == registry_info->type)
    215         value=(void *) CloneImageList((Image *) registry_info->value,exception);
    216       break;
    217     }
    218     case ImageInfoRegistryType:
    219     {
    220       if (type == registry_info->type)
    221         value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
    222       break;
    223     }
    224     case StringRegistryType:
    225     {
    226       switch (registry_info->type)
    227       {
    228         case ImageRegistryType:
    229         {
    230           value=(Image *) ConstantString(((Image *)
    231             registry_info->value)->filename);
    232           break;
    233         }
    234         case ImageInfoRegistryType:
    235         {
    236           value=(Image *) ConstantString(((ImageInfo *)
    237             registry_info->value)->filename);
    238           break;
    239         }
    240         case StringRegistryType:
    241         {
    242           value=(void *) ConstantString((char *) registry_info->value);
    243           break;
    244         }
    245         default:
    246           break;
    247       }
    248       break;
    249     }
    250     default:
    251       break;
    252   }
    253   return(value);
    254 }
    255 
    256 /*
    258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    259 %                                                                             %
    260 %                                                                             %
    261 %                                                                             %
    262 %   G e t N e x t I m a g e R e g i s t r y                                   %
    263 %                                                                             %
    264 %                                                                             %
    265 %                                                                             %
    266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    267 %
    268 %  GetNextImageRegistry() gets the next image registry value.
    269 %
    270 %  The format of the GetNextImageRegistry method is:
    271 %
    272 %      char *GetNextImageRegistry(void)
    273 %
    274 */
    275 MagickExport char *GetNextImageRegistry(void)
    276 {
    277   if (IsEventLogging() != MagickFalse)
    278     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    279   if (registry == (void *) NULL)
    280     return((char *) NULL);
    281   return((char *) GetNextKeyInSplayTree(registry));
    282 }
    283 
    284 /*
    286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    287 %                                                                             %
    288 %                                                                             %
    289 %                                                                             %
    290 +   R e g i s t r y C o m p o n e n t G e n e s i s                           %
    291 %                                                                             %
    292 %                                                                             %
    293 %                                                                             %
    294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    295 %
    296 %  RegistryComponentGenesis() instantiates the registry component.
    297 %
    298 %  The format of the RegistryComponentGenesis method is:
    299 %
    300 %      MagickBooleanType RegistryComponentGenesis(void)
    301 %
    302 */
    303 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
    304 {
    305   if (registry_semaphore == (SemaphoreInfo *) NULL)
    306     registry_semaphore=AcquireSemaphoreInfo();
    307   return(MagickTrue);
    308 }
    309 
    310 /*
    312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    313 %                                                                             %
    314 %                                                                             %
    315 %                                                                             %
    316 %   R e g i s t r y C o m p o n e n t T e r m i n u s                         %
    317 %                                                                             %
    318 %                                                                             %
    319 %                                                                             %
    320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    321 %
    322 %  RegistryComponentTerminus() destroys the registry component.
    323 %
    324 %  The format of the DestroyDefines method is:
    325 %
    326 %      void RegistryComponentTerminus(void)
    327 %
    328 */
    329 MagickPrivate void RegistryComponentTerminus(void)
    330 {
    331   if (registry_semaphore == (SemaphoreInfo *) NULL)
    332     ActivateSemaphoreInfo(&registry_semaphore);
    333   LockSemaphoreInfo(registry_semaphore);
    334   if (IsEventLogging() != MagickFalse)
    335     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    336   if (registry != (void *) NULL)
    337     registry=DestroySplayTree(registry);
    338   UnlockSemaphoreInfo(registry_semaphore);
    339   RelinquishSemaphoreInfo(&registry_semaphore);
    340 }
    341 
    342 /*
    344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    345 %                                                                             %
    346 %                                                                             %
    347 %                                                                             %
    348 %   R e m o v e I m a g e R e g i s t r y                                     %
    349 %                                                                             %
    350 %                                                                             %
    351 %                                                                             %
    352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    353 %
    354 %  RemoveImageRegistry() removes a key from the image registry and returns its
    355 %  value.
    356 %
    357 %  The format of the RemoveImageRegistry method is:
    358 %
    359 %      void *RemoveImageRegistry(const char *key)
    360 %
    361 %  A description of each parameter follows:
    362 %
    363 %    o key: the registry.
    364 %
    365 */
    366 MagickExport void *RemoveImageRegistry(const char *key)
    367 {
    368   if (IsEventLogging() != MagickFalse)
    369     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
    370   if (registry == (void *) NULL)
    371     return((void *) NULL);
    372   return(RemoveNodeFromSplayTree(registry,key));
    373 }
    374 
    375 /*
    377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    378 %                                                                             %
    379 %                                                                             %
    380 %                                                                             %
    381 %   R e s e t I m a g e R e g i s t r y I t e r a t o r                       %
    382 %                                                                             %
    383 %                                                                             %
    384 %                                                                             %
    385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    386 %
    387 %  ResetImageRegistryIterator() resets the registry iterator.  Use it in
    388 %  conjunction with GetNextImageRegistry() to iterate over all the values
    389 %  in the image registry.
    390 %
    391 %  The format of the ResetImageRegistryIterator method is:
    392 %
    393 %      ResetImageRegistryIterator(void)
    394 %
    395 */
    396 MagickExport void ResetImageRegistryIterator(void)
    397 {
    398   if (IsEventLogging() != MagickFalse)
    399     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    400   if (registry == (void *) NULL)
    401     return;
    402   ResetSplayTreeIterator(registry);
    403 }
    404 
    405 /*
    407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    408 %                                                                             %
    409 %                                                                             %
    410 %                                                                             %
    411 %   S e t I m a g e R e g i s t r y                                           %
    412 %                                                                             %
    413 %                                                                             %
    414 %                                                                             %
    415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    416 %
    417 %  SetImageRegistry() associates a value with an image registry key.
    418 %
    419 %  The format of the SetImageRegistry method is:
    420 %
    421 %      MagickBooleanType SetImageRegistry(const RegistryType type,
    422 %        const char *key,const void *value,ExceptionInfo *exception)
    423 %
    424 %  A description of each parameter follows:
    425 %
    426 %    o type: the type.
    427 %
    428 %    o key: the key.
    429 %
    430 %    o value: the value.
    431 %
    432 %    o exception: the exception.
    433 %
    434 */
    435 
    436 static void *DestroyRegistryNode(void *registry_info)
    437 {
    438   register RegistryInfo
    439     *p;
    440 
    441   p=(RegistryInfo *) registry_info;
    442   switch (p->type)
    443   {
    444     case StringRegistryType:
    445     default:
    446     {
    447       p->value=RelinquishMagickMemory(p->value);
    448       break;
    449     }
    450     case ImageRegistryType:
    451     {
    452       p->value=(void *) DestroyImageList((Image *) p->value);
    453       break;
    454     }
    455     case ImageInfoRegistryType:
    456     {
    457       p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
    458       break;
    459     }
    460   }
    461   return(RelinquishMagickMemory(p));
    462 }
    463 
    464 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
    465   const char *key,const void *value,ExceptionInfo *exception)
    466 {
    467   MagickBooleanType
    468     status;
    469 
    470   RegistryInfo
    471     *registry_info;
    472 
    473   void
    474     *clone_value;
    475 
    476   if (IsEventLogging() != MagickFalse)
    477     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
    478   if (value == (const void *) NULL)
    479     return(MagickFalse);
    480   clone_value=(void *) NULL;
    481   switch (type)
    482   {
    483     case StringRegistryType:
    484     default:
    485     {
    486       const char
    487         *string;
    488 
    489       string=(const char *) value;
    490       clone_value=(void *) ConstantString(string);
    491       break;
    492     }
    493     case ImageRegistryType:
    494     {
    495       const Image
    496         *image;
    497 
    498       image=(const Image *) value;
    499       if (image->signature != MagickCoreSignature)
    500         {
    501           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
    502             "UnableToSetRegistry","%s",key);
    503           return(MagickFalse);
    504         }
    505       clone_value=(void *) CloneImageList(image,exception);
    506       break;
    507     }
    508     case ImageInfoRegistryType:
    509     {
    510       const ImageInfo
    511         *image_info;
    512 
    513       image_info=(const ImageInfo *) value;
    514       if (image_info->signature != MagickCoreSignature)
    515         {
    516           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
    517             "UnableToSetRegistry","%s",key);
    518           return(MagickFalse);
    519         }
    520       clone_value=(void *) CloneImageInfo(image_info);
    521       break;
    522     }
    523   }
    524   if (clone_value == (void *) NULL)
    525     return(MagickFalse);
    526   registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info));
    527   (void) memset(registry_info,0,sizeof(*registry_info));
    528   registry_info->type=type;
    529   registry_info->value=clone_value;
    530   registry_info->signature=MagickCoreSignature;
    531   if (registry == (SplayTreeInfo *) NULL)
    532     {
    533       if (registry_semaphore == (SemaphoreInfo *) NULL)
    534         ActivateSemaphoreInfo(&registry_semaphore);
    535       LockSemaphoreInfo(registry_semaphore);
    536       if (registry == (SplayTreeInfo *) NULL)
    537         registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
    538           DestroyRegistryNode);
    539       UnlockSemaphoreInfo(registry_semaphore);
    540     }
    541   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
    542   return(status);
    543 }
    544