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-2010 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 "magick/studio.h"
44 #include "magick/exception.h"
45 #include "magick/exception-private.h"
46 #include "magick/image.h"
47 #include "magick/list.h"
48 #include "magick/memory_.h"
49 #include "magick/registry.h"
50 #include "magick/splay-tree.h"
51 #include "magick/string_.h"
52 #include "magick/utility.h"
57 typedef struct _RegistryInfo
73 *registry = (SplayTreeInfo *) NULL;
76 *registry_semaphore = (SemaphoreInfo *) NULL;
78 static volatile MagickBooleanType
79 instantiate_registry = MagickFalse;
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % D e f i n e I m a g e R e g i s t r y %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 % DefineImageRegistry() associates a key/value pair with the image registry.
94 % The format of the DefineImageRegistry method is:
96 % MagickBooleanType DefineImageRegistry(const RegistryType type,
97 % const char *option,ExceptionInfo *exception)
99 % A description of each parameter follows:
103 % o option: the option.
105 % o exception: the exception.
108 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
109 const char *option,ExceptionInfo *exception)
113 value[MaxTextExtent];
118 assert(option != (const char *) NULL);
119 (void) CopyMagickString(key,option,MaxTextExtent);
120 for (p=key; *p != '\0'; p++)
125 (void) CopyMagickString(value,p+1,MaxTextExtent);
127 return(SetImageRegistry(type,key,value,exception));
131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % D e l e t e I m a g e R e g i s t r y %
139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 % DeleteImageRegistry() deletes a key from the image registry.
143 % The format of the DeleteImageRegistry method is:
145 % MagickBooleanType DeleteImageRegistry(const char *key)
147 % A description of each parameter follows:
149 % o key: the registry.
152 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
154 if (IsEventLogging() != MagickFalse)
155 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
156 if (registry == (void *) NULL)
158 return(DeleteNodeFromSplayTree(registry,key));
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166 % G e t I m a g e R e g i s t r y %
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % GetImageRegistry() returns a value associated with an image registry key.
174 % The format of the GetImageRegistry method is:
176 % void *GetImageRegistry(const RegistryType type,const char *key,
177 % ExceptionInfo *exception)
179 % A description of each parameter follows:
185 % o exception: the exception.
188 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
189 ExceptionInfo *exception)
197 if (IsEventLogging() != MagickFalse)
198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
199 if (registry == (void *) NULL)
200 return((void *) NULL);
201 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
202 if (registry_info == (void *) NULL)
204 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
205 "UnableToGetRegistryID","`%s'",key);
206 return((void *) NULL);
211 case ImageRegistryType:
213 if (type == registry_info->type)
214 value=(void *) CloneImageList((Image *) registry_info->value,exception);
217 case ImageInfoRegistryType:
219 if (type == registry_info->type)
220 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
223 case StringRegistryType:
225 switch (registry_info->type)
227 case ImageRegistryType:
229 value=(Image *) ConstantString(((Image *)
230 registry_info->value)->filename);
233 case ImageInfoRegistryType:
235 value=(Image *) ConstantString(((ImageInfo *)
236 registry_info->value)->filename);
239 case StringRegistryType:
241 value=(void *) ConstantString((char *) registry_info->value);
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 % G e t N e x t I m a g e R e g i s t r y %
264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 % GetNextImageRegistry() gets the next image registry value.
268 % The format of the GetNextImageRegistry method is:
270 % char *GetNextImageRegistry(void)
273 MagickExport char *GetNextImageRegistry(void)
275 if (IsEventLogging() != MagickFalse)
276 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
277 if (registry == (void *) NULL)
278 return((char *) NULL);
279 return((char *) GetNextKeyInSplayTree(registry));
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 + 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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 % RegistryComponentGenesis() instantiates the registry component.
295 % The format of the RegistryComponentGenesis method is:
297 % MagickBooleanType RegistryComponentGenesis(void)
300 MagickExport MagickBooleanType RegistryComponentGenesis(void)
302 AcquireSemaphoreInfo(®istry_semaphore);
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % 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 %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % RegistryComponentTerminus() destroys the registry component.
319 % The format of the DestroyDefines method is:
321 % void RegistryComponentTerminus(void)
324 MagickExport void RegistryComponentTerminus(void)
326 if (registry_semaphore == (SemaphoreInfo *) NULL)
327 AcquireSemaphoreInfo(®istry_semaphore);
328 LockSemaphoreInfo(registry_semaphore);
329 if (IsEventLogging() != MagickFalse)
330 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
331 if (registry != (void *) NULL)
332 registry=DestroySplayTree(registry);
333 instantiate_registry=MagickFalse;
334 UnlockSemaphoreInfo(registry_semaphore);
335 DestroySemaphoreInfo(®istry_semaphore);
339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % R e m o v e I m a g e R e g i s t r y %
347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 % RemoveImageRegistry() removes a key from the image registry and returns its
352 % The format of the RemoveImageRegistry method is:
354 % void *RemoveImageRegistry(const char *key)
356 % A description of each parameter follows:
358 % o key: the registry.
361 MagickExport void *RemoveImageRegistry(const char *key)
363 if (IsEventLogging() != MagickFalse)
364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
365 if (registry == (void *) NULL)
366 return((void *) NULL);
367 return(RemoveNodeFromSplayTree(registry,key));
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375 % 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 %
379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 % ResetImageRegistryIterator() resets the registry iterator. Use it in
382 % conjunction with GetNextImageRegistry() to iterate over all the values
383 % in the image registry.
385 % The format of the ResetImageRegistryIterator method is:
387 % ResetImageRegistryIterator(void)
390 MagickExport void ResetImageRegistryIterator(void)
392 if (IsEventLogging() != MagickFalse)
393 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
394 if (registry == (void *) NULL)
396 ResetSplayTreeIterator(registry);
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 % S e t I m a g e R e g i s t r y %
408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410 % SetImageRegistry() associates a value with an image registry key.
412 % The format of the SetImageRegistry method is:
414 % MagickBooleanType SetImageRegistry(const RegistryType type,
415 % const char *key,const void *value,ExceptionInfo *exception)
417 % A description of each parameter follows:
423 % o value: the value.
425 % o exception: the exception.
429 static void *DestroyRegistryNode(void *registry_info)
431 register RegistryInfo
434 p=(RegistryInfo *) registry_info;
437 case StringRegistryType:
440 p->value=RelinquishMagickMemory(p->value);
443 case ImageRegistryType:
445 p->value=(void *) DestroyImageList((Image *) p->value);
448 case ImageInfoRegistryType:
450 p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
454 return(RelinquishMagickMemory(p));
457 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
458 const char *key,const void *value,ExceptionInfo *exception)
469 if (IsEventLogging() != MagickFalse)
470 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
471 clone_value=(void *) NULL;
474 case StringRegistryType:
480 string=(const char *) value;
481 clone_value=(void *) ConstantString(string);
484 case ImageRegistryType:
489 image=(const Image *) value;
490 if (image->signature != MagickSignature)
492 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
493 "UnableToSetRegistry","%s",key);
496 clone_value=(void *) CloneImageList(image,exception);
499 case ImageInfoRegistryType:
504 image_info=(const ImageInfo *) value;
505 if (image_info->signature != MagickSignature)
507 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
508 "UnableToSetRegistry","%s",key);
511 clone_value=(void *) CloneImageInfo(image_info);
515 if (clone_value == (void *) NULL)
517 registry_info=(RegistryInfo *) AcquireMagickMemory(sizeof(*registry_info));
518 if (registry_info == (RegistryInfo *) NULL)
519 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
520 (void) ResetMagickMemory(registry_info,0,sizeof(*registry_info));
521 registry_info->type=type;
522 registry_info->value=clone_value;
523 registry_info->signature=MagickSignature;
524 if ((registry == (SplayTreeInfo *) NULL) &&
525 (instantiate_registry == MagickFalse))
527 if (registry_semaphore == (SemaphoreInfo *) NULL)
528 AcquireSemaphoreInfo(®istry_semaphore);
529 LockSemaphoreInfo(registry_semaphore);
530 if ((registry == (SplayTreeInfo *) NULL) &&
531 (instantiate_registry == MagickFalse))
533 registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
534 DestroyRegistryNode);
535 instantiate_registry=MagickTrue;
537 UnlockSemaphoreInfo(registry_semaphore);
539 status=AddValueToSplayTree(registry,ConstantString(key),registry_info);