blob: 71b2e876606a40d661479efb62d108c22ebbc029 [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% %
cristy41c3c772009-10-19 02:17:37 +0000166% D e s t r o y R e g i s t r y F a c i l i t y %
cristy3ed852e2009-09-05 21:47:34 +0000167% %
168% %
169% %
170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171%
cristy41c3c772009-10-19 02:17:37 +0000172% DestroyRegistryFacility() destroys the registry facility.
cristy3ed852e2009-09-05 21:47:34 +0000173%
174% The format of the DestroyDefines method is:
175%
cristy41c3c772009-10-19 02:17:37 +0000176% void DestroyRegistryFacility(void)
cristy3ed852e2009-09-05 21:47:34 +0000177%
178*/
cristy41c3c772009-10-19 02:17:37 +0000179MagickExport void DestroyRegistryFacility(void)
cristy3ed852e2009-09-05 21:47:34 +0000180{
cristy41c3c772009-10-19 02:17:37 +0000181 AcquireSemaphoreInfo(&registry_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000182 if (IsEventLogging() != MagickFalse)
183 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
184 if (registry != (void *) NULL)
185 registry=DestroySplayTree(registry);
cristy41c3c772009-10-19 02:17:37 +0000186 instantiate_registry=MagickFalse;
187 RelinquishSemaphoreInfo(registry_semaphore);
188 DestroySemaphoreInfo(&registry_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000189}
190
191/*
192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193% %
194% %
195% %
196% G e t I m a g e R e g i s t r y %
197% %
198% %
199% %
200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201%
202% GetImageRegistry() returns a value associated with an image registry key.
203%
204% The format of the GetImageRegistry method is:
205%
206% void *GetImageRegistry(const RegistryType type,const char *key,
207% ExceptionInfo *exception)
208%
209% A description of each parameter follows:
210%
211% o type: the type.
212%
213% o key: the key.
214%
215% o exception: the exception.
216%
217*/
218MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
219 ExceptionInfo *exception)
220{
221 void
222 *value;
223
224 RegistryInfo
225 *registry_info;
226
227 if (IsEventLogging() != MagickFalse)
228 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
229 if (registry == (void *) NULL)
230 return((void *) NULL);
231 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
232 if (registry_info == (void *) NULL)
233 {
234 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
235 "UnableToGetRegistryID","`%s'",key);
236 return((void *) NULL);
237 }
238 value=(void *) NULL;
239 switch (type)
240 {
241 case ImageRegistryType:
242 {
243 if (type == registry_info->type)
244 value=(void *) CloneImageList((Image *) registry_info->value,exception);
245 break;
246 }
247 case ImageInfoRegistryType:
248 {
249 if (type == registry_info->type)
250 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
251 break;
252 }
253 case StringRegistryType:
254 {
255 switch (registry_info->type)
256 {
257 case ImageRegistryType:
258 {
259 value=(Image *) ConstantString(((Image *)
260 registry_info->value)->filename);
261 break;
262 }
263 case ImageInfoRegistryType:
264 {
265 value=(Image *) ConstantString(((ImageInfo *)
266 registry_info->value)->filename);
267 break;
268 }
269 case StringRegistryType:
270 {
271 value=(void *) ConstantString((char *) registry_info->value);
272 break;
273 }
274 default:
275 break;
276 }
277 break;
278 }
279 default:
280 break;
281 }
282 return(value);
283}
284
285/*
286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287% %
288% %
289% %
290% G e t N e x t I m a g e R e g i s t r y %
291% %
292% %
293% %
294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295%
296% GetNextImageRegistry() gets the next image registry value.
297%
298% The format of the GetNextImageRegistry method is:
299%
300% char *GetNextImageRegistry(void)
301%
302*/
303MagickExport char *GetNextImageRegistry(void)
304{
305 if (IsEventLogging() != MagickFalse)
306 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
307 if (registry == (void *) NULL)
308 return((char *) NULL);
309 return((char *) GetNextKeyInSplayTree(registry));
310}
311
312/*
313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314% %
315% %
316% %
cristy41c3c772009-10-19 02:17:37 +0000317+ I n s t a n t i a t e R e g i s t r y F a c i l i t y %
318% %
319% %
320% %
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322%
323% InstantiateRegistryFacility() instantiates the registry facility.
324%
325% The format of the InstantiateRegistryFacility method is:
326%
327% MagickBooleanType InstantiateRegistryFacility(void)
328%
329*/
330MagickExport MagickBooleanType InstantiateRegistryFacility(void)
331{
332 AcquireSemaphoreInfo(&registry_semaphore);
333 RelinquishSemaphoreInfo(registry_semaphore);
334 return(MagickTrue);
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}