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