MagickCore 7.1.2-26
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
module.c
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M OOO DDDD U U L EEEEE %
7% MM MM O O D D U U L E %
8% M M M O O D D U U L EEE %
9% M M O O D D U U L E %
10% M M OOO DDDD UUU LLLLL EEEEE %
11% %
12% %
13% MagickCore Module Methods %
14% %
15% Software Design %
16% Bob Friesenhahn %
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/license/ %
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/blob.h"
45#include "MagickCore/coder.h"
46#include "MagickCore/client.h"
47#include "MagickCore/configure.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/log.h"
51#include "MagickCore/linked-list.h"
52#include "MagickCore/magic.h"
53#include "MagickCore/magick.h"
54#include "MagickCore/memory_.h"
55#include "MagickCore/memory-private.h"
56#include "MagickCore/module.h"
57#include "MagickCore/module-private.h"
58#include "MagickCore/nt-base-private.h"
59#include "MagickCore/policy.h"
60#include "MagickCore/semaphore.h"
61#include "MagickCore/splay-tree.h"
62#include "MagickCore/static.h"
63#include "MagickCore/string_.h"
64#include "MagickCore/string-private.h"
65#include "MagickCore/timer-private.h"
66#include "MagickCore/token.h"
67#include "MagickCore/utility.h"
68#include "MagickCore/utility-private.h"
69#if defined(MAGICKCORE_MODULES_SUPPORT)
70#if defined(MAGICKCORE_LTDL_DELEGATE)
71#include "ltdl.h"
72typedef lt_dlhandle ModuleHandle;
73#else
74typedef void *ModuleHandle;
75#endif
76
77/*
78 Define declarations.
79*/
80#if defined(MAGICKCORE_LTDL_DELEGATE)
81# define FilterGlobExpression "*.la"
82# define ModuleGlobExpression "*.la"
83#else
84# if defined(_DEBUG)
85# define FilterGlobExpression "FILTER_DB_*.dll"
86# define ModuleGlobExpression "IM_MOD_DB_*.dll"
87# else
88# define FilterGlobExpression "FILTER_RL_*.dll"
89# define ModuleGlobExpression "IM_MOD_RL_*.dll"
90# endif
91#endif
92
93/*
94 Global declarations.
95*/
96static SemaphoreInfo
97 *module_semaphore = (SemaphoreInfo *) NULL;
98
99static SplayTreeInfo
100 *module_list = (SplayTreeInfo *) NULL;
101
102/*
103 Forward declarations.
104*/
105static const ModuleInfo
106 *RegisterModule(const ModuleInfo *,ExceptionInfo *);
107
108static MagickBooleanType
109 GetMagickModulePath(const char *,MagickModuleType,char *,ExceptionInfo *),
110 IsModuleTreeInstantiated(void),
111 UnregisterModule(const ModuleInfo *,ExceptionInfo *);
112
113static void
114 TagToCoderModuleName(const char *,char *),
115 TagToFilterModuleName(const char *,char *),
116 TagToModuleName(const char *,const char *,char *);
117
118/*
119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120% %
121% %
122% %
123% A c q u i r e M o d u l e I n f o %
124% %
125% %
126% %
127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128%
129% AcquireModuleInfo() allocates the ModuleInfo structure.
130%
131% The format of the AcquireModuleInfo method is:
132%
133% ModuleInfo *AcquireModuleInfo(const char *path,const char *tag)
134%
135% A description of each parameter follows:
136%
137% o path: the path associated with the tag.
138%
139% o tag: a character string that represents the image format we are
140% looking for.
141%
142*/
143MagickExport ModuleInfo *AcquireModuleInfo(const char *path,const char *tag)
144{
145 ModuleInfo
146 *module_info;
147
148 module_info=(ModuleInfo *) AcquireCriticalMemory(sizeof(*module_info));
149 (void) memset(module_info,0,sizeof(*module_info));
150 if (path != (const char *) NULL)
151 module_info->path=ConstantString(path);
152 if (tag != (const char *) NULL)
153 module_info->tag=ConstantString(tag);
154 module_info->timestamp=GetMagickTime();
155 module_info->signature=MagickCoreSignature;
156 return(module_info);
157}
158
159/*
160%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161% %
162% %
163% %
164% D e s t r o y M o d u l e L i s t %
165% %
166% %
167% %
168%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169%
170% DestroyModuleList() unregisters any previously loaded modules and exits
171% the module loaded environment.
172%
173% The format of the DestroyModuleList module is:
174%
175% void DestroyModuleList(void)
176%
177*/
178MagickExport void DestroyModuleList(void)
179{
180 /*
181 Destroy magick modules.
182 */
183 LockSemaphoreInfo(module_semaphore);
184#if defined(MAGICKCORE_MODULES_SUPPORT)
185 if (module_list != (SplayTreeInfo *) NULL)
186 module_list=DestroySplayTree(module_list);
187#endif
188 UnlockSemaphoreInfo(module_semaphore);
189}
190
191/*
192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193% %
194% %
195% %
196% G e t M o d u l e I n f o %
197% %
198% %
199% %
200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201%
202% GetModuleInfo() returns a pointer to a ModuleInfo structure that matches the
203% specified tag. If tag is NULL, the head of the module list is returned. If
204% no modules are loaded, or the requested module is not found, NULL is
205% returned.
206%
207% The format of the GetModuleInfo module is:
208%
209% ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception)
210%
211% A description of each parameter follows:
212%
213% o tag: a character string that represents the image format we are
214% looking for.
215%
216% o exception: return any errors or warnings in this structure.
217%
218*/
219MagickExport ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception)
220{
221 ModuleInfo
222 *module_info;
223
224 if (IsModuleTreeInstantiated() == MagickFalse)
225 return((ModuleInfo *) NULL);
226 LockSemaphoreInfo(module_semaphore);
227 ResetSplayTreeIterator(module_list);
228 if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
229 {
230#if defined(MAGICKCORE_MODULES_SUPPORT)
231 if (LocaleCompare(tag,"*") == 0)
232 (void) OpenModules(exception);
233#endif
234 module_info=(ModuleInfo *) GetNextValueInSplayTree(module_list);
235 UnlockSemaphoreInfo(module_semaphore);
236 return(module_info);
237 }
238 module_info=(ModuleInfo *) GetValueFromSplayTree(module_list,tag);
239 UnlockSemaphoreInfo(module_semaphore);
240 return(module_info);
241}
242
243/*
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245% %
246% %
247% %
248% G e t M o d u l e I n f o L i s t %
249% %
250% %
251% %
252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253%
254% GetModuleInfoList() returns any modules that match the specified pattern.
255%
256% The format of the GetModuleInfoList function is:
257%
258% const ModuleInfo **GetModuleInfoList(const char *pattern,
259% size_t *number_modules,ExceptionInfo *exception)
260%
261% A description of each parameter follows:
262%
263% o pattern: Specifies a pointer to a text string containing a pattern.
264%
265% o number_modules: This integer returns the number of modules in the list.
266%
267% o exception: return any errors or warnings in this structure.
268%
269*/
270
271#if defined(__cplusplus) || defined(c_plusplus)
272extern "C" {
273#endif
274
275static int ModuleInfoCompare(const void *x,const void *y)
276{
277 const ModuleInfo
278 **p,
279 **q;
280
281 p=(const ModuleInfo **) x,
282 q=(const ModuleInfo **) y;
283 if (LocaleCompare((*p)->path,(*q)->path) == 0)
284 return(LocaleCompare((*p)->tag,(*q)->tag));
285 return(LocaleCompare((*p)->path,(*q)->path));
286}
287
288#if defined(__cplusplus) || defined(c_plusplus)
289}
290#endif
291
292MagickExport const ModuleInfo **GetModuleInfoList(const char *pattern,
293 size_t *number_modules,ExceptionInfo *exception)
294{
295 const ModuleInfo
296 **modules;
297
298 const ModuleInfo
299 *p;
300
301 ssize_t
302 i;
303
304 /*
305 Allocate module list.
306 */
307 assert(pattern != (char *) NULL);
308 assert(number_modules != (size_t *) NULL);
309 if (IsEventLogging() != MagickFalse)
310 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
311 *number_modules=0;
312 p=GetModuleInfo("*",exception);
313 if (p == (const ModuleInfo *) NULL)
314 return((const ModuleInfo **) NULL);
315 modules=(const ModuleInfo **) AcquireQuantumMemory((size_t)
316 GetNumberOfNodesInSplayTree(module_list)+1UL,sizeof(*modules));
317 if (modules == (const ModuleInfo **) NULL)
318 return((const ModuleInfo **) NULL);
319 /*
320 Generate module list.
321 */
322 LockSemaphoreInfo(module_semaphore);
323 ResetSplayTreeIterator(module_list);
324 p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
325 for (i=0; p != (const ModuleInfo *) NULL; )
326 {
327 if ((p->stealth == MagickFalse) &&
328 (GlobExpression(p->tag,pattern,MagickFalse) != MagickFalse))
329 modules[i++]=p;
330 p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
331 }
332 UnlockSemaphoreInfo(module_semaphore);
333 qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleInfoCompare);
334 modules[i]=(ModuleInfo *) NULL;
335 *number_modules=(size_t) i;
336 return(modules);
337}
338
339/*
340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341% %
342% %
343% %
344% G e t M o d u l e L i s t %
345% %
346% %
347% %
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349%
350% GetModuleList() returns any image format modules that match the specified
351% pattern.
352%
353% The format of the GetModuleList function is:
354%
355% char **GetModuleList(const char *pattern,const MagickModuleType type,
356% size_t *number_modules,ExceptionInfo *exception)
357%
358% A description of each parameter follows:
359%
360% o pattern: Specifies a pointer to a text string containing a pattern.
361%
362% o type: choose from MagickImageCoderModule or MagickImageFilterModule.
363%
364% o number_modules: This integer returns the number of modules in the
365% list.
366%
367% o exception: return any errors or warnings in this structure.
368%
369*/
370
371#if defined(__cplusplus) || defined(c_plusplus)
372extern "C" {
373#endif
374
375static int ModuleCompare(const void *x,const void *y)
376{
377 const char
378 **p,
379 **q;
380
381 p=(const char **) x;
382 q=(const char **) y;
383 return(LocaleCompare(*p,*q));
384}
385
386#if defined(__cplusplus) || defined(c_plusplus)
387}
388#endif
389
390MagickExport char **GetModuleList(const char *pattern,
391 const MagickModuleType type,size_t *number_modules,ExceptionInfo *exception)
392{
393#define MaxModules 511
394
395 char
396 **modules,
397 filename[MagickPathExtent],
398 module_path[MagickPathExtent],
399 path[MagickPathExtent];
400
401 DIR
402 *directory;
403
404 MagickBooleanType
405 status;
406
407 ssize_t
408 i;
409
410 size_t
411 max_entries;
412
413 struct dirent
414 *buffer,
415 *entry;
416
417 /*
418 Locate all modules in the image coder or filter path.
419 */
420 switch (type)
421 {
422 case MagickImageCoderModule:
423 default:
424 {
425 TagToCoderModuleName("magick",filename);
426 status=GetMagickModulePath(filename,MagickImageCoderModule,module_path,
427 exception);
428 break;
429 }
430 case MagickImageFilterModule:
431 {
432 TagToFilterModuleName("analyze",filename);
433 status=GetMagickModulePath(filename,MagickImageFilterModule,module_path,
434 exception);
435 break;
436 }
437 }
438 if (status == MagickFalse)
439 return((char **) NULL);
440 GetPathComponent(module_path,HeadPath,path);
441 max_entries=MaxModules;
442 modules=(char **) AcquireQuantumMemory((size_t) max_entries+1UL,
443 sizeof(*modules));
444 if (modules == (char **) NULL)
445 return((char **) NULL);
446 *modules=(char *) NULL;
447 directory=opendir(path);
448 if (directory == (DIR *) NULL)
449 {
450 modules=(char **) RelinquishMagickMemory(modules);
451 return((char **) NULL);
452 }
453 buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1);
454 if (buffer == (struct dirent *) NULL)
455 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
456 i=0;
457 while ((MagickReadDirectory(directory,buffer,&entry) == 0) &&
458 (entry != (struct dirent *) NULL))
459 {
460 if (type == MagickImageFilterModule)
461 status=GlobExpression(entry->d_name,FilterGlobExpression,MagickFalse);
462 else
463 status=GlobExpression(entry->d_name,ModuleGlobExpression,MagickFalse);
464 if (status == MagickFalse)
465 continue;
466 if (GlobExpression(entry->d_name,pattern,MagickFalse) == MagickFalse)
467 continue;
468 if (i >= (ssize_t) max_entries)
469 {
470 modules=(char **) NULL;
471 if (~max_entries > max_entries)
472 modules=(char **) ResizeQuantumMemory(modules,(size_t)
473 (max_entries << 1),sizeof(*modules));
474 max_entries<<=1;
475 if (modules == (char **) NULL)
476 break;
477 }
478 /*
479 Add new module name to list.
480 */
481 modules[i]=AcquireString((char *) NULL);
482 GetPathComponent(entry->d_name,BasePath,modules[i]);
483 if (LocaleNCompare("IM_MOD_",modules[i],7) == 0)
484 {
485 (void) CopyMagickString(modules[i],modules[i]+10,MagickPathExtent);
486 modules[i][strlen(modules[i])-1]='\0';
487 }
488 else if (LocaleNCompare("FILTER_",modules[i],7) == 0)
489 {
490 (void) CopyMagickString(modules[i],modules[i]+10,MagickPathExtent);
491 modules[i][strlen(modules[i])-1]='\0';
492 }
493 i++;
494 }
495 buffer=(struct dirent *) RelinquishMagickMemory(buffer);
496 (void) closedir(directory);
497 if (modules == (char **) NULL)
498 {
499 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureError,
500 "MemoryAllocationFailed","`%s'",pattern);
501 return((char **) NULL);
502 }
503 qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleCompare);
504 modules[i]=(char *) NULL;
505 *number_modules=(size_t) i;
506 return(modules);
507}
508
509/*
510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511% %
512% %
513% %
514% G e t M a g i c k M o d u l e P a t h %
515% %
516% %
517% %
518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519%
520% GetMagickModulePath() finds a module with the specified module type and
521% filename.
522%
523% The format of the GetMagickModulePath module is:
524%
525% MagickBooleanType GetMagickModulePath(const char *filename,
526% MagickModuleType module_type,char *path,ExceptionInfo *exception)
527%
528% A description of each parameter follows:
529%
530% o filename: the module file name.
531%
532% o module_type: the module type: MagickImageCoderModule or
533% MagickImageFilterModule.
534%
535% o path: the path associated with the filename.
536%
537% o exception: return any errors or warnings in this structure.
538%
539*/
540static MagickBooleanType GetMagickModulePath(const char *filename,
541 MagickModuleType module_type,char *path,ExceptionInfo *exception)
542{
543 char
544 *module_path;
545
546 assert(filename != (const char *) NULL);
547 assert(path != (char *) NULL);
548 assert(exception != (ExceptionInfo *) NULL);
549 if (IsEventLogging() != MagickFalse)
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
551 if (strchr(filename,'/') != (char *) NULL)
552 return(MagickFalse);
553 (void) CopyMagickString(path,filename,MagickPathExtent);
554 module_path=(char *) NULL;
555 switch (module_type)
556 {
557 case MagickImageCoderModule:
558 default:
559 {
560 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
561 "Searching for coder module file \"%s\" ...",filename);
562 module_path=GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");
563#if defined(MAGICKCORE_CODER_PATH)
564 if (module_path == (char *) NULL)
565 module_path=AcquireString(MAGICKCORE_CODER_PATH);
566#endif
567 break;
568 }
569 case MagickImageFilterModule:
570 {
571 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
572 "Searching for filter module file \"%s\" ...",filename);
573 module_path=GetEnvironmentValue("MAGICK_FILTER_MODULE_PATH");
574#if defined(MAGICKCORE_FILTER_PATH)
575 if (module_path == (char *) NULL)
576 module_path=AcquireString(MAGICKCORE_FILTER_PATH);
577#endif
578 break;
579 }
580 }
581 if (module_path != (char *) NULL)
582 {
583 char
584 *p,
585 *q;
586
587 for (p=module_path-1; p != (char *) NULL; )
588 {
589 (void) CopyMagickString(path,p+1,MagickPathExtent);
590 q=strchr(path,DirectoryListSeparator);
591 if (q != (char *) NULL)
592 *q='\0';
593 q=path+strlen(path)-1;
594 if ((q >= path) && (*q != *DirectorySeparator))
595 (void) ConcatenateMagickString(path,DirectorySeparator,
596 MagickPathExtent);
597 (void) ConcatenateMagickString(path,filename,MagickPathExtent);
598 {
599 char
600 *real_path = realpath_utf8(path);
601
602 if (real_path != (char *) NULL)
603 {
604 (void) CopyMagickString(path,real_path,MagickPathExtent);
605 real_path=DestroyString(real_path);
606 }
607 }
608 if (IsPathAccessible(path) != MagickFalse)
609 {
610 module_path=DestroyString(module_path);
611 return(MagickTrue);
612 }
613 p=strchr(p+1,DirectoryListSeparator);
614 }
615 module_path=DestroyString(module_path);
616 }
617#if defined(MAGICKCORE_INSTALLED_SUPPORT)
618 else
619#if defined(MAGICKCORE_CODER_PATH)
620 {
621 const char
622 *directory;
623
624 /*
625 Search hard coded paths.
626 */
627 switch (module_type)
628 {
629 case MagickImageCoderModule:
630 default:
631 {
632 directory=MAGICKCORE_CODER_PATH;
633 break;
634 }
635 case MagickImageFilterModule:
636 {
637 directory=MAGICKCORE_FILTER_PATH;
638 break;
639 }
640 }
641 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",directory,
642 filename);
643 if (IsPathAccessible(path) == MagickFalse)
644 {
645 ThrowFileException(exception,ConfigureWarning,
646 "UnableToOpenModuleFile",path);
647 return(MagickFalse);
648 }
649 return(MagickTrue);
650 }
651#else
652#if defined(MAGICKCORE_WINDOWS_SUPPORT)
653 {
654 const char
655 *registry_key;
656
657 unsigned char
658 *key_value;
659
660 /*
661 Locate path via registry key.
662 */
663 switch (module_type)
664 {
665 case MagickImageCoderModule:
666 default:
667 {
668 registry_key="CoderModulesPath";
669 break;
670 }
671 case MagickImageFilterModule:
672 {
673 registry_key="FilterModulesPath";
674 break;
675 }
676 }
677 key_value=NTRegistryKeyLookup(registry_key);
678 if (key_value == (unsigned char *) NULL)
679 {
680 ThrowMagickException(exception,GetMagickModule(),ConfigureError,
681 "RegistryKeyLookupFailed","`%s'",registry_key);
682 return(MagickFalse);
683 }
684 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",(char *)
685 key_value,DirectorySeparator,filename);
686 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
687 if (IsPathAccessible(path) == MagickFalse)
688 {
689 ThrowFileException(exception,ConfigureWarning,
690 "UnableToOpenModuleFile",path);
691 return(MagickFalse);
692 }
693 return(MagickTrue);
694 }
695#endif
696#endif
697#if !defined(MAGICKCORE_CODER_PATH) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
698# error MAGICKCORE_CODER_PATH or MAGICKCORE_WINDOWS_SUPPORT must be defined when MAGICKCORE_INSTALLED_SUPPORT is defined
699#endif
700#else
701 {
702 char
703 *home;
704
705 home=GetEnvironmentValue("MAGICK_HOME");
706 if (home != (char *) NULL)
707 {
708 /*
709 Search MAGICK_HOME.
710 */
711#if !defined(MAGICKCORE_POSIX_SUPPORT)
712 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",home,
713 DirectorySeparator,filename);
714#else
715 const char
716 *directory;
717
718 switch (module_type)
719 {
720 case MagickImageCoderModule:
721 default:
722 {
723 directory=MAGICKCORE_CODER_RELATIVE_PATH;
724 break;
725 }
726 case MagickImageFilterModule:
727 {
728 directory=MAGICKCORE_FILTER_RELATIVE_PATH;
729 break;
730 }
731 }
732 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s",home,
733 directory,filename);
734#endif
735 home=DestroyString(home);
736 if (IsPathAccessible(path) != MagickFalse)
737 return(MagickTrue);
738 }
739 }
740 if (*GetClientPath() != '\0')
741 {
742 /*
743 Search based on executable directory.
744 */
745#if !defined(MAGICKCORE_POSIX_SUPPORT)
746 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",GetClientPath(),
747 DirectorySeparator,filename);
748#else
749 char
750 prefix[MagickPathExtent];
751
752 const char
753 *directory;
754
755 switch (module_type)
756 {
757 case MagickImageCoderModule:
758 default:
759 {
760 directory="coders";
761 break;
762 }
763 case MagickImageFilterModule:
764 {
765 directory="filters";
766 break;
767 }
768 }
769 (void) CopyMagickString(prefix,GetClientPath(),MagickPathExtent);
770 ChopPathComponents(prefix,1);
771 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s/%s",prefix,
772 MAGICKCORE_MODULES_RELATIVE_PATH,directory,filename);
773#endif
774 if (IsPathAccessible(path) != MagickFalse)
775 return(MagickTrue);
776 }
777#if defined(MAGICKCORE_WINDOWS_SUPPORT)
778 {
779 /*
780 Search module path.
781 */
782 if ((NTGetModulePath("CORE_RL_MagickCore_.dll",path) != MagickFalse) ||
783 (NTGetModulePath("CORE_DB_MagickCore_.dll",path) != MagickFalse))
784 {
785 (void) ConcatenateMagickString(path,DirectorySeparator,
786 MagickPathExtent);
787 (void) ConcatenateMagickString(path,filename,MagickPathExtent);
788 if (IsPathAccessible(path) != MagickFalse)
789 return(MagickTrue);
790 }
791 }
792#endif
793 {
794 char
795 *home;
796
797 home=GetEnvironmentValue("XDG_CONFIG_HOME");
798 if (home == (char *) NULL)
799#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
800 home=GetEnvironmentValue("LOCALAPPDATA");
801 if (home == (char *) NULL)
802 home=GetEnvironmentValue("APPDATA");
803 if (home == (char *) NULL)
804 home=GetEnvironmentValue("USERPROFILE");
805#endif
806 if (home != (char *) NULL)
807 {
808 /*
809 Search $XDG_CONFIG_HOME/ImageMagick.
810 */
811 (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s%s",
812 home,DirectorySeparator,DirectorySeparator,filename);
813 home=DestroyString(home);
814 if (IsPathAccessible(path) != MagickFalse)
815 return(MagickTrue);
816 }
817 home=GetEnvironmentValue("HOME");
818 if (home != (char *) NULL)
819 {
820 /*
821 Search $HOME/.config/ImageMagick.
822 */
823 (void) FormatLocaleString(path,MagickPathExtent,
824 "%s%s.config%sImageMagick%s%s",home,DirectorySeparator,
825 DirectorySeparator,DirectorySeparator,filename);
826 home=DestroyString(home);
827 if (IsPathAccessible(path) != MagickFalse)
828 return(MagickTrue);
829 }
830 }
831 /*
832 Search current directory.
833 */
834 if (IsPathAccessible(path) != MagickFalse)
835 return(MagickTrue);
836 if (exception->severity < ConfigureError)
837 ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
838 path);
839#endif
840 return(MagickFalse);
841}
842
843/*
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845% %
846% %
847% %
848% I s M o d u l e T r e e I n s t a n t i a t e d %
849% %
850% %
851% %
852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853%
854% IsModuleTreeInstantiated() determines if the module tree is instantiated.
855% If not, it instantiates the tree and returns it.
856%
857% The format of the IsModuleTreeInstantiated() method is:
858%
859% MagickBooleanType IsModuleTreeInstantiated(void)
860%
861*/
862
863static void *DestroyModuleNode(void *module_info)
864{
865 ExceptionInfo
866 *exception;
867
868 ModuleInfo
869 *p;
870
871 exception=AcquireExceptionInfo();
872 p=(ModuleInfo *) module_info;
873 if (UnregisterModule(p,exception) == MagickFalse)
874 CatchException(exception);
875 if (p->tag != (char *) NULL)
876 p->tag=DestroyString(p->tag);
877 if (p->path != (char *) NULL)
878 p->path=DestroyString(p->path);
879 exception=DestroyExceptionInfo(exception);
880 return(RelinquishMagickMemory(p));
881}
882
883static MagickBooleanType IsModuleTreeInstantiated(void)
884{
885 if (module_list == (SplayTreeInfo *) NULL)
886 {
887 if (module_semaphore == (SemaphoreInfo *) NULL)
888 ActivateSemaphoreInfo(&module_semaphore);
889 LockSemaphoreInfo(module_semaphore);
890 if (module_list == (SplayTreeInfo *) NULL)
891 {
892 MagickBooleanType
893 status;
894
895 ModuleInfo
896 *module_info;
897
898 SplayTreeInfo
899 *splay_tree;
900
901 splay_tree=NewSplayTree(CompareSplayTreeString,
902 (void *(*)(void *)) NULL,DestroyModuleNode);
903 module_info=AcquireModuleInfo((const char *) NULL,"[boot-strap]");
904 module_info->stealth=MagickTrue;
905 status=AddValueToSplayTree(splay_tree,module_info->tag,module_info);
906 if (status == MagickFalse)
907 ThrowFatalException(ResourceLimitFatalError,
908 "MemoryAllocationFailed");
909#if defined(MAGICKCORE_LTDL_DELEGATE)
910 if (lt_dlinit() != 0)
911 ThrowFatalException(ModuleFatalError,
912 "UnableToInitializeModuleLoader");
913#endif
914 module_list=splay_tree;
915 }
916 UnlockSemaphoreInfo(module_semaphore);
917 }
918 return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
919}
920
921/*
922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923% %
924% %
925% %
926% I n v o k e D y n a m i c I m a g e F i l t e r %
927% %
928% %
929% %
930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931%
932% InvokeDynamicImageFilter() invokes a dynamic image filter.
933%
934% The format of the InvokeDynamicImageFilter module is:
935%
936% MagickBooleanType InvokeDynamicImageFilter(const char *tag,Image **image,
937% const int argc,const char **argv,ExceptionInfo *exception)
938%
939% A description of each parameter follows:
940%
941% o tag: a character string that represents the name of the particular
942% module.
943%
944% o image: the image.
945%
946% o argc: a pointer to an integer describing the number of elements in the
947% argument vector.
948%
949% o argv: a pointer to a text array containing the command line arguments.
950%
951% o exception: return any errors or warnings in this structure.
952%
953*/
954MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
955 Image **images,const int argc,const char **argv,ExceptionInfo *exception)
956{
957 char
958 name[MagickPathExtent],
959 path[MagickPathExtent];
960
961 ImageFilterHandler
962 *image_filter;
963
964 MagickBooleanType
965 status;
966
967 ModuleHandle
968 handle;
969
970 PolicyRights
971 rights;
972
973 /*
974 Find the module.
975 */
976 assert(images != (Image **) NULL);
977 assert((*images)->signature == MagickCoreSignature);
978 if (IsEventLogging() != MagickFalse)
979 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
980 (*images)->filename);
981 rights=ReadPolicyRights;
982 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
983 ThrowPolicyException(tag,MagickFalse);
984#if !defined(MAGICKCORE_BUILD_MODULES)
985 {
986 MagickBooleanType
987 status;
988
989 status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
990 if (status != MagickFalse)
991 return(status);
992 }
993#endif
994 TagToFilterModuleName(tag,name);
995 status=GetMagickModulePath(name,MagickImageFilterModule,path,exception);
996 if (status == MagickFalse)
997 {
998 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
999 "UnableToLoadModule","'%s': %s",name,path);
1000 return(MagickFalse);
1001 }
1002 /*
1003 Open the module.
1004 */
1005 handle=(ModuleHandle) lt_dlopen(path);
1006 if (handle == (ModuleHandle) NULL)
1007 {
1008 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1009 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1010 return(MagickFalse);
1011 }
1012 /*
1013 Locate the module.
1014 */
1015#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1016 (void) FormatLocaleString(name,MagickPathExtent,"%sImage",tag);
1017#else
1018 (void) FormatLocaleString(name,MagickPathExtent,"%s%sImage",
1019 MAGICKCORE_NAMESPACE_PREFIX_TAG,tag);
1020#endif
1021 /*
1022 Execute the module.
1023 */
1024 ClearMagickException(exception);
1025 image_filter=(ImageFilterHandler *) lt_dlsym(handle,name);
1026 if (image_filter == (ImageFilterHandler *) NULL)
1027 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1028 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1029 else
1030 {
1031 size_t
1032 signature;
1033
1034 if (IsEventLogging() != MagickFalse)
1035 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1036 "Invoking \"%s\" dynamic image filter",tag);
1037 signature=image_filter(images,argc,argv,exception);
1038 if (IsEventLogging() != MagickFalse)
1039 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
1040 tag);
1041 if (signature != MagickImageFilterSignature)
1042 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1043 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1044 (unsigned long) signature,(unsigned long) MagickImageFilterSignature);
1045 }
1046 /*
1047 Close the module.
1048 */
1049 if (lt_dlclose(handle) != 0)
1050 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1051 "UnableToCloseModule","'%s': %s",name,lt_dlerror());
1052 return(exception->severity < ErrorException ? MagickTrue : MagickFalse);
1053}
1054
1055/*
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057% %
1058% %
1059% %
1060% L i s t M o d u l e I n f o %
1061% %
1062% %
1063% %
1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065%
1066% ListModuleInfo() lists the module info to a file.
1067%
1068% The format of the ListModuleInfo module is:
1069%
1070% MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
1071%
1072% A description of each parameter follows.
1073%
1074% o file: An pointer to a FILE.
1075%
1076% o exception: return any errors or warnings in this structure.
1077%
1078*/
1079MagickExport MagickBooleanType ListModuleInfo(FILE *file,
1080 ExceptionInfo *exception)
1081{
1082 char
1083 filename[MagickPathExtent],
1084 module_path[MagickPathExtent],
1085 **modules,
1086 path[MagickPathExtent];
1087
1088 ssize_t
1089 i;
1090
1091 size_t
1092 number_modules;
1093
1094 if (file == (const FILE *) NULL)
1095 file=stdout;
1096 /*
1097 List image coders.
1098 */
1099 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1100 if (modules == (char **) NULL)
1101 return(MagickFalse);
1102 TagToCoderModuleName("magick",filename);
1103 (void) GetMagickModulePath(filename,MagickImageCoderModule,module_path,
1104 exception);
1105 GetPathComponent(module_path,HeadPath,path);
1106 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1107 (void) FormatLocaleFile(file,"Image Coder\n");
1108 (void) FormatLocaleFile(file,
1109 "-------------------------------------------------"
1110 "------------------------------\n");
1111 for (i=0; i < (ssize_t) number_modules; i++)
1112 {
1113 (void) FormatLocaleFile(file,"%s",modules[i]);
1114 (void) FormatLocaleFile(file,"\n");
1115 }
1116 (void) fflush(file);
1117 /*
1118 Relinquish resources.
1119 */
1120 for (i=0; i < (ssize_t) number_modules; i++)
1121 modules[i]=DestroyString(modules[i]);
1122 modules=(char **) RelinquishMagickMemory(modules);
1123 /*
1124 List image filters.
1125 */
1126 modules=GetModuleList("*",MagickImageFilterModule,&number_modules,exception);
1127 if (modules == (char **) NULL)
1128 return(MagickFalse);
1129 TagToFilterModuleName("analyze",filename);
1130 (void) GetMagickModulePath(filename,MagickImageFilterModule,module_path,
1131 exception);
1132 GetPathComponent(module_path,HeadPath,path);
1133 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1134 (void) FormatLocaleFile(file,"Image Filter\n");
1135 (void) FormatLocaleFile(file,
1136 "-------------------------------------------------"
1137 "------------------------------\n");
1138 for (i=0; i < (ssize_t) number_modules; i++)
1139 {
1140 (void) FormatLocaleFile(file,"%s",modules[i]);
1141 (void) FormatLocaleFile(file,"\n");
1142 }
1143 (void) fflush(file);
1144 /*
1145 Relinquish resources.
1146 */
1147 for (i=0; i < (ssize_t) number_modules; i++)
1148 modules[i]=DestroyString(modules[i]);
1149 modules=(char **) RelinquishMagickMemory(modules);
1150 return(MagickTrue);
1151}
1152
1153/*
1154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155% %
1156% %
1157% %
1158+ M o d u l e C o m p o n e n t G e n e s i s %
1159% %
1160% %
1161% %
1162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163%
1164% ModuleComponentGenesis() instantiates the module component.
1165%
1166% The format of the ModuleComponentGenesis method is:
1167%
1168% MagickBooleanType ModuleComponentGenesis(void)
1169%
1170*/
1171MagickPrivate MagickBooleanType ModuleComponentGenesis(void)
1172{
1173 MagickBooleanType
1174 status;
1175
1176 if (module_semaphore == (SemaphoreInfo *) NULL)
1177 module_semaphore=AcquireSemaphoreInfo();
1178 status=IsModuleTreeInstantiated();
1179 return(status);
1180}
1181
1182/*
1183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1184% %
1185% %
1186% %
1187+ M o d u l e C o m p o n e n t T e r m i n u s %
1188% %
1189% %
1190% %
1191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192%
1193% ModuleComponentTerminus() destroys the module component.
1194%
1195% The format of the ModuleComponentTerminus method is:
1196%
1197% ModuleComponentTerminus(void)
1198%
1199*/
1200MagickPrivate void ModuleComponentTerminus(void)
1201{
1202 if (module_semaphore == (SemaphoreInfo *) NULL)
1203 ActivateSemaphoreInfo(&module_semaphore);
1204 DestroyModuleList();
1205 RelinquishSemaphoreInfo(&module_semaphore);
1206}
1207
1208/*
1209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1210% %
1211% %
1212% %
1213% O p e n M o d u l e %
1214% %
1215% %
1216% %
1217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1218%
1219% OpenModule() loads a module, and invokes its registration module. It
1220% returns MagickTrue on success, and MagickFalse if there is an error.
1221%
1222% The format of the OpenModule module is:
1223%
1224% MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
1225%
1226% A description of each parameter follows:
1227%
1228% o module: a character string that indicates the module to load.
1229%
1230% o exception: return any errors or warnings in this structure.
1231%
1232*/
1233MagickPrivate MagickBooleanType OpenModule(const char *module,
1234 ExceptionInfo *exception)
1235{
1236 char
1237 module_name[MagickPathExtent],
1238 name[MagickPathExtent],
1239 path[MagickPathExtent];
1240
1241 MagickBooleanType
1242 status;
1243
1244 ModuleHandle
1245 handle;
1246
1247 ModuleInfo
1248 *module_info;
1249
1250 PolicyRights
1251 rights;
1252
1253 const CoderInfo
1254 *p;
1255
1256 size_t
1257 signature;
1258
1259 /*
1260 Assign module name from alias.
1261 */
1262 assert(module != (const char *) NULL);
1263 module_info=(ModuleInfo *) GetModuleInfo(module,exception);
1264 if (module_info != (ModuleInfo *) NULL)
1265 return(MagickTrue);
1266 (void) CopyMagickString(module_name,module,MagickPathExtent);
1267 p=GetCoderInfo(module,exception);
1268 if (p != (CoderInfo *) NULL)
1269 (void) CopyMagickString(module_name,p->name,MagickPathExtent);
1270 LocaleUpper(module_name);
1271 rights=(PolicyRights) (ReadPolicyRights | WritePolicyRights);
1272 if (IsRightsAuthorized(ModulePolicyDomain,rights,module_name) == MagickFalse)
1273 ThrowPolicyException(module_name,MagickFalse);
1274 if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
1275 return(MagickTrue); /* module already opened, return */
1276 /*
1277 Locate module.
1278 */
1279 handle=(ModuleHandle) NULL;
1280 TagToCoderModuleName(module_name,name);
1281 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1282 "Searching for module \"%s\" using filename \"%s\"",module_name,name);
1283 *path='\0';
1284 status=GetMagickModulePath(name,MagickImageCoderModule,path,exception);
1285 if (status == MagickFalse)
1286 return(MagickFalse);
1287 /*
1288 Load module
1289 */
1290 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1291 "Opening module at path \"%s\"",path);
1292 handle=(ModuleHandle) lt_dlopen(path);
1293 if (handle == (ModuleHandle) NULL)
1294 {
1295 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1296 "UnableToLoadModule","'%s': %s",path,lt_dlerror());
1297 return(MagickFalse);
1298 }
1299 /*
1300 Register module.
1301 */
1302 module_info=AcquireModuleInfo(path,module_name);
1303 module_info->handle=handle;
1304 if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
1305 return(MagickFalse);
1306 /*
1307 Define RegisterFORMATImage method.
1308 */
1309 TagToModuleName(module_name,"Register%sImage",name);
1310 module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name);
1311 if (module_info->register_module == (size_t (*)(void)) NULL)
1312 {
1313 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1314 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1315 return(MagickFalse);
1316 }
1317 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1318 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1319 (void *) module_info->register_module);
1320 /*
1321 Define UnregisterFORMATImage method.
1322 */
1323 TagToModuleName(module_name,"Unregister%sImage",name);
1324 module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
1325 if (module_info->unregister_module == (void (*)(void)) NULL)
1326 {
1327 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1328 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1329 return(MagickFalse);
1330 }
1331 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1332 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1333 (void *) module_info->unregister_module);
1334 signature=module_info->register_module();
1335 if (signature != MagickImageCoderSignature)
1336 {
1337 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1338 "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name,
1339 (unsigned long) signature,(unsigned long) MagickImageCoderSignature);
1340 return(MagickFalse);
1341 }
1342 return(MagickTrue);
1343}
1344
1345/*
1346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1347% %
1348% %
1349% %
1350% O p e n M o d u l e s %
1351% %
1352% %
1353% %
1354%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1355%
1356% OpenModules() loads all available modules.
1357%
1358% The format of the OpenModules module is:
1359%
1360% MagickBooleanType OpenModules(ExceptionInfo *exception)
1361%
1362% A description of each parameter follows:
1363%
1364% o exception: return any errors or warnings in this structure.
1365%
1366*/
1367MagickPrivate MagickBooleanType OpenModules(ExceptionInfo *exception)
1368{
1369 char
1370 **modules;
1371
1372 ssize_t
1373 i;
1374
1375 size_t
1376 number_modules;
1377
1378 /*
1379 Load all modules.
1380 */
1381 (void) GetMagickInfo((char *) NULL,exception);
1382 number_modules=0;
1383 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1384 if ((modules == (char **) NULL) || (*modules == (char *) NULL))
1385 {
1386 if (modules != (char **) NULL)
1387 modules=(char **) RelinquishMagickMemory(modules);
1388 return(MagickFalse);
1389 }
1390 for (i=0; i < (ssize_t) number_modules; i++)
1391 (void) OpenModule(modules[i],exception);
1392 /*
1393 Relinquish resources.
1394 */
1395 for (i=0; i < (ssize_t) number_modules; i++)
1396 modules[i]=DestroyString(modules[i]);
1397 modules=(char **) RelinquishMagickMemory(modules);
1398 return(MagickTrue);
1399}
1400
1401/*
1402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403% %
1404% %
1405% %
1406% R e g i s t e r M o d u l e %
1407% %
1408% %
1409% %
1410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411%
1412% RegisterModule() adds an entry to the module list. It returns a pointer to
1413% the registered entry on success.
1414%
1415% The format of the RegisterModule module is:
1416%
1417% ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1418% ExceptionInfo *exception)
1419%
1420% A description of each parameter follows:
1421%
1422% o info: a pointer to the registered entry is returned.
1423%
1424% o module_info: a pointer to the ModuleInfo structure to register.
1425%
1426% o exception: return any errors or warnings in this structure.
1427%
1428*/
1429static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1430 ExceptionInfo *exception)
1431{
1432 MagickBooleanType
1433 status;
1434
1435 assert(module_info != (ModuleInfo *) NULL);
1436 assert(module_info->signature == MagickCoreSignature);
1437 if (IsEventLogging() != MagickFalse)
1438 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1439 if (module_list == (SplayTreeInfo *) NULL)
1440 return((const ModuleInfo *) NULL);
1441 status=AddValueToSplayTree(module_list,module_info->tag,module_info);
1442 if (status == MagickFalse)
1443 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
1444 "MemoryAllocationFailed","`%s'",module_info->tag);
1445 return(module_info);
1446}
1447
1448/*
1449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1450% %
1451% %
1452% %
1453% T a g T o C o d e r M o d u l e N a m e %
1454% %
1455% %
1456% %
1457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1458%
1459% TagToCoderModuleName() munges a module tag and obtains the filename of the
1460% corresponding module.
1461%
1462% The format of the TagToCoderModuleName module is:
1463%
1464% char *TagToCoderModuleName(const char *tag,char *name)
1465%
1466% A description of each parameter follows:
1467%
1468% o tag: a character string representing the module tag.
1469%
1470% o name: return the module name here.
1471%
1472*/
1473static void TagToCoderModuleName(const char *tag,char *name)
1474{
1475 assert(tag != (char *) NULL);
1476 assert(name != (char *) NULL);
1477 if (IsEventLogging() != MagickFalse)
1478 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1479#if defined(MAGICKCORE_LTDL_DELEGATE)
1480 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1481 (void) LocaleLower(name);
1482#else
1483#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1484 if (LocaleNCompare("IM_MOD_",tag,7) == 0)
1485 (void) CopyMagickString(name,tag,MagickPathExtent);
1486 else
1487 {
1488#if defined(_DEBUG)
1489 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag);
1490#else
1491 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag);
1492#endif
1493 }
1494#endif
1495#endif
1496}
1497
1498/*
1499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500% %
1501% %
1502% %
1503% T a g T o F i l t e r M o d u l e N a m e %
1504% %
1505% %
1506% %
1507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1508%
1509% TagToFilterModuleName() munges a module tag and returns the filename of the
1510% corresponding filter module.
1511%
1512% The format of the TagToFilterModuleName module is:
1513%
1514% void TagToFilterModuleName(const char *tag,char name)
1515%
1516% A description of each parameter follows:
1517%
1518% o tag: a character string representing the module tag.
1519%
1520% o name: return the filter name here.
1521%
1522*/
1523static void TagToFilterModuleName(const char *tag,char *name)
1524{
1525 assert(tag != (char *) NULL);
1526 assert(name != (char *) NULL);
1527 if (IsEventLogging() != MagickFalse)
1528 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1529#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1530#if defined(_DEBUG)
1531 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_DB_%s_.dll",tag);
1532#else
1533 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_RL_%s_.dll",tag);
1534#endif
1535#elif !defined(MAGICKCORE_LTDL_DELEGATE)
1536 (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag);
1537#else
1538 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1539#endif
1540}
1541
1542/*
1543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1544% %
1545% %
1546% %
1547% T a g T o M o d u l e N a m e %
1548% %
1549% %
1550% %
1551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1552%
1553% TagToModuleName() munges the module tag name and returns an upper-case tag
1554% name as the input string, and a user-provided format.
1555%
1556% The format of the TagToModuleName module is:
1557%
1558% void TagToModuleName(const char *tag,const char *format,char *module)
1559%
1560% A description of each parameter follows:
1561%
1562% o tag: the module tag.
1563%
1564% o format: a sprintf-compatible format string containing %s where the
1565% upper-case tag name is to be inserted.
1566%
1567% o module: pointer to a destination buffer for the formatted result.
1568%
1569*/
1570static void TagToModuleName(const char *tag,const char *format,char *module)
1571{
1572 char
1573 name[MagickPathExtent];
1574
1575 assert(tag != (const char *) NULL);
1576 assert(format != (const char *) NULL);
1577 assert(module != (char *) NULL);
1578 if (IsEventLogging() != MagickFalse)
1579 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1580 (void) CopyMagickString(name,tag,MagickPathExtent);
1581 LocaleUpper(name);
1582#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1583 (void) FormatLocaleString(module,MagickPathExtent,format,name);
1584#else
1585 {
1586 char
1587 prefix_format[MagickPathExtent];
1588
1589 (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s",
1590 MAGICKCORE_NAMESPACE_PREFIX_TAG,format);
1591 (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name);
1592 }
1593#endif
1594}
1595
1596/*
1597%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1598% %
1599% %
1600% %
1601% U n r e g i s t e r M o d u l e %
1602% %
1603% %
1604% %
1605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1606%
1607% UnregisterModule() unloads a module, and invokes its de-registration module.
1608% Returns MagickTrue on success, and MagickFalse if there is an error.
1609%
1610% The format of the UnregisterModule module is:
1611%
1612% MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1613% ExceptionInfo *exception)
1614%
1615% A description of each parameter follows:
1616%
1617% o module_info: the module info.
1618%
1619% o exception: return any errors or warnings in this structure.
1620%
1621*/
1622static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1623 ExceptionInfo *exception)
1624{
1625 /*
1626 Locate and execute UnregisterFORMATImage module.
1627 */
1628 assert(module_info != (const ModuleInfo *) NULL);
1629 assert(exception != (ExceptionInfo *) NULL);
1630 if (IsEventLogging() != MagickFalse)
1631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1632 if (module_info->unregister_module == NULL)
1633 return(MagickTrue);
1634 module_info->unregister_module();
1635 if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
1636 {
1637 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1638 "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror());
1639 return(MagickFalse);
1640 }
1641 return(MagickTrue);
1642}
1643#else
1644
1645#if !defined(MAGICKCORE_BUILD_MODULES)
1646extern size_t
1647 analyzeImage(Image **,const int,const char **,ExceptionInfo *);
1648#endif
1649
1650MagickExport MagickBooleanType ListModuleInfo(FILE *magick_unused(file),
1651 ExceptionInfo *magick_unused(exception))
1652{
1653 magick_unreferenced(file);
1654 magick_unreferenced(exception);
1655 return(MagickTrue);
1656}
1657
1658MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
1659 Image **image,const int argc,const char **argv,ExceptionInfo *exception)
1660{
1661 PolicyRights
1662 rights;
1663
1664 assert(image != (Image **) NULL);
1665 assert((*image)->signature == MagickCoreSignature);
1666 if (IsEventLogging() != MagickFalse)
1667 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1668 rights=ReadPolicyRights;
1669 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
1670 ThrowPolicyException(tag,MagickFalse);
1671#if defined(MAGICKCORE_BUILD_MODULES)
1672 (void) tag;
1673 (void) argc;
1674 (void) argv;
1675 (void) exception;
1676#else
1677 {
1678 ImageFilterHandler
1679 *image_filter;
1680
1681 image_filter=(ImageFilterHandler *) NULL;
1682 if (LocaleCompare("analyze",tag) == 0)
1683 image_filter=(ImageFilterHandler *) analyzeImage;
1684 if (image_filter == (ImageFilterHandler *) NULL)
1685 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1686 "UnableToLoadModule","`%s'",tag);
1687 else
1688 {
1689 size_t
1690 signature;
1691
1692 if ((*image)->debug != MagickFalse)
1693 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1694 "Invoking \"%s\" static image filter",tag);
1695 signature=image_filter(image,argc,argv,exception);
1696 if ((*image)->debug != MagickFalse)
1697 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1698 "\"%s\" completes",tag);
1699 if (signature != MagickImageFilterSignature)
1700 {
1701 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1702 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1703 (unsigned long) signature,(unsigned long)
1704 MagickImageFilterSignature);
1705 return(MagickFalse);
1706 }
1707 }
1708 }
1709#endif
1710 return(MagickTrue);
1711}
1712#endif
Definition vms.h:942