]> granicus.if.org Git - imagemagick/blob - magick/registry.c
(no commit message)
[imagemagick] / magick / 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-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 \f
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 \f
54 /*
55   Typedef declarations.
56 */
57 typedef struct _RegistryInfo
58 {
59   RegistryType
60     type;
61
62   void
63     *value;
64
65   unsigned long
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 %   D e s t r o y R e g i s t r y F a c i l i t y                             %
167 %                                                                             %
168 %                                                                             %
169 %                                                                             %
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 %
172 %  DestroyRegistryFacility() destroys the registry facility.
173 %
174 %  The format of the DestroyDefines method is:
175 %
176 %      void DestroyRegistryFacility(void)
177 %
178 */
179 MagickExport void DestroyRegistryFacility(void)
180 {
181   AcquireSemaphoreInfo(&registry_semaphore);
182   if (IsEventLogging() != MagickFalse)
183     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
184   if (registry != (void *) NULL)
185     registry=DestroySplayTree(registry);
186   instantiate_registry=MagickFalse;
187   RelinquishSemaphoreInfo(registry_semaphore);
188   DestroySemaphoreInfo(&registry_semaphore);
189 }
190 \f
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 */
218 MagickExport 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 \f
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 */
303 MagickExport 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 \f
312 /*
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 %                                                                             %
315 %                                                                             %
316 %                                                                             %
317 +   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 */
330 MagickExport MagickBooleanType InstantiateRegistryFacility(void)
331 {
332   AcquireSemaphoreInfo(&registry_semaphore);
333   RelinquishSemaphoreInfo(registry_semaphore);
334   return(MagickTrue);
335 }
336 \f
337 /*
338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339 %                                                                             %
340 %                                                                             %
341 %                                                                             %
342 %   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 */
360 MagickExport 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 \f
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 */
389 MagickExport 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 \f
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
428 static void *DestroyRegistryNode(void *registry_info)
429 {
430   register RegistryInfo
431     *p;
432
433   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     }
452   }
453   return(RelinquishMagickMemory(p));
454 }
455
456 MagickExport 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;
523   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     }
536   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
537   return(status);
538 }