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