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/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 {
984 errno=EPERM;
985 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
986 "NotAuthorized","`%s'",tag);
987 return(MagickFalse);
988 }
989#if !defined(MAGICKCORE_BUILD_MODULES)
990 {
991 MagickBooleanType
992 status;
993
994 status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
995 if (status != MagickFalse)
996 return(status);
997 }
998#endif
999 TagToFilterModuleName(tag,name);
1000 status=GetMagickModulePath(name,MagickImageFilterModule,path,exception);
1001 if (status == MagickFalse)
1002 {
1003 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1004 "UnableToLoadModule","'%s': %s",name,path);
1005 return(MagickFalse);
1006 }
1007 /*
1008 Open the module.
1009 */
1010 handle=(ModuleHandle) lt_dlopen(path);
1011 if (handle == (ModuleHandle) NULL)
1012 {
1013 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1014 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1015 return(MagickFalse);
1016 }
1017 /*
1018 Locate the module.
1019 */
1020#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1021 (void) FormatLocaleString(name,MagickPathExtent,"%sImage",tag);
1022#else
1023 (void) FormatLocaleString(name,MagickPathExtent,"%s%sImage",
1024 MAGICKCORE_NAMESPACE_PREFIX_TAG,tag);
1025#endif
1026 /*
1027 Execute the module.
1028 */
1029 ClearMagickException(exception);
1030 image_filter=(ImageFilterHandler *) lt_dlsym(handle,name);
1031 if (image_filter == (ImageFilterHandler *) NULL)
1032 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1033 "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1034 else
1035 {
1036 size_t
1037 signature;
1038
1039 if (IsEventLogging() != MagickFalse)
1040 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1041 "Invoking \"%s\" dynamic image filter",tag);
1042 signature=image_filter(images,argc,argv,exception);
1043 if (IsEventLogging() != MagickFalse)
1044 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
1045 tag);
1046 if (signature != MagickImageFilterSignature)
1047 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1048 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1049 (unsigned long) signature,(unsigned long) MagickImageFilterSignature);
1050 }
1051 /*
1052 Close the module.
1053 */
1054 if (lt_dlclose(handle) != 0)
1055 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1056 "UnableToCloseModule","'%s': %s",name,lt_dlerror());
1057 return(exception->severity < ErrorException ? MagickTrue : MagickFalse);
1058}
1059
1060/*
1061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062% %
1063% %
1064% %
1065% L i s t M o d u l e I n f o %
1066% %
1067% %
1068% %
1069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070%
1071% ListModuleInfo() lists the module info to a file.
1072%
1073% The format of the ListModuleInfo module is:
1074%
1075% MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
1076%
1077% A description of each parameter follows.
1078%
1079% o file: An pointer to a FILE.
1080%
1081% o exception: return any errors or warnings in this structure.
1082%
1083*/
1084MagickExport MagickBooleanType ListModuleInfo(FILE *file,
1085 ExceptionInfo *exception)
1086{
1087 char
1088 filename[MagickPathExtent],
1089 module_path[MagickPathExtent],
1090 **modules,
1091 path[MagickPathExtent];
1092
1093 ssize_t
1094 i;
1095
1096 size_t
1097 number_modules;
1098
1099 if (file == (const FILE *) NULL)
1100 file=stdout;
1101 /*
1102 List image coders.
1103 */
1104 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1105 if (modules == (char **) NULL)
1106 return(MagickFalse);
1107 TagToCoderModuleName("magick",filename);
1108 (void) GetMagickModulePath(filename,MagickImageCoderModule,module_path,
1109 exception);
1110 GetPathComponent(module_path,HeadPath,path);
1111 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1112 (void) FormatLocaleFile(file,"Image Coder\n");
1113 (void) FormatLocaleFile(file,
1114 "-------------------------------------------------"
1115 "------------------------------\n");
1116 for (i=0; i < (ssize_t) number_modules; i++)
1117 {
1118 (void) FormatLocaleFile(file,"%s",modules[i]);
1119 (void) FormatLocaleFile(file,"\n");
1120 }
1121 (void) fflush(file);
1122 /*
1123 Relinquish resources.
1124 */
1125 for (i=0; i < (ssize_t) number_modules; i++)
1126 modules[i]=DestroyString(modules[i]);
1127 modules=(char **) RelinquishMagickMemory(modules);
1128 /*
1129 List image filters.
1130 */
1131 modules=GetModuleList("*",MagickImageFilterModule,&number_modules,exception);
1132 if (modules == (char **) NULL)
1133 return(MagickFalse);
1134 TagToFilterModuleName("analyze",filename);
1135 (void) GetMagickModulePath(filename,MagickImageFilterModule,module_path,
1136 exception);
1137 GetPathComponent(module_path,HeadPath,path);
1138 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1139 (void) FormatLocaleFile(file,"Image Filter\n");
1140 (void) FormatLocaleFile(file,
1141 "-------------------------------------------------"
1142 "------------------------------\n");
1143 for (i=0; i < (ssize_t) number_modules; i++)
1144 {
1145 (void) FormatLocaleFile(file,"%s",modules[i]);
1146 (void) FormatLocaleFile(file,"\n");
1147 }
1148 (void) fflush(file);
1149 /*
1150 Relinquish resources.
1151 */
1152 for (i=0; i < (ssize_t) number_modules; i++)
1153 modules[i]=DestroyString(modules[i]);
1154 modules=(char **) RelinquishMagickMemory(modules);
1155 return(MagickTrue);
1156}
1157
1158/*
1159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1160% %
1161% %
1162% %
1163+ M o d u l e C o m p o n e n t G e n e s i s %
1164% %
1165% %
1166% %
1167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1168%
1169% ModuleComponentGenesis() instantiates the module component.
1170%
1171% The format of the ModuleComponentGenesis method is:
1172%
1173% MagickBooleanType ModuleComponentGenesis(void)
1174%
1175*/
1176MagickPrivate MagickBooleanType ModuleComponentGenesis(void)
1177{
1178 MagickBooleanType
1179 status;
1180
1181 if (module_semaphore == (SemaphoreInfo *) NULL)
1182 module_semaphore=AcquireSemaphoreInfo();
1183 status=IsModuleTreeInstantiated();
1184 return(status);
1185}
1186
1187/*
1188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1189% %
1190% %
1191% %
1192+ M o d u l e C o m p o n e n t T e r m i n u s %
1193% %
1194% %
1195% %
1196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197%
1198% ModuleComponentTerminus() destroys the module component.
1199%
1200% The format of the ModuleComponentTerminus method is:
1201%
1202% ModuleComponentTerminus(void)
1203%
1204*/
1205MagickPrivate void ModuleComponentTerminus(void)
1206{
1207 if (module_semaphore == (SemaphoreInfo *) NULL)
1208 ActivateSemaphoreInfo(&module_semaphore);
1209 DestroyModuleList();
1210 RelinquishSemaphoreInfo(&module_semaphore);
1211}
1212
1213/*
1214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1215% %
1216% %
1217% %
1218% O p e n M o d u l e %
1219% %
1220% %
1221% %
1222%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1223%
1224% OpenModule() loads a module, and invokes its registration module. It
1225% returns MagickTrue on success, and MagickFalse if there is an error.
1226%
1227% The format of the OpenModule module is:
1228%
1229% MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
1230%
1231% A description of each parameter follows:
1232%
1233% o module: a character string that indicates the module to load.
1234%
1235% o exception: return any errors or warnings in this structure.
1236%
1237*/
1238MagickPrivate MagickBooleanType OpenModule(const char *module,
1239 ExceptionInfo *exception)
1240{
1241 char
1242 module_name[MagickPathExtent],
1243 name[MagickPathExtent],
1244 path[MagickPathExtent];
1245
1246 MagickBooleanType
1247 status;
1248
1249 ModuleHandle
1250 handle;
1251
1252 ModuleInfo
1253 *module_info;
1254
1255 PolicyRights
1256 rights;
1257
1258 const CoderInfo
1259 *p;
1260
1261 size_t
1262 signature;
1263
1264 /*
1265 Assign module name from alias.
1266 */
1267 assert(module != (const char *) NULL);
1268 module_info=(ModuleInfo *) GetModuleInfo(module,exception);
1269 if (module_info != (ModuleInfo *) NULL)
1270 return(MagickTrue);
1271 (void) CopyMagickString(module_name,module,MagickPathExtent);
1272 p=GetCoderInfo(module,exception);
1273 if (p != (CoderInfo *) NULL)
1274 (void) CopyMagickString(module_name,p->name,MagickPathExtent);
1275 LocaleUpper(module_name);
1276 rights=(PolicyRights) (ReadPolicyRights | WritePolicyRights);
1277 if (IsRightsAuthorized(ModulePolicyDomain,rights,module_name) == MagickFalse)
1278 {
1279 errno=EPERM;
1280 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
1281 "NotAuthorized","`%s'",module);
1282 return(MagickFalse);
1283 }
1284 if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
1285 return(MagickTrue); /* module already opened, return */
1286 /*
1287 Locate module.
1288 */
1289 handle=(ModuleHandle) NULL;
1290 TagToCoderModuleName(module_name,name);
1291 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1292 "Searching for module \"%s\" using filename \"%s\"",module_name,name);
1293 *path='\0';
1294 status=GetMagickModulePath(name,MagickImageCoderModule,path,exception);
1295 if (status == MagickFalse)
1296 return(MagickFalse);
1297 /*
1298 Load module
1299 */
1300 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1301 "Opening module at path \"%s\"",path);
1302 handle=(ModuleHandle) lt_dlopen(path);
1303 if (handle == (ModuleHandle) NULL)
1304 {
1305 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1306 "UnableToLoadModule","'%s': %s",path,lt_dlerror());
1307 return(MagickFalse);
1308 }
1309 /*
1310 Register module.
1311 */
1312 module_info=AcquireModuleInfo(path,module_name);
1313 module_info->handle=handle;
1314 if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
1315 return(MagickFalse);
1316 /*
1317 Define RegisterFORMATImage method.
1318 */
1319 TagToModuleName(module_name,"Register%sImage",name);
1320 module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name);
1321 if (module_info->register_module == (size_t (*)(void)) NULL)
1322 {
1323 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1324 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1325 return(MagickFalse);
1326 }
1327 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1328 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1329 (void *) module_info->register_module);
1330 /*
1331 Define UnregisterFORMATImage method.
1332 */
1333 TagToModuleName(module_name,"Unregister%sImage",name);
1334 module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
1335 if (module_info->unregister_module == (void (*)(void)) NULL)
1336 {
1337 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1338 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1339 return(MagickFalse);
1340 }
1341 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
1342 "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1343 (void *) module_info->unregister_module);
1344 signature=module_info->register_module();
1345 if (signature != MagickImageCoderSignature)
1346 {
1347 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1348 "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name,
1349 (unsigned long) signature,(unsigned long) MagickImageCoderSignature);
1350 return(MagickFalse);
1351 }
1352 return(MagickTrue);
1353}
1354
1355/*
1356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357% %
1358% %
1359% %
1360% O p e n M o d u l e s %
1361% %
1362% %
1363% %
1364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1365%
1366% OpenModules() loads all available modules.
1367%
1368% The format of the OpenModules module is:
1369%
1370% MagickBooleanType OpenModules(ExceptionInfo *exception)
1371%
1372% A description of each parameter follows:
1373%
1374% o exception: return any errors or warnings in this structure.
1375%
1376*/
1377MagickPrivate MagickBooleanType OpenModules(ExceptionInfo *exception)
1378{
1379 char
1380 **modules;
1381
1382 ssize_t
1383 i;
1384
1385 size_t
1386 number_modules;
1387
1388 /*
1389 Load all modules.
1390 */
1391 (void) GetMagickInfo((char *) NULL,exception);
1392 number_modules=0;
1393 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1394 if ((modules == (char **) NULL) || (*modules == (char *) NULL))
1395 {
1396 if (modules != (char **) NULL)
1397 modules=(char **) RelinquishMagickMemory(modules);
1398 return(MagickFalse);
1399 }
1400 for (i=0; i < (ssize_t) number_modules; i++)
1401 (void) OpenModule(modules[i],exception);
1402 /*
1403 Relinquish resources.
1404 */
1405 for (i=0; i < (ssize_t) number_modules; i++)
1406 modules[i]=DestroyString(modules[i]);
1407 modules=(char **) RelinquishMagickMemory(modules);
1408 return(MagickTrue);
1409}
1410
1411/*
1412%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413% %
1414% %
1415% %
1416% R e g i s t e r M o d u l e %
1417% %
1418% %
1419% %
1420%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1421%
1422% RegisterModule() adds an entry to the module list. It returns a pointer to
1423% the registered entry on success.
1424%
1425% The format of the RegisterModule module is:
1426%
1427% ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1428% ExceptionInfo *exception)
1429%
1430% A description of each parameter follows:
1431%
1432% o info: a pointer to the registered entry is returned.
1433%
1434% o module_info: a pointer to the ModuleInfo structure to register.
1435%
1436% o exception: return any errors or warnings in this structure.
1437%
1438*/
1439static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1440 ExceptionInfo *exception)
1441{
1442 MagickBooleanType
1443 status;
1444
1445 assert(module_info != (ModuleInfo *) NULL);
1446 assert(module_info->signature == MagickCoreSignature);
1447 if (IsEventLogging() != MagickFalse)
1448 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1449 if (module_list == (SplayTreeInfo *) NULL)
1450 return((const ModuleInfo *) NULL);
1451 status=AddValueToSplayTree(module_list,module_info->tag,module_info);
1452 if (status == MagickFalse)
1453 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
1454 "MemoryAllocationFailed","`%s'",module_info->tag);
1455 return(module_info);
1456}
1457
1458/*
1459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460% %
1461% %
1462% %
1463% T a g T o C o d e r M o d u l e N a m e %
1464% %
1465% %
1466% %
1467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468%
1469% TagToCoderModuleName() munges a module tag and obtains the filename of the
1470% corresponding module.
1471%
1472% The format of the TagToCoderModuleName module is:
1473%
1474% char *TagToCoderModuleName(const char *tag,char *name)
1475%
1476% A description of each parameter follows:
1477%
1478% o tag: a character string representing the module tag.
1479%
1480% o name: return the module name here.
1481%
1482*/
1483static void TagToCoderModuleName(const char *tag,char *name)
1484{
1485 assert(tag != (char *) NULL);
1486 assert(name != (char *) NULL);
1487 if (IsEventLogging() != MagickFalse)
1488 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1489#if defined(MAGICKCORE_LTDL_DELEGATE)
1490 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1491 (void) LocaleLower(name);
1492#else
1493#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1494 if (LocaleNCompare("IM_MOD_",tag,7) == 0)
1495 (void) CopyMagickString(name,tag,MagickPathExtent);
1496 else
1497 {
1498#if defined(_DEBUG)
1499 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag);
1500#else
1501 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag);
1502#endif
1503 }
1504#endif
1505#endif
1506}
1507
1508/*
1509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1510% %
1511% %
1512% %
1513% T a g T o F i l t e r M o d u l e N a m e %
1514% %
1515% %
1516% %
1517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1518%
1519% TagToFilterModuleName() munges a module tag and returns the filename of the
1520% corresponding filter module.
1521%
1522% The format of the TagToFilterModuleName module is:
1523%
1524% void TagToFilterModuleName(const char *tag,char name)
1525%
1526% A description of each parameter follows:
1527%
1528% o tag: a character string representing the module tag.
1529%
1530% o name: return the filter name here.
1531%
1532*/
1533static void TagToFilterModuleName(const char *tag,char *name)
1534{
1535 assert(tag != (char *) NULL);
1536 assert(name != (char *) NULL);
1537 if (IsEventLogging() != MagickFalse)
1538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1539#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1540#if defined(_DEBUG)
1541 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_DB_%s_.dll",tag);
1542#else
1543 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_RL_%s_.dll",tag);
1544#endif
1545#elif !defined(MAGICKCORE_LTDL_DELEGATE)
1546 (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag);
1547#else
1548 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1549#endif
1550}
1551
1552/*
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554% %
1555% %
1556% %
1557% T a g T o M o d u l e N a m e %
1558% %
1559% %
1560% %
1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562%
1563% TagToModuleName() munges the module tag name and returns an upper-case tag
1564% name as the input string, and a user-provided format.
1565%
1566% The format of the TagToModuleName module is:
1567%
1568% void TagToModuleName(const char *tag,const char *format,char *module)
1569%
1570% A description of each parameter follows:
1571%
1572% o tag: the module tag.
1573%
1574% o format: a sprintf-compatible format string containing %s where the
1575% upper-case tag name is to be inserted.
1576%
1577% o module: pointer to a destination buffer for the formatted result.
1578%
1579*/
1580static void TagToModuleName(const char *tag,const char *format,char *module)
1581{
1582 char
1583 name[MagickPathExtent];
1584
1585 assert(tag != (const char *) NULL);
1586 assert(format != (const char *) NULL);
1587 assert(module != (char *) NULL);
1588 if (IsEventLogging() != MagickFalse)
1589 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1590 (void) CopyMagickString(name,tag,MagickPathExtent);
1591 LocaleUpper(name);
1592#if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1593 (void) FormatLocaleString(module,MagickPathExtent,format,name);
1594#else
1595 {
1596 char
1597 prefix_format[MagickPathExtent];
1598
1599 (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s",
1600 MAGICKCORE_NAMESPACE_PREFIX_TAG,format);
1601 (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name);
1602 }
1603#endif
1604}
1605
1606/*
1607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608% %
1609% %
1610% %
1611% U n r e g i s t e r M o d u l e %
1612% %
1613% %
1614% %
1615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1616%
1617% UnregisterModule() unloads a module, and invokes its de-registration module.
1618% Returns MagickTrue on success, and MagickFalse if there is an error.
1619%
1620% The format of the UnregisterModule module is:
1621%
1622% MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1623% ExceptionInfo *exception)
1624%
1625% A description of each parameter follows:
1626%
1627% o module_info: the module info.
1628%
1629% o exception: return any errors or warnings in this structure.
1630%
1631*/
1632static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1633 ExceptionInfo *exception)
1634{
1635 /*
1636 Locate and execute UnregisterFORMATImage module.
1637 */
1638 assert(module_info != (const ModuleInfo *) NULL);
1639 assert(exception != (ExceptionInfo *) NULL);
1640 if (IsEventLogging() != MagickFalse)
1641 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1642 if (module_info->unregister_module == NULL)
1643 return(MagickTrue);
1644 module_info->unregister_module();
1645 if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
1646 {
1647 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
1648 "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror());
1649 return(MagickFalse);
1650 }
1651 return(MagickTrue);
1652}
1653#else
1654
1655#if !defined(MAGICKCORE_BUILD_MODULES)
1656extern size_t
1657 analyzeImage(Image **,const int,const char **,ExceptionInfo *);
1658#endif
1659
1660MagickExport MagickBooleanType ListModuleInfo(FILE *magick_unused(file),
1661 ExceptionInfo *magick_unused(exception))
1662{
1663 magick_unreferenced(file);
1664 magick_unreferenced(exception);
1665 return(MagickTrue);
1666}
1667
1668MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
1669 Image **image,const int argc,const char **argv,ExceptionInfo *exception)
1670{
1671 PolicyRights
1672 rights;
1673
1674 assert(image != (Image **) NULL);
1675 assert((*image)->signature == MagickCoreSignature);
1676 if (IsEventLogging() != MagickFalse)
1677 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1678 rights=ReadPolicyRights;
1679 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
1680 {
1681 errno=EPERM;
1682 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
1683 "NotAuthorized","`%s'",tag);
1684 return(MagickFalse);
1685 }
1686#if defined(MAGICKCORE_BUILD_MODULES)
1687 (void) tag;
1688 (void) argc;
1689 (void) argv;
1690 (void) exception;
1691#else
1692 {
1693 ImageFilterHandler
1694 *image_filter;
1695
1696 image_filter=(ImageFilterHandler *) NULL;
1697 if (LocaleCompare("analyze",tag) == 0)
1698 image_filter=(ImageFilterHandler *) analyzeImage;
1699 if (image_filter == (ImageFilterHandler *) NULL)
1700 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1701 "UnableToLoadModule","`%s'",tag);
1702 else
1703 {
1704 size_t
1705 signature;
1706
1707 if ((*image)->debug != MagickFalse)
1708 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1709 "Invoking \"%s\" static image filter",tag);
1710 signature=image_filter(image,argc,argv,exception);
1711 if ((*image)->debug != MagickFalse)
1712 (void) LogMagickEvent(TransformEvent,GetMagickModule(),
1713 "\"%s\" completes",tag);
1714 if (signature != MagickImageFilterSignature)
1715 {
1716 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
1717 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1718 (unsigned long) signature,(unsigned long)
1719 MagickImageFilterSignature);
1720 return(MagickFalse);
1721 }
1722 }
1723 }
1724#endif
1725 return(MagickTrue);
1726}
1727#endif
Definition vms.h:942