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-2012 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 % http://www.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/registry.h"
50 #include "MagickCore/registry-private.h"
51 #include "MagickCore/splay-tree.h"
52 #include "MagickCore/string_.h"
53 #include "MagickCore/utility.h"
58 typedef struct _RegistryInfo
74 *registry = (SplayTreeInfo *) NULL;
77 *registry_semaphore = (SemaphoreInfo *) NULL;
79 static volatile MagickBooleanType
80 instantiate_registry = MagickFalse;
83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 % D e f i n e I m a g e R e g i s t r y %
91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 % DefineImageRegistry() associates a key/value pair with the image registry.
95 % The format of the DefineImageRegistry method is:
97 % MagickBooleanType DefineImageRegistry(const RegistryType type,
98 % const char *option,ExceptionInfo *exception)
100 % A description of each parameter follows:
104 % o option: the option.
106 % o exception: the exception.
109 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
110 const char *option,ExceptionInfo *exception)
114 value[MaxTextExtent];
119 assert(option != (const char *) NULL);
120 (void) CopyMagickString(key,option,MaxTextExtent);
121 for (p=key; *p != '\0'; p++)
126 (void) CopyMagickString(value,p+1,MaxTextExtent);
128 return(SetImageRegistry(type,key,value,exception));
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 % D e l e t e I m a g e R e g i s t r y %
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 % DeleteImageRegistry() deletes a key from the image registry.
144 % The format of the DeleteImageRegistry method is:
146 % MagickBooleanType DeleteImageRegistry(const char *key)
148 % A description of each parameter follows:
150 % o key: the registry.
153 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
155 if (IsEventLogging() != MagickFalse)
156 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
157 if (registry == (void *) NULL)
159 return(DeleteNodeFromSplayTree(registry,key));
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % G e t I m a g e R e g i s t r y %
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % GetImageRegistry() returns a value associated with an image registry key.
175 % The format of the GetImageRegistry method is:
177 % void *GetImageRegistry(const RegistryType type,const char *key,
178 % ExceptionInfo *exception)
180 % A description of each parameter follows:
186 % o exception: the exception.
189 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
190 ExceptionInfo *exception)
198 if (IsEventLogging() != MagickFalse)
199 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
200 if (registry == (void *) NULL)
201 return((void *) NULL);
202 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
203 if (registry_info == (void *) NULL)
205 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
206 "UnableToGetRegistryID","`%s'",key);
207 return((void *) NULL);
212 case ImageRegistryType:
214 if (type == registry_info->type)
215 value=(void *) CloneImageList((Image *) registry_info->value,exception);
218 case ImageInfoRegistryType:
220 if (type == registry_info->type)
221 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
224 case StringRegistryType:
226 switch (registry_info->type)
228 case ImageRegistryType:
230 value=(Image *) ConstantString(((Image *)
231 registry_info->value)->filename);
234 case ImageInfoRegistryType:
236 value=(Image *) ConstantString(((ImageInfo *)
237 registry_info->value)->filename);
240 case StringRegistryType:
242 value=(void *) ConstantString((char *) registry_info->value);
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 % G e t N e x t I m a g e R e g i s t r y %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 % GetNextImageRegistry() gets the next image registry value.
269 % The format of the GetNextImageRegistry method is:
271 % char *GetNextImageRegistry(void)
274 MagickExport char *GetNextImageRegistry(void)
276 if (IsEventLogging() != MagickFalse)
277 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
278 if (registry == (void *) NULL)
279 return((char *) NULL);
280 return((char *) GetNextKeyInSplayTree(registry));
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 + R e g i s t r y C o m p o n e n t G e n e s i s %
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 % RegistryComponentGenesis() instantiates the registry component.
296 % The format of the RegistryComponentGenesis method is:
298 % MagickBooleanType RegistryComponentGenesis(void)
301 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
303 AcquireSemaphoreInfo(®istry_semaphore);
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 % 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 %
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 % RegistryComponentTerminus() destroys the registry component.
320 % The format of the DestroyDefines method is:
322 % void RegistryComponentTerminus(void)
325 MagickPrivate void RegistryComponentTerminus(void)
327 if (registry_semaphore == (SemaphoreInfo *) NULL)
328 AcquireSemaphoreInfo(®istry_semaphore);
329 LockSemaphoreInfo(registry_semaphore);
330 if (IsEventLogging() != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
332 if (registry != (void *) NULL)
333 registry=DestroySplayTree(registry);
334 instantiate_registry=MagickFalse;
335 UnlockSemaphoreInfo(registry_semaphore);
336 DestroySemaphoreInfo(®istry_semaphore);
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 % R e m o v e I m a g e R e g i s t r y %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 % RemoveImageRegistry() removes a key from the image registry and returns its
353 % The format of the RemoveImageRegistry method is:
355 % void *RemoveImageRegistry(const char *key)
357 % A description of each parameter follows:
359 % o key: the registry.
362 MagickExport void *RemoveImageRegistry(const char *key)
364 if (IsEventLogging() != MagickFalse)
365 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
366 if (registry == (void *) NULL)
367 return((void *) NULL);
368 return(RemoveNodeFromSplayTree(registry,key));
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 % 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 %
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 % ResetImageRegistryIterator() resets the registry iterator. Use it in
383 % conjunction with GetNextImageRegistry() to iterate over all the values
384 % in the image registry.
386 % The format of the ResetImageRegistryIterator method is:
388 % ResetImageRegistryIterator(void)
391 MagickExport void ResetImageRegistryIterator(void)
393 if (IsEventLogging() != MagickFalse)
394 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
395 if (registry == (void *) NULL)
397 ResetSplayTreeIterator(registry);
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405 % S e t I m a g e R e g i s t r y %
409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411 % SetImageRegistry() associates a value with an image registry key.
413 % The format of the SetImageRegistry method is:
415 % MagickBooleanType SetImageRegistry(const RegistryType type,
416 % const char *key,const void *value,ExceptionInfo *exception)
418 % A description of each parameter follows:
424 % o value: the value.
426 % o exception: the exception.
430 static void *DestroyRegistryNode(void *registry_info)
432 register RegistryInfo
435 p=(RegistryInfo *) registry_info;
438 case StringRegistryType:
441 p->value=RelinquishMagickMemory(p->value);
444 case ImageRegistryType:
446 p->value=(void *) DestroyImageList((Image *) p->value);
449 case ImageInfoRegistryType:
451 p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
455 return(RelinquishMagickMemory(p));
458 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
459 const char *key,const void *value,ExceptionInfo *exception)
470 if (IsEventLogging() != MagickFalse)
471 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
472 clone_value=(void *) NULL;
475 case StringRegistryType:
481 string=(const char *) value;
482 clone_value=(void *) ConstantString(string);
485 case ImageRegistryType:
490 image=(const Image *) value;
491 if (image->signature != MagickSignature)
493 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
494 "UnableToSetRegistry","%s",key);
497 clone_value=(void *) CloneImageList(image,exception);
500 case ImageInfoRegistryType:
505 image_info=(const ImageInfo *) value;
506 if (image_info->signature != MagickSignature)
508 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
509 "UnableToSetRegistry","%s",key);
512 clone_value=(void *) CloneImageInfo(image_info);
516 if (clone_value == (void *) NULL)
518 registry_info=(RegistryInfo *) AcquireMagickMemory(sizeof(*registry_info));
519 if (registry_info == (RegistryInfo *) NULL)
520 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
521 (void) ResetMagickMemory(registry_info,0,sizeof(*registry_info));
522 registry_info->type=type;
523 registry_info->value=clone_value;
524 registry_info->signature=MagickSignature;
525 if ((registry == (SplayTreeInfo *) NULL) &&
526 (instantiate_registry == MagickFalse))
528 if (registry_semaphore == (SemaphoreInfo *) NULL)
529 AcquireSemaphoreInfo(®istry_semaphore);
530 LockSemaphoreInfo(registry_semaphore);
531 if ((registry == (SplayTreeInfo *) NULL) &&
532 (instantiate_registry == MagickFalse))
534 registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
535 DestroyRegistryNode);
536 instantiate_registry=MagickTrue;
538 UnlockSemaphoreInfo(registry_semaphore);
540 status=AddValueToSplayTree(registry,ConstantString(key),registry_info);