MagickCore 7.1.2
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/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/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_CODER_FILTER_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#if defined(MAGICKCORE_HAVE_REALPATH)
599 {
600 char
601 resolved_path[PATH_MAX+1];
602
603 if (realpath(path,resolved_path) != (char *) NULL)
604 (void) CopyMagickString(path,resolved_path,MagickPathExtent);
605 }
606#endif
607 if (IsPathAccessible(path) != MagickFalse)
608 {
609 module_path=DestroyString(module_path);
610 return(MagickTrue);
611 }
612 p=strchr(p+1,DirectoryListSeparator);
613 }
614 module_path=DestroyString(module_path);
615 }
616#if defined(MAGICKCORE_INSTALLED_SUPPORT)
617 else
618#if defined(MAGICKCORE_CODER_PATH)
619 {
620 const char
621 *directory;
622
623 /*
624 Search hard coded paths.
625 */
626 switch (module_type)
627 {
628 case MagickImageCoderModule:
629 default:
630 {
631 directory=MAGICKCORE_CODER_PATH;
632 break;
633 }
634 case MagickImageFilterModule:
635 {
636 directory=MAGICKCORE_FILTER_PATH;
637 break;
638 }
639 }
640 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",directory,
641 filename);
642 if (IsPathAccessible(path) == MagickFalse)
643 {
644 ThrowFileException(exception,ConfigureWarning,
645 "UnableToOpenModuleFile",path);
646 return(MagickFalse);
647 }
648 return(MagickTrue);
649 }
650#else
651#if defined(MAGICKCORE_WINDOWS_SUPPORT)
652 {
653 const char
654 *registry_key;
655
656 unsigned char
657 *key_value;
658
659 /*
660 Locate path via registry key.
661 */
662 switch (module_type)
663 {
664 case MagickImageCoderModule:
665 default:
666 {
667 registry_key="CoderModulesPath";
668 break;
669 }
670 case MagickImageFilterModule:
671 {
672 registry_key="FilterModulesPath";
673 break;
674 }
675 }
676 key_value=NTRegistryKeyLookup(registry_key);
677 if (key_value == (unsigned char *) NULL)
678 {
679 ThrowMagickException(exception,GetMagickModule(),ConfigureError,
680 "RegistryKeyLookupFailed","`%s'",registry_key);
681 return(MagickFalse);
682 }
683 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",(char *)
684 key_value,DirectorySeparator,filename);
685 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
686 if (IsPathAccessible(path) == MagickFalse)
687 {
688 ThrowFileException(exception,ConfigureWarning,
689 "UnableToOpenModuleFile",path);
690 return(MagickFalse);
691 }
692 return(MagickTrue);
693 }
694#endif
695#endif
696#if !defined(MAGICKCORE_CODER_PATH) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
697# error MAGICKCORE_CODER_PATH or MAGICKCORE_WINDOWS_SUPPORT must be defined when MAGICKCORE_INSTALLED_SUPPORT is defined
698#endif
699#else
700 {
701 char
702 *home;
703
704 home=GetEnvironmentValue("MAGICK_HOME");
705 if (home != (char *) NULL)
706 {
707 /*
708 Search MAGICK_HOME.
709 */
710#if !defined(MAGICKCORE_POSIX_SUPPORT)
711 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",home,
712 DirectorySeparator,filename);
713#else
714 const char
715 *directory;
716
717 switch (module_type)
718 {
719 case MagickImageCoderModule:
720 default:
721 {
722 directory=MAGICKCORE_CODER_RELATIVE_PATH;
723 break;
724 }
725 case MagickImageFilterModule:
726 {
727 directory=MAGICKCORE_FILTER_RELATIVE_PATH;
728 break;
729 }
730 }
731 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s",home,
732 directory,filename);
733#endif
734 home=DestroyString(home);
735 if (IsPathAccessible(path) != MagickFalse)
736 return(MagickTrue);
737 }
738 }
739 if (*GetClientPath() != '\0')
740 {
741 /*
742 Search based on executable directory.
743 */
744#if !defined(MAGICKCORE_POSIX_SUPPORT)
745 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",GetClientPath(),
746 DirectorySeparator,filename);
747#else
748 char
749 prefix[MagickPathExtent];
750
751 const char
752 *directory;
753
754 switch (module_type)
755 {
756 case MagickImageCoderModule:
757 default:
758 {
759 directory="coders";
760 break;
761 }
762 case MagickImageFilterModule:
763 {
764 directory="filters";
765 break;
766 }
767 }
768 (void) CopyMagickString(prefix,GetClientPath(),MagickPathExtent);
769 ChopPathComponents(prefix,1);
770 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s/%s",prefix,
771 MAGICKCORE_MODULES_RELATIVE_PATH,directory,filename);
772#endif
773 if (IsPathAccessible(path) != MagickFalse)
774 return(MagickTrue);
775 }
776#if defined(MAGICKCORE_WINDOWS_SUPPORT)
777 {
778 /*
779 Search module path.
780 */
781 if ((NTGetModulePath("CORE_RL_MagickCore_.dll",path) != MagickFalse) ||
782 (NTGetModulePath("CORE_DB_MagickCore_.dll",path) != MagickFalse))
783 {
784 (void) ConcatenateMagickString(path,DirectorySeparator,
785 MagickPathExtent);
786 (void) ConcatenateMagickString(path,filename,MagickPathExtent);
787 if (IsPathAccessible(path) != MagickFalse)
788 return(MagickTrue);
789 }
790 }
791#endif
792 {
793 char
794 *home;
795
796 home=GetEnvironmentValue("XDG_CONFIG_HOME");
797 if (home == (char *) NULL)
798#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
799 home=GetEnvironmentValue("LOCALAPPDATA");
800 if (home == (char *) NULL)
801 home=GetEnvironmentValue("APPDATA");
802 if (home == (char *) NULL)
803 home=GetEnvironmentValue("USERPROFILE");
804#endif
805 if (home != (char *) NULL)
806 {
807 /*
808 Search $XDG_CONFIG_HOME/ImageMagick.
809 */
810 (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s%s",
811 home,DirectorySeparator,DirectorySeparator,filename);
812 home=DestroyString(home);
813 if (IsPathAccessible(path) != MagickFalse)
814 return(MagickTrue);
815 }
816 home=GetEnvironmentValue("HOME");
817 if (home != (char *) NULL)
818 {
819 /*
820 Search $HOME/.config/ImageMagick.
821 */
822 (void) FormatLocaleString(path,MagickPathExtent,
823 "%s%s.config%sImageMagick%s%s",home,DirectorySeparator,
824 DirectorySeparator,DirectorySeparator,filename);
825 home=DestroyString(home);
826 if (IsPathAccessible(path) != MagickFalse)
827 return(MagickTrue);
828 }
829 }
830 /*
831 Search current directory.
832 */
833 if (IsPathAccessible(path) != MagickFalse)
834 return(MagickTrue);
835 if (exception->severity < ConfigureError)
836 ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
837 path);
838#endif
839 return(MagickFalse);
840}
841
842/*
843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844% %
845% %
846% %
847% I s M o d u l e T r e e I n s t a n t i a t e d %
848% %
849% %
850% %
851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852%
853% IsModuleTreeInstantiated() determines if the module tree is instantiated.
854% If not, it instantiates the tree and returns it.
855%
856% The format of the IsModuleTreeInstantiated() method is:
857%
858% IsModuleTreeInstantiated()
859%
860*/
861
862static void *DestroyModuleNode(void *module_info)
863{
864 ExceptionInfo
865 *exception;
866
867 ModuleInfo
868 *p;
869
870 exception=AcquireExceptionInfo();
871 p=(ModuleInfo *) module_info;
872 if (UnregisterModule(p,exception) == MagickFalse)
873 CatchException(exception);
874 if (p->tag != (char *) NULL)
875 p->tag=DestroyString(p->tag);
876 if (p->path != (char *) NULL)
877 p->path=DestroyString(p->path);
878 exception=DestroyExceptionInfo(exception);
879 return(RelinquishMagickMemory(p));
880}
881
882static MagickBooleanType IsModuleTreeInstantiated(void)
883{
884 if (module_list == (SplayTreeInfo *) NULL)
885 {
886 if (module_semaphore == (SemaphoreInfo *) NULL)
887 ActivateSemaphoreInfo(&module_semaphore);
888 LockSemaphoreInfo(module_semaphore);
889 if (module_list == (SplayTreeInfo *) NULL)
890 {
891 MagickBooleanType
892 status;
893
894 ModuleInfo
895 *module_info;
896
897 SplayTreeInfo
898 *splay_tree;
899
900 splay_tree=NewSplayTree(CompareSplayTreeString,
901 (void *(*)(void *)) NULL,DestroyModuleNode);
902 module_info=AcquireModuleInfo((const char *) NULL,"[boot-strap]");
903 module_info->stealth=MagickTrue;
904 status=AddValueToSplayTree(splay_tree,module_info->tag,module_info);
905 if (status == MagickFalse)
906 ThrowFatalException(ResourceLimitFatalError,
907 "MemoryAllocationFailed");
908#if defined(MAGICKCORE_LTDL_DELEGATE)
909 if (lt_dlinit() != 0)
910 ThrowFatalException(ModuleFatalError,
911 "UnableToInitializeModuleLoader");
912#endif
913 module_list=splay_tree;
914 }
915 UnlockSemaphoreInfo(module_semaphore);
916 }
917 return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
918}
919
920/*
921%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
922% %
923% %
924% %
925% I n v o k e D y n a m i c I m a g e F i l t e r %
926% %
927% %
928% %
929%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
930%
931% InvokeDynamicImageFilter() invokes a dynamic image filter.
932%
933% The format of the InvokeDynamicImageFilter module is:
934%
935% MagickBooleanType InvokeDynamicImageFilter(const char *tag,Image **image,
936% const int argc,const char **argv,ExceptionInfo *exception)
937%
938% A description of each parameter follows:
939%
940% o tag: a character string that represents the name of the particular
941% module.
942%
943% o image: the image.
944%
945% o argc: a pointer to an integer describing the number of elements in the
946% argument vector.
947%
948% o argv: a pointer to a text array containing the command line arguments.
949%
950% o exception: return any errors or warnings in this structure.
951%
952*/
953MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
954 Image **images,const int argc,const char **argv,ExceptionInfo *exception)
955{
956 char
957 name[MagickPathExtent],
958 path[MagickPathExtent];
959
960 ImageFilterHandler
961 *image_filter;
962
963 MagickBooleanType
964 status;
965
966 ModuleHandle
967 handle;
968
969 PolicyRights
970 rights;
971
972 /*
973 Find the module.
974 */
975 assert(images != (Image **) NULL);
976 assert((*images)->signature == MagickCoreSignature);
977 if (IsEventLogging() != MagickFalse)
978 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
979 (*images)->filename);
980 rights=ReadPolicyRights;
981 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
982 {
983 errno=EPERM;
984 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
985 "NotAuthorized","`%s'",tag);
986 return(MagickFalse);
987 }
988#if !defined(MAGICKCORE_BUILD_MODULES)
989 {
990 MagickBooleanType
991 status;
992
993 status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
994 if (status != MagickFalse)
995 return(status);
996 }
997#endif
998 TagToFilterModuleName(tag,name);
999 status=GetMagickModulePath(name,MagickImageFilterModule,path,exception);
1000 if (status == MagickFalse)
1001 {
1002 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1003 "UnableToLoadModule","'%s': %s",name,path);
1004 return(MagickFalse);
1005 }
1006 /*
1007 Open the module.
1008 */
1009 handle=(ModuleHandle) lt_dlopen(path);
1010 if (handle == (ModuleHandle) NULL)
1011 {
1012 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1013 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1014 return(MagickFalse);
1015 }
1016 /*
1017 Locate the module.
1018 */
1019#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1020 (void) FormatLocaleString(name,MagickPathExtent,"%sImage",tag);
1021#else
1022 (void) FormatLocaleString(name,MagickPathExtent,"%s%sImage",
1023 MAGICKCORE_NAMESPACE_PREFIX_TAG,tag);
1024#endif
1025 /*
1026 Execute the module.
1027 */
1028 ClearMagickException(exception);
1029 image_filter=(ImageFilterHandler *) lt_dlsym(handle,name);
1030 if (image_filter == (ImageFilterHandler *) NULL)
1031 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1032 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1033 else
1034 {
1035 size_t
1036 signature;
1037
1038 if (IsEventLogging() != MagickFalse)
1039 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1040 "Invoking \"%s\" dynamic image filter",tag);
1041 signature=image_filter(images,argc,argv,exception);
1042 if (IsEventLogging() != MagickFalse)
1043 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
1044 tag);
1045 if (signature != MagickImageFilterSignature)
1046 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1047 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1048 (unsigned long) signature,(unsigned long) MagickImageFilterSignature);
1049 }
1050 /*
1051 Close the module.
1052 */
1053 if (lt_dlclose(handle) != 0)
1054 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1055 "UnableToCloseModule","'%s': %s",name,lt_dlerror());
1056 return(exception->severity < ErrorException ? MagickTrue : MagickFalse);
1057}
1058
1059/*
1060%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1061% %
1062% %
1063% %
1064% L i s t M o d u l e I n f o %
1065% %
1066% %
1067% %
1068%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069%
1070% ListModuleInfo() lists the module info to a file.
1071%
1072% The format of the ListModuleInfo module is:
1073%
1074% MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
1075%
1076% A description of each parameter follows.
1077%
1078% o file: An pointer to a FILE.
1079%
1080% o exception: return any errors or warnings in this structure.
1081%
1082*/
1083MagickExport MagickBooleanType ListModuleInfo(FILE *file,
1084 ExceptionInfo *exception)
1085{
1086 char
1087 filename[MagickPathExtent],
1088 module_path[MagickPathExtent],
1089 **modules,
1090 path[MagickPathExtent];
1091
1092 ssize_t
1093 i;
1094
1095 size_t
1096 number_modules;
1097
1098 if (file == (const FILE *) NULL)
1099 file=stdout;
1100 /*
1101 List image coders.
1102 */
1103 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1104 if (modules == (char **) NULL)
1105 return(MagickFalse);
1106 TagToCoderModuleName("magick",filename);
1107 (void) GetMagickModulePath(filename,MagickImageCoderModule,module_path,
1108 exception);
1109 GetPathComponent(module_path,HeadPath,path);
1110 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1111 (void) FormatLocaleFile(file,"Image Coder\n");
1112 (void) FormatLocaleFile(file,
1113 "-------------------------------------------------"
1114 "------------------------------\n");
1115 for (i=0; i < (ssize_t) number_modules; i++)
1116 {
1117 (void) FormatLocaleFile(file,"%s",modules[i]);
1118 (void) FormatLocaleFile(file,"\n");
1119 }
1120 (void) fflush(file);
1121 /*
1122 Relinquish resources.
1123 */
1124 for (i=0; i < (ssize_t) number_modules; i++)
1125 modules[i]=DestroyString(modules[i]);
1126 modules=(char **) RelinquishMagickMemory(modules);
1127 /*
1128 List image filters.
1129 */
1130 modules=GetModuleList("*",MagickImageFilterModule,&number_modules,exception);
1131 if (modules == (char **) NULL)
1132 return(MagickFalse);
1133 TagToFilterModuleName("analyze",filename);
1134 (void) GetMagickModulePath(filename,MagickImageFilterModule,module_path,
1135 exception);
1136 GetPathComponent(module_path,HeadPath,path);
1137 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1138 (void) FormatLocaleFile(file,"Image Filter\n");
1139 (void) FormatLocaleFile(file,
1140 "-------------------------------------------------"
1141 "------------------------------\n");
1142 for (i=0; i < (ssize_t) number_modules; i++)
1143 {
1144 (void) FormatLocaleFile(file,"%s",modules[i]);
1145 (void) FormatLocaleFile(file,"\n");
1146 }
1147 (void) fflush(file);
1148 /*
1149 Relinquish resources.
1150 */
1151 for (i=0; i < (ssize_t) number_modules; i++)
1152 modules[i]=DestroyString(modules[i]);
1153 modules=(char **) RelinquishMagickMemory(modules);
1154 return(MagickTrue);
1155}
1156
1157/*
1158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159% %
1160% %
1161% %
1162+ M o d u l e C o m p o n e n t G e n e s i s %
1163% %
1164% %
1165% %
1166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1167%
1168% ModuleComponentGenesis() instantiates the module component.
1169%
1170% The format of the ModuleComponentGenesis method is:
1171%
1172% MagickBooleanType ModuleComponentGenesis(void)
1173%
1174*/
1175MagickPrivate MagickBooleanType ModuleComponentGenesis(void)
1176{
1177 MagickBooleanType
1178 status;
1179
1180 if (module_semaphore == (SemaphoreInfo *) NULL)
1181 module_semaphore=AcquireSemaphoreInfo();
1182 status=IsModuleTreeInstantiated();
1183 return(status);
1184}
1185
1186/*
1187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1188% %
1189% %
1190% %
1191+ M o d u l e C o m p o n e n t T e r m i n u s %
1192% %
1193% %
1194% %
1195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1196%
1197% ModuleComponentTerminus() destroys the module component.
1198%
1199% The format of the ModuleComponentTerminus method is:
1200%
1201% ModuleComponentTerminus(void)
1202%
1203*/
1204MagickPrivate void ModuleComponentTerminus(void)
1205{
1206 if (module_semaphore == (SemaphoreInfo *) NULL)
1207 ActivateSemaphoreInfo(&module_semaphore);
1208 DestroyModuleList();
1209 RelinquishSemaphoreInfo(&module_semaphore);
1210}
1211
1212/*
1213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214% %
1215% %
1216% %
1217% O p e n M o d u l e %
1218% %
1219% %
1220% %
1221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222%
1223% OpenModule() loads a module, and invokes its registration module. It
1224% returns MagickTrue on success, and MagickFalse if there is an error.
1225%
1226% The format of the OpenModule module is:
1227%
1228% MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
1229%
1230% A description of each parameter follows:
1231%
1232% o module: a character string that indicates the module to load.
1233%
1234% o exception: return any errors or warnings in this structure.
1235%
1236*/
1237MagickPrivate MagickBooleanType OpenModule(const char *module,
1238 ExceptionInfo *exception)
1239{
1240 char
1241 module_name[MagickPathExtent],
1242 name[MagickPathExtent],
1243 path[MagickPathExtent];
1244
1245 MagickBooleanType
1246 status;
1247
1248 ModuleHandle
1249 handle;
1250
1251 ModuleInfo
1252 *module_info;
1253
1254 PolicyRights
1255 rights;
1256
1257 const CoderInfo
1258 *p;
1259
1260 size_t
1261 signature;
1262
1263 /*
1264 Assign module name from alias.
1265 */
1266 assert(module != (const char *) NULL);
1267 module_info=(ModuleInfo *) GetModuleInfo(module,exception);
1268 if (module_info != (ModuleInfo *) NULL)
1269 return(MagickTrue);
1270 (void) CopyMagickString(module_name,module,MagickPathExtent);
1271 p=GetCoderInfo(module,exception);
1272 if (p != (CoderInfo *) NULL)
1273 (void) CopyMagickString(module_name,p->name,MagickPathExtent);
1274 LocaleUpper(module_name);
1275 rights=(PolicyRights) (ReadPolicyRights | WritePolicyRights);
1276 if (IsRightsAuthorized(ModulePolicyDomain,rights,module_name) == MagickFalse)
1277 {
1278 errno=EPERM;
1279 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
1280 "NotAuthorized","`%s'",module);
1281 return(MagickFalse);
1282 }
1283 if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
1284 return(MagickTrue); /* module already opened, return */
1285 /*
1286 Locate module.
1287 */
1288 handle=(ModuleHandle) NULL;
1289 TagToCoderModuleName(module_name,name);
1290 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1291 "Searching for module \"%s\" using filename \"%s\"",module_name,name);
1292 *path='\0';
1293 status=GetMagickModulePath(name,MagickImageCoderModule,path,exception);
1294 if (status == MagickFalse)
1295 return(MagickFalse);
1296 /*
1297 Load module
1298 */
1299 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1300 "Opening module at path \"%s\"",path);
1301 handle=(ModuleHandle) lt_dlopen(path);
1302 if (handle == (ModuleHandle) NULL)
1303 {
1304 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1305 "UnableToLoadModule","'%s': %s",path,lt_dlerror());
1306 return(MagickFalse);
1307 }
1308 /*
1309 Register module.
1310 */
1311 module_info=AcquireModuleInfo(path,module_name);
1312 module_info->handle=handle;
1313 if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
1314 return(MagickFalse);
1315 /*
1316 Define RegisterFORMATImage method.
1317 */
1318 TagToModuleName(module_name,"Register%sImage",name);
1319 module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name);
1320 if (module_info->register_module == (size_t (*)(void)) NULL)
1321 {
1322 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1323 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1324 return(MagickFalse);
1325 }
1326 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1327 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1328 (void *) module_info->register_module);
1329 /*
1330 Define UnregisterFORMATImage method.
1331 */
1332 TagToModuleName(module_name,"Unregister%sImage",name);
1333 module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
1334 if (module_info->unregister_module == (void (*)(void)) NULL)
1335 {
1336 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1337 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1338 return(MagickFalse);
1339 }
1340 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1341 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1342 (void *) module_info->unregister_module);
1343 signature=module_info->register_module();
1344 if (signature != MagickImageCoderSignature)
1345 {
1346 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1347 "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name,
1348 (unsigned long) signature,(unsigned long) MagickImageCoderSignature);
1349 return(MagickFalse);
1350 }
1351 return(MagickTrue);
1352}
1353
1354/*
1355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356% %
1357% %
1358% %
1359% O p e n M o d u l e s %
1360% %
1361% %
1362% %
1363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364%
1365% OpenModules() loads all available modules.
1366%
1367% The format of the OpenModules module is:
1368%
1369% MagickBooleanType OpenModules(ExceptionInfo *exception)
1370%
1371% A description of each parameter follows:
1372%
1373% o exception: return any errors or warnings in this structure.
1374%
1375*/
1376MagickPrivate MagickBooleanType OpenModules(ExceptionInfo *exception)
1377{
1378 char
1379 **modules;
1380
1381 ssize_t
1382 i;
1383
1384 size_t
1385 number_modules;
1386
1387 /*
1388 Load all modules.
1389 */
1390 (void) GetMagickInfo((char *) NULL,exception);
1391 number_modules=0;
1392 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1393 if ((modules == (char **) NULL) || (*modules == (char *) NULL))
1394 {
1395 if (modules != (char **) NULL)
1396 modules=(char **) RelinquishMagickMemory(modules);
1397 return(MagickFalse);
1398 }
1399 for (i=0; i < (ssize_t) number_modules; i++)
1400 (void) OpenModule(modules[i],exception);
1401 /*
1402 Relinquish resources.
1403 */
1404 for (i=0; i < (ssize_t) number_modules; i++)
1405 modules[i]=DestroyString(modules[i]);
1406 modules=(char **) RelinquishMagickMemory(modules);
1407 return(MagickTrue);
1408}
1409
1410/*
1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412% %
1413% %
1414% %
1415% R e g i s t e r M o d u l e %
1416% %
1417% %
1418% %
1419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420%
1421% RegisterModule() adds an entry to the module list. It returns a pointer to
1422% the registered entry on success.
1423%
1424% The format of the RegisterModule module is:
1425%
1426% ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1427% ExceptionInfo *exception)
1428%
1429% A description of each parameter follows:
1430%
1431% o info: a pointer to the registered entry is returned.
1432%
1433% o module_info: a pointer to the ModuleInfo structure to register.
1434%
1435% o exception: return any errors or warnings in this structure.
1436%
1437*/
1438static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1439 ExceptionInfo *exception)
1440{
1441 MagickBooleanType
1442 status;
1443
1444 assert(module_info != (ModuleInfo *) NULL);
1445 assert(module_info->signature == MagickCoreSignature);
1446 if (IsEventLogging() != MagickFalse)
1447 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1448 if (module_list == (SplayTreeInfo *) NULL)
1449 return((const ModuleInfo *) NULL);
1450 status=AddValueToSplayTree(module_list,module_info->tag,module_info);
1451 if (status == MagickFalse)
1452 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
1453 "MemoryAllocationFailed","`%s'",module_info->tag);
1454 return(module_info);
1455}
1456
1457/*
1458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1459% %
1460% %
1461% %
1462% T a g T o C o d e r M o d u l e N a m e %
1463% %
1464% %
1465% %
1466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1467%
1468% TagToCoderModuleName() munges a module tag and obtains the filename of the
1469% corresponding module.
1470%
1471% The format of the TagToCoderModuleName module is:
1472%
1473% char *TagToCoderModuleName(const char *tag,char *name)
1474%
1475% A description of each parameter follows:
1476%
1477% o tag: a character string representing the module tag.
1478%
1479% o name: return the module name here.
1480%
1481*/
1482static void TagToCoderModuleName(const char *tag,char *name)
1483{
1484 assert(tag != (char *) NULL);
1485 assert(name != (char *) NULL);
1486 if (IsEventLogging() != MagickFalse)
1487 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1488#if defined(MAGICKCORE_LTDL_DELEGATE)
1489 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1490 (void) LocaleLower(name);
1491#else
1492#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1493 if (LocaleNCompare("IM_MOD_",tag,7) == 0)
1494 (void) CopyMagickString(name,tag,MagickPathExtent);
1495 else
1496 {
1497#if defined(_DEBUG)
1498 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag);
1499#else
1500 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag);
1501#endif
1502 }
1503#endif
1504#endif
1505}
1506
1507/*
1508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1509% %
1510% %
1511% %
1512% T a g T o F i l t e r M o d u l e N a m e %
1513% %
1514% %
1515% %
1516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1517%
1518% TagToFilterModuleName() munges a module tag and returns the filename of the
1519% corresponding filter module.
1520%
1521% The format of the TagToFilterModuleName module is:
1522%
1523% void TagToFilterModuleName(const char *tag,char name)
1524%
1525% A description of each parameter follows:
1526%
1527% o tag: a character string representing the module tag.
1528%
1529% o name: return the filter name here.
1530%
1531*/
1532static void TagToFilterModuleName(const char *tag,char *name)
1533{
1534 assert(tag != (char *) NULL);
1535 assert(name != (char *) NULL);
1536 if (IsEventLogging() != MagickFalse)
1537 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1538#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1539#if defined(_DEBUG)
1540 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_DB_%s_.dll",tag);
1541#else
1542 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_RL_%s_.dll",tag);
1543#endif
1544#elif !defined(MAGICKCORE_LTDL_DELEGATE)
1545 (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag);
1546#else
1547 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1548#endif
1549}
1550
1551/*
1552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1553% %
1554% %
1555% %
1556% T a g T o M o d u l e N a m e %
1557% %
1558% %
1559% %
1560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1561%
1562% TagToModuleName() munges the module tag name and returns an upper-case tag
1563% name as the input string, and a user-provided format.
1564%
1565% The format of the TagToModuleName module is:
1566%
1567% TagToModuleName(const char *tag,const char *format,char *module)
1568%
1569% A description of each parameter follows:
1570%
1571% o tag: the module tag.
1572%
1573% o format: a sprintf-compatible format string containing %s where the
1574% upper-case tag name is to be inserted.
1575%
1576% o module: pointer to a destination buffer for the formatted result.
1577%
1578*/
1579static void TagToModuleName(const char *tag,const char *format,char *module)
1580{
1581 char
1582 name[MagickPathExtent];
1583
1584 assert(tag != (const char *) NULL);
1585 assert(format != (const char *) NULL);
1586 assert(module != (char *) NULL);
1587 if (IsEventLogging() != MagickFalse)
1588 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1589 (void) CopyMagickString(name,tag,MagickPathExtent);
1590 LocaleUpper(name);
1591#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1592 (void) FormatLocaleString(module,MagickPathExtent,format,name);
1593#else
1594 {
1595 char
1596 prefix_format[MagickPathExtent];
1597
1598 (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s",
1599 MAGICKCORE_NAMESPACE_PREFIX_TAG,format);
1600 (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name);
1601 }
1602#endif
1603}
1604
1605/*
1606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1607% %
1608% %
1609% %
1610% U n r e g i s t e r M o d u l e %
1611% %
1612% %
1613% %
1614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1615%
1616% UnregisterModule() unloads a module, and invokes its de-registration module.
1617% Returns MagickTrue on success, and MagickFalse if there is an error.
1618%
1619% The format of the UnregisterModule module is:
1620%
1621% MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1622% ExceptionInfo *exception)
1623%
1624% A description of each parameter follows:
1625%
1626% o module_info: the module info.
1627%
1628% o exception: return any errors or warnings in this structure.
1629%
1630*/
1631static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1632 ExceptionInfo *exception)
1633{
1634 /*
1635 Locate and execute UnregisterFORMATImage module.
1636 */
1637 assert(module_info != (const ModuleInfo *) NULL);
1638 assert(exception != (ExceptionInfo *) NULL);
1639 if (IsEventLogging() != MagickFalse)
1640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1641 if (module_info->unregister_module == NULL)
1642 return(MagickTrue);
1643 module_info->unregister_module();
1644 if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
1645 {
1646 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1647 "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror());
1648 return(MagickFalse);
1649 }
1650 return(MagickTrue);
1651}
1652#else
1653
1654#if !defined(MAGICKCORE_BUILD_MODULES)
1655extern size_t
1656 analyzeImage(Image **,const int,const char **,ExceptionInfo *);
1657#endif
1658
1659MagickExport MagickBooleanType ListModuleInfo(FILE *magick_unused(file),
1660 ExceptionInfo *magick_unused(exception))
1661{
1662 magick_unreferenced(file);
1663 magick_unreferenced(exception);
1664 return(MagickTrue);
1665}
1666
1667MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
1668 Image **image,const int argc,const char **argv,ExceptionInfo *exception)
1669{
1670 PolicyRights
1671 rights;
1672
1673 assert(image != (Image **) NULL);
1674 assert((*image)->signature == MagickCoreSignature);
1675 if (IsEventLogging() != MagickFalse)
1676 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1677 rights=ReadPolicyRights;
1678 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
1679 {
1680 errno=EPERM;
1681 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
1682 "NotAuthorized","`%s'",tag);
1683 return(MagickFalse);
1684 }
1685#if defined(MAGICKCORE_BUILD_MODULES)
1686 (void) tag;
1687 (void) argc;
1688 (void) argv;
1689 (void) exception;
1690#else
1691 {
1692 ImageFilterHandler
1693 *image_filter;
1694
1695 image_filter=(ImageFilterHandler *) NULL;
1696 if (LocaleCompare("analyze",tag) == 0)
1697 image_filter=(ImageFilterHandler *) analyzeImage;
1698 if (image_filter == (ImageFilterHandler *) NULL)
1699 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1700 "UnableToLoadModule","`%s'",tag);
1701 else
1702 {
1703 size_t
1704 signature;
1705
1706 if ((*image)->debug != MagickFalse)
1707 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1708 "Invoking \"%s\" static image filter",tag);
1709 signature=image_filter(image,argc,argv,exception);
1710 if ((*image)->debug != MagickFalse)
1711 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1712 "\"%s\" completes",tag);
1713 if (signature != MagickImageFilterSignature)
1714 {
1715 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1716 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1717 (unsigned long) signature,(unsigned long)
1718 MagickImageFilterSignature);
1719 return(MagickFalse);
1720 }
1721 }
1722 }
1723#endif
1724 return(MagickTrue);
1725}
1726#endif
Definition vms.h:942