]> granicus.if.org Git - imagemagick/blob - MagickCore/registry.c
b8af0acfca5ab29fb1daba5ac9f34bf7aacd7793
[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 %                                   Cristy                                    %
17 %                                 March 2000                                  %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2014 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 \f
79 /*
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %                                                                             %
82 %                                                                             %
83 %                                                                             %
84 %   D e f i n e I m a g e R e g i s t r y                                     %
85 %                                                                             %
86 %                                                                             %
87 %                                                                             %
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 %
90 %  DefineImageRegistry() associates a key/value pair with the image registry.
91 %
92 %  The format of the DefineImageRegistry method is:
93 %
94 %      MagickBooleanType DefineImageRegistry(const RegistryType type,
95 %        const char *option,ExceptionInfo *exception)
96 %
97 %  A description of each parameter follows:
98 %
99 %    o type: the type.
100 %
101 %    o option: the option.
102 %
103 %    o exception: the exception.
104 %
105 */
106 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
107   const char *option,ExceptionInfo *exception)
108 {
109   char
110     key[MaxTextExtent],
111     value[MaxTextExtent];
112
113   register char
114     *p;
115
116   assert(option != (const char *) NULL);
117   (void) CopyMagickString(key,option,MaxTextExtent);
118   for (p=key; *p != '\0'; p++)
119     if (*p == '=')
120       break;
121   *value='\0';
122   if (*p == '=')
123     (void) CopyMagickString(value,p+1,MaxTextExtent);
124   *p='\0';
125   return(SetImageRegistry(type,key,value,exception));
126 }
127 \f
128 /*
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 %                                                                             %
131 %                                                                             %
132 %                                                                             %
133 %   D e l e t e I m a g e R e g i s t r y                                     %
134 %                                                                             %
135 %                                                                             %
136 %                                                                             %
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 %
139 %  DeleteImageRegistry() deletes a key from the image registry.
140 %
141 %  The format of the DeleteImageRegistry method is:
142 %
143 %      MagickBooleanType DeleteImageRegistry(const char *key)
144 %
145 %  A description of each parameter follows:
146 %
147 %    o key: the registry.
148 %
149 */
150 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
151 {
152   if (IsEventLogging() != MagickFalse)
153     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
154   if (registry == (void *) NULL)
155     return(MagickFalse);
156   return(DeleteNodeFromSplayTree(registry,key));
157 }
158 \f
159 /*
160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 %                                                                             %
162 %                                                                             %
163 %                                                                             %
164 %   G e t I m a g e R e g i s t r y                                           %
165 %                                                                             %
166 %                                                                             %
167 %                                                                             %
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 %
170 %  GetImageRegistry() returns a value associated with an image registry key.
171 %
172 %  The format of the GetImageRegistry method is:
173 %
174 %      void *GetImageRegistry(const RegistryType type,const char *key,
175 %        ExceptionInfo *exception)
176 %
177 %  A description of each parameter follows:
178 %
179 %    o type: the type.
180 %
181 %    o key: the key.
182 %
183 %    o exception: the exception.
184 %
185 */
186 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
187   ExceptionInfo *exception)
188 {
189   void
190     *value;
191
192   RegistryInfo
193     *registry_info;
194
195   if (IsEventLogging() != MagickFalse)
196     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
197   if (registry == (void *) NULL)
198     return((void *) NULL);
199   registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
200   if (registry_info == (void *) NULL)
201     {
202       (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
203         "UnableToGetRegistryID","`%s'",key);
204       return((void *) NULL);
205     }
206   value=(void *) NULL;
207   switch (type)
208   {
209     case ImageRegistryType:
210     {
211       if (type == registry_info->type)
212         value=(void *) CloneImageList((Image *) registry_info->value,exception);
213       break;
214     }
215     case ImageInfoRegistryType:
216     {
217       if (type == registry_info->type)
218         value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
219       break;
220     }
221     case StringRegistryType:
222     {
223       switch (registry_info->type)
224       {
225         case ImageRegistryType:
226         {
227           value=(Image *) ConstantString(((Image *)
228             registry_info->value)->filename);
229           break;
230         }
231         case ImageInfoRegistryType:
232         {
233           value=(Image *) ConstantString(((ImageInfo *)
234             registry_info->value)->filename);
235           break;
236         }
237         case StringRegistryType:
238         {
239           value=(void *) ConstantString((char *) registry_info->value);
240           break;
241         }
242         default:
243           break;
244       }
245       break;
246     }
247     default:
248       break;
249   }
250   return(value);
251 }
252 \f
253 /*
254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 %                                                                             %
256 %                                                                             %
257 %                                                                             %
258 %   G e t N e x t I m a g e R e g i s t r y                                   %
259 %                                                                             %
260 %                                                                             %
261 %                                                                             %
262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
263 %
264 %  GetNextImageRegistry() gets the next image registry value.
265 %
266 %  The format of the GetNextImageRegistry method is:
267 %
268 %      char *GetNextImageRegistry(void)
269 %
270 */
271 MagickExport char *GetNextImageRegistry(void)
272 {
273   if (IsEventLogging() != MagickFalse)
274     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
275   if (registry == (void *) NULL)
276     return((char *) NULL);
277   return((char *) GetNextKeyInSplayTree(registry));
278 }
279 \f
280 /*
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 %                                                                             %
283 %                                                                             %
284 %                                                                             %
285 +   R e g i s t r y C o m p o n e n t G e n e s i s                           %
286 %                                                                             %
287 %                                                                             %
288 %                                                                             %
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 %
291 %  RegistryComponentGenesis() instantiates the registry component.
292 %
293 %  The format of the RegistryComponentGenesis method is:
294 %
295 %      MagickBooleanType RegistryComponentGenesis(void)
296 %
297 */
298 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
299 {
300   if (registry_semaphore == (SemaphoreInfo *) NULL)
301     registry_semaphore=AcquireSemaphoreInfo();
302   return(MagickTrue);
303 }
304 \f
305 /*
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 %                                                                             %
308 %                                                                             %
309 %                                                                             %
310 %   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                         %
311 %                                                                             %
312 %                                                                             %
313 %                                                                             %
314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315 %
316 %  RegistryComponentTerminus() destroys the registry component.
317 %
318 %  The format of the DestroyDefines method is:
319 %
320 %      void RegistryComponentTerminus(void)
321 %
322 */
323 MagickPrivate void RegistryComponentTerminus(void)
324 {
325   if (registry_semaphore == (SemaphoreInfo *) NULL)
326     ActivateSemaphoreInfo(&registry_semaphore);
327   LockSemaphoreInfo(registry_semaphore);
328   if (IsEventLogging() != MagickFalse)
329     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
330   if (registry != (void *) NULL)
331     registry=DestroySplayTree(registry);
332   UnlockSemaphoreInfo(registry_semaphore);
333   RelinquishSemaphoreInfo(&registry_semaphore);
334 }
335 \f
336 /*
337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 %                                                                             %
339 %                                                                             %
340 %                                                                             %
341 %   R e m o v e I m a g e R e g i s t r y                                     %
342 %                                                                             %
343 %                                                                             %
344 %                                                                             %
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 %
347 %  RemoveImageRegistry() removes a key from the image registry and returns its
348 %  value.
349 %
350 %  The format of the RemoveImageRegistry method is:
351 %
352 %      void *RemoveImageRegistry(const char *key)
353 %
354 %  A description of each parameter follows:
355 %
356 %    o key: the registry.
357 %
358 */
359 MagickExport void *RemoveImageRegistry(const char *key)
360 {
361   if (IsEventLogging() != MagickFalse)
362     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
363   if (registry == (void *) NULL)
364     return((void *) NULL);
365   return(RemoveNodeFromSplayTree(registry,key));
366 }
367 \f
368 /*
369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370 %                                                                             %
371 %                                                                             %
372 %                                                                             %
373 %   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                       %
374 %                                                                             %
375 %                                                                             %
376 %                                                                             %
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 %
379 %  ResetImageRegistryIterator() resets the registry iterator.  Use it in
380 %  conjunction with GetNextImageRegistry() to iterate over all the values
381 %  in the image registry.
382 %
383 %  The format of the ResetImageRegistryIterator method is:
384 %
385 %      ResetImageRegistryIterator(void)
386 %
387 */
388 MagickExport void ResetImageRegistryIterator(void)
389 {
390   if (IsEventLogging() != MagickFalse)
391     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
392   if (registry == (void *) NULL)
393     return;
394   ResetSplayTreeIterator(registry);
395 }
396 \f
397 /*
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399 %                                                                             %
400 %                                                                             %
401 %                                                                             %
402 %   S e t I m a g e R e g i s t r y                                           %
403 %                                                                             %
404 %                                                                             %
405 %                                                                             %
406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407 %
408 %  SetImageRegistry() associates a value with an image registry key.
409 %
410 %  The format of the SetImageRegistry method is:
411 %
412 %      MagickBooleanType SetImageRegistry(const RegistryType type,
413 %        const char *key,const void *value,ExceptionInfo *exception)
414 %
415 %  A description of each parameter follows:
416 %
417 %    o type: the type.
418 %
419 %    o key: the key.
420 %
421 %    o value: the value.
422 %
423 %    o exception: the exception.
424 %
425 */
426
427 static void *DestroyRegistryNode(void *registry_info)
428 {
429   register RegistryInfo
430     *p;
431
432   p=(RegistryInfo *) registry_info;
433   switch (p->type)
434   {
435     case StringRegistryType:
436     default:
437     {
438       p->value=RelinquishMagickMemory(p->value);
439       break;
440     }
441     case ImageRegistryType:
442     {
443       p->value=(void *) DestroyImageList((Image *) p->value);
444       break;
445     }
446     case ImageInfoRegistryType:
447     {
448       p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
449       break;
450     }
451   }
452   return(RelinquishMagickMemory(p));
453 }
454
455 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
456   const char *key,const void *value,ExceptionInfo *exception)
457 {
458   MagickBooleanType
459     status;
460
461   RegistryInfo
462     *registry_info;
463
464   void
465     *clone_value;
466
467   if (IsEventLogging() != MagickFalse)
468     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
469   if (value == (const void *) NULL)
470     return(MagickFalse);
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     {
526       if (registry_semaphore == (SemaphoreInfo *) NULL)
527         ActivateSemaphoreInfo(&registry_semaphore);
528       LockSemaphoreInfo(registry_semaphore);
529       if (registry == (SplayTreeInfo *) NULL)
530         registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
531           DestroyRegistryNode);
532       UnlockSemaphoreInfo(registry_semaphore);
533     }
534   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
535   return(status);
536 }