module.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                  M   M   OOO   DDDD   U   U  L      EEEEE                   %
00007 %                  MM MM  O   O  D   D  U   U  L      E                       %
00008 %                  M M M  O   O  D   D  U   U  L      EEE                     %
00009 %                  M   M  O   O  D   D  U   U  L      E                       %
00010 %                  M   M   OOO   DDDD    UUU   LLLLL  EEEEE                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                          MagickCore Module Methods                          %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                              Bob Friesenhahn                                %
00017 %                                March 2000                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "magick/studio.h"
00044 #include "magick/blob.h"
00045 #include "magick/coder.h"
00046 #include "magick/client.h"
00047 #include "magick/configure.h"
00048 #include "magick/exception.h"
00049 #include "magick/exception-private.h"
00050 #include "magick/log.h"
00051 #include "magick/hashmap.h"
00052 #include "magick/magic.h"
00053 #include "magick/magick.h"
00054 #include "magick/memory_.h"
00055 #include "magick/module.h"
00056 #include "magick/policy.h"
00057 #include "magick/semaphore.h"
00058 #include "magick/splay-tree.h"
00059 #include "magick/static.h"
00060 #include "magick/string_.h"
00061 #include "magick/token.h"
00062 #include "magick/utility.h"
00063 #if defined(MAGICKCORE_MODULES_SUPPORT)
00064 #if defined(MAGICKCORE_LTDL_DELEGATE)
00065 #include "ltdl.h"
00066 typedef lt_dlhandle ModuleHandle;
00067 #else
00068 typedef void *ModuleHandle;
00069 #endif
00070 
00071 /*
00072   Define declarations.
00073 */
00074 #if defined(MAGICKCORE_LTDL_DELEGATE)
00075 #  define ModuleGlobExpression "*.la"
00076 #else
00077 #  if defined(_DEBUG)
00078 #    define ModuleGlobExpression "IM_MOD_DB_*.dll"
00079 #  else
00080 #    define ModuleGlobExpression "IM_MOD_RL_*.dll"
00081 #  endif
00082 #endif
00083 
00084 /*
00085   Global declarations.
00086 */
00087 static SemaphoreInfo
00088   *module_semaphore = (SemaphoreInfo *) NULL;
00089 
00090 static SplayTreeInfo
00091   *module_list = (SplayTreeInfo *) NULL;
00092 
00093 static volatile MagickBooleanType
00094   instantiate_module = MagickFalse;
00095 
00096 /*
00097   Forward declarations.
00098 */
00099 static const ModuleInfo
00100   *RegisterModule(const ModuleInfo *,ExceptionInfo *);
00101 
00102 static MagickBooleanType
00103   GetMagickModulePath(const char *,MagickModuleType,char *,ExceptionInfo *),
00104   UnregisterModule(const ModuleInfo *,ExceptionInfo *);
00105 
00106 static void
00107   TagToCoderModuleName(const char *,char *),
00108   TagToFilterModuleName(const char *,char *),
00109   TagToModuleName(const char *,const char *,char *);
00110 
00111 /*
00112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00113 %                                                                             %
00114 %                                                                             %
00115 %                                                                             %
00116 %   A c q u i r e M o d u l e I n f o                                         %
00117 %                                                                             %
00118 %                                                                             %
00119 %                                                                             %
00120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00121 %
00122 %  AcquireModuleInfo() allocates the ModuleInfo structure.
00123 %
00124 %  The format of the AcquireModuleInfo method is:
00125 %
00126 %      ModuleInfo *AcquireModuleInfo(const char *path,const char *tag)
00127 %
00128 %  A description of each parameter follows:
00129 %
00130 %    o path: the path associated with the tag.
00131 %
00132 %    o tag: a character string that represents the image format we are
00133 %      looking for.
00134 %
00135 */
00136 MagickExport ModuleInfo *AcquireModuleInfo(const char *path,const char *tag)
00137 {
00138   ModuleInfo
00139     *module_info;
00140 
00141   module_info=(ModuleInfo *) AcquireMagickMemory(sizeof(*module_info));
00142   if (module_info == (ModuleInfo *) NULL)
00143     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00144   (void) ResetMagickMemory(module_info,0,sizeof(*module_info));
00145   if (path != (const char *) NULL)
00146     module_info->path=ConstantString(path);
00147   if (tag != (const char *) NULL)
00148     module_info->tag=ConstantString(tag);
00149   module_info->timestamp=time(0);
00150   module_info->signature=MagickSignature;
00151   return(module_info);
00152 }
00153 
00154 /*
00155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00156 %                                                                             %
00157 %                                                                             %
00158 %                                                                             %
00159 %   D e s t r o y M o d u l e L i s t                                         %
00160 %                                                                             %
00161 %                                                                             %
00162 %                                                                             %
00163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00164 %
00165 %  DestroyModuleList() unregisters any previously loaded modules and exits
00166 %  the module loaded environment.
00167 %
00168 %  The format of the DestroyModuleList module is:
00169 %
00170 %      void DestroyModuleList(void)
00171 %
00172 */
00173 MagickExport void DestroyModuleList(void)
00174 {
00175   /*
00176     Destroy magick modules.
00177   */
00178   (void) LockSemaphoreInfo(module_semaphore);
00179 #if defined(MAGICKCORE_MODULES_SUPPORT)
00180   if (module_list != (SplayTreeInfo *) NULL)
00181     module_list=DestroySplayTree(module_list);
00182   if (instantiate_module != MagickFalse)
00183     (void) lt_dlexit();
00184 #endif
00185   instantiate_module=MagickFalse;
00186   (void) UnlockSemaphoreInfo(module_semaphore);
00187 }
00188 
00189 /*
00190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00191 %                                                                             %
00192 %                                                                             %
00193 %                                                                             %
00194 %   G e t M o d u l e I n f o                                                 %
00195 %                                                                             %
00196 %                                                                             %
00197 %                                                                             %
00198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00199 %
00200 %  GetModuleInfo() returns a pointer to a ModuleInfo structure that matches the
00201 %  specified tag.  If tag is NULL, the head of the module list is returned. If
00202 %  no modules are loaded, or the requested module is not found, NULL is
00203 %  returned.
00204 %
00205 %  The format of the GetModuleInfo module is:
00206 %
00207 %      ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception)
00208 %
00209 %  A description of each parameter follows:
00210 %
00211 %    o tag: a character string that represents the image format we are
00212 %      looking for.
00213 %
00214 %    o exception: return any errors or warnings in this structure.
00215 %
00216 */
00217 MagickExport ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception)
00218 {
00219   if ((module_list == (SplayTreeInfo *) NULL) ||
00220       (instantiate_module == MagickFalse))
00221     if (InitializeModuleList(exception) == MagickFalse)
00222       return((ModuleInfo *) NULL);
00223   if ((module_list == (SplayTreeInfo *) NULL) ||
00224       (GetNumberOfNodesInSplayTree(module_list) == 0))
00225     return((ModuleInfo *) NULL);
00226   if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
00227     {
00228       ModuleInfo
00229         *p;
00230 
00231 #if defined(MAGICKCORE_MODULES_SUPPORT)
00232       if (LocaleCompare(tag,"*") == 0)
00233         (void) OpenModules(exception);
00234 #endif
00235       (void) LockSemaphoreInfo(module_semaphore);
00236       ResetSplayTreeIterator(module_list);
00237       p=(ModuleInfo *) GetNextValueInSplayTree(module_list);
00238       (void) UnlockSemaphoreInfo(module_semaphore);
00239       return(p);
00240     }
00241   return((ModuleInfo *) GetValueFromSplayTree(module_list,tag));
00242 }
00243 
00244 /*
00245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00246 %                                                                             %
00247 %                                                                             %
00248 %                                                                             %
00249 %   G e t M o d u l e I n f o L i s t                                         %
00250 %                                                                             %
00251 %                                                                             %
00252 %                                                                             %
00253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00254 %
00255 %  GetModuleInfoList() returns any modules that match the specified pattern.
00256 %
00257 %  The format of the GetModuleInfoList function is:
00258 %
00259 %      const ModuleInfo **GetModuleInfoList(const char *pattern,
00260 %        unsigned long *number_modules,ExceptionInfo *exception)
00261 %
00262 %  A description of each parameter follows:
00263 %
00264 %    o pattern: Specifies a pointer to a text string containing a pattern.
00265 %
00266 %    o number_modules:  This integer returns the number of modules in the list.
00267 %
00268 %    o exception: return any errors or warnings in this structure.
00269 %
00270 */
00271 
00272 #if defined(__cplusplus) || defined(c_plusplus)
00273 extern "C" {
00274 #endif
00275 
00276 static int ModuleInfoCompare(const void *x,const void *y)
00277 {
00278   const ModuleInfo
00279     **p,
00280     **q;
00281 
00282   p=(const ModuleInfo **) x,
00283   q=(const ModuleInfo **) y;
00284   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00285     return(LocaleCompare((*p)->tag,(*q)->tag));
00286   return(LocaleCompare((*p)->path,(*q)->path));
00287 }
00288 
00289 #if defined(__cplusplus) || defined(c_plusplus)
00290 }
00291 #endif
00292 
00293 MagickExport const ModuleInfo **GetModuleInfoList(const char *pattern,
00294   unsigned long *number_modules,ExceptionInfo *exception)
00295 {
00296   const ModuleInfo
00297     **modules;
00298 
00299   register const ModuleInfo
00300     *p;
00301 
00302   register long
00303     i;
00304 
00305   /*
00306     Allocate module list.
00307   */
00308   assert(pattern != (char *) NULL);
00309   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00310   assert(number_modules != (unsigned long *) NULL);
00311   *number_modules=0;
00312   p=GetModuleInfo("*",exception);
00313   if (p == (const ModuleInfo *) NULL)
00314     return((const ModuleInfo **) NULL);
00315   modules=(const ModuleInfo **) AcquireQuantumMemory((size_t)
00316     GetNumberOfNodesInSplayTree(module_list)+1UL,sizeof(*modules));
00317   if (modules == (const ModuleInfo **) NULL)
00318     return((const ModuleInfo **) NULL);
00319   /*
00320     Generate module list.
00321   */
00322   (void) LockSemaphoreInfo(module_semaphore);
00323   ResetSplayTreeIterator(module_list);
00324   p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
00325   for (i=0; p != (const ModuleInfo *) NULL; )
00326   {
00327     if ((p->stealth == MagickFalse) &&
00328         (GlobExpression(p->tag,pattern,MagickFalse) != MagickFalse))
00329       modules[i++]=p;
00330     p=(const ModuleInfo *) GetNextValueInSplayTree(module_list);
00331   }
00332   (void) UnlockSemaphoreInfo(module_semaphore);
00333   qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleInfoCompare);
00334   modules[i]=(ModuleInfo *) NULL;
00335   *number_modules=(unsigned long) i;
00336   return(modules);
00337 }
00338 
00339 /*
00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00341 %                                                                             %
00342 %                                                                             %
00343 %                                                                             %
00344 %   G e t M o d u l e L i s t                                                 %
00345 %                                                                             %
00346 %                                                                             %
00347 %                                                                             %
00348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00349 %
00350 %  GetModuleList() returns any image format modules that match the specified
00351 %  pattern.
00352 %
00353 %  The format of the GetModuleList function is:
00354 %
00355 %      char **GetModuleList(const char *pattern,unsigned long *number_modules,
00356 %        ExceptionInfo *exception)
00357 %
00358 %  A description of each parameter follows:
00359 %
00360 %    o pattern: Specifies a pointer to a text string containing a pattern.
00361 %
00362 %    o number_modules:  This integer returns the number of modules in the
00363 %      list.
00364 %
00365 %    o exception: return any errors or warnings in this structure.
00366 %
00367 */
00368 
00369 #if defined(__cplusplus) || defined(c_plusplus)
00370 extern "C" {
00371 #endif
00372 
00373 static int ModuleCompare(const void *x,const void *y)
00374 {
00375   register const char
00376     **p,
00377     **q;
00378 
00379    p=(const char **) x;
00380   q=(const char **) y;
00381   return(LocaleCompare(*p,*q));
00382 }
00383 
00384 #if defined(__cplusplus) || defined(c_plusplus)
00385 }
00386 #endif
00387 
00388 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
00389   struct dirent **result)
00390 {
00391 #if defined(MAGICKCORE_HAVE_READDIR_R)
00392   return(readdir_r(directory,entry,result));
00393 #else
00394   (void) entry;
00395   errno=0;
00396   *result=readdir(directory);
00397   return(errno);
00398 #endif
00399 }
00400 
00401 MagickExport char **GetModuleList(const char *pattern,
00402   unsigned long *number_modules,ExceptionInfo *exception)
00403 {
00404   char
00405     **modules,
00406     filename[MaxTextExtent],
00407     module_path[MaxTextExtent],
00408     path[MaxTextExtent];
00409 
00410   DIR
00411     *directory;
00412 
00413   MagickBooleanType
00414     status;
00415 
00416   register long
00417     i;
00418 
00419   size_t
00420     length;
00421 
00422   struct dirent
00423     *buffer,
00424     *entry;
00425 
00426   unsigned long
00427     max_entries;
00428 
00429   /*
00430     Locate all modules in the coder path.
00431   */
00432   TagToCoderModuleName("magick",filename);
00433   length=GetMagickModulePath(filename,MagickImageCoderModule,module_path,
00434     exception);
00435   if (length == 0)
00436     return((char **) NULL);
00437   GetPathComponent(module_path,HeadPath,path);
00438   max_entries=255;
00439   modules=(char **) AcquireQuantumMemory((size_t) max_entries+1UL,
00440     sizeof(*modules));
00441   if (modules == (char **) NULL)
00442     return((char **) NULL);
00443   *modules=(char *) NULL;
00444   directory=opendir(path);
00445   if (directory == (DIR *) NULL)
00446     {
00447       modules=(char **) RelinquishMagickMemory(modules);
00448       return((char **) NULL);
00449     }
00450   buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1);
00451   if (buffer == (struct dirent *) NULL)
00452     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00453   i=0;
00454   while ((MagickReadDirectory(directory,buffer,&entry) == 0) &&
00455          (entry != (struct dirent *) NULL))
00456   {
00457     status=GlobExpression(entry->d_name,ModuleGlobExpression,MagickFalse);
00458     if (status == MagickFalse)
00459       continue;
00460     if (GlobExpression(entry->d_name,pattern,MagickFalse) == MagickFalse)
00461       continue;
00462     if (i >= (long) max_entries)
00463       {
00464         modules=(char **) NULL;
00465         if (~max_entries > max_entries)
00466           modules=(char **) ResizeQuantumMemory(modules,(size_t)
00467             (max_entries << 1),sizeof(*modules));
00468         max_entries<<=1;
00469         if (modules == (char **) NULL)
00470           break;
00471       }
00472     /*
00473       Add new module name to list.
00474     */
00475     modules[i]=AcquireString((char *) NULL);
00476     GetPathComponent(entry->d_name,BasePath,modules[i]);
00477     LocaleUpper(modules[i]);
00478     if (LocaleNCompare("IM_MOD_",modules[i],7) == 0)
00479       {
00480         (void) CopyMagickString(modules[i],modules[i]+10,MaxTextExtent);
00481         modules[i][strlen(modules[i])-1]='\0';
00482       }
00483     i++;
00484   }
00485   buffer=(struct dirent *) RelinquishMagickMemory(buffer);
00486   (void) closedir(directory);
00487   if (modules == (char **) NULL)
00488     {
00489       (void) ThrowMagickException(exception,GetMagickModule(),ConfigureError,
00490         "MemoryAllocationFailed","`%s'",pattern);
00491       return((char **) NULL);
00492     }
00493   qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleCompare);
00494   modules[i]=(char *) NULL;
00495   *number_modules=(unsigned long) i;
00496   return(modules);
00497 }
00498 
00499 /*
00500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00501 %                                                                             %
00502 %                                                                             %
00503 %                                                                             %
00504 %  G e t M a g i c k M o d u l e P a t h                                      %
00505 %                                                                             %
00506 %                                                                             %
00507 %                                                                             %
00508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00509 %
00510 %  GetMagickModulePath() finds a module with the specified module type and
00511 %  filename.
00512 %
00513 %  The format of the GetMagickModulePath module is:
00514 %
00515 %      MagickBooleanType GetMagickModulePath(const char *filename,
00516 %        MagickModuleType module_type,char *path,ExceptionInfo *exception)
00517 %
00518 %  A description of each parameter follows:
00519 %
00520 %    o filename: the module file name.
00521 %
00522 %    o module_type: the module type: MagickImageCoderModule or
00523 %      MagickImageFilterModule.
00524 %
00525 %    o path: the path associated with the filename.
00526 %
00527 %    o exception: return any errors or warnings in this structure.
00528 %
00529 */
00530 static MagickBooleanType GetMagickModulePath(const char *filename,
00531   MagickModuleType module_type,char *path,ExceptionInfo *exception)
00532 {
00533   char
00534     *module_path;
00535 
00536   assert(filename != (const char *) NULL);
00537   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00538   assert(path != (char *) NULL);
00539   assert(exception != (ExceptionInfo *) NULL);
00540   (void) CopyMagickString(path,filename,MaxTextExtent);
00541   module_path=(char *) NULL;
00542   switch (module_type)
00543   {
00544     case MagickImageCoderModule:
00545     default:
00546     {
00547       (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
00548         "Searching for coder module file \"%s\" ...",filename);
00549       module_path=GetEnvironmentValue("MAGICK_CODER_MODULE_PATH");
00550 #if defined(MAGICKCORE_CODER_PATH)
00551       if (module_path == (char *) NULL)
00552         module_path=AcquireString(MAGICKCORE_CODER_PATH);
00553 #endif
00554       break;
00555     }
00556     case MagickImageFilterModule:
00557     {
00558       (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
00559         "Searching for filter module file \"%s\" ...",filename);
00560       module_path=GetEnvironmentValue("MAGICK_CODER_FILTER_PATH");
00561 #if defined(MAGICKCORE_FILTER_PATH)
00562       if (module_path == (char *) NULL)
00563         module_path=AcquireString(MAGICKCORE_FILTER_PATH);
00564 #endif
00565       break;
00566     }
00567   }
00568   if (module_path != (char *) NULL)
00569     {
00570       register char
00571         *p,
00572         *q;
00573 
00574       for (p=module_path-1; p != (char *) NULL; )
00575       {
00576         (void) CopyMagickString(path,p+1,MaxTextExtent);
00577         q=strchr(path,DirectoryListSeparator);
00578         if (q != (char *) NULL)
00579           *q='\0';
00580         q=path+strlen(path)-1;
00581         if ((q >= path) && (*q != *DirectorySeparator))
00582           (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
00583         (void) ConcatenateMagickString(path,filename,MaxTextExtent);
00584         if (IsPathAccessible(path) != MagickFalse)
00585           {
00586             module_path=DestroyString(module_path);
00587             return(MagickTrue);
00588           }
00589         p=strchr(p+1,DirectoryListSeparator);
00590       }
00591       module_path=DestroyString(module_path);
00592     }
00593 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
00594    else
00595 #if defined(MAGICKCORE_CODER_PATH)
00596     {
00597       const char
00598         *directory;
00599 
00600       /*
00601         Search hard coded paths.
00602       */
00603       switch (module_type)
00604       {
00605         case MagickImageCoderModule:
00606         default:
00607         {
00608           directory=MAGICKCORE_CODER_PATH;
00609           break;
00610         }
00611         case MagickImageFilterModule:
00612         {
00613           directory=MAGICKCORE_FILTER_PATH;
00614           break;
00615         }
00616       }
00617       (void) FormatMagickString(path,MaxTextExtent,"%s%s",directory,filename);
00618       if (IsPathAccessible(path) == MagickFalse)
00619         {
00620           ThrowFileException(exception,ConfigureWarning,
00621             "UnableToOpenModuleFile",path);
00622           return(MagickFalse);
00623         }
00624       return(MagickTrue);
00625     }
00626 #else
00627 #if defined(__WINDOWS__)
00628     {
00629       const char
00630         *registery_key;
00631 
00632       unsigned char
00633         *key_value;
00634 
00635       /*
00636         Locate path via registry key.
00637       */
00638       switch (module_type)
00639       {
00640         case MagickImageCoderModule:
00641         default:
00642         {
00643           registery_key="CoderModulesPath";
00644           break;
00645         }
00646         case MagickImageFilterModule:
00647         {
00648           registery_key="FilterModulesPath";
00649           break;
00650         }
00651       }
00652       key_value=NTRegistryKeyLookup(registery_key);
00653       if (key_value == (unsigned char *) NULL)
00654         {
00655           ThrowMagickException(exception,GetMagickModule(),ConfigureError,
00656             "RegistryKeyLookupFailed","`%s'",registery_key);
00657           return(MagickFalse);
00658         }
00659       (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",(char *) key_value,
00660         DirectorySeparator,filename);
00661       key_value=(unsigned char *) RelinquishMagickMemory(key_value);
00662       if (IsPathAccessible(path) == MagickFalse)
00663         {
00664           ThrowFileException(exception,ConfigureWarning,
00665             "UnableToOpenModuleFile",path);
00666           return(MagickFalse);
00667         }
00668       return(MagickTrue);
00669     }
00670 #endif
00671 #endif
00672 #if !defined(MAGICKCORE_CODER_PATH) && !defined(__WINDOWS__)
00673 # error MAGICKCORE_CODER_PATH or __WINDOWS__ must be defined when MAGICKCORE_INSTALLED_SUPPORT is defined
00674 #endif
00675 #else
00676   {
00677     char
00678       *home;
00679 
00680     home=GetEnvironmentValue("MAGICK_HOME");
00681     if (home != (char *) NULL)
00682       {
00683         /*
00684           Search MAGICK_HOME.
00685         */
00686 #if !defined(MAGICKCORE_POSIX_SUPPORT)
00687         (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",home,
00688           DirectorySeparator,filename);
00689 #else
00690         const char
00691           *directory;
00692 
00693         switch (module_type)
00694         {
00695           case MagickImageCoderModule:
00696           default:
00697           {
00698             directory=MAGICKCORE_CODER_RELATIVE_PATH;
00699             break;
00700           }
00701           case MagickImageFilterModule:
00702           {
00703             directory=MAGICKCORE_FILTER_RELATIVE_PATH;
00704             break;
00705           }
00706         }
00707         (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/%s",home,
00708           directory,filename);
00709 #endif
00710         home=DestroyString(home);
00711         if (IsPathAccessible(path) != MagickFalse)
00712           return(MagickTrue);
00713       }
00714   }
00715   if (*GetClientPath() != '\0')
00716     {
00717       /*
00718         Search based on executable directory.
00719       */
00720 #if !defined(MAGICKCORE_POSIX_SUPPORT)
00721       (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
00722         DirectorySeparator,filename);
00723 #else
00724       char
00725         prefix[MaxTextExtent];
00726 
00727       const char
00728         *directory;
00729 
00730       switch (module_type)
00731       {
00732         case MagickImageCoderModule:
00733         default:
00734         {
00735           directory="modules";
00736           break;
00737         }
00738         case MagickImageFilterModule:
00739         {
00740           directory="filters";
00741           break;
00742         }
00743       }
00744       (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
00745       ChopPathComponents(prefix,1);
00746       (void) FormatMagickString(path,MaxTextExtent,
00747         "%s/lib/%s/modules-Q%d/%s/%s",prefix,MAGICKCORE_LIBRARY_RELATIVE_PATH,
00748         MAGICKCORE_QUANTUM_DEPTH,directory,filename);
00749 #endif
00750       if (IsPathAccessible(path) != MagickFalse)
00751         return(MagickTrue);
00752     }
00753 #if defined(__WINDOWS__)
00754   {
00755     /*
00756       Search module path.
00757     */
00758     if ((NTGetModulePath("CORE_RL_magick_.dll",path) != MagickFalse) ||
00759         (NTGetModulePath("CORE_DB_magick_.dll",path) != MagickFalse) ||
00760         (NTGetModulePath("Magick.dll",path) != MagickFalse))
00761       {
00762         (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
00763         (void) ConcatenateMagickString(path,filename,MaxTextExtent);
00764         if (IsPathAccessible(path) != MagickFalse)
00765           return(MagickTrue);
00766       }
00767   }
00768 #endif
00769   {
00770     char
00771       *home;
00772 
00773     home=GetEnvironmentValue("HOME");
00774     if (home == (char *) NULL)
00775       home=GetEnvironmentValue("USERPROFILE");
00776     if (home != (char *) NULL)
00777       {
00778         /*
00779           Search $HOME/.magick.
00780         */
00781         (void) FormatMagickString(path,MaxTextExtent,"%s%s.magick%s%s",home,
00782           DirectorySeparator,DirectorySeparator,filename);
00783         home=DestroyString(home);
00784         if (IsPathAccessible(path) != MagickFalse)
00785           return(MagickTrue);
00786       }
00787   }
00788   /*
00789     Search current directory.
00790   */
00791   if (IsPathAccessible(path) != MagickFalse)
00792     return(MagickTrue);
00793   if (exception->severity < ConfigureError)
00794     ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile",
00795       path);
00796   return(MagickFalse);
00797 #endif
00798   return(MagickFalse);
00799 }
00800 
00801 /*
00802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00803 %                                                                             %
00804 %                                                                             %
00805 %                                                                             %
00806 %   I n i t i a l i z e M o d u l e L i s t                                   %
00807 %                                                                             %
00808 %                                                                             %
00809 %                                                                             %
00810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00811 %
00812 %  InitializeModuleList() initializes the module loader.
00813 %
00814 %  The format of the InitializeModuleList() method is:
00815 %
00816 %      InitializeModuleList(Exceptioninfo *exception)
00817 %
00818 %  A description of each parameter follows.
00819 %
00820 %    o exception: return any errors or warnings in this structure.
00821 %
00822 */
00823 
00824 static void *DestroyModuleNode(void *module_info)
00825 {
00826   ExceptionInfo
00827     *exception;
00828 
00829   register ModuleInfo
00830     *p;
00831 
00832   exception=AcquireExceptionInfo();
00833   p=(ModuleInfo *) module_info;
00834   if (UnregisterModule(p,exception) == MagickFalse)
00835     CatchException(exception);
00836   if (p->tag != (char *) NULL)
00837     p->tag=DestroyString(p->tag);
00838   if (p->path != (char *) NULL)
00839     p->path=DestroyString(p->path);
00840   exception=DestroyExceptionInfo(exception);
00841   return(RelinquishMagickMemory(p));
00842 }
00843 
00844 MagickExport MagickBooleanType InitializeModuleList(
00845   ExceptionInfo *magick_unused(exception))
00846 {
00847   if ((module_list == (SplayTreeInfo *) NULL) &&
00848       (instantiate_module == MagickFalse))
00849     {
00850       if (module_semaphore == (SemaphoreInfo *) NULL)
00851         AcquireSemaphoreInfo(&module_semaphore);
00852       (void) LockSemaphoreInfo(module_semaphore);
00853       if ((module_list == (SplayTreeInfo *) NULL) &&
00854           (instantiate_module == MagickFalse))
00855         {
00856           MagickBooleanType
00857             status;
00858 
00859           ModuleInfo
00860             *module_info;
00861 
00862           module_list=NewSplayTree(CompareSplayTreeString,
00863             (void *(*)(void *)) NULL,DestroyModuleNode);
00864           if (module_list == (SplayTreeInfo *) NULL)
00865             ThrowFatalException(ResourceLimitFatalError,
00866               "MemoryAllocationFailed");
00867           module_info=AcquireModuleInfo((const char *) NULL,"[boot-strap]");
00868           module_info->stealth=MagickTrue;
00869           status=AddValueToSplayTree(module_list,module_info->tag,module_info);
00870           if (status == MagickFalse)
00871             ThrowFatalException(ResourceLimitFatalError,
00872               "MemoryAllocationFailed");
00873           if (lt_dlinit() != 0)
00874             ThrowFatalException(ModuleFatalError,
00875               "UnableToInitializeModuleLoader");
00876           instantiate_module=MagickTrue;
00877         }
00878       (void) UnlockSemaphoreInfo(module_semaphore);
00879     }
00880   return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
00881 }
00882 
00883 /*
00884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00885 %                                                                             %
00886 %                                                                             %
00887 %                                                                             %
00888 %   I n v o k e D y n a m i c I m a g e F i l t e r                           %
00889 %                                                                             %
00890 %                                                                             %
00891 %                                                                             %
00892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00893 %
00894 %  InvokeDynamicImageFilter() invokes a dynamic image filter.
00895 %
00896 %  The format of the InvokeDynamicImageFilter module is:
00897 %
00898 %      MagickBooleanType InvokeDynamicImageFilter(const char *tag,Image **image,
00899 %        const int argc,const char **argv,ExceptionInfo *exception)
00900 %
00901 %  A description of each parameter follows:
00902 %
00903 %    o tag: a character string that represents the name of the particular
00904 %      module.
00905 %
00906 %    o image: the image.
00907 %
00908 %    o argc: a pointer to an integer describing the number of elements in the
00909 %      argument vector.
00910 %
00911 %    o argv: a pointer to a text array containing the command line arguments.
00912 %
00913 %    o exception: return any errors or warnings in this structure.
00914 %
00915 */
00916 MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
00917   Image **images,const int argc,const char **argv,ExceptionInfo *exception)
00918 {
00919   char
00920     name[MaxTextExtent],
00921     path[MaxTextExtent];
00922 
00923   ImageFilterHandler
00924     *image_filter;
00925 
00926   ModuleHandle
00927     handle;
00928 
00929   PolicyRights
00930     rights;
00931 
00932   size_t
00933     length;
00934 
00935   /*
00936     Find the module.
00937   */
00938   assert(images != (Image **) NULL);
00939   assert((*images)->signature == MagickSignature);
00940   if ((*images)->debug != MagickFalse)
00941     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00942       (*images)->filename);
00943 #if !defined(MAGICKCORE_BUILD_MODULES)
00944   {
00945     MagickBooleanType
00946       status;
00947 
00948     status=InvokeStaticImageFilter(tag,images,argc,argv,exception);
00949     if (status != MagickFalse)
00950       return(status);
00951   }
00952 #endif
00953   rights=ReadPolicyRights;
00954   if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
00955     {
00956       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
00957         "NotAuthorized","`%s'",tag);
00958       return(MagickFalse);
00959     }
00960   TagToFilterModuleName(tag,name);
00961   length=GetMagickModulePath(name,MagickImageFilterModule,path,exception);
00962   if (length == 0)
00963     return(MagickFalse);
00964   /*
00965     Open the module.
00966   */
00967   handle=(ModuleHandle) lt_dlopen(path);
00968   if (handle == (ModuleHandle) NULL)
00969     {
00970       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
00971         "UnableToLoadModule","`%s': %s",name,lt_dlerror());
00972       return(MagickFalse);
00973     }
00974   /*
00975     Locate the module.
00976   */
00977 #if !defined(MAGICKCORE_NAMESPACE_PREFIX)
00978   (void) FormatMagickString(name,MaxTextExtent,"%sImage",tag);
00979 #else
00980   (void) FormatMagickString(name,MaxTextExtent,"%s%sImage",
00981     MAGICKCORE_NAMESPACE_PREFIX,tag);
00982 #endif
00983   /*
00984     Execute the module.
00985   */
00986   image_filter=(ImageFilterHandler *) lt_dlsym(handle,name);
00987   if (image_filter == (ImageFilterHandler *) NULL)
00988     (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
00989       "UnableToLoadModule","`%s': %s",name,lt_dlerror());
00990   else
00991     {
00992       unsigned long
00993         signature;
00994 
00995       if ((*images)->debug != MagickFalse)
00996         (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
00997           "Invoking \"%s\" dynamic image filter",tag);
00998       signature=image_filter(images,argc,argv,exception);
00999       if ((*images)->debug != MagickFalse)
01000         (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes",
01001           tag);
01002       if (signature != MagickImageFilterSignature)
01003         {
01004           (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01005             "ImageFilterSignatureMismatch","`%s': %8lx != %8lx",tag,signature,
01006             MagickImageFilterSignature);
01007           return(MagickFalse);
01008         }
01009     }
01010   /*
01011     Close the module.
01012   */
01013   if (lt_dlclose(handle) != 0)
01014     {
01015       (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
01016         "UnableToCloseModule","`%s': %s",name,lt_dlerror());
01017       return(MagickFalse);
01018     }
01019   return(MagickTrue);
01020 }
01021 
01022 /*
01023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01024 %                                                                             %
01025 %                                                                             %
01026 %                                                                             %
01027 %  L i s t M o d u l e I n f o                                                %
01028 %                                                                             %
01029 %                                                                             %
01030 %                                                                             %
01031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01032 %
01033 %  ListModuleInfo() lists the module info to a file.
01034 %
01035 %  The format of the ListModuleInfo module is:
01036 %
01037 %      MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception)
01038 %
01039 %  A description of each parameter follows.
01040 %
01041 %    o file:  An pointer to a FILE.
01042 %
01043 %    o exception: return any errors or warnings in this structure.
01044 %
01045 */
01046 MagickExport MagickBooleanType ListModuleInfo(FILE *file,
01047   ExceptionInfo *exception)
01048 {
01049   const ModuleInfo
01050     **module_info;
01051 
01052   register long
01053     i;
01054 
01055   unsigned long
01056     number_modules;
01057 
01058   if (file == (const FILE *) NULL)
01059     file=stdout;
01060   module_info=GetModuleInfoList("*",&number_modules,exception);
01061   if (module_info == (const ModuleInfo **) NULL)
01062     return(MagickFalse);
01063   if (module_info[0]->path != (char *) NULL)
01064     {
01065       char
01066         path[MaxTextExtent];
01067 
01068       GetPathComponent(module_info[0]->path,HeadPath,path);
01069       (void) fprintf(file,"\nPath: %s\n\n",path);
01070     }
01071   (void) fprintf(file,"Module\n");
01072   (void) fprintf(file,"-------------------------------------------------"
01073     "------------------------------\n");
01074   for (i=0; i < (long) number_modules; i++)
01075   {
01076     if (module_info[i]->stealth != MagickFalse)
01077       continue;
01078     (void) fprintf(file,"%s",module_info[i]->tag);
01079     (void) fprintf(file,"\n");
01080   }
01081   (void) fflush(file);
01082   module_info=(const ModuleInfo **)
01083     RelinquishMagickMemory((void *) module_info);
01084   return(MagickTrue);
01085 }
01086 
01087 /*
01088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01089 %                                                                             %
01090 %                                                                             %
01091 %                                                                             %
01092 +   M o d u l e C o m p o n e n t G e n e s i s                               %
01093 %                                                                             %
01094 %                                                                             %
01095 %                                                                             %
01096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01097 %
01098 %  ModuleComponentGenesis() instantiates the module component.
01099 %
01100 %  The format of the ModuleComponentGenesis method is:
01101 %
01102 %      MagickBooleanType ModuleComponentGenesis(void)
01103 %
01104 */
01105 MagickExport MagickBooleanType ModuleComponentGenesis(void)
01106 {
01107   ExceptionInfo
01108     *exception;
01109 
01110   AcquireSemaphoreInfo(&module_semaphore);
01111   exception=AcquireExceptionInfo();
01112   InitializeModuleList(exception);
01113   exception=DestroyExceptionInfo(exception);
01114   return(MagickTrue);
01115 }
01116 
01117 /*
01118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01119 %                                                                             %
01120 %                                                                             %
01121 %                                                                             %
01122 +   M o d u l e C o m p o n e n t T e r m i n u s                             %
01123 %                                                                             %
01124 %                                                                             %
01125 %                                                                             %
01126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01127 %
01128 %  ModuleComponentTerminus() destroys the module component.
01129 %
01130 %  The format of the ModuleComponentTerminus method is:
01131 %
01132 %      ModuleComponentTerminus(void)
01133 %
01134 */
01135 MagickExport void ModuleComponentTerminus(void)
01136 {
01137   if (module_semaphore == (SemaphoreInfo *) NULL)
01138     AcquireSemaphoreInfo(&module_semaphore);
01139   DestroyModuleList();
01140   DestroySemaphoreInfo(&module_semaphore);
01141 }
01142 
01143 /*
01144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01145 %                                                                             %
01146 %                                                                             %
01147 %                                                                             %
01148 %   O p e n M o d u l e                                                       %
01149 %                                                                             %
01150 %                                                                             %
01151 %                                                                             %
01152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01153 %
01154 %  OpenModule() loads a module, and invokes its registration module.  It
01155 %  returns MagickTrue on success, and MagickFalse if there is an error.
01156 %
01157 %  The format of the OpenModule module is:
01158 %
01159 %      MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception)
01160 %
01161 %  A description of each parameter follows:
01162 %
01163 %    o module: a character string that indicates the module to load.
01164 %
01165 %    o exception: return any errors or warnings in this structure.
01166 %
01167 */
01168 MagickExport MagickBooleanType OpenModule(const char *module,
01169   ExceptionInfo *exception)
01170 {
01171   char
01172     filename[MaxTextExtent],
01173     module_name[MaxTextExtent],
01174     name[MaxTextExtent],
01175     path[MaxTextExtent];
01176 
01177   ModuleHandle
01178     handle;
01179 
01180   ModuleInfo
01181     *module_info;
01182 
01183   register const CoderInfo
01184     *p;
01185 
01186   size_t
01187     length;
01188 
01189   unsigned long
01190     signature;
01191 
01192   /*
01193     Assign module name from alias.
01194   */
01195   assert(module != (const char *) NULL);
01196   module_info=(ModuleInfo *) GetModuleInfo(module,exception);
01197   if (module_info != (ModuleInfo *) NULL)
01198     return(MagickTrue);
01199   (void) CopyMagickString(module_name,module,MaxTextExtent);
01200   p=GetCoderInfo(module,exception);
01201   if (p != (CoderInfo *) NULL)
01202     (void) CopyMagickString(module_name,p->name,MaxTextExtent);
01203   if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL)
01204     return(MagickTrue);  /* module already opened, return */
01205   /*
01206     Locate module.
01207   */
01208   handle=(ModuleHandle) NULL;
01209   TagToCoderModuleName(module_name,filename);
01210   (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
01211     "Searching for module \"%s\" using filename \"%s\"",module_name,filename);
01212   *path='\0';
01213   length=GetMagickModulePath(filename,MagickImageCoderModule,path,exception);
01214   if (length == 0)
01215     return(MagickFalse);
01216   /*
01217     Load module
01218   */
01219   (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
01220     "Opening module at path \"%s\"",path);
01221   handle=(ModuleHandle) lt_dlopen(path);
01222   if (handle == (ModuleHandle) NULL)
01223     {
01224       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01225         "UnableToLoadModule","`%s': %s",path,lt_dlerror());
01226       return(MagickFalse);
01227     }
01228   /*
01229     Register module.
01230   */
01231   module_info=AcquireModuleInfo(path,module_name);
01232   module_info->handle=handle;
01233   if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL)
01234     return(MagickFalse);
01235   /*
01236     Define RegisterFORMATImage method.
01237   */
01238   TagToModuleName(module_name,"Register%sImage",name);
01239   module_info->register_module=(unsigned long (*)(void)) lt_dlsym(handle,name);
01240   if (module_info->register_module == (unsigned long (*)(void)) NULL)
01241     {
01242       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01243         "UnableToRegisterImageFormat","`%s': %s",module_name,lt_dlerror());
01244       return(MagickFalse);
01245     }
01246   (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
01247     "Method \"%s\" in module \"%s\" at address %p",name,module_name,
01248     (void *) module_info->register_module);
01249   /*
01250     Define UnregisterFORMATImage method.
01251   */
01252   TagToModuleName(module_name,"Unregister%sImage",name);
01253   module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name);
01254   if (module_info->unregister_module == (void (*)(void)) NULL)
01255     {
01256       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01257         "UnableToRegisterImageFormat","`%s': %s",module_name,lt_dlerror());
01258       return(MagickFalse);
01259     }
01260   (void) LogMagickEvent(ModuleEvent,GetMagickModule(),
01261     "Method \"%s\" in module \"%s\" at address %p",name,module_name,
01262     (void *) module_info->unregister_module);
01263   signature=module_info->register_module();
01264   if (signature != MagickImageCoderSignature)
01265     {
01266       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01267         "ImageCoderSignatureMismatch","`%s': %8lx != %8lx",module_name,
01268         signature,MagickImageCoderSignature);
01269       return(MagickFalse);
01270     }
01271   return(MagickTrue);
01272 }
01273 
01274 /*
01275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01276 %                                                                             %
01277 %                                                                             %
01278 %                                                                             %
01279 %   O p e n M o d u l e s                                                     %
01280 %                                                                             %
01281 %                                                                             %
01282 %                                                                             %
01283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01284 %
01285 %  OpenModules() loads all available modules.
01286 %
01287 %  The format of the OpenModules module is:
01288 %
01289 %      MagickBooleanType OpenModules(ExceptionInfo *exception)
01290 %
01291 %  A description of each parameter follows:
01292 %
01293 %    o exception: return any errors or warnings in this structure.
01294 %
01295 */
01296 MagickExport MagickBooleanType OpenModules(ExceptionInfo *exception)
01297 {
01298   char
01299     **modules;
01300 
01301   register long
01302     i;
01303 
01304   unsigned long
01305     number_modules;
01306 
01307   /*
01308     Load all modules.
01309   */
01310   (void) GetMagickInfo((char *) NULL,exception);
01311   number_modules=0;
01312   modules=GetModuleList("*",&number_modules,exception);
01313   if (modules == (char **) NULL)
01314     return(MagickFalse);
01315   for (i=0; i < (long) number_modules; i++)
01316     (void) OpenModule(modules[i],exception);
01317   /*
01318     Relinquish resources.
01319   */
01320   for (i=0; i < (long) number_modules; i++)
01321     modules[i]=DestroyString(modules[i]);
01322   modules=(char **) RelinquishMagickMemory(modules);
01323   return(MagickTrue);
01324 }
01325 
01326 /*
01327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01328 %                                                                             %
01329 %                                                                             %
01330 %                                                                             %
01331 %   R e g i s t e r M o d u l e                                               %
01332 %                                                                             %
01333 %                                                                             %
01334 %                                                                             %
01335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01336 %
01337 %  RegisterModule() adds an entry to the module list.  It returns a pointer to
01338 %  the registered entry on success.
01339 %
01340 %  The format of the RegisterModule module is:
01341 %
01342 %      ModuleInfo *RegisterModule(const ModuleInfo *module_info,
01343 %        ExceptionInfo *exception)
01344 %
01345 %  A description of each parameter follows:
01346 %
01347 %    o info: a pointer to the registered entry is returned.
01348 %
01349 %    o module_info: a pointer to the ModuleInfo structure to register.
01350 %
01351 %    o exception: return any errors or warnings in this structure.
01352 %
01353 */
01354 static const ModuleInfo *RegisterModule(const ModuleInfo *module_info,
01355   ExceptionInfo *exception)
01356 {
01357   MagickBooleanType
01358     status;
01359 
01360   assert(module_info != (ModuleInfo *) NULL);
01361   assert(module_info->signature == MagickSignature);
01362   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
01363   if (module_list == (SplayTreeInfo *) NULL)
01364     return((const ModuleInfo *) NULL);
01365   status=AddValueToSplayTree(module_list,module_info->tag,module_info);
01366   if (status == MagickFalse)
01367     (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
01368       "MemoryAllocationFailed","`%s'",module_info->tag);
01369   return(module_info);
01370 }
01371 
01372 /*
01373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01374 %                                                                             %
01375 %                                                                             %
01376 %                                                                             %
01377 %  T a g T o C o d e r M o d u l e N a m e                                    %
01378 %                                                                             %
01379 %                                                                             %
01380 %                                                                             %
01381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01382 %
01383 %  TagToCoderModuleName() munges a module tag and obtains the filename of the
01384 %  corresponding module.
01385 %
01386 %  The format of the TagToCoderModuleName module is:
01387 %
01388 %      char *TagToCoderModuleName(const char *tag,char *name)
01389 %
01390 %  A description of each parameter follows:
01391 %
01392 %    o tag: a character string representing the module tag.
01393 %
01394 %    o name: return the module name here.
01395 %
01396 */
01397 static void TagToCoderModuleName(const char *tag,char *name)
01398 {
01399   assert(tag != (char *) NULL);
01400   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
01401   assert(name != (char *) NULL);
01402 #if defined(MAGICKCORE_LTDL_DELEGATE)
01403   (void) FormatMagickString(name,MaxTextExtent,"%s.la",tag);
01404   (void) LocaleLower(name);
01405 #else
01406 #if defined(__WINDOWS__)
01407   if (LocaleNCompare("IM_MOD_",tag,7) == 0)
01408     (void) CopyMagickString(name,tag,MaxTextExtent);
01409   else
01410     {
01411 #if defined(_DEBUG)
01412       (void) FormatMagickString(name,MaxTextExtent,"IM_MOD_DB_%s_.dll",tag);
01413 #else
01414       (void) FormatMagickString(name,MaxTextExtent,"IM_MOD_RL_%s_.dll",tag);
01415 #endif
01416     }
01417 #endif
01418 #endif
01419 }
01420 
01421 /*
01422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01423 %                                                                             %
01424 %                                                                             %
01425 %                                                                             %
01426 %  T a g T o F i l t e r M o d u l e N a m e                                  %
01427 %                                                                             %
01428 %                                                                             %
01429 %                                                                             %
01430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01431 %
01432 %  TagToFilterModuleName() munges a module tag and returns the filename of the
01433 %  corresponding filter module.
01434 %
01435 %  The format of the TagToFilterModuleName module is:
01436 %
01437 %      void TagToFilterModuleName(const char *tag,char name)
01438 %
01439 %  A description of each parameter follows:
01440 %
01441 %    o tag: a character string representing the module tag.
01442 %
01443 %    o name: return the filter name here.
01444 %
01445 */
01446 static void TagToFilterModuleName(const char *tag,char *name)
01447 {
01448   assert(tag != (char *) NULL);
01449   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
01450   assert(name != (char *) NULL);
01451 #if !defined(MAGICKCORE_LTDL_DELEGATE)
01452   (void) FormatMagickString(name,MaxTextExtent,"%s.dll",tag);
01453 #else
01454   (void) FormatMagickString(name,MaxTextExtent,"%s.la",tag);
01455   (void) LocaleLower(name);
01456 #endif
01457 }
01458 
01459 /*
01460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01461 %                                                                             %
01462 %                                                                             %
01463 %                                                                             %
01464 %   T a g T o M o d u l e N a m e                                             %
01465 %                                                                             %
01466 %                                                                             %
01467 %                                                                             %
01468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01469 %
01470 %  TagToModuleName() munges the module tag name and returns an upper-case tag
01471 %  name as the input string, and a user-provided format.
01472 %
01473 %  The format of the TagToModuleName module is:
01474 %
01475 %      TagToModuleName(const char *tag,const char *format,char *module)
01476 %
01477 %  A description of each parameter follows:
01478 %
01479 %    o tag: the module tag.
01480 %
01481 %    o format: a sprintf-compatible format string containing %s where the
01482 %      upper-case tag name is to be inserted.
01483 %
01484 %    o module: pointer to a destination buffer for the formatted result.
01485 %
01486 */
01487 static void TagToModuleName(const char *tag,const char *format,char *module)
01488 {
01489   char
01490     name[MaxTextExtent];
01491 
01492   assert(tag != (const char *) NULL);
01493   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag);
01494   assert(format != (const char *) NULL);
01495   assert(module != (char *) NULL);
01496   (void) CopyMagickString(name,tag,MaxTextExtent);
01497   LocaleUpper(name);
01498 #if !defined(MAGICKCORE_NAMESPACE_PREFIX)
01499   (void) FormatMagickString(module,MaxTextExtent,format,name);
01500 #else
01501   {
01502     char
01503       prefix_format[MaxTextExtent];
01504 
01505     (void) FormatMagickString(prefix_format,MaxTextExtent,"%s%s",
01506       MAGICKCORE_NAMESPACE_PREFIX,format);
01507     (void) FormatMagickString(module,MaxTextExtent,prefix_format,name);
01508   }
01509 #endif
01510 }
01511 
01512 /*
01513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01514 %                                                                             %
01515 %                                                                             %
01516 %                                                                             %
01517 %   U n r e g i s t e r M o d u l e                                           %
01518 %                                                                             %
01519 %                                                                             %
01520 %                                                                             %
01521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01522 %
01523 %  UnregisterModule() unloads a module, and invokes its de-registration module.
01524 %  Returns MagickTrue on success, and MagickFalse if there is an error.
01525 %
01526 %  The format of the UnregisterModule module is:
01527 %
01528 %      MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
01529 %        ExceptionInfo *exception)
01530 %
01531 %  A description of each parameter follows:
01532 %
01533 %    o module_info: the module info.
01534 %
01535 %    o exception: return any errors or warnings in this structure.
01536 %
01537 */
01538 static MagickBooleanType UnregisterModule(const ModuleInfo *module_info,
01539   ExceptionInfo *exception)
01540 {
01541   /*
01542     Locate and execute UnregisterFORMATImage module.
01543   */
01544   assert(module_info != (const ModuleInfo *) NULL);
01545   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag);
01546   assert(exception != (ExceptionInfo *) NULL);
01547   if (module_info->unregister_module == NULL)
01548     return(MagickTrue);
01549   module_info->unregister_module();
01550   if (lt_dlclose((ModuleHandle) module_info->handle) != 0)
01551     {
01552       (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning,
01553         "UnableToCloseModule","`%s': %s",module_info->tag,lt_dlerror());
01554       return(MagickFalse);
01555     }
01556   return(MagickTrue);
01557 }
01558 #else
01559 MagickExport MagickBooleanType ListModuleInfo(FILE *magick_unused(file),
01560   ExceptionInfo *magick_unused(exception))
01561 {
01562   return(MagickTrue);
01563 }
01564 
01565 MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag,
01566   Image **image,const int argc,const char **argv,ExceptionInfo *exception)
01567 {
01568 #if !defined(MAGICKCORE_BUILD_MODULES)
01569   {
01570     extern unsigned long
01571       analyzeImage(Image **,const int,const char **,ExceptionInfo *);
01572 
01573     ImageFilterHandler
01574       *image_filter;
01575 
01576     image_filter=(ImageFilterHandler *) NULL;
01577     if (LocaleCompare("analyze",tag) == 0)
01578       image_filter=analyzeImage;
01579     if (image_filter != (ImageFilterHandler *) NULL)
01580       {
01581         unsigned long
01582           signature;
01583 
01584         signature=image_filter(image,argc,argv,exception);
01585         if (signature != MagickImageFilterSignature)
01586           {
01587             (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
01588               "ImageFilterSignatureMismatch","`%s': %8lx != %8lx",tag,signature,
01589               MagickImageFilterSignature);
01590             return(MagickFalse);
01591           }
01592       }
01593   }
01594 #endif
01595   return(MagickTrue);
01596 }
01597 #endif

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1