MagickCore  7.1.1-43
Convert, Edit, Or Compose Bitmap Images
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 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 % https://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 
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/memory-private.h"
50 #include "MagickCore/registry.h"
51 #include "MagickCore/registry-private.h"
52 #include "MagickCore/splay-tree.h"
53 #include "MagickCore/string_.h"
54 #include "MagickCore/string-private.h"
55 #include "MagickCore/timer-private.h"
56 #include "MagickCore/utility.h"
57 
58 /*
59  Typedef declarations.
60 */
61 typedef struct _RegistryInfo
62 {
63  RegistryType
64  type;
65 
66  void
67  *value;
68 
69  size_t
70  signature;
71 } RegistryInfo;
72 
73 /*
74  Static declarations.
75 */
76 static SplayTreeInfo
77  *registry = (SplayTreeInfo *) NULL;
78 
79 static SemaphoreInfo
80  *registry_semaphore = (SemaphoreInfo *) NULL;
81 
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[MagickPathExtent],
114  value[MagickPathExtent];
115 
116  char
117  *p;
118 
119  assert(option != (const char *) NULL);
120  (void) CopyMagickString(key,option,MagickPathExtent);
121  for (p=key; *p != '\0'; p++)
122  if (*p == '=')
123  break;
124  *value='\0';
125  if (*p == '=')
126  (void) CopyMagickString(value,p+1,MagickPathExtent);
127  *p='\0';
128  return(SetImageRegistry(type,key,value,exception));
129 }
130 
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  assert(key != (const char *) NULL);
156  if (IsEventLogging() != MagickFalse)
157  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
158  if (registry == (void *) NULL)
159  return(MagickFalse);
160  return(DeleteNodeFromSplayTree(registry,key));
161 }
162 
163 /*
164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 % %
166 % %
167 % %
168 % G e t I m a g e R e g i s t r y %
169 % %
170 % %
171 % %
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 %
174 % GetImageRegistry() returns a value associated with an image registry key.
175 %
176 % The format of the GetImageRegistry method is:
177 %
178 % void *GetImageRegistry(const RegistryType type,const char *key,
179 % ExceptionInfo *exception)
180 %
181 % A description of each parameter follows:
182 %
183 % o type: the type.
184 %
185 % o key: the key.
186 %
187 % o exception: the exception.
188 %
189 */
190 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
191  ExceptionInfo *exception)
192 {
193  void
194  *value;
195 
197  *registry_info;
198 
199  assert(key != (const char *) NULL);
200  if (IsEventLogging() != MagickFalse)
201  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
202  if (registry == (void *) NULL)
203  return((void *) NULL);
204  registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
205  if (registry_info == (void *) NULL)
206  return((void *) NULL);
207  value=(void *) NULL;
208  switch (type)
209  {
210  case ImageRegistryType:
211  {
212  if (type == registry_info->type)
213  value=(void *) CloneImageList((Image *) registry_info->value,exception);
214  break;
215  }
216  case ImageInfoRegistryType:
217  {
218  if (type == registry_info->type)
219  value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
220  break;
221  }
222  case StringRegistryType:
223  {
224  switch (registry_info->type)
225  {
226  case ImageRegistryType:
227  {
228  value=(Image *) ConstantString(((Image *)
229  registry_info->value)->filename);
230  break;
231  }
232  case ImageInfoRegistryType:
233  {
234  value=(Image *) ConstantString(((ImageInfo *)
235  registry_info->value)->filename);
236  break;
237  }
238  case StringRegistryType:
239  {
240  value=(void *) ConstantString((char *) registry_info->value);
241  break;
242  }
243  default:
244  break;
245  }
246  break;
247  }
248  default:
249  break;
250  }
251  return(value);
252 }
253 
254 /*
255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256 % %
257 % %
258 % %
259 % G e t N e x t I m a g e R e g i s t r y %
260 % %
261 % %
262 % %
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 %
265 % GetNextImageRegistry() gets the next image registry value.
266 %
267 % The format of the GetNextImageRegistry method is:
268 %
269 % char *GetNextImageRegistry(void)
270 %
271 */
272 MagickExport char *GetNextImageRegistry(void)
273 {
274  if (IsEventLogging() != MagickFalse)
275  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
276  if (registry == (void *) NULL)
277  return((char *) NULL);
278  return((char *) GetNextKeyInSplayTree(registry));
279 }
280 
281 /*
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % %
284 % %
285 % %
286 + R e g i s t r y C o m p o n e n t G e n e s i s %
287 % %
288 % %
289 % %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 %
292 % RegistryComponentGenesis() instantiates the registry component.
293 %
294 % The format of the RegistryComponentGenesis method is:
295 %
296 % MagickBooleanType RegistryComponentGenesis(void)
297 %
298 */
299 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
300 {
301  if (registry_semaphore == (SemaphoreInfo *) NULL)
302  registry_semaphore=AcquireSemaphoreInfo();
303  return(MagickTrue);
304 }
305 
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 MagickPrivate void RegistryComponentTerminus(void)
325 {
326  if (registry_semaphore == (SemaphoreInfo *) NULL)
327  ActivateSemaphoreInfo(&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  UnlockSemaphoreInfo(registry_semaphore);
334  RelinquishSemaphoreInfo(&registry_semaphore);
335 }
336 
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  assert(key != (const char *) NULL);
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 
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 
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 {
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 {
461  *registry_info;
462 
463  void
464  *clone_value;
465 
466  assert(key != (const char *) NULL);
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  if (LocaleCompare(key,"date:precision") == 0)
482  SetMagickDatePrecision((size_t) StringToInteger(string));
483  clone_value=(void *) ConstantString(string);
484  break;
485  }
486  case ImageRegistryType:
487  {
488  const Image
489  *image;
490 
491  image=(const Image *) value;
492  if ((image == (const Image *) NULL) ||
493  (image->signature != MagickCoreSignature))
494  {
495  (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
496  "UnableToSetRegistry","%s",key);
497  return(MagickFalse);
498  }
499  clone_value=(void *) CloneImageList(image,exception);
500  break;
501  }
502  case ImageInfoRegistryType:
503  {
504  const ImageInfo
505  *image_info;
506 
507  image_info=(const ImageInfo *) value;
508  if ((image_info == (const ImageInfo *) NULL) ||
509  (image_info->signature != MagickCoreSignature))
510  {
511  (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
512  "UnableToSetRegistry","%s",key);
513  return(MagickFalse);
514  }
515  clone_value=(void *) CloneImageInfo(image_info);
516  break;
517  }
518  }
519  if (clone_value == (void *) NULL)
520  return(MagickFalse);
521  registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info));
522  (void) memset(registry_info,0,sizeof(*registry_info));
523  registry_info->type=type;
524  registry_info->value=clone_value;
525  registry_info->signature=MagickCoreSignature;
526  if (registry == (SplayTreeInfo *) NULL)
527  {
528  if (registry_semaphore == (SemaphoreInfo *) NULL)
529  ActivateSemaphoreInfo(&registry_semaphore);
530  LockSemaphoreInfo(registry_semaphore);
531  if (registry == (SplayTreeInfo *) NULL)
532  registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
533  DestroyRegistryNode);
534  UnlockSemaphoreInfo(registry_semaphore);
535  }
536  return(AddValueToSplayTree(registry,ConstantString(key),registry_info));
537 }
_SplayTreeInfo
Definition: splay-tree.c:83
_RegistryInfo
Definition: registry.c:61
SemaphoreInfo
Definition: semaphore.c:60
_Image
Definition: image.h:131
_ImageInfo
Definition: image.h:358
_ExceptionInfo
Definition: exception.h:101