PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/ImageMagick-6.3.2/magick/module.c

https://bitbucket.org/sisko/operation-caribou
C | 1459 lines | 871 code | 63 blank | 525 comment | 199 complexity | 2231e47334bace0eac572bb18bcf1824 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1
  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. % ImageMagick Module Methods %
  14. % %
  15. % Software Design %
  16. % Bob Friesenhahn %
  17. % March 2000 %
  18. % %
  19. % %
  20. % Copyright 1999-2006 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. % http://www.imagemagick.org/script/license.php %
  27. % %
  28. % Unless required by applicable law or agreed to in writing, software %
  29. % distributed under the License is distributed on an "AS IS" BASIS, %
  30. % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
  31. % See the License for the specific language governing permissions and %
  32. % limitations under the License. %
  33. % %
  34. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  35. %
  36. %
  37. %
  38. */
  39. /*
  40. Include declarations.
  41. */
  42. #include "magick/studio.h"
  43. #include "magick/blob.h"
  44. #include "magick/coder.h"
  45. #include "magick/client.h"
  46. #include "magick/configure.h"
  47. #include "magick/exception.h"
  48. #include "magick/exception-private.h"
  49. #include "magick/log.h"
  50. #include "magick/hashmap.h"
  51. #include "magick/magic.h"
  52. #include "magick/magick.h"
  53. #include "magick/memory_.h"
  54. #include "magick/module.h"
  55. #include "magick/semaphore.h"
  56. #include "magick/splay-tree.h"
  57. #include "magick/static.h"
  58. #include "magick/string_.h"
  59. #include "magick/token.h"
  60. #include "magick/utility.h"
  61. #if defined(SupportMagickModules)
  62. #if defined(HasLTDL)
  63. #include "ltdl.h"
  64. typedef lt_dlhandle ModuleHandle;
  65. #else
  66. typedef void *ModuleHandle;
  67. #endif
  68. /*
  69. Define declarations.
  70. */
  71. #if defined(HasLTDL)
  72. # define ModuleGlobExpression "*.la"
  73. #else
  74. # if defined(_DEBUG)
  75. # define ModuleGlobExpression "IM_MOD_DB_*.dll"
  76. # else
  77. # define ModuleGlobExpression "IM_MOD_RL_*.dll"
  78. # endif
  79. #endif
  80. /*
  81. Global declarations.
  82. */
  83. static SemaphoreInfo
  84. *module_semaphore = (SemaphoreInfo *) NULL;
  85. static SplayTreeInfo
  86. *module_list = (SplayTreeInfo *) NULL;
  87. static volatile MagickBooleanType
  88. instantiate_module = MagickFalse;
  89. /*
  90. Forward declarations.
  91. */
  92. static const ModuleInfo
  93. *RegisterModule(const ModuleInfo *,ExceptionInfo *);
  94. static MagickBooleanType
  95. GetMagickModulePath(const char *,MagickModuleType,char *,ExceptionInfo *),
  96. InitializeModuleList(ExceptionInfo *),
  97. UnregisterModule(const ModuleInfo *,ExceptionInfo *);
  98. static void
  99. TagToCoderModuleName(const char *,char *),
  100. TagToFilterModuleName(const char *,char *),
  101. TagToModuleName(const char *,const char *,char *);
  102. /*
  103. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  104. % %
  105. % %
  106. % %
  107. % D e s t r o y M o d u l e L i s t %
  108. % %
  109. % %
  110. % %
  111. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  112. %
  113. % DestroyMagickList() unregisters any previously loaded modules and exits
  114. % the module loaded environment.
  115. %
  116. % The format of the DestroyMagickList module is:
  117. %
  118. % void DestroyMagickList(void)
  119. %
  120. */
  121. MagickExport void DestroyModuleList(void)
  122. {
  123. /*
  124. Deestroy magick modules.
  125. */
  126. AcquireSemaphoreInfo(&module_semaphore);
  127. #if defined(SupportMagickModules)
  128. if (module_list != (SplayTreeInfo *) NULL)
  129. module_list=DestroySplayTree(module_list);
  130. if (instantiate_module != MagickFalse)
  131. (void) lt_dlexit();
  132. #endif
  133. instantiate_module=MagickFalse;
  134. RelinquishSemaphoreInfo(module_semaphore);
  135. module_semaphore=DestroySemaphoreInfo(module_semaphore);
  136. }
  137. /*
  138. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  139. % %
  140. % %
  141. % %
  142. % E x e c u t e M o d u l e P r o c e s s %
  143. % %
  144. % %
  145. % %
  146. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  147. %
  148. % ExecuteModuleProcess() executes a dynamic modules.
  149. %
  150. % The format of the ExecuteModuleProcess module is:
  151. %
  152. % MagickBooleanType ExecuteModuleProcess(const char *tag,Image **image,
  153. % const int argc,char **argv)
  154. %
  155. % A description of each parameter follows:
  156. %
  157. % o tag: a character string that represents the name of the particular
  158. % module.
  159. %
  160. % o image: The image.
  161. %
  162. % o argc: Specifies a pointer to an integer describing the number of
  163. % elements in the argument vector.
  164. %
  165. % o argv: Specifies a pointer to a text array containing the command line
  166. % arguments.
  167. %
  168. */
  169. MagickExport MagickBooleanType ExecuteModuleProcess(const char *tag,
  170. Image **image,const int argc,char **argv)
  171. {
  172. char
  173. name[MaxTextExtent],
  174. path[MaxTextExtent];
  175. MagickBooleanType
  176. (*module)(Image **,const int,char **),
  177. status;
  178. ModuleHandle
  179. handle;
  180. size_t
  181. length;
  182. /*
  183. Find the module.
  184. */
  185. assert(image != (Image **) NULL);
  186. assert((*image)->signature == MagickSignature);
  187. if ((*image)->debug != MagickFalse)
  188. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
  189. #if !defined(BuildMagickModules)
  190. status=ExecuteStaticModuleProcess(tag,image,argc,argv);
  191. if (status != MagickFalse)
  192. return(status);
  193. #endif
  194. status=MagickFalse;
  195. TagToFilterModuleName(tag,name);
  196. length=GetMagickModulePath(name,MagickFilterModule,path,&(*image)->exception);
  197. if (length == 0)
  198. return(MagickFalse);
  199. /*
  200. Open the module.
  201. */
  202. handle=lt_dlopen(path);
  203. if (handle == (ModuleHandle) NULL)
  204. {
  205. (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
  206. ModuleError,"UnableToLoadModule","`%s': %s",name,lt_dlerror());
  207. return(status);
  208. }
  209. /*
  210. Locate the module.
  211. */
  212. #if !defined(MagickMethodPrefix)
  213. (void) FormatMagickString(name,MaxTextExtent,"%sImage",tag);
  214. #else
  215. (void) FormatMagickString(name,MaxTextExtent,"%s%sImage",MagickMethodPrefix,
  216. tag);
  217. #endif
  218. /*
  219. Execute the module.
  220. */
  221. module=(MagickBooleanType (*)(Image **,const int,char **))
  222. lt_dlsym(handle,name);
  223. if (module == (MagickBooleanType (*)(Image **,const int,char **)) NULL)
  224. (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
  225. ModuleError,"UnableToLoadModule","`%s': %s",name,lt_dlerror());
  226. else
  227. {
  228. if ((*image)->debug != MagickFalse)
  229. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  230. "Invoking \"%s\" dynamic filter module",tag);
  231. status=(*module)(image,argc,argv);
  232. if ((*image)->debug != MagickFalse)
  233. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
  234. tag);
  235. }
  236. /*
  237. Close the module.
  238. */
  239. (void) lt_dlclose(handle);
  240. return(status);
  241. }
  242. /*
  243. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  244. % %
  245. % %
  246. % %
  247. % G e t M o d u l e I n f o %
  248. % %
  249. % %
  250. % %
  251. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  252. %
  253. % GetModuleInfo() returns a pointer to a ModuleInfo structure that matches the
  254. % specified tag. If tag is NULL, the head of the module list is returned. If
  255. % no modules are loaded, or the requested module is not found, NULL is
  256. % returned.
  257. %
  258. % The format of the GetModuleInfo module is:
  259. %
  260. % const ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception)
  261. %
  262. % A description of each parameter follows:
  263. %
  264. % o tag: a character string that represents the image format we are
  265. % looking for.
  266. %
  267. % o exception: Return any errors or warnings in this structure.
  268. %
  269. %
  270. */
  271. MagickExport const ModuleInfo *GetModuleInfo(const char *tag,
  272. ExceptionInfo *exception)
  273. {
  274. if ((module_list == (SplayTreeInfo *) NULL) ||
  275. (instantiate_module == MagickFalse))
  276. if (InitializeModuleList(exception) == MagickFalse)
  277. return((const ModuleInfo *) NULL);
  278. if ((module_list == (SplayTreeInfo *) NULL) ||
  279. (GetNumberOfNodesInSplayTree(module_list) == 0))
  280. return((const ModuleInfo *) NULL);
  281. if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
  282. {
  283. #if defined(SupportMagickModules)
  284. if (LocaleCompare(tag,"*") == 0)
  285. (void) OpenModules(exception);
  286. #endif
  287. ResetSplayTreeIterator(module_list);
  288. return((const ModuleInfo *) GetNextValueInSplayTree(module_list));
  289. }
  290. return((const ModuleInfo *) GetValueFromSplayTree(module_list,tag));
  291. }
  292. /*
  293. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  294. % %
  295. % %
  296. % %
  297. % G e t M o d u l e I n f o L i s t %
  298. % %
  299. % %
  300. % %
  301. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  302. %
  303. % GetModuleInfoList() returns any modules that match the specified pattern.
  304. %
  305. % The format of the GetModuleInfoList function is:
  306. %
  307. % const ModuleInfo **GetModuleInfoList(const char *pattern,
  308. % unsigned long *number_modules,ExceptionInfo *exception)
  309. %
  310. % A description of each parameter follows:
  311. %
  312. % o pattern: Specifies a pointer to a text string containing a pattern.
  313. %
  314. % o number_modules: This integer returns the number of modules in the list.
  315. %
  316. % o exception: Return any errors or warnings in this structure.
  317. %
  318. */
  319. #if defined(__cplusplus) || defined(c_plusplus)
  320. extern "C" {
  321. #endif
  322. static int ModuleInfoCompare(const void *x,const void *y)
  323. {
  324. const ModuleInfo
  325. **p,
  326. **q;
  327. p=(const ModuleInfo **) x,
  328. q=(const ModuleInfo **) y;
  329. if (LocaleCompare((*p)->path,(*q)->path) == 0)
  330. return(LocaleCompare((*p)->tag,(*q)->tag));
  331. return(LocaleCompare((*p)->path,(*q)->path));
  332. }
  333. #if defined(__cplusplus) || defined(c_plusplus)
  334. }
  335. #endif
  336. MagickExport const ModuleInfo **GetModuleInfoList(const char *pattern,
  337. unsigned long *number_modules,ExceptionInfo *exception)
  338. {
  339. const ModuleInfo
  340. **modules;
  341. register const ModuleInfo
  342. *p;
  343. register long
  344. i;
  345. /*
  346. Allocate module list.
  347. */
  348. assert(pattern != (char *) NULL);
  349. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
  350. assert(number_modules != (unsigned long *) NULL);
  351. *number_modules=0;
  352. p=GetModuleInfo("*",exception);
  353. if (p == (const ModuleInfo *) NULL)
  354. return((const ModuleInfo **) NULL);
  355. modules=(const ModuleInfo **) AcquireMagickMemory((size_t)
  356. (GetNumberOfNodesInSplayTree(module_list)+1)*sizeof(*modules));
  357. if (modules == (const ModuleInfo **) NULL)
  358. return((const ModuleInfo **) NULL);
  359. /*
  360. Generate module list.
  361. */
  362. AcquireSemaphoreInfo(&module_semaphore);
  363. ResetSplayTreeIterator(module_list);
  364. p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
  365. for (i=0; p != (const ModuleInfo *) NULL; )
  366. {
  367. if ((p->stealth == MagickFalse) &&
  368. (GlobExpression(p->tag,pattern) != MagickFalse))
  369. modules[i++]=p;
  370. p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
  371. }
  372. RelinquishSemaphoreInfo(module_semaphore);
  373. qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleInfoCompare);
  374. modules[i]=(ModuleInfo *) NULL;
  375. *number_modules=(unsigned long) i;
  376. return(modules);
  377. }
  378. /*
  379. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  380. % %
  381. % %
  382. % %
  383. % G e t M o d u l e L i s t %
  384. % %
  385. % %
  386. % %
  387. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  388. %
  389. % GetModuleList() returns any image format modules that match the specified
  390. % pattern.
  391. %
  392. % The format of the GetModuleList function is:
  393. %
  394. % char **GetModuleList(const char *pattern,unsigned long *number_modules,
  395. % ExceptionInfo *exception)
  396. %
  397. % A description of each parameter follows:
  398. %
  399. % o pattern: Specifies a pointer to a text string containing a pattern.
  400. %
  401. % o number_modules: This integer returns the number of modules in the
  402. % list.
  403. %
  404. % o exception: Return any errors or warnings in this structure.
  405. %
  406. */
  407. #if defined(__cplusplus) || defined(c_plusplus)
  408. extern "C" {
  409. #endif
  410. static int ModuleCompare(const void *x,const void *y)
  411. {
  412. register const char
  413. **p,
  414. **q;
  415. p=(const char **) x;
  416. q=(const char **) y;
  417. return(LocaleCompare(*p,*q));
  418. }
  419. #if defined(__cplusplus) || defined(c_plusplus)
  420. }
  421. #endif
  422. MagickExport char **GetModuleList(const char *pattern,
  423. unsigned long *number_modules,ExceptionInfo *exception)
  424. {
  425. char
  426. **modules,
  427. filename[MaxTextExtent],
  428. module_path[MaxTextExtent],
  429. path[MaxTextExtent];
  430. DIR
  431. *directory;
  432. register long
  433. i;
  434. size_t
  435. length;
  436. struct dirent
  437. *entry;
  438. unsigned long
  439. max_entries;
  440. /*
  441. Locate all modules in the coder path.
  442. */
  443. TagToCoderModuleName("magick",filename);
  444. length=GetMagickModulePath(filename,MagickCoderModule,module_path,
  445. exception);
  446. if (length == 0)
  447. return((char **) NULL);
  448. GetPathComponent(module_path,HeadPath,path);
  449. max_entries=255;
  450. modules=(char **)
  451. AcquireMagickMemory((size_t) (max_entries+1)*sizeof(*modules));
  452. if (modules == (char **) NULL)
  453. return((char **) NULL);
  454. *modules=(char *) NULL;
  455. directory=opendir(path);
  456. if (directory == (DIR *) NULL)
  457. return((char **) NULL);
  458. i=0;
  459. entry=readdir(directory);
  460. while (entry != (struct dirent *) NULL)
  461. {
  462. if (GlobExpression(entry->d_name,ModuleGlobExpression) == MagickFalse)
  463. {
  464. entry=readdir(directory);
  465. continue;
  466. }
  467. if (GlobExpression(entry->d_name,pattern) == MagickFalse)
  468. continue;
  469. if (i >= (long) max_entries)
  470. {
  471. max_entries<<=1;
  472. modules=(char **)
  473. ResizeMagickMemory(modules,(size_t) max_entries*sizeof(*modules));
  474. if (modules == (char **) NULL)
  475. break;
  476. }
  477. /*
  478. Add new module name to list.
  479. */
  480. modules[i]=AcquireString((char *) NULL);
  481. GetPathComponent(entry->d_name,BasePath,modules[i]);
  482. LocaleUpper(modules[i]);
  483. if (LocaleNCompare("IM_MOD_",modules[i],7) == 0)
  484. {
  485. (void) CopyMagickString(modules[i],modules[i]+10,MaxTextExtent);
  486. modules[i][strlen(modules[i])-1]='\0';
  487. }
  488. i++;
  489. entry=readdir(directory);
  490. }
  491. (void) closedir(directory);
  492. qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleCompare);
  493. modules[i]=(char *) NULL;
  494. *number_modules=(unsigned long) i;
  495. return(modules);
  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: MagickCoderModule or MagickFilterModule.
  521. %
  522. % o path: The path associated with the filename.
  523. %
  524. % o exception: Return any errors or warnings in this structure.
  525. %
  526. %
  527. */
  528. static MagickBooleanType GetMagickModulePath(const char *filename,
  529. MagickModuleType module_type,char *path,ExceptionInfo *exception)
  530. {
  531. char
  532. *module_path;
  533. assert(filename != (const char *) NULL);
  534. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
  535. assert(path != (char *) NULL);
  536. assert(exception != (ExceptionInfo *) NULL);
  537. (void) CopyMagickString(path,filename,MaxTextExtent);
  538. module_path=(char *) NULL;
  539. switch (module_type)
  540. {
  541. case MagickCoderModule:
  542. default:
  543. {
  544. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  545. "Searching for coder module file \"%s\" ...",filename);
  546. module_path=GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");
  547. break;
  548. }
  549. case MagickFilterModule:
  550. {
  551. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  552. "Searching for filter module file \"%s\" ...",filename);
  553. module_path=GetEnvironmentValue("MAGICK_CODER_FILTER_PATH");
  554. break;
  555. }
  556. }
  557. if (module_path != (char *) NULL)
  558. {
  559. register char
  560. *p,
  561. *q;
  562. for (p=module_path-1; p != (char *) NULL; )
  563. {
  564. (void) CopyMagickString(path,p+1,MaxTextExtent);
  565. q=strchr(path,DirectoryListSeparator);
  566. if (q != (char *) NULL)
  567. *q='\0';
  568. q=path+strlen(path)-1;
  569. if ((q >= path) && (*q != *DirectorySeparator))
  570. (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
  571. (void) ConcatenateMagickString(path,filename,MaxTextExtent);
  572. if (IsAccessible(path) != MagickFalse)
  573. {
  574. module_path=(char *) RelinquishMagickMemory(module_path);
  575. return(MagickTrue);
  576. }
  577. p=strchr(p+1,DirectoryListSeparator);
  578. }
  579. module_path=(char *) RelinquishMagickMemory(module_path);
  580. }
  581. #if defined(UseInstalledMagick)
  582. #if defined(MagickCoderModulesPath)
  583. {
  584. const char
  585. *directory;
  586. /*
  587. Search hard coded paths.
  588. */
  589. switch (module_type)
  590. {
  591. case MagickCoderModule:
  592. default:
  593. {
  594. directory=MagickCoderModulesPath;
  595. break;
  596. }
  597. case MagickFilterModule:
  598. {
  599. directory=MagickFilterModulesPath;
  600. break;
  601. }
  602. }
  603. (void) FormatMagickString(path,MaxTextExtent,"%s%s",directory,filename);
  604. if (IsAccessible(path) == MagickFalse)
  605. {
  606. ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
  607. path);
  608. return(MagickFalse);
  609. }
  610. return(MagickTrue);
  611. }
  612. #else
  613. #if defined(__WINDOWS__)
  614. {
  615. const char
  616. *key,
  617. *value;
  618. /*
  619. Locate path via registry key.
  620. */
  621. switch (module_type)
  622. {
  623. case MagickCoderModule:
  624. default:
  625. {
  626. key="CoderModulesPath";
  627. break;
  628. }
  629. case MagickFilterModule:
  630. {
  631. key="FilterModulesPath";
  632. break;
  633. }
  634. }
  635. value=NTRegistryKeyLookup(key);
  636. if (value == (char *) NULL)
  637. {
  638. ThrowMagickException(exception,GetMagickModule(),ConfigureError,
  639. "RegistryKeyLookupFailed","`%s'",key);
  640. return (MagickFalse);
  641. }
  642. (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",value,
  643. DirectorySeparator,filename);
  644. if (IsAccessible(path) == MagickFalse)
  645. {
  646. ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
  647. path);
  648. return(MagickFalse);
  649. }
  650. return(MagickTrue);
  651. }
  652. #endif
  653. #endif
  654. #if !defined(MagickCoderModulesPath) && !defined(__WINDOWS__)
  655. # error MagickCoderModulesPath or __WINDOWS__ must be defined when UseInstalledMagick is defined
  656. #endif
  657. #else
  658. {
  659. char
  660. *home;
  661. home=GetEnvironmentValue("MAGICK_HOME");
  662. if (home != (char *) NULL)
  663. {
  664. /*
  665. Search MAGICK_HOME.
  666. */
  667. #if !defined(POSIX)
  668. (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",home,
  669. DirectorySeparator,filename);
  670. #else
  671. const char
  672. *directory;
  673. switch (module_type)
  674. {
  675. case MagickCoderModule:
  676. default:
  677. {
  678. directory=MagickCoderModulesSubdir;
  679. break;
  680. }
  681. case MagickFilterModule:
  682. {
  683. directory=MagickFilterModulesSubdir;
  684. break;
  685. }
  686. }
  687. (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/%s",home,
  688. directory,filename);
  689. #endif
  690. home=(char *) RelinquishMagickMemory(home);
  691. if (IsAccessible(path) != MagickFalse)
  692. return(MagickTrue);
  693. }
  694. }
  695. if (*GetClientPath() != '\0')
  696. {
  697. /*
  698. Search based on executable directory.
  699. */
  700. #if !defined(POSIX)
  701. (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
  702. DirectorySeparator,filename);
  703. #else
  704. char
  705. prefix[MaxTextExtent];
  706. const char
  707. *directory;
  708. switch (module_type)
  709. {
  710. case MagickCoderModule:
  711. default:
  712. {
  713. directory="modules";
  714. break;
  715. }
  716. case MagickFilterModule:
  717. {
  718. directory="filters";
  719. break;
  720. }
  721. }
  722. (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
  723. ChopPathComponents(prefix,1);
  724. (void) FormatMagickString(path,MaxTextExtent,
  725. "%s/lib/%s/modules-Q%d/%s/%s",prefix,MagickLibSubdir,QuantumDepth,
  726. directory,filename);
  727. #endif
  728. if (IsAccessible(path) != MagickFalse)
  729. return(MagickTrue);
  730. }
  731. #if defined(__WINDOWS__)
  732. {
  733. /*
  734. Search module path.
  735. */
  736. if (NTGetModulePath("CORE_RL_magick_.dll",path) != MagickFalse)
  737. if (IsAccessible(path) != MagickFalse)
  738. return(MagickTrue);
  739. if (NTGetModulePath("Magick.dll",path) != MagickFalse)
  740. if (IsAccessible(path) != MagickFalse)
  741. return(MagickTrue);
  742. }
  743. #endif
  744. {
  745. char
  746. *home;
  747. home=GetEnvironmentValue("HOME");
  748. if (home == (char *) NULL)
  749. home=GetEnvironmentValue("USERPROFILE");
  750. if (home != (char *) NULL)
  751. {
  752. /*
  753. Search $HOME/.magick.
  754. */
  755. (void) FormatMagickString(path,MaxTextExtent,"%s%s%s%s",home,
  756. *home == '/' ? "/.magick" : "",DirectorySeparator,filename);
  757. home=(char *) RelinquishMagickMemory(home);
  758. if (IsAccessible(path) != MagickFalse)
  759. return(MagickTrue);
  760. }
  761. }
  762. /*
  763. Search current directory.
  764. */
  765. if (IsAccessible(path) != MagickFalse)
  766. return(MagickTrue);
  767. if (exception->severity < ConfigureError)
  768. ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
  769. path);
  770. return(MagickFalse);
  771. #endif
  772. }
  773. /*
  774. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  775. % %
  776. % %
  777. % %
  778. + I n i t i a l i z e M o d u l e L i s t %
  779. % %
  780. % %
  781. % %
  782. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  783. %
  784. % InitializeModuleList() initializes the module loader.
  785. %
  786. % The format of the InitializeModuleList() method is:
  787. %
  788. % InitializeModuleList(Exceptioninfo *exception)
  789. %
  790. % A description of each parameter follows.
  791. %
  792. % o exception: Return any errors or warnings in this structure.
  793. %
  794. %
  795. */
  796. static void *DestroyModuleNode(void *module_info)
  797. {
  798. ExceptionInfo
  799. exception;
  800. register ModuleInfo
  801. *p;
  802. GetExceptionInfo(&exception);
  803. p=(ModuleInfo *) module_info;
  804. if (UnregisterModule(p,&exception) == MagickFalse)
  805. CatchException(&exception);
  806. if (p->tag != (char *) NULL)
  807. p->tag=(char *) RelinquishMagickMemory(p->tag);
  808. if (p->path != (char *) NULL)
  809. p->path=(char *) RelinquishMagickMemory(p->path);
  810. (void) DestroyExceptionInfo(&exception);
  811. return(RelinquishMagickMemory(p));
  812. }
  813. static MagickBooleanType InitializeModuleList(
  814. ExceptionInfo *magick_unused(exception))
  815. {
  816. if ((module_list == (SplayTreeInfo *) NULL) &&
  817. (instantiate_module == MagickFalse))
  818. {
  819. AcquireSemaphoreInfo(&module_semaphore);
  820. if ((module_list == (SplayTreeInfo *) NULL) &&
  821. (instantiate_module == MagickFalse))
  822. {
  823. MagickBooleanType
  824. status;
  825. ModuleInfo
  826. *module_info;
  827. module_list=NewSplayTree(CompareSplayTreeString,
  828. RelinquishMagickMemory,DestroyModuleNode);
  829. if (module_list == (SplayTreeInfo *) NULL)
  830. {
  831. char
  832. *message;
  833. message=GetExceptionMessage(errno);
  834. ThrowMagickFatalException(ResourceLimitFatalError,
  835. "MemoryAllocationFailed",message);
  836. message=(char *) RelinquishMagickMemory(message);
  837. }
  838. module_info=(ModuleInfo *) AcquireMagickMemory(sizeof(*module_info));
  839. if (module_info == (ModuleInfo *) NULL)
  840. {
  841. char
  842. *message;
  843. message=GetExceptionMessage(errno);
  844. ThrowMagickFatalException(ResourceLimitFatalError,
  845. "MemoryAllocationFailed",message);
  846. message=(char *) RelinquishMagickMemory(message);
  847. }
  848. (void) ResetMagickMemory(module_info,0,sizeof(*module_info));
  849. module_info->tag=ConstantString("[boot-strap]");
  850. module_info->stealth=MagickTrue;
  851. (void) time(&module_info->load_time);
  852. module_info->signature=MagickSignature;
  853. status=AddValueToSplayTree(module_list,
  854. ConstantString(module_info->tag),module_info);
  855. if (status == MagickFalse)
  856. {
  857. char
  858. *message;
  859. message=GetExceptionMessage(errno);
  860. ThrowMagickFatalException(ResourceLimitFatalError,
  861. "MemoryAllocationFailed",message);
  862. message=(char *) RelinquishMagickMemory(message);
  863. }
  864. if (lt_dlinit() != 0)
  865. ThrowMagickFatalException(ModuleFatalError,
  866. "UnableToInitializeModuleLoader",lt_dlerror());
  867. instantiate_module=MagickTrue;
  868. }
  869. RelinquishSemaphoreInfo(module_semaphore);
  870. }
  871. return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
  872. }
  873. /*
  874. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  875. % %
  876. % %
  877. % %
  878. % L i s t M o d u l e I n f o %
  879. % %
  880. % %
  881. % %
  882. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  883. %
  884. % ListModuleInfo() lists the module info to a file.
  885. %
  886. % The format of the ListModuleInfo module is:
  887. %
  888. % MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
  889. %
  890. % A description of each parameter follows.
  891. %
  892. % o file: An pointer to a FILE.
  893. %
  894. % o exception: Return any errors or warnings in this structure.
  895. %
  896. %
  897. */
  898. MagickExport MagickBooleanType ListModuleInfo(FILE *file,
  899. ExceptionInfo *exception)
  900. {
  901. const ModuleInfo
  902. **module_info;
  903. register long
  904. i;
  905. unsigned long
  906. number_modules;
  907. if (file == (const FILE *) NULL)
  908. file=stdout;
  909. module_info=GetModuleInfoList("*",&number_modules,exception);
  910. if (module_info == (const ModuleInfo **) NULL)
  911. return(MagickFalse);
  912. if (module_info[0]->path != (char *) NULL)
  913. {
  914. char
  915. path[MaxTextExtent];
  916. GetPathComponent(module_info[0]->path,HeadPath,path);
  917. (void) fprintf(file,"\nPath: %s\n\n",path);
  918. }
  919. (void) fprintf(file,"Module\n");
  920. (void) fprintf(file,"-------------------------------------------------"
  921. "------------------------------\n");
  922. for (i=0; i < (long) number_modules; i++)
  923. {
  924. if (module_info[i]->stealth != MagickFalse)
  925. continue;
  926. (void) fprintf(file,"%s",module_info[i]->tag);
  927. (void) fprintf(file,"\n");
  928. }
  929. (void) fflush(file);
  930. module_info=(const ModuleInfo **)
  931. RelinquishMagickMemory((void *) module_info);
  932. return(MagickTrue);
  933. }
  934. /*
  935. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  936. % %
  937. % %
  938. % %
  939. % O p e n M o d u l e %
  940. % %
  941. % %
  942. % %
  943. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  944. %
  945. % OpenModule() loads a module, and invokes its registration module. It
  946. % returns MagickTrue on success, and MagickFalse if there is an error.
  947. %
  948. % The format of the OpenModule module is:
  949. %
  950. % MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
  951. %
  952. % A description of each parameter follows:
  953. %
  954. % o module: a character string that indicates the module to load.
  955. %
  956. % o exception: Return any errors or warnings in this structure.
  957. %
  958. %
  959. */
  960. MagickExport MagickBooleanType OpenModule(const char *module,
  961. ExceptionInfo *exception)
  962. {
  963. char
  964. filename[MaxTextExtent],
  965. module_name[MaxTextExtent],
  966. name[MaxTextExtent],
  967. path[MaxTextExtent];
  968. ModuleHandle
  969. handle;
  970. ModuleInfo
  971. *module_info;
  972. register const CoderInfo
  973. *p;
  974. size_t
  975. length;
  976. /*
  977. Assign module name from alias.
  978. */
  979. assert(module != (const char *) NULL);
  980. module_info=(ModuleInfo *) GetModuleInfo(module,exception);
  981. if (module_info != (ModuleInfo *) NULL)
  982. return(MagickTrue);
  983. AcquireSemaphoreInfo(&module_semaphore);
  984. (void) CopyMagickString(module_name,module,MaxTextExtent);
  985. p=GetCoderInfo(module,exception);
  986. if (p != (CoderInfo *) NULL)
  987. (void) CopyMagickString(module_name,p->name,MaxTextExtent);
  988. if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
  989. {
  990. RelinquishSemaphoreInfo(module_semaphore);
  991. return(MagickTrue); /* module alread opened, return */
  992. }
  993. /*
  994. Locate module.
  995. */
  996. handle=(ModuleHandle) NULL;
  997. TagToCoderModuleName(module_name,filename);
  998. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  999. "Searching for module \"%s\" using filename \"%s\"",module_name,filename);
  1000. *path='\0';
  1001. length=GetMagickModulePath(filename,MagickCoderModule,path,exception);
  1002. if (length == 0)
  1003. {
  1004. RelinquishSemaphoreInfo(module_semaphore);
  1005. return(MagickFalse);
  1006. }
  1007. /*
  1008. Load module
  1009. */
  1010. handle=lt_dlopen(path);
  1011. if (handle == (ModuleHandle) NULL)
  1012. {
  1013. (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
  1014. "UnableToLoadModule","`%s': %s",path,lt_dlerror());
  1015. RelinquishSemaphoreInfo(module_semaphore);
  1016. return(MagickFalse);
  1017. }
  1018. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  1019. "Opening module at path \"%s\"",path);
  1020. /*
  1021. Register module.
  1022. */
  1023. module_info=(ModuleInfo *) AcquireMagickMemory(sizeof(*module_info));
  1024. if (module_info == (ModuleInfo *) NULL)
  1025. {
  1026. RelinquishSemaphoreInfo(module_semaphore);
  1027. ThrowMagickFatalException(ResourceLimitFatalError,
  1028. "UnableToAllocateModuleInfo",module_name);
  1029. }
  1030. (void) ResetMagickMemory(module_info,0,sizeof(*module_info));
  1031. module_info->path=ConstantString(path);
  1032. module_info->tag=ConstantString(module_name);
  1033. module_info->handle=handle;
  1034. (void) time(&module_info->load_time);
  1035. module_info->signature=MagickSignature;
  1036. if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
  1037. {
  1038. RelinquishSemaphoreInfo(module_semaphore);
  1039. return(MagickFalse);
  1040. }
  1041. /*
  1042. Define RegisterFORMATImage method.
  1043. */
  1044. TagToModuleName(module_name,"Register%sImage",name);
  1045. module_info->register_module=(void (*)(void)) lt_dlsym(handle,name);
  1046. if (module_info->register_module == (void (*)(void)) NULL)
  1047. {
  1048. (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
  1049. "UnableToRegisterImageFormat","`%s': %s",module_name,lt_dlerror());
  1050. RelinquishSemaphoreInfo(module_semaphore);
  1051. return(MagickFalse);
  1052. }
  1053. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  1054. "Method \"%s\" in module \"%s\" at address %p",name,module_name,
  1055. (void *) module_info->register_module);
  1056. /*
  1057. Define UnregisterFORMATImage method.
  1058. */
  1059. TagToModuleName(module_name,"Unregister%sImage",name);
  1060. module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
  1061. if (module_info->unregister_module == (void (*)(void)) NULL)
  1062. {
  1063. (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
  1064. "UnableToRegisterImageFormat","`%s': %s",module_name,lt_dlerror());
  1065. RelinquishSemaphoreInfo(module_semaphore);
  1066. return(MagickFalse);
  1067. }
  1068. (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
  1069. "Method \"%s\" in module \"%s\" at address %p",name,module_name,
  1070. (void *) module_info->unregister_module);
  1071. module_info->register_module();
  1072. RelinquishSemaphoreInfo(module_semaphore);
  1073. return(MagickTrue);
  1074. }
  1075. /*
  1076. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1077. % %
  1078. % %
  1079. % %
  1080. % O p e n M o d u l e s %
  1081. % %
  1082. % %
  1083. % %
  1084. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1085. %
  1086. % OpenModules() loads all available modules.
  1087. %
  1088. % The format of the OpenModules module is:
  1089. %
  1090. % MagickBooleanType OpenModules(ExceptionInfo *exception)
  1091. %
  1092. % A description of each parameter follows:
  1093. %
  1094. % o exception: Return any errors or warnings in this structure.
  1095. %
  1096. */
  1097. MagickExport MagickBooleanType OpenModules(ExceptionInfo *exception)
  1098. {
  1099. char
  1100. **modules;
  1101. register long
  1102. i;
  1103. unsigned long
  1104. number_modules;
  1105. /*
  1106. Load all modules.
  1107. */
  1108. (void) GetMagickInfo((char *) NULL,exception);
  1109. number_modules=0;
  1110. modules=GetModuleList("*",&number_modules,exception);
  1111. if (modules == (char **) NULL)
  1112. return(MagickFalse);
  1113. for (i=0; i < (long) number_modules; i++)
  1114. (void) OpenModule(modules[i],exception);
  1115. /*
  1116. Free resources.
  1117. */
  1118. for (i=0; i < (long) number_modules; i++)
  1119. modules[i]=(char *) RelinquishMagickMemory(modules[i]);
  1120. modules=(char **) RelinquishMagickMemory(modules);
  1121. return(MagickTrue);
  1122. }
  1123. /*
  1124. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1125. % %
  1126. % %
  1127. % %
  1128. % R e g i s t e r M o d u l e %
  1129. % %
  1130. % %
  1131. % %
  1132. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1133. %
  1134. % RegisterModule() adds an entry to the module list. It returns a pointer to
  1135. % the registered entry on success.
  1136. %
  1137. % The format of the RegisterModule module is:
  1138. %
  1139. % ModuleInfo *RegisterModule(const ModuleInfo *module_info,
  1140. % ExceptionInfo *exception)
  1141. %
  1142. % A description of each parameter follows:
  1143. %
  1144. % o info: a pointer to the registered entry is returned.
  1145. %
  1146. % o module_info: a pointer to the ModuleInfo structure to register.
  1147. %
  1148. % o exception: Return any errors or warnings in this structure.
  1149. %
  1150. %
  1151. */
  1152. static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
  1153. ExceptionInfo *exception)
  1154. {
  1155. MagickBooleanType
  1156. status;
  1157. assert(module_info != (ModuleInfo *) NULL);
  1158. assert(module_info->signature == MagickSignature);
  1159. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
  1160. if (module_list == (SplayTreeInfo *) NULL)
  1161. return((const ModuleInfo *) NULL);
  1162. status=AddValueToSplayTree(module_list,ConstantString(module_info->tag),
  1163. module_info);
  1164. if (status == MagickFalse)
  1165. (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
  1166. "MemoryAllocationFailed","`%s'",module_info->tag);
  1167. return(module_info);
  1168. }
  1169. /*
  1170. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1171. % %
  1172. % %
  1173. % %
  1174. % T a g T o C o d e r M o d u l e N a m e %
  1175. % %
  1176. % %
  1177. % %
  1178. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1179. %
  1180. % TagToCoderModuleName() munges a module tag and obtains the filename of the
  1181. % corresponding module module.
  1182. %
  1183. % The format of the TagToCoderModuleName module is:
  1184. %
  1185. % char *TagToCoderModuleName(const char *tag,char *name)
  1186. %
  1187. % A description of each parameter follows:
  1188. %
  1189. % o tag: a character string representing the module tag.
  1190. %
  1191. % o name: return the module module name here.
  1192. %
  1193. */
  1194. static void TagToCoderModuleName(const char *tag,char *name)
  1195. {
  1196. assert(tag != (char *) NULL);
  1197. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
  1198. assert(name != (char *) NULL);
  1199. #if defined(HasLTDL)
  1200. (void) FormatMagickString(name,MaxTextExtent,"%s.la",tag);
  1201. (void) LocaleLower(name);
  1202. #else
  1203. #if defined(__WINDOWS__)
  1204. if (LocaleNCompare("IM_MOD_",tag,7) == 0)
  1205. (void) CopyMagickString(name,tag,MaxTextExtent);
  1206. else
  1207. {
  1208. #if defined(_DEBUG)
  1209. (void) FormatMagickString(name,MaxTextExtent,"IM_MOD_DB_%s_.dll",tag);
  1210. #else
  1211. (void) FormatMagickString(name,MaxTextExtent,"IM_MOD_RL_%s_.dll",tag);
  1212. #endif
  1213. }
  1214. #endif
  1215. #endif
  1216. }
  1217. /*
  1218. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1219. % %
  1220. % %
  1221. % %
  1222. % T a g T o F i l t e r M o d u l e N a m e %
  1223. % %
  1224. % %
  1225. % %
  1226. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1227. %
  1228. % TagToFilterModuleName() munges a module tag and returns the filename of the
  1229. % corresponding filter module.
  1230. %
  1231. % The format of the TagToFilterModuleName module is:
  1232. %
  1233. % void TagToFilterModuleName(const char *tag,char name)
  1234. %
  1235. % A description of each parameter follows:
  1236. %
  1237. % o tag: a character string representing the module tag.
  1238. %
  1239. % o name: return the filter name here.
  1240. %
  1241. */
  1242. static void TagToFilterModuleName(const char *tag,char *name)
  1243. {
  1244. assert(tag != (char *) NULL);
  1245. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
  1246. assert(name != (char *) NULL);
  1247. #if !defined(HasLTDL)
  1248. (void) FormatMagickString(name,MaxTextExtent,"%s.dll",tag);
  1249. #else
  1250. (void) FormatMagickString(name,MaxTextExtent,"%s.la",tag);
  1251. (void) LocaleLower(name);
  1252. #endif
  1253. }
  1254. /*
  1255. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1256. % %
  1257. % %
  1258. % %
  1259. % T a g T o M o d u l e N a m e %
  1260. % %
  1261. % %
  1262. % %
  1263. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1264. %
  1265. % TagToModuleName() munges the module tag name and returns an upper-case tag
  1266. % name as the input string, and a user-provided format.
  1267. %
  1268. % The format of the TagToModuleName module is:
  1269. %
  1270. % TagToModuleName(const char *tag,const char *format,char *module)
  1271. %
  1272. % A description of each parameter follows:
  1273. %
  1274. % o tag: the module tag.
  1275. %
  1276. % o format: a sprintf-compatible format string containing %s where the
  1277. % upper-case tag name is to be inserted.
  1278. %
  1279. % o module: pointer to a destination buffer for the formatted result.
  1280. %
  1281. */
  1282. static void TagToModuleName(const char *tag,const char *format,char *module)
  1283. {
  1284. char
  1285. name[MaxTextExtent];
  1286. assert(tag != (const char *) NULL);
  1287. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
  1288. assert(format != (const char *) NULL);
  1289. assert(module != (char *) NULL);
  1290. (void) CopyMagickString(name,tag,MaxTextExtent);
  1291. LocaleUpper(name);
  1292. #if !defined(MagickMethodPrefix)
  1293. (void) FormatMagickString(module,MaxTextExtent,format,name);
  1294. #else
  1295. {
  1296. char
  1297. prefix_format[MaxTextExtent];
  1298. (void) FormatMagickString(prefix_format,MaxTextExtent,"%s%s",
  1299. MagickMethodPrefix,format);
  1300. (void) FormatMagickString(module,MaxTextExtent,prefix_format,name);
  1301. }
  1302. #endif
  1303. }
  1304. /*
  1305. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1306. % %
  1307. % %
  1308. % %
  1309. % U n R e g i s t e r M o d u l e %
  1310. % %
  1311. % %
  1312. % %
  1313. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1314. %
  1315. % UnregisterModule() unloads a module, and invokes its de-registration module.
  1316. % Returns MagickTrue on success, and MagickFalse if there is an error.
  1317. %
  1318. % The format of the UnregisterModule module is:
  1319. %
  1320. % MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
  1321. % ExceptionInfo *exception)
  1322. %
  1323. % A description of each parameter follows:
  1324. %
  1325. % o module_info: The module info.
  1326. %
  1327. % o exception: Return any errors or warnings in this structure.
  1328. %
  1329. %
  1330. */
  1331. static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
  1332. ExceptionInfo *exception)
  1333. {
  1334. /*
  1335. Locate and execute UnregisterFORMATImage module.
  1336. */
  1337. assert(module_info != (const ModuleInfo *) NULL);
  1338. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
  1339. assert(exception != (ExceptionInfo *) NULL);
  1340. if (module_info->unregister_module == NULL)
  1341. return(MagickTrue);
  1342. module_info->unregister_module();
  1343. if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
  1344. {
  1345. (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
  1346. "UnableToCloseModule","`%s': %s",module_info->tag,lt_dlerror());
  1347. return(MagickFalse);
  1348. }
  1349. return(MagickTrue);
  1350. }
  1351. #else
  1352. MagickExport MagickBooleanType ListModuleInfo(FILE *file,
  1353. ExceptionInfo *exception)
  1354. {
  1355. return(MagickTrue);
  1356. }
  1357. MagickExport MagickBooleanType ExecuteModuleProcess(const char *tag,
  1358. Image **image,const int argc,char **argv)
  1359. {
  1360. MagickBooleanType
  1361. status;
  1362. status=MagickFalse;
  1363. #if !defined(BuildMagickModules)
  1364. {
  1365. MagickBooleanType
  1366. AnalyzeImage(Image **,const int,char **),
  1367. (*method)(Image **,const int,char **);
  1368. method=NULL;
  1369. if (LocaleCompare("analyze",tag) == 0)
  1370. method=AnalyzeImage;
  1371. if (method != NULL)
  1372. status=(*method)(image,argc,argv);
  1373. }
  1374. #endif
  1375. return(status);
  1376. }
  1377. #endif