]> granicus.if.org Git - imagemagick/blob - MagickCore/registry.c
(no commit message)
[imagemagick] / MagickCore / registry.c
1 /*
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-2011 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 \f
40 /*
41   Include declarations.
42 */
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/splay-tree.h"
51 #include "MagickCore/string_.h"
52 #include "MagickCore/utility.h"
53 \f
54 /*
55   Typedef declarations.
56 */
57 typedef struct _RegistryInfo
58 {
59   RegistryType
60     type;
61
62   void
63     *value;
64
65   size_t
66     signature;
67 } RegistryInfo;
68 \f
69 /*
70   Static declarations.
71 */
72 static SplayTreeInfo
73   *registry = (SplayTreeInfo *) NULL;
74
75 static SemaphoreInfo
76   *registry_semaphore = (SemaphoreInfo *) NULL;
77
78 static volatile MagickBooleanType
79   instantiate_registry = MagickFalse;
80 \f
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 */
108 MagickExport 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 \f
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 */
152 MagickExport 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 \f
161 /*
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 %                                                                             %
164 %                                                                             %
165 %                                                                             %
166 %   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 */
188 MagickExport 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 \f
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 */
273 MagickExport 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 \f
282 /*
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 %                                                                             %
285 %                                                                             %
286 %                                                                             %
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                           %
288 %                                                                             %
289 %                                                                             %
290 %                                                                             %
291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 %
293 %  RegistryComponentGenesis() instantiates the registry component.
294 %
295 %  The format of the RegistryComponentGenesis method is:
296 %
297 %      MagickBooleanType RegistryComponentGenesis(void)
298 %
299 */
300 MagickExport MagickBooleanType RegistryComponentGenesis(void)
301 {
302   AcquireSemaphoreInfo(&registry_semaphore);
303   return(MagickTrue);
304 }
305 \f
306 /*
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 %                                                                             %
309 %                                                                             %
310 %                                                                             %
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                         %
312 %                                                                             %
313 %                                                                             %
314 %                                                                             %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 %
317 %  RegistryComponentTerminus() destroys the registry component.
318 %
319 %  The format of the DestroyDefines method is:
320 %
321 %      void RegistryComponentTerminus(void)
322 %
323 */
324 MagickExport void RegistryComponentTerminus(void)
325 {
326   if (registry_semaphore == (SemaphoreInfo *) NULL)
327     AcquireSemaphoreInfo(&registry_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(&registry_semaphore);
336 }
337 \f
338 /*
339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 %                                                                             %
341 %                                                                             %
342 %                                                                             %
343 %   R e m o v e I m a g e R e g i s t r y                                     %
344 %                                                                             %
345 %                                                                             %
346 %                                                                             %
347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348 %
349 %  RemoveImageRegistry() removes a key from the image registry and returns its
350 %  value.
351 %
352 %  The format of the RemoveImageRegistry method is:
353 %
354 %      void *RemoveImageRegistry(const char *key)
355 %
356 %  A description of each parameter follows:
357 %
358 %    o key: the registry.
359 %
360 */
361 MagickExport void *RemoveImageRegistry(const char *key)
362 {
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));
368 }
369 \f
370 /*
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 %                                                                             %
373 %                                                                             %
374 %                                                                             %
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                       %
376 %                                                                             %
377 %                                                                             %
378 %                                                                             %
379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 %
381 %  ResetImageRegistryIterator() resets the registry iterator.  Use it in
382 %  conjunction with GetNextImageRegistry() to iterate over all the values
383 %  in the image registry.
384 %
385 %  The format of the ResetImageRegistryIterator method is:
386 %
387 %      ResetImageRegistryIterator(void)
388 %
389 */
390 MagickExport void ResetImageRegistryIterator(void)
391 {
392   if (IsEventLogging() != MagickFalse)
393     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
394   if (registry == (void *) NULL)
395     return;
396   ResetSplayTreeIterator(registry);
397 }
398 \f
399 /*
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 %                                                                             %
402 %                                                                             %
403 %                                                                             %
404 %   S e t I m a g e R e g i s t r y                                           %
405 %                                                                             %
406 %                                                                             %
407 %                                                                             %
408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 %
410 %  SetImageRegistry() associates a value with an image registry key.
411 %
412 %  The format of the SetImageRegistry method is:
413 %
414 %      MagickBooleanType SetImageRegistry(const RegistryType type,
415 %        const char *key,const void *value,ExceptionInfo *exception)
416 %
417 %  A description of each parameter follows:
418 %
419 %    o type: the type.
420 %
421 %    o key: the key.
422 %
423 %    o value: the value.
424 %
425 %    o exception: the exception.
426 %
427 */
428
429 static void *DestroyRegistryNode(void *registry_info)
430 {
431   register RegistryInfo
432     *p;
433
434   p=(RegistryInfo *) registry_info;
435   switch (p->type)
436   {
437     case StringRegistryType:
438     default:
439     {
440       p->value=RelinquishMagickMemory(p->value);
441       break;
442     }
443     case ImageRegistryType:
444     {
445       p->value=(void *) DestroyImageList((Image *) p->value);
446       break;
447     }
448     case ImageInfoRegistryType:
449     {
450       p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
451       break;
452     }
453   }
454   return(RelinquishMagickMemory(p));
455 }
456
457 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
458   const char *key,const void *value,ExceptionInfo *exception)
459 {
460   MagickBooleanType
461     status;
462
463   RegistryInfo
464     *registry_info;
465
466   void
467     *clone_value;
468
469   if (IsEventLogging() != MagickFalse)
470     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
471   clone_value=(void *) NULL;
472   switch (type)
473   {
474     case StringRegistryType:
475     default:
476     {
477       const char
478         *string;
479
480       string=(const char *) value;
481       clone_value=(void *) ConstantString(string);
482       break;
483     }
484     case ImageRegistryType:
485     {
486       const Image
487         *image;
488
489       image=(const Image *) value;
490       if (image->signature != MagickSignature)
491         {
492           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
493             "UnableToSetRegistry","%s",key);
494           return(MagickFalse);
495         }
496       clone_value=(void *) CloneImageList(image,exception);
497       break;
498     }
499     case ImageInfoRegistryType:
500     {
501       const ImageInfo
502         *image_info;
503
504       image_info=(const ImageInfo *) value;
505       if (image_info->signature != MagickSignature)
506         {
507           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
508             "UnableToSetRegistry","%s",key);
509           return(MagickFalse);
510         }
511       clone_value=(void *) CloneImageInfo(image_info);
512       break;
513     }
514   }
515   if (clone_value == (void *) NULL)
516     return(MagickFalse);
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))
526     {
527       if (registry_semaphore == (SemaphoreInfo *) NULL)
528         AcquireSemaphoreInfo(&registry_semaphore);
529       LockSemaphoreInfo(registry_semaphore);
530       if ((registry == (SplayTreeInfo *) NULL) &&
531           (instantiate_registry == MagickFalse))
532         {
533           registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
534             DestroyRegistryNode);
535           instantiate_registry=MagickTrue;
536         }
537       UnlockSemaphoreInfo(registry_semaphore);
538     }
539   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
540   return(status);
541 }