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