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