MagickCore  7.0.7
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://www.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) ResetMagickMemory(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  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,
808  DirectorySeparator,DirectorySeparator,filename);
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 #if !defined(MAGICKCORE_BUILD_MODULES)
963  {
965  status;
966 
967  status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
968  if (status != MagickFalse)
969  return(status);
970  }
971 #endif
972  rights=ReadPolicyRights;
974  {
975  errno=EPERM;
977  "NotAuthorized","`%s'",tag);
978  return(MagickFalse);
979  }
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 */
1219 MagickPrivate MagickBooleanType OpenModule(const char *module,
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  register const CoderInfo
1238  *p;
1239 
1240  size_t
1241  signature;
1242 
1243  /*
1244  Assign module name from alias.
1245  */
1246  assert(module != (const char *) NULL);
1247  module_info=(ModuleInfo *) GetModuleInfo(module,exception);
1248  if (module_info != (ModuleInfo *) NULL)
1249  return(MagickTrue);
1250  (void) CopyMagickString(module_name,module,MagickPathExtent);
1251  p=GetCoderInfo(module,exception);
1252  if (p != (CoderInfo *) NULL)
1253  (void) CopyMagickString(module_name,p->name,MagickPathExtent);
1254  if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
1255  return(MagickTrue); /* module already opened, return */
1256  /*
1257  Locate module.
1258  */
1259  handle=(ModuleHandle) NULL;
1260  TagToCoderModuleName(module_name,filename);
1262  "Searching for module \"%s\" using filename \"%s\"",module_name,filename);
1263  *path='\0';
1264  status=GetMagickModulePath(filename,MagickImageCoderModule,path,exception);
1265  if (status == MagickFalse)
1266  return(MagickFalse);
1267  /*
1268  Load module
1269  */
1271  "Opening module at path \"%s\"",path);
1272  handle=(ModuleHandle) lt_dlopen(path);
1273  if (handle == (ModuleHandle) NULL)
1274  {
1276  "UnableToLoadModule","'%s': %s",path,lt_dlerror());
1277  return(MagickFalse);
1278  }
1279  /*
1280  Register module.
1281  */
1282  module_info=AcquireModuleInfo(path,module_name);
1283  module_info->handle=handle;
1284  if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
1285  return(MagickFalse);
1286  /*
1287  Define RegisterFORMATImage method.
1288  */
1289  TagToModuleName(module_name,"Register%sImage",name);
1290  module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name);
1291  if (module_info->register_module == (size_t (*)(void)) NULL)
1292  {
1294  "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1295  return(MagickFalse);
1296  }
1298  "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1299  (void *) module_info->register_module);
1300  /*
1301  Define UnregisterFORMATImage method.
1302  */
1303  TagToModuleName(module_name,"Unregister%sImage",name);
1304  module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
1305  if (module_info->unregister_module == (void (*)(void)) NULL)
1306  {
1308  "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror());
1309  return(MagickFalse);
1310  }
1312  "Method \"%s\" in module \"%s\" at address %p",name,module_name,
1313  (void *) module_info->unregister_module);
1314  signature=module_info->register_module();
1315  if (signature != MagickImageCoderSignature)
1316  {
1318  "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name,
1319  (unsigned long) signature,(unsigned long) MagickImageCoderSignature);
1320  return(MagickFalse);
1321  }
1322  return(MagickTrue);
1323 }
1324 
1325 /*
1326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327 % %
1328 % %
1329 % %
1330 % O p e n M o d u l e s %
1331 % %
1332 % %
1333 % %
1334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1335 %
1336 % OpenModules() loads all available modules.
1337 %
1338 % The format of the OpenModules module is:
1339 %
1340 % MagickBooleanType OpenModules(ExceptionInfo *exception)
1341 %
1342 % A description of each parameter follows:
1343 %
1344 % o exception: return any errors or warnings in this structure.
1345 %
1346 */
1348 {
1349  char
1350  **modules;
1351 
1352  register ssize_t
1353  i;
1354 
1355  size_t
1356  number_modules;
1357 
1358  /*
1359  Load all modules.
1360  */
1361  (void) GetMagickInfo((char *) NULL,exception);
1362  number_modules=0;
1363  modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception);
1364  if ((modules == (char **) NULL) || (*modules == (char *) NULL))
1365  {
1366  if (modules != (char **) NULL)
1367  modules=(char **) RelinquishMagickMemory(modules);
1368  return(MagickFalse);
1369  }
1370  for (i=0; i < (ssize_t) number_modules; i++)
1371  (void) OpenModule(modules[i],exception);
1372  /*
1373  Relinquish resources.
1374  */
1375  for (i=0; i < (ssize_t) number_modules; i++)
1376  modules[i]=DestroyString(modules[i]);
1377  modules=(char **) RelinquishMagickMemory(modules);
1378  return(MagickTrue);
1379 }
1380 
1381 /*
1382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1383 % %
1384 % %
1385 % %
1386 % R e g i s t e r M o d u l e %
1387 % %
1388 % %
1389 % %
1390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391 %
1392 % RegisterModule() adds an entry to the module list. It returns a pointer to
1393 % the registered entry on success.
1394 %
1395 % The format of the RegisterModule module is:
1396 %
1397 % ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1398 % ExceptionInfo *exception)
1399 %
1400 % A description of each parameter follows:
1401 %
1402 % o info: a pointer to the registered entry is returned.
1403 %
1404 % o module_info: a pointer to the ModuleInfo structure to register.
1405 %
1406 % o exception: return any errors or warnings in this structure.
1407 %
1408 */
1409 static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
1410  ExceptionInfo *exception)
1411 {
1413  status;
1414 
1415  assert(module_info != (ModuleInfo *) NULL);
1416  assert(module_info->signature == MagickCoreSignature);
1417  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1418  if (module_list == (SplayTreeInfo *) NULL)
1419  return((const ModuleInfo *) NULL);
1420  status=AddValueToSplayTree(module_list,module_info->tag,module_info);
1421  if (status == MagickFalse)
1423  "MemoryAllocationFailed","`%s'",module_info->tag);
1424  return(module_info);
1425 }
1426 
1427 /*
1428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1429 % %
1430 % %
1431 % %
1432 % T a g T o C o d e r M o d u l e N a m e %
1433 % %
1434 % %
1435 % %
1436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1437 %
1438 % TagToCoderModuleName() munges a module tag and obtains the filename of the
1439 % corresponding module.
1440 %
1441 % The format of the TagToCoderModuleName module is:
1442 %
1443 % char *TagToCoderModuleName(const char *tag,char *name)
1444 %
1445 % A description of each parameter follows:
1446 %
1447 % o tag: a character string representing the module tag.
1448 %
1449 % o name: return the module name here.
1450 %
1451 */
1452 static void TagToCoderModuleName(const char *tag,char *name)
1453 {
1454  assert(tag != (char *) NULL);
1455  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1456  assert(name != (char *) NULL);
1457 #if defined(MAGICKCORE_LTDL_DELEGATE)
1458  (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1459  (void) LocaleLower(name);
1460 #else
1461 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1462  if (LocaleNCompare("IM_MOD_",tag,7) == 0)
1463  (void) CopyMagickString(name,tag,MagickPathExtent);
1464  else
1465  {
1466 #if defined(_DEBUG)
1467  (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag);
1468 #else
1469  (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag);
1470 #endif
1471  }
1472 #endif
1473 #endif
1474 }
1475 
1476 /*
1477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1478 % %
1479 % %
1480 % %
1481 % T a g T o F i l t e r M o d u l e N a m e %
1482 % %
1483 % %
1484 % %
1485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1486 %
1487 % TagToFilterModuleName() munges a module tag and returns the filename of the
1488 % corresponding filter module.
1489 %
1490 % The format of the TagToFilterModuleName module is:
1491 %
1492 % void TagToFilterModuleName(const char *tag,char name)
1493 %
1494 % A description of each parameter follows:
1495 %
1496 % o tag: a character string representing the module tag.
1497 %
1498 % o name: return the filter name here.
1499 %
1500 */
1501 static void TagToFilterModuleName(const char *tag,char *name)
1502 {
1503  assert(tag != (char *) NULL);
1504  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1505  assert(name != (char *) NULL);
1506 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1507  (void) FormatLocaleString(name,MagickPathExtent,"FILTER_%s_.dll",tag);
1508 #elif !defined(MAGICKCORE_LTDL_DELEGATE)
1509  (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag);
1510 #else
1511  (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag);
1512 #endif
1513 }
1514 
1515 /*
1516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1517 % %
1518 % %
1519 % %
1520 % T a g T o M o d u l e N a m e %
1521 % %
1522 % %
1523 % %
1524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1525 %
1526 % TagToModuleName() munges the module tag name and returns an upper-case tag
1527 % name as the input string, and a user-provided format.
1528 %
1529 % The format of the TagToModuleName module is:
1530 %
1531 % TagToModuleName(const char *tag,const char *format,char *module)
1532 %
1533 % A description of each parameter follows:
1534 %
1535 % o tag: the module tag.
1536 %
1537 % o format: a sprintf-compatible format string containing %s where the
1538 % upper-case tag name is to be inserted.
1539 %
1540 % o module: pointer to a destination buffer for the formatted result.
1541 %
1542 */
1543 static void TagToModuleName(const char *tag,const char *format,char *module)
1544 {
1545  char
1546  name[MagickPathExtent];
1547 
1548  assert(tag != (const char *) NULL);
1549  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
1550  assert(format != (const char *) NULL);
1551  assert(module != (char *) NULL);
1552  (void) CopyMagickString(name,tag,MagickPathExtent);
1553  LocaleUpper(name);
1554 #if !defined(MAGICKCORE_NAMESPACE_PREFIX)
1555  (void) FormatLocaleString(module,MagickPathExtent,format,name);
1556 #else
1557  {
1558  char
1559  prefix_format[MagickPathExtent];
1560 
1561  (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s",
1562  MAGICKCORE_NAMESPACE_PREFIX_TAG,format);
1563  (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name);
1564  }
1565 #endif
1566 }
1567 
1568 /*
1569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570 % %
1571 % %
1572 % %
1573 % U n r e g i s t e r M o d u l e %
1574 % %
1575 % %
1576 % %
1577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1578 %
1579 % UnregisterModule() unloads a module, and invokes its de-registration module.
1580 % Returns MagickTrue on success, and MagickFalse if there is an error.
1581 %
1582 % The format of the UnregisterModule module is:
1583 %
1584 % MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1585 % ExceptionInfo *exception)
1586 %
1587 % A description of each parameter follows:
1588 %
1589 % o module_info: the module info.
1590 %
1591 % o exception: return any errors or warnings in this structure.
1592 %
1593 */
1594 static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
1595  ExceptionInfo *exception)
1596 {
1597  /*
1598  Locate and execute UnregisterFORMATImage module.
1599  */
1600  assert(module_info != (const ModuleInfo *) NULL);
1601  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
1602  assert(exception != (ExceptionInfo *) NULL);
1603  if (module_info->unregister_module == NULL)
1604  return(MagickTrue);
1605  module_info->unregister_module();
1606  if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
1607  {
1609  "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror());
1610  return(MagickFalse);
1611  }
1612  return(MagickTrue);
1613 }
1614 #else
1615 
1616 #if !defined(MAGICKCORE_BUILD_MODULES)
1617 extern size_t
1618  analyzeImage(Image **,const int,const char **,ExceptionInfo *);
1619 #endif
1620 
1622  ExceptionInfo *magick_unused(exception))
1623 {
1624  return(MagickTrue);
1625 }
1626 
1628  Image **image,const int argc,const char **argv,ExceptionInfo *exception)
1629 {
1630  PolicyRights
1631  rights;
1632 
1633  assert(image != (Image **) NULL);
1634  assert((*image)->signature == MagickCoreSignature);
1635  if ((*image)->debug != MagickFalse)
1636  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1637  rights=ReadPolicyRights;
1639  {
1640  errno=EPERM;
1642  "NotAuthorized","`%s'",tag);
1643  return(MagickFalse);
1644  }
1645 #if defined(MAGICKCORE_BUILD_MODULES)
1646  (void) tag;
1647  (void) argc;
1648  (void) argv;
1649  (void) exception;
1650 #else
1651  {
1653  *image_filter;
1654 
1655  image_filter=(ImageFilterHandler *) NULL;
1656  if (LocaleCompare("analyze",tag) == 0)
1657  image_filter=(ImageFilterHandler *) analyzeImage;
1658  if (image_filter == (ImageFilterHandler *) NULL)
1660  "UnableToLoadModule","`%s'",tag);
1661  else
1662  {
1663  size_t
1664  signature;
1665 
1666  if ((*image)->debug != MagickFalse)
1668  "Invoking \"%s\" static image filter",tag);
1669  signature=image_filter(image,argc,argv,exception);
1670  if ((*image)->debug != MagickFalse)
1671  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"\"%s\" completes",
1672  tag);
1673  if (signature != MagickImageFilterSignature)
1674  {
1676  "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
1677  (unsigned long) signature,(unsigned long)
1679  return(MagickFalse);
1680  }
1681  }
1682  }
1683 #endif
1684  return(MagickTrue);
1685 }
1686 #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:589
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
char d_name[255]
Definition: vms.h:944
PolicyRights
Definition: policy.h:40
#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:410
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:473
void(* unregister_module)(void)
Definition: module.h:46
MagickExport void * ResizeQuantumMemory(void *memory, const size_t count, const size_t quantum)
Definition: memory.c:1277
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:1621
#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:378
MagickBooleanType
Definition: magick-type.h:156
#define DirectorySeparator
Definition: studio.h:254
MagickExport char * AcquireString(const char *source)
Definition: string.c:124
MagickPrivate MagickBooleanType ModuleComponentGenesis(void)
MagickExport void LocaleLower(char *string)
Definition: locale.c:1462
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1164
size_t signature
Definition: module.h:58
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
Definition: vms.h:950
MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag, Image **image, const int argc, const char **argv, ExceptionInfo *exception)
Definition: module.c:1627
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1509
#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:349
#define MagickPathExtent
MagickExport MagickBooleanType static void * AcquireCriticalMemory(const size_t size)
#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:1058
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:1466
MagickExport const MagickInfo * GetMagickInfo(const char *name, ExceptionInfo *exception)
Definition: magick.c:597
char * type
Definition: mime.c:72
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1250
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:742
MagickExport const void * GetValueFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:921
#define PATH_MAX
Definition: studio.h:324
MagickModuleType
Definition: module.h:32
MagickPrivate MagickBooleanType OpenModules(ExceptionInfo *)
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1409
#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:471
MagickExport char * DestroyString(char *string)
Definition: string.c:810
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:458
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:1038
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:1567
MagickExport char * ConstantString(const char *source)
Definition: string.c:687
#define DirectoryListSeparator
Definition: studio.h:255
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:417
MagickExport const char * GetClientPath(void)
Definition: client.c:87
ExceptionType severity
Definition: exception.h:104