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