]> 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 %   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   assert(registry_semaphore == (SemaphoreInfo *) NULL);
303   registry_semaphore=AllocateSemaphoreInfo();
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 MagickExport void RegistryComponentTerminus(void)
326 {
327   if (registry_semaphore == (SemaphoreInfo *) NULL)
328     AcquireSemaphoreInfo(&registry_semaphore);
329   (void) 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   (void) 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       (void) 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       (void) UnlockSemaphoreInfo(registry_semaphore);
539     }
540   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
541   return(status);
542 }