2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % MagickCore Registry Methods %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/exception.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/image.h"
47 #include "MagickCore/list.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/memory-private.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"
59 typedef struct _RegistryInfo
75 *registry = (SplayTreeInfo *) NULL;
78 *registry_semaphore = (SemaphoreInfo *) NULL;
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85 % D e f i n e I m a g e R e g i s t r y %
89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 % DefineImageRegistry() associates a key/value pair with the image registry.
93 % The format of the DefineImageRegistry method is:
95 % MagickBooleanType DefineImageRegistry(const RegistryType type,
96 % const char *option,ExceptionInfo *exception)
98 % A description of each parameter follows:
102 % o option: the option.
104 % o exception: the exception.
107 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
108 const char *option,ExceptionInfo *exception)
111 key[MagickPathExtent],
112 value[MagickPathExtent];
117 assert(option != (const char *) NULL);
118 (void) CopyMagickString(key,option,MagickPathExtent);
119 for (p=key; *p != '\0'; p++)
124 (void) CopyMagickString(value,p+1,MagickPathExtent);
126 return(SetImageRegistry(type,key,value,exception));
130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 % D e l e t e I m a g e R e g i s t r y %
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 % DeleteImageRegistry() deletes a key from the image registry.
142 % The format of the DeleteImageRegistry method is:
144 % MagickBooleanType DeleteImageRegistry(const char *key)
146 % A description of each parameter follows:
148 % o key: the registry.
151 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
153 if (IsEventLogging() != MagickFalse)
154 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
155 if (registry == (void *) NULL)
157 return(DeleteNodeFromSplayTree(registry,key));
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 % G e t I m a g e R e g i s t r y %
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 % GetImageRegistry() returns a value associated with an image registry key.
173 % The format of the GetImageRegistry method is:
175 % void *GetImageRegistry(const RegistryType type,const char *key,
176 % ExceptionInfo *exception)
178 % A description of each parameter follows:
184 % o exception: the exception.
187 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
188 ExceptionInfo *exception)
196 if (IsEventLogging() != MagickFalse)
197 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
198 if (registry == (void *) NULL)
199 return((void *) NULL);
200 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
201 if (registry_info == (void *) NULL)
202 return((void *) NULL);
206 case ImageRegistryType:
208 if (type == registry_info->type)
209 value=(void *) CloneImageList((Image *) registry_info->value,exception);
212 case ImageInfoRegistryType:
214 if (type == registry_info->type)
215 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
218 case StringRegistryType:
220 switch (registry_info->type)
222 case ImageRegistryType:
224 value=(Image *) ConstantString(((Image *)
225 registry_info->value)->filename);
228 case ImageInfoRegistryType:
230 value=(Image *) ConstantString(((ImageInfo *)
231 registry_info->value)->filename);
234 case StringRegistryType:
236 value=(void *) ConstantString((char *) registry_info->value);
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 % G e t N e x t I m a g e R e g i s t r y %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 % GetNextImageRegistry() gets the next image registry value.
263 % The format of the GetNextImageRegistry method is:
265 % char *GetNextImageRegistry(void)
268 MagickExport char *GetNextImageRegistry(void)
270 if (IsEventLogging() != MagickFalse)
271 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
272 if (registry == (void *) NULL)
273 return((char *) NULL);
274 return((char *) GetNextKeyInSplayTree(registry));
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 + R e g i s t r y C o m p o n e n t G e n e s i s %
286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 % RegistryComponentGenesis() instantiates the registry component.
290 % The format of the RegistryComponentGenesis method is:
292 % MagickBooleanType RegistryComponentGenesis(void)
295 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
297 if (registry_semaphore == (SemaphoreInfo *) NULL)
298 registry_semaphore=AcquireSemaphoreInfo();
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 % 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 %
311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313 % RegistryComponentTerminus() destroys the registry component.
315 % The format of the DestroyDefines method is:
317 % void RegistryComponentTerminus(void)
320 MagickPrivate void RegistryComponentTerminus(void)
322 if (registry_semaphore == (SemaphoreInfo *) NULL)
323 ActivateSemaphoreInfo(®istry_semaphore);
324 LockSemaphoreInfo(registry_semaphore);
325 if (IsEventLogging() != MagickFalse)
326 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
327 if (registry != (void *) NULL)
328 registry=DestroySplayTree(registry);
329 UnlockSemaphoreInfo(registry_semaphore);
330 RelinquishSemaphoreInfo(®istry_semaphore);
334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 % R e m o v e I m a g e R e g i s t r y %
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 % RemoveImageRegistry() removes a key from the image registry and returns its
347 % The format of the RemoveImageRegistry method is:
349 % void *RemoveImageRegistry(const char *key)
351 % A description of each parameter follows:
353 % o key: the registry.
356 MagickExport void *RemoveImageRegistry(const char *key)
358 if (IsEventLogging() != MagickFalse)
359 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
360 if (registry == (void *) NULL)
361 return((void *) NULL);
362 return(RemoveNodeFromSplayTree(registry,key));
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370 % 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 %
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 % ResetImageRegistryIterator() resets the registry iterator. Use it in
377 % conjunction with GetNextImageRegistry() to iterate over all the values
378 % in the image registry.
380 % The format of the ResetImageRegistryIterator method is:
382 % ResetImageRegistryIterator(void)
385 MagickExport void ResetImageRegistryIterator(void)
387 if (IsEventLogging() != MagickFalse)
388 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
389 if (registry == (void *) NULL)
391 ResetSplayTreeIterator(registry);
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399 % S e t I m a g e R e g i s t r y %
403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405 % SetImageRegistry() associates a value with an image registry key.
407 % The format of the SetImageRegistry method is:
409 % MagickBooleanType SetImageRegistry(const RegistryType type,
410 % const char *key,const void *value,ExceptionInfo *exception)
412 % A description of each parameter follows:
418 % o value: the value.
420 % o exception: the exception.
424 static void *DestroyRegistryNode(void *registry_info)
426 register RegistryInfo
429 p=(RegistryInfo *) registry_info;
432 case StringRegistryType:
435 p->value=RelinquishMagickMemory(p->value);
438 case ImageRegistryType:
440 p->value=(void *) DestroyImageList((Image *) p->value);
443 case ImageInfoRegistryType:
445 p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
449 return(RelinquishMagickMemory(p));
452 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
453 const char *key,const void *value,ExceptionInfo *exception)
464 if (IsEventLogging() != MagickFalse)
465 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
466 if (value == (const void *) NULL)
468 clone_value=(void *) NULL;
471 case StringRegistryType:
477 string=(const char *) value;
478 clone_value=(void *) ConstantString(string);
481 case ImageRegistryType:
486 image=(const Image *) value;
487 if (image->signature != MagickCoreSignature)
489 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
490 "UnableToSetRegistry","%s",key);
493 clone_value=(void *) CloneImageList(image,exception);
496 case ImageInfoRegistryType:
501 image_info=(const ImageInfo *) value;
502 if (image_info->signature != MagickCoreSignature)
504 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
505 "UnableToSetRegistry","%s",key);
508 clone_value=(void *) CloneImageInfo(image_info);
512 if (clone_value == (void *) NULL)
514 registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info));
515 (void) memset(registry_info,0,sizeof(*registry_info));
516 registry_info->type=type;
517 registry_info->value=clone_value;
518 registry_info->signature=MagickCoreSignature;
519 if (registry == (SplayTreeInfo *) NULL)
521 if (registry_semaphore == (SemaphoreInfo *) NULL)
522 ActivateSemaphoreInfo(®istry_semaphore);
523 LockSemaphoreInfo(registry_semaphore);
524 if (registry == (SplayTreeInfo *) NULL)
525 registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
526 DestroyRegistryNode);
527 UnlockSemaphoreInfo(registry_semaphore);
529 status=AddValueToSplayTree(registry,ConstantString(key),registry_info);