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