MagickCore  7.0.8
Convert, Edit, Or Compose Bitmap Images
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-2018 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) &&
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],
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  {
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  home=GetEnvironmentValue("LOCALAPPDATA");
785  if (home == (char *) NULL)
786  home=GetEnvironmentValue("APPDATA");
787  if (home == (char *) NULL)
788  home=GetEnvironmentValue("USERPROFILE");
789  if (home != (char *) NULL)
790  {
791  /*
792  Search $XDG_CONFIG_HOME/ImageMagick.
793  */
794  (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s%s",
795  home,DirectorySeparator,DirectorySeparator,filename);
796  home=DestroyString(home);
797  if (IsPathAccessible(path) != MagickFalse)
798  return(MagickTrue);
799  }
800  home=GetEnvironmentValue("HOME");
801  if (home != (char *) NULL)
802  {
803  /*
804  Search $HOME/.config/ImageMagick.
805  */
807  "%s%s.config%sImageMagick%s%s",home,DirectorySeparator,
809  home=DestroyString(home);
810  if (IsPathAccessible(path) != MagickFalse)
811  return(MagickTrue);
812  }
813  }
814  /*
815  Search current directory.
816  */
817  if (IsPathAccessible(path) != MagickFalse)
818  return(MagickTrue);
819  if (exception->severity < ConfigureError)
820  ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
821  path);
822 #endif
823  return(MagickFalse);
824 }
825 
826 /*
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 % %
829 % %
830 % %
831 % I s M o d u l e T r e e I n s t a n t i a t e d %
832 % %
833 % %
834 % %
835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 %
837 % IsModuleTreeInstantiated() determines if the module tree is instantiated.
838 % If not, it instantiates the tree and returns it.
839 %
840 % The format of the IsModuleTreeInstantiated() method is:
841 %
842 % IsModuleTreeInstantiated()
843 %
844 */
845 
846 static void *DestroyModuleNode(void *module_info)
847 {
849  *exception;
850 
851  register ModuleInfo
852  *p;
853 
854  exception=AcquireExceptionInfo();
855  p=(ModuleInfo *) module_info;
856  if (UnregisterModule(p,exception) == MagickFalse)
857  CatchException(exception);
858  if (p->tag != (char *) NULL)
859  p->tag=DestroyString(p->tag);
860  if (p->path != (char *) NULL)
861  p->path=DestroyString(p->path);
862  exception=DestroyExceptionInfo(exception);
863  return(RelinquishMagickMemory(p));
864 }
865 
866 static MagickBooleanType IsModuleTreeInstantiated()
867 {
868  if (module_list == (SplayTreeInfo *) NULL)
869  {
870  if (module_semaphore == (SemaphoreInfo *) NULL)
871  ActivateSemaphoreInfo(&module_semaphore);
872  LockSemaphoreInfo(module_semaphore);
873  if (module_list == (SplayTreeInfo *) NULL)
874  {
876  status;
877 
878  ModuleInfo
879  *module_info;
880 
882  *splay_tree;
883 
885  (void *(*)(void *)) NULL,DestroyModuleNode);
886  module_info=AcquireModuleInfo((const char *) NULL,"[boot-strap]");
887  module_info->stealth=MagickTrue;
888  status=AddValueToSplayTree(splay_tree,module_info->tag,module_info);
889  if (status == MagickFalse)
891  "MemoryAllocationFailed");
892  if (lt_dlinit() != 0)
894  "UnableToInitializeModuleLoader");
895  module_list=splay_tree;
896  }
897  UnlockSemaphoreInfo(module_semaphore);
898  }
899  return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
900 }
901 
902 /*
903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
904 % %
905 % %
906 % %
907 % I n v o k e D y n a m i c I m a g e F i l t e r %
908 % %
909 % %
910 % %
911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
912 %
913 % InvokeDynamicImageFilter() invokes a dynamic image filter.
914 %
915 % The format of the InvokeDynamicImageFilter module is:
916 %
917 % MagickBooleanType InvokeDynamicImageFilter(const char *tag,Image **image,
918 % const int argc,const char **argv,ExceptionInfo *exception)
919 %
920 % A description of each parameter follows:
921 %
922 % o tag: a character string that represents the name of the particular
923 % module.
924 %
925 % o image: the image.
926 %
927 % o argc: a pointer to an integer describing the number of elements in the
928 % argument vector.
929 %
930 % o argv: a pointer to a text array containing the command line arguments.
931 %
932 % o exception: return any errors or warnings in this structure.
933 %
934 */
936  Image **images,const int argc,const char **argv,ExceptionInfo *exception)
937 {
938  char
939  name[MagickPathExtent],
940  path[MagickPathExtent];
941 
943  *image_filter;
944 
946  status;
947 
948  ModuleHandle
949  handle;
950 
952  rights;
953 
954  /*
955  Find the module.
956  */
957  assert(images != (Image **) NULL);
958  assert((*images)->signature == MagickCoreSignature);
959  if ((*images)->debug != MagickFalse)
961  (*images)->filename);
962  rights=ReadPolicyRights;
964  {
965  errno=EPERM;
967  "NotAuthorized","`%s'",tag);
968  return(MagickFalse);
969  }
970 #if !defined(MAGICKCORE_BUILD_MODULES)
971  {
973  status;
974 
975  status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
976  if (status != MagickFalse)
977  return(status);
978  }
979 #endif
980  TagToFilterModuleName(tag,name);
981  status=GetMagickModulePath(name,MagickImageFilterModule,path,exception);
982  if (status == MagickFalse)
983  {
985  "UnableToLoadModule","'%s': %s",name,path);
986  return(MagickFalse);
987  }
988  /*
989  Open the module.
990  */
991  handle=(ModuleHandle) lt_dlopen(path);
992  if (handle == (ModuleHandle) NULL)
993  {
995  "UnableToLoadModule","'%s': %s",name,lt_dlerror());
996  return(MagickFalse);
997  }
998  /*
999  Locate the module.
1000  */
1001 #if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1002  (void) FormatLocaleString(name,MagickPathExtent,"%sImage",tag);
1003 #else
1004  (void) FormatLocaleString(name,MagickPathExtent,"%s%sImage",
1005  MAGICKCORE_NAMESPACE_PREFIX_TAG,tag);
1006 #endif
1007  /*
1008  Execute the module.
1009  */
1010  ClearMagickException(exception);
1011  image_filter=(ImageFilterHandler *) lt_dlsym(handle,name);
1012  if (image_filter == (ImageFilterHandler *) NULL)
1014  "UnableToLoadModule","'%s': %s",name,lt_dlerror());
1015  else
1016  {
1017  size_t
1018  signature;
1019 
1020  if ((*images)->debug != MagickFalse)
1022  "Invoking \"%s\" dynamic image filter",tag);
1023  signature=image_filter(images,argc,argv,exception);
1024  if ((*images)->debug != MagickFalse)
1025  (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
1026  tag);
1027  if (signature != MagickImageFilterSignature)
1029  "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1030  (unsigned long) signature,(unsigned long) MagickImageFilterSignature);
1031  }
1032  /*
1033  Close the module.
1034  */
1035  if (lt_dlclose(handle) != 0)
1037  "UnableToCloseModule","'%s': %s",name,lt_dlerror());
1038  return(exception->severity < ErrorException ? MagickTrue : MagickFalse);
1039 }
1040 
1041 /*
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % %
1044 % %
1045 % %
1046 % L i s t M o d u l e I n f o %
1047 % %
1048 % %
1049 % %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 %
1052 % ListModuleInfo() lists the module info to a file.
1053 %
1054 % The format of the ListModuleInfo module is:
1055 %
1056 % MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
1057 %
1058 % A description of each parameter follows.
1059 %
1060 % o file: An pointer to a FILE.
1061 %
1062 % o exception: return any errors or warnings in this structure.
1063 %
1064 */
1066  ExceptionInfo *exception)
1067 {
1068  char
1069  filename[MagickPathExtent],
1070  module_path[MagickPathExtent],
1071  **modules,
1072  path[MagickPathExtent];
1073 
1074  register ssize_t
1075  i;
1076 
1077  size_t
1078  number_modules;
1079 
1080  if (file == (const FILE *) NULL)
1081  file=stdout;
1082  /*
1083  List image coders.
1084  */
1085  modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1086  if (modules == (char **) NULL)
1087  return(MagickFalse);
1088  TagToCoderModuleName("magick",filename);
1089  (void) GetMagickModulePath(filename,MagickImageCoderModule,module_path,
1090  exception);
1091  GetPathComponent(module_path,HeadPath,path);
1092  (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1093  (void) FormatLocaleFile(file,"Image Coder\n");
1094  (void) FormatLocaleFile(file,
1095  "-------------------------------------------------"
1096  "------------------------------\n");
1097  for (i=0; i < (ssize_t) number_modules; i++)
1098  {
1099  (void) FormatLocaleFile(file,"%s",modules[i]);
1100  (void) FormatLocaleFile(file,"\n");
1101  }
1102  (void) fflush(file);
1103  /*
1104  Relinquish resources.
1105  */
1106  for (i=0; i < (ssize_t) number_modules; i++)
1107  modules[i]=DestroyString(modules[i]);
1108  modules=(char **) RelinquishMagickMemory(modules);
1109  /*
1110  List image filters.
1111  */
1112  modules=GetModuleList("*",MagickImageFilterModule,&number_modules,exception);
1113  if (modules == (char **) NULL)
1114  return(MagickFalse);
1115  TagToFilterModuleName("analyze",filename);
1116  (void) GetMagickModulePath(filename,MagickImageFilterModule,module_path,
1117  exception);
1118  GetPathComponent(module_path,HeadPath,path);
1119  (void) FormatLocaleFile(file,"\nPath: %s\n\n",path);
1120  (void) FormatLocaleFile(file,"Image Filter\n");
1121  (void) FormatLocaleFile(file,
1122  "-------------------------------------------------"
1123  "------------------------------\n");
1124  for (i=0; i < (ssize_t) number_modules; i++)
1125  {
1126  (void) FormatLocaleFile(file,"%s",modules[i]);
1127  (void) FormatLocaleFile(file,"\n");
1128  }
1129  (void) fflush(file);
1130  /*
1131  Relinquish resources.
1132  */
1133  for (i=0; i < (ssize_t) number_modules; i++)
1134  modules[i]=DestroyString(modules[i]);
1135  modules=(char **) RelinquishMagickMemory(modules);
1136  return(MagickTrue);
1137 }
1138 
1139 /*
1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141 % %
1142 % %
1143 % %
1144 + M o d u l e C o m p o n e n t G e n e s i s %
1145 % %
1146 % %
1147 % %
1148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149 %
1150 % ModuleComponentGenesis() instantiates the module component.
1151 %
1152 % The format of the ModuleComponentGenesis method is:
1153 %
1154 % MagickBooleanType ModuleComponentGenesis(void)
1155 %
1156 */
1158 {
1160  status;
1161 
1162  if (module_semaphore == (SemaphoreInfo *) NULL)
1163  module_semaphore=AcquireSemaphoreInfo();
1164  status=IsModuleTreeInstantiated();
1165  return(status);
1166 }
1167 
1168 /*
1169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1170 % %
1171 % %
1172 % %
1173 + M o d u l e C o m p o n e n t T e r m i n u s %
1174 % %
1175 % %
1176 % %
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1178 %
1179 % ModuleComponentTerminus() destroys the module component.
1180 %
1181 % The format of the ModuleComponentTerminus method is:
1182 %
1183 % ModuleComponentTerminus(void)
1184 %
1185 */
1187 {
1188  if (module_semaphore == (SemaphoreInfo *) NULL)
1189  ActivateSemaphoreInfo(&module_semaphore);
1191  RelinquishSemaphoreInfo(&module_semaphore);
1192 }
1193 
1194 /*
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1196 % %
1197 % %
1198 % %
1199 % O p e n M o d u l e %
1200 % %
1201 % %
1202 % %
1203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204 %
1205 % OpenModule() loads a module, and invokes its registration module. It
1206 % returns MagickTrue on success, and MagickFalse if there is an error.
1207 %
1208 % The format of the OpenModule module is:
1209 %
1210 % MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
1211 %
1212 % A description of each parameter follows:
1213 %
1214 % o module: a character string that indicates the module to load.
1215 %
1216 % o exception: return any errors or warnings in this structure.
1217 %
1218 */
1220  ExceptionInfo *exception)
1221 {
1222  char
1223  filename[MagickPathExtent],
1224  module_name[MagickPathExtent],
1225  name[MagickPathExtent],
1226  path[MagickPathExtent];
1227 
1229  status;
1230 
1231  ModuleHandle
1232  handle;
1233 
1234  ModuleInfo
1235  *module_info;
1236 
1237  PolicyRights
1238  rights;
1239 
1240  register const CoderInfo
1241  *p;
1242 
1243  size_t
1244  signature;
1245 
1246  /*
1247  Assign module name from alias.
1248  */
1249  assert(module != (const char *) NULL);
1250  module_info=(ModuleInfo *) GetModuleInfo(module,exception);
1251  if (module_info != (ModuleInfo *) NULL)
1252  return(MagickTrue);
1253  rights=ReadPolicyRights;
1255  {
1256  errno=EPERM;
1258  "NotAuthorized","`%s'",module);
1259  return(MagickFalse);
1260  }
1261  (void) CopyMagickString(module_name,module,MagickPathExtent);
1262  p=GetCoderInfo(module,exception);
1263  if (p != (CoderInfo *) NULL)
1264  (void) CopyMagickString(module_name,p->name,MagickPathExtent);
1265  if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
1266  return(MagickTrue); /* module already opened, return */
1267  /*
1268  Locate module.
1269  */
1270  handle=(ModuleHandle) NULL;
1271  TagToCoderModuleName(module_name,filename);
1273  "Searching for module \"%s\" using filename \"%s\"",module_name,filename);
1274  *path='\0';
1275  status=GetMagickModulePath(filename,MagickImageCoderModule,path,exception);
1276  if (status == MagickFalse)
1277  return(MagickFalse);
1278  /*
1279  Load module
1280  */
1282  "Opening module at path \"%s\"",path);
1283  handle=(ModuleHandle) lt_dlopen(path);
1284  if (handle == (ModuleHandle) NULL)
1285  {
1287  "UnableToLoadModule","'%s': %s",path,lt_dlerror());
1288  return(MagickFalse);
1289  }
1290  /*
1291  Register module.
1292  */
1293  module_info=AcquireModuleInfo(path,module_name);
1294  module_info->handle=handle;
1295  if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
1296  return(MagickFalse);
1297  /*
1298  Define RegisterFORMATImage method.
1299  */
1300  TagToModuleName(module_name,"Register%sImage",name);
1301  module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name);
1302  if (module_info->register_module == (size_t (*)(void)) NULL)
1303  {
1305  "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1306  return(MagickFalse);
1307  }
1309  "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1310  (void *) module_info->register_module);
1311  /*
1312  Define UnregisterFORMATImage method.
1313  */
1314  TagToModuleName(module_name,"Unregister%sImage",name);
1315  module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
1316  if (module_info->unregister_module == (void (*)(void)) NULL)
1317  {
1319  "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1320  return(MagickFalse);
1321  }
1323  "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1324  (void *) module_info->unregister_module);
1325  signature=module_info->register_module();
1326  if (signature != MagickImageCoderSignature)
1327  {
1329  "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name,
1330  (unsigned long) signature,(unsigned long) MagickImageCoderSignature);
1331  return(MagickFalse);
1332  }
1333  return(MagickTrue);
1334 }
1335 
1336 /*
1337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338 % %
1339 % %
1340 % %
1341 % O p e n M o d u l e s %
1342 % %
1343 % %
1344 % %
1345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1346 %
1347 % OpenModules() loads all available modules.
1348 %
1349 % The format of the OpenModules module is:
1350 %
1351 % MagickBooleanType OpenModules(ExceptionInfo *exception)
1352 %
1353 % A description of each parameter follows:
1354 %
1355 % o exception: return any errors or warnings in this structure.
1356 %
1357 */
1359 {
1360  char
1361  **modules;
1362 
1363  register ssize_t
1364  i;
1365 
1366  size_t
1367  number_modules;
1368 
1369  /*
1370  Load all modules.
1371  */
1372  (void) GetMagickInfo((char *) NULL,exception);
1373  number_modules=0;
1374  modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1375  if ((modules == (char **) NULL) || (*modules == (char *) NULL))
1376  {
1377  if (modules != (char **) NULL)
1378  modules=(char **) RelinquishMagickMemory(modules);
1379  return(MagickFalse);
1380  }
1381  for (i=0; i < (ssize_t) number_modules; i++)
1382  (void) OpenModule(modules[i],exception);
1383  /*
1384  Relinquish resources.
1385  */
1386  for (i=0; i < (ssize_t) number_modules; i++)
1387  modules[i]=DestroyString(modules[i]);
1388  modules=(char **) RelinquishMagickMemory(modules);
1389  return(MagickTrue);
1390 }
1391 
1392 /*
1393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1394 % %
1395 % %
1396 % %
1397 % R e g i s t e r M o d u l e %
1398 % %
1399 % %
1400 % %
1401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1402 %
1403 % RegisterModule() adds an entry to the module list. It returns a pointer to
1404 % the registered entry on success.
1405 %
1406 % The format of the RegisterModule module is:
1407 %
1408 % ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1409 % ExceptionInfo *exception)
1410 %
1411 % A description of each parameter follows:
1412 %
1413 % o info: a pointer to the registered entry is returned.
1414 %
1415 % o module_info: a pointer to the ModuleInfo structure to register.
1416 %
1417 % o exception: return any errors or warnings in this structure.
1418 %
1419 */
1420 static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1421  ExceptionInfo *exception)
1422 {
1424  status;
1425 
1426  assert(module_info != (ModuleInfo *) NULL);
1427  assert(module_info->signature == MagickCoreSignature);
1428  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1429  if (module_list == (SplayTreeInfo *) NULL)
1430  return((const ModuleInfo *) NULL);
1431  status=AddValueToSplayTree(module_list,module_info->tag,module_info);
1432  if (status == MagickFalse)
1434  "MemoryAllocationFailed","`%s'",module_info->tag);
1435  return(module_info);
1436 }
1437 
1438 /*
1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440 % %
1441 % %
1442 % %
1443 % T a g T o C o d e r M o d u l e N a m e %
1444 % %
1445 % %
1446 % %
1447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1448 %
1449 % TagToCoderModuleName() munges a module tag and obtains the filename of the
1450 % corresponding module.
1451 %
1452 % The format of the TagToCoderModuleName module is:
1453 %
1454 % char *TagToCoderModuleName(const char *tag,char *name)
1455 %
1456 % A description of each parameter follows:
1457 %
1458 % o tag: a character string representing the module tag.
1459 %
1460 % o name: return the module name here.
1461 %
1462 */
1463 static void TagToCoderModuleName(const char *tag,char *name)
1464 {
1465  assert(tag != (char *) NULL);
1466  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1467  assert(name != (char *) NULL);
1468 #if defined(MAGICKCORE_LTDL_DELEGATE)
1469  (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1470  (void) LocaleLower(name);
1471 #else
1472 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1473  if (LocaleNCompare("IM_MOD_",tag,7) == 0)
1474  (void) CopyMagickString(name,tag,MagickPathExtent);
1475  else
1476  {
1477 #if defined(_DEBUG)
1478  (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag);
1479 #else
1480  (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag);
1481 #endif
1482  }
1483 #endif
1484 #endif
1485 }
1486 
1487 /*
1488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1489 % %
1490 % %
1491 % %
1492 % T a g T o F i l t e r M o d u l e N a m e %
1493 % %
1494 % %
1495 % %
1496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1497 %
1498 % TagToFilterModuleName() munges a module tag and returns the filename of the
1499 % corresponding filter module.
1500 %
1501 % The format of the TagToFilterModuleName module is:
1502 %
1503 % void TagToFilterModuleName(const char *tag,char name)
1504 %
1505 % A description of each parameter follows:
1506 %
1507 % o tag: a character string representing the module tag.
1508 %
1509 % o name: return the filter name here.
1510 %
1511 */
1512 static void TagToFilterModuleName(const char *tag,char *name)
1513 {
1514  assert(tag != (char *) NULL);
1515  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1516  assert(name != (char *) NULL);
1517 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1518  (void) FormatLocaleString(name,MagickPathExtent,"FILTER_%s_.dll",tag);
1519 #elif !defined(MAGICKCORE_LTDL_DELEGATE)
1520  (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag);
1521 #else
1522  (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1523 #endif
1524 }
1525 
1526 /*
1527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1528 % %
1529 % %
1530 % %
1531 % T a g T o M o d u l e N a m e %
1532 % %
1533 % %
1534 % %
1535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1536 %
1537 % TagToModuleName() munges the module tag name and returns an upper-case tag
1538 % name as the input string, and a user-provided format.
1539 %
1540 % The format of the TagToModuleName module is:
1541 %
1542 % TagToModuleName(const char *tag,const char *format,char *module)
1543 %
1544 % A description of each parameter follows:
1545 %
1546 % o tag: the module tag.
1547 %
1548 % o format: a sprintf-compatible format string containing %s where the
1549 % upper-case tag name is to be inserted.
1550 %
1551 % o module: pointer to a destination buffer for the formatted result.
1552 %
1553 */
1554 static void TagToModuleName(const char *tag,const char *format,char *module)
1555 {
1556  char
1557  name[MagickPathExtent];
1558 
1559  assert(tag != (const char *) NULL);
1560  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1561  assert(format != (const char *) NULL);
1562  assert(module != (char *) NULL);
1563  (void) CopyMagickString(name,tag,MagickPathExtent);
1564  LocaleUpper(name);
1565 #if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1566  (void) FormatLocaleString(module,MagickPathExtent,format,name);
1567 #else
1568  {
1569  char
1570  prefix_format[MagickPathExtent];
1571 
1572  (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s",
1573  MAGICKCORE_NAMESPACE_PREFIX_TAG,format);
1574  (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name);
1575  }
1576 #endif
1577 }
1578 
1579 /*
1580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581 % %
1582 % %
1583 % %
1584 % U n r e g i s t e r M o d u l e %
1585 % %
1586 % %
1587 % %
1588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589 %
1590 % UnregisterModule() unloads a module, and invokes its de-registration module.
1591 % Returns MagickTrue on success, and MagickFalse if there is an error.
1592 %
1593 % The format of the UnregisterModule module is:
1594 %
1595 % MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1596 % ExceptionInfo *exception)
1597 %
1598 % A description of each parameter follows:
1599 %
1600 % o module_info: the module info.
1601 %
1602 % o exception: return any errors or warnings in this structure.
1603 %
1604 */
1605 static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1606  ExceptionInfo *exception)
1607 {
1608  /*
1609  Locate and execute UnregisterFORMATImage module.
1610  */
1611  assert(module_info != (const ModuleInfo *) NULL);
1612  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1613  assert(exception != (ExceptionInfo *) NULL);
1614  if (module_info->unregister_module == NULL)
1615  return(MagickTrue);
1616  module_info->unregister_module();
1617  if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
1618  {
1620  "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror());
1621  return(MagickFalse);
1622  }
1623  return(MagickTrue);
1624 }
1625 #else
1626 
1627 #if !defined(MAGICKCORE_BUILD_MODULES)
1628 extern size_t
1629  analyzeImage(Image **,const int,const char **,ExceptionInfo *);
1630 #endif
1631 
1633  ExceptionInfo *magick_unused(exception))
1634 {
1635  return(MagickTrue);
1636 }
1637 
1639  Image **image,const int argc,const char **argv,ExceptionInfo *exception)
1640 {
1641  PolicyRights
1642  rights;
1643 
1644  assert(image != (Image **) NULL);
1645  assert((*image)->signature == MagickCoreSignature);
1646  if ((*image)->debug != MagickFalse)
1647  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1648  rights=ReadPolicyRights;
1650  {
1651  errno=EPERM;
1653  "NotAuthorized","`%s'",tag);
1654  return(MagickFalse);
1655  }
1656 #if defined(MAGICKCORE_BUILD_MODULES)
1657  (void) tag;
1658  (void) argc;
1659  (void) argv;
1660  (void) exception;
1661 #else
1662  {
1664  *image_filter;
1665 
1666  image_filter=(ImageFilterHandler *) NULL;
1667  if (LocaleCompare("analyze",tag) == 0)
1668  image_filter=(ImageFilterHandler *) analyzeImage;
1669  if (image_filter == (ImageFilterHandler *) NULL)
1671  "UnableToLoadModule","`%s'",tag);
1672  else
1673  {
1674  size_t
1675  signature;
1676 
1677  if ((*image)->debug != MagickFalse)
1679  "Invoking \"%s\" static image filter",tag);
1680  signature=image_filter(image,argc,argv,exception);
1681  if ((*image)->debug != MagickFalse)
1682  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"\"%s\" completes",
1683  tag);
1684  if (signature != MagickImageFilterSignature)
1685  {
1687  "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1688  (unsigned long) signature,(unsigned long)
1690  return(MagickFalse);
1691  }
1692  }
1693  }
1694 #endif
1695  return(MagickTrue);
1696 }
1697 #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:594
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)
size_t(* register_module)(void)
Definition: module.h:49
#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:108
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:504
static void * AcquireCriticalMemory(const size_t size)
void(* unregister_module)(void)
Definition: module.h:46
MagickExport void * ResizeQuantumMemory(void *memory, const size_t count, const size_t quantum)
Definition: memory.c:1339
Definition: vms.h:941
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:1632
#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:409
MagickBooleanType
Definition: magick-type.h:156
#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:1493
size_t signature
Definition: module.h:58
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:533
Definition: vms.h:950
MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag, Image **image, const int argc, const char **argv, ExceptionInfo *exception)
Definition: module.c:1638
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1540
#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:353
#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:1064
const char * module
Definition: static.c:70
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1398
MagickExport MagickBooleanType IsPathAccessible(const char *path)
Definition: utility.c:1462
MagickExport const MagickInfo * GetMagickInfo(const char *name, ExceptionInfo *exception)
Definition: magick.c:603
char * type
Definition: mime.c:72
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1262
MagickExport void CatchException(ExceptionInfo *exception)
Definition: exception.c:196
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:1440
#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:157
void * handle
Definition: module.h:45
MagickExport const CoderInfo * GetCoderInfo(const char *name, ExceptionInfo *exception)
Definition: coder.c:472
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:462
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:1054
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:1598
MagickExport char * ConstantString(const char *source)
Definition: string.c:700
#define DirectoryListSeparator
Definition: studio.h:260
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:411
MagickExport const char * GetClientPath(void)
Definition: client.c:87
ExceptionType severity
Definition: exception.h:104