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