/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/Plugin.cpp
Line | Count | Source |
1 | | // ===================================================================== |
2 | | // FreeImage Plugin Interface |
3 | | // |
4 | | // Design and implementation by |
5 | | // - Floris van den Berg (floris@geekhq.nl) |
6 | | // - Rui Lopes (ruiglopes@yahoo.com) |
7 | | // - Detlev Vendt (detlev.vendt@brillit.de) |
8 | | // - Petr Pytelka (pyta@lightcomp.com) |
9 | | // - Hervé Drolon (drolon@infonie.fr) |
10 | | // |
11 | | // This file is part of FreeImage 3 |
12 | | // |
13 | | // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY |
14 | | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES |
15 | | // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE |
16 | | // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED |
17 | | // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT |
18 | | // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY |
19 | | // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL |
20 | | // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER |
21 | | // THIS DISCLAIMER. |
22 | | // |
23 | | // Use at your own risk! |
24 | | // ===================================================================== |
25 | | |
26 | | #ifdef _MSC_VER |
27 | | #pragma warning (disable : 4786) // identifier was truncated to 'number' characters |
28 | | #endif |
29 | | |
30 | | #ifdef _WIN32 |
31 | | #include <windows.h> |
32 | | #include <io.h> |
33 | | #else |
34 | | #include <ctype.h> |
35 | | #endif // _WIN32 |
36 | | |
37 | | #include "FreeImage.h" |
38 | | #include "Utilities.h" |
39 | | #include "FreeImageIO.h" |
40 | | #include "Plugin.h" |
41 | | |
42 | | #include "../Metadata/FreeImageTag.h" |
43 | | |
44 | | // ===================================================================== |
45 | | |
46 | | using namespace std; |
47 | | |
48 | | // ===================================================================== |
49 | | // Plugin search list |
50 | | // ===================================================================== |
51 | | |
52 | | const char * |
53 | | s_search_list[] = { |
54 | | "", |
55 | | "plugins\\", |
56 | | }; |
57 | | |
58 | | static int s_search_list_size = sizeof(s_search_list) / sizeof(char *); |
59 | | static PluginList *s_plugins = NULL; |
60 | | static int s_plugin_reference_count = 0; |
61 | | |
62 | | |
63 | | // ===================================================================== |
64 | | // Reimplementation of stricmp (it is not supported on some systems) |
65 | | // ===================================================================== |
66 | | |
67 | | int |
68 | 0 | FreeImage_stricmp(const char *s1, const char *s2) { |
69 | 0 | int c1, c2; |
70 | |
|
71 | 0 | do { |
72 | 0 | c1 = tolower(*s1++); |
73 | 0 | c2 = tolower(*s2++); |
74 | 0 | } while (c1 && c1 == c2); |
75 | |
|
76 | 0 | return c1 - c2; |
77 | 0 | } |
78 | | |
79 | | // ===================================================================== |
80 | | // Implementation of PluginList |
81 | | // ===================================================================== |
82 | | |
83 | | PluginList::PluginList() : |
84 | 2 | m_plugin_map(), |
85 | 2 | m_node_count(0) { |
86 | 2 | } |
87 | | |
88 | | FREE_IMAGE_FORMAT |
89 | 74 | PluginList::AddNode(FI_InitProc init_proc, void *instance, const char *format, const char *description, const char *extension, const char *regexpr) { |
90 | 74 | if (init_proc != NULL) { |
91 | 74 | PluginNode *node = new(std::nothrow) PluginNode; |
92 | 74 | Plugin *plugin = new(std::nothrow) Plugin; |
93 | 74 | if(!node || !plugin) { |
94 | 0 | if(node) delete node; |
95 | 0 | if(plugin) delete plugin; |
96 | 0 | FreeImage_OutputMessageProc(FIF_UNKNOWN, FI_MSG_ERROR_MEMORY); |
97 | 0 | return FIF_UNKNOWN; |
98 | 0 | } |
99 | | |
100 | 74 | memset(plugin, 0, sizeof(Plugin)); |
101 | | |
102 | | // fill-in the plugin structure |
103 | | // note we have memset to 0, so all unset pointers should be NULL) |
104 | | |
105 | 74 | init_proc(plugin, (int)m_plugin_map.size()); |
106 | | |
107 | | // get the format string (two possible ways) |
108 | | |
109 | 74 | const char *the_format = NULL; |
110 | | |
111 | 74 | if (format != NULL) { |
112 | 12 | the_format = format; |
113 | 62 | } else if (plugin->format_proc != NULL) { |
114 | 62 | the_format = plugin->format_proc(); |
115 | 62 | } |
116 | | |
117 | | // add the node if it wasn't there already |
118 | | |
119 | 74 | if (the_format != NULL) { |
120 | 74 | node->m_id = (int)m_plugin_map.size(); |
121 | 74 | node->m_instance = instance; |
122 | 74 | node->m_plugin = plugin; |
123 | 74 | node->m_format = format; |
124 | 74 | node->m_description = description; |
125 | 74 | node->m_extension = extension; |
126 | 74 | node->m_regexpr = regexpr; |
127 | 74 | node->m_enabled = TRUE; |
128 | | |
129 | 74 | m_plugin_map[(const int)m_plugin_map.size()] = node; |
130 | | |
131 | 74 | return (FREE_IMAGE_FORMAT)node->m_id; |
132 | 74 | } |
133 | | |
134 | | // something went wrong while allocating the plugin... cleanup |
135 | | |
136 | 0 | delete plugin; |
137 | 0 | delete node; |
138 | 0 | } |
139 | | |
140 | 0 | return FIF_UNKNOWN; |
141 | 74 | } |
142 | | |
143 | | PluginNode * |
144 | 0 | PluginList::FindNodeFromFormat(const char *format) { |
145 | 0 | for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) { |
146 | 0 | const char *the_format = ((*i).second->m_format != NULL) ? (*i).second->m_format : (*i).second->m_plugin->format_proc(); |
147 | |
|
148 | 0 | if ((*i).second->m_enabled) { |
149 | 0 | if (FreeImage_stricmp(the_format, format) == 0) { |
150 | 0 | return (*i).second; |
151 | 0 | } |
152 | 0 | } |
153 | 0 | } |
154 | | |
155 | 0 | return NULL; |
156 | 0 | } |
157 | | |
158 | | PluginNode * |
159 | 0 | PluginList::FindNodeFromMime(const char *mime) { |
160 | 0 | for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) { |
161 | 0 | const char *the_mime = ((*i).second->m_plugin->mime_proc != NULL) ? (*i).second->m_plugin->mime_proc() : ""; |
162 | |
|
163 | 0 | if ((*i).second->m_enabled) { |
164 | 0 | if ((the_mime != NULL) && (strcmp(the_mime, mime) == 0)) { |
165 | 0 | return (*i).second; |
166 | 0 | } |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | 0 | return NULL; |
171 | 0 | } |
172 | | |
173 | | PluginNode * |
174 | 902k | PluginList::FindNodeFromFIF(int node_id) { |
175 | 902k | map<int, PluginNode *>::iterator i = m_plugin_map.find(node_id); |
176 | | |
177 | 902k | if (i != m_plugin_map.end()) { |
178 | 902k | return (*i).second; |
179 | 902k | } |
180 | | |
181 | 0 | return NULL; |
182 | 902k | } |
183 | | |
184 | | int |
185 | 24.7k | PluginList::Size() const { |
186 | 24.7k | return (int)m_plugin_map.size(); |
187 | 24.7k | } |
188 | | |
189 | | BOOL |
190 | 0 | PluginList::IsEmpty() const { |
191 | 0 | return m_plugin_map.empty(); |
192 | 0 | } |
193 | | |
194 | 0 | PluginList::~PluginList() { |
195 | 0 | for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) { |
196 | | #ifdef _WIN32 |
197 | | if ((*i).second->m_instance != NULL) { |
198 | | FreeLibrary((HINSTANCE)(*i).second->m_instance); |
199 | | } |
200 | | #endif |
201 | 0 | delete (*i).second->m_plugin; |
202 | 0 | delete ((*i).second); |
203 | 0 | } |
204 | 0 | } |
205 | | |
206 | | // ===================================================================== |
207 | | // Retrieve a pointer to the plugin list container |
208 | | // ===================================================================== |
209 | | |
210 | | PluginList * DLL_CALLCONV |
211 | 0 | FreeImage_GetPluginList() { |
212 | 0 | return s_plugins; |
213 | 0 | } |
214 | | |
215 | | // ===================================================================== |
216 | | // Plugin System Initialization |
217 | | // ===================================================================== |
218 | | |
219 | | void DLL_CALLCONV |
220 | 24.6k | FreeImage_Initialise(BOOL load_local_plugins_only) { |
221 | 24.6k | if (s_plugin_reference_count++ == 0) { |
222 | | |
223 | | /* |
224 | | Note: initialize all singletons here |
225 | | in order to avoid race conditions with multi-threading |
226 | | */ |
227 | | |
228 | | // initialise the TagLib singleton |
229 | 2 | TagLib& s = TagLib::instance(); |
230 | | |
231 | | // internal plugin initialization |
232 | | |
233 | 2 | s_plugins = new(std::nothrow) PluginList; |
234 | | |
235 | 2 | if (s_plugins) { |
236 | | /* NOTE : |
237 | | The order used to initialize internal plugins below MUST BE the same order |
238 | | as the one used to define the FREE_IMAGE_FORMAT enum. |
239 | | */ |
240 | 2 | s_plugins->AddNode(InitBMP); |
241 | 2 | s_plugins->AddNode(InitICO); |
242 | 2 | s_plugins->AddNode(InitJPEG); |
243 | 2 | s_plugins->AddNode(InitJNG); |
244 | 2 | s_plugins->AddNode(InitKOALA); |
245 | 2 | s_plugins->AddNode(InitIFF); |
246 | 2 | s_plugins->AddNode(InitMNG); |
247 | 2 | s_plugins->AddNode(InitPNM, NULL, "PBM", "Portable Bitmap (ASCII)", "pbm", "^P1"); |
248 | 2 | s_plugins->AddNode(InitPNM, NULL, "PBMRAW", "Portable Bitmap (RAW)", "pbm", "^P4"); |
249 | 2 | s_plugins->AddNode(InitPCD); |
250 | 2 | s_plugins->AddNode(InitPCX); |
251 | 2 | s_plugins->AddNode(InitPNM, NULL, "PGM", "Portable Greymap (ASCII)", "pgm", "^P2"); |
252 | 2 | s_plugins->AddNode(InitPNM, NULL, "PGMRAW", "Portable Greymap (RAW)", "pgm", "^P5"); |
253 | 2 | s_plugins->AddNode(InitPNG); |
254 | 2 | s_plugins->AddNode(InitPNM, NULL, "PPM", "Portable Pixelmap (ASCII)", "ppm", "^P3"); |
255 | 2 | s_plugins->AddNode(InitPNM, NULL, "PPMRAW", "Portable Pixelmap (RAW)", "ppm", "^P6"); |
256 | 2 | s_plugins->AddNode(InitRAS); |
257 | 2 | s_plugins->AddNode(InitTARGA); |
258 | 2 | s_plugins->AddNode(InitTIFF); |
259 | 2 | s_plugins->AddNode(InitWBMP); |
260 | 2 | s_plugins->AddNode(InitPSD); |
261 | 2 | s_plugins->AddNode(InitCUT); |
262 | 2 | s_plugins->AddNode(InitXBM); |
263 | 2 | s_plugins->AddNode(InitXPM); |
264 | 2 | s_plugins->AddNode(InitDDS); |
265 | 2 | s_plugins->AddNode(InitGIF); |
266 | 2 | s_plugins->AddNode(InitHDR); |
267 | 2 | s_plugins->AddNode(InitG3); |
268 | 2 | s_plugins->AddNode(InitSGI); |
269 | 2 | s_plugins->AddNode(InitEXR); |
270 | 2 | s_plugins->AddNode(InitJ2K); |
271 | 2 | s_plugins->AddNode(InitJP2); |
272 | 2 | s_plugins->AddNode(InitPFM); |
273 | 2 | s_plugins->AddNode(InitPICT); |
274 | 2 | s_plugins->AddNode(InitRAW); |
275 | 2 | s_plugins->AddNode(InitWEBP); |
276 | 2 | s_plugins->AddNode(InitJXR); |
277 | | |
278 | | // external plugin initialization |
279 | | |
280 | | #ifdef _WIN32 |
281 | | if (!load_local_plugins_only) { |
282 | | const DWORD nPathSize = 8 * _MAX_PATH; // should be enough to handle a path |
283 | | int count = 0; |
284 | | char buffer[nPathSize]; |
285 | | wchar_t current_dir[nPathSize]; |
286 | | wchar_t module_name[nPathSize]; |
287 | | BOOL bOk = FALSE; |
288 | | |
289 | | // store the current directory, then set the directory to the application location |
290 | | if (GetCurrentDirectoryW(nPathSize, current_dir) != 0) { |
291 | | if (GetModuleFileNameW(NULL, module_name, nPathSize) != 0) { |
292 | | wchar_t *last_point = wcsrchr(module_name, L'\\'); |
293 | | if (last_point) { |
294 | | *last_point = L'\0'; |
295 | | bOk = SetCurrentDirectoryW(module_name); |
296 | | } |
297 | | } |
298 | | } |
299 | | |
300 | | // search for plugins |
301 | | |
302 | | while (count < s_search_list_size) { |
303 | | _finddata_t find_data; |
304 | | long find_handle; |
305 | | |
306 | | strcpy(buffer, s_search_list[count]); |
307 | | strcat(buffer, "*.fip"); |
308 | | |
309 | | if ((find_handle = (long)_findfirst(buffer, &find_data)) != -1L) { |
310 | | do { |
311 | | strcpy(buffer, s_search_list[count]); |
312 | | strncat(buffer, find_data.name, nPathSize); |
313 | | |
314 | | HINSTANCE instance = LoadLibrary(buffer); |
315 | | |
316 | | if (instance != NULL) { |
317 | | FARPROC proc_address = GetProcAddress(instance, "_Init@8"); |
318 | | |
319 | | if (proc_address != NULL) { |
320 | | s_plugins->AddNode((FI_InitProc)proc_address, (void *)instance); |
321 | | } else { |
322 | | FreeLibrary(instance); |
323 | | } |
324 | | } |
325 | | } while (_findnext(find_handle, &find_data) != -1L); |
326 | | |
327 | | _findclose(find_handle); |
328 | | } |
329 | | |
330 | | count++; |
331 | | } |
332 | | |
333 | | // restore the current directory |
334 | | |
335 | | if (bOk) { |
336 | | SetCurrentDirectoryW(current_dir); |
337 | | } |
338 | | } |
339 | | #endif // _WIN32 |
340 | 2 | } |
341 | 2 | } |
342 | 24.6k | } |
343 | | |
344 | | void DLL_CALLCONV |
345 | 0 | FreeImage_DeInitialise() { |
346 | 0 | --s_plugin_reference_count; |
347 | |
|
348 | 0 | if (s_plugin_reference_count == 0) { |
349 | 0 | delete s_plugins; |
350 | 0 | } |
351 | 0 | } |
352 | | |
353 | | // ===================================================================== |
354 | | // Open and close a bitmap |
355 | | // ===================================================================== |
356 | | |
357 | | void * DLL_CALLCONV |
358 | 81 | FreeImage_Open(PluginNode *node, FreeImageIO *io, fi_handle handle, BOOL open_for_reading) { |
359 | 81 | if (node->m_plugin->open_proc != NULL) { |
360 | 0 | return node->m_plugin->open_proc(io, handle, open_for_reading); |
361 | 0 | } |
362 | | |
363 | 81 | return NULL; |
364 | 81 | } |
365 | | |
366 | | void DLL_CALLCONV |
367 | 81 | FreeImage_Close(PluginNode *node, FreeImageIO *io, fi_handle handle, void *data) { |
368 | 81 | if (node->m_plugin->close_proc != NULL) { |
369 | 0 | node->m_plugin->close_proc(io, handle, data); |
370 | 0 | } |
371 | 81 | } |
372 | | |
373 | | // ===================================================================== |
374 | | // Plugin System Load/Save Functions |
375 | | // ===================================================================== |
376 | | |
377 | | FIBITMAP * DLL_CALLCONV |
378 | 81 | FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) { |
379 | 81 | if ((fif >= 0) && (fif < FreeImage_GetFIFCount())) { |
380 | 81 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
381 | | |
382 | 81 | if (node != NULL) { |
383 | 81 | if(node->m_plugin->load_proc != NULL) { |
384 | 81 | void *data = FreeImage_Open(node, io, handle, TRUE); |
385 | | |
386 | 81 | FIBITMAP *bitmap = node->m_plugin->load_proc(io, handle, -1, flags, data); |
387 | | |
388 | 81 | FreeImage_Close(node, io, handle, data); |
389 | | |
390 | 81 | return bitmap; |
391 | 81 | } |
392 | 81 | } |
393 | 81 | } |
394 | | |
395 | 0 | return NULL; |
396 | 81 | } |
397 | | |
398 | | FIBITMAP * DLL_CALLCONV |
399 | 0 | FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags) { |
400 | 0 | FreeImageIO io; |
401 | 0 | SetDefaultIO(&io); |
402 | | |
403 | 0 | FILE *handle = fopen(filename, "rb"); |
404 | |
|
405 | 0 | if (handle) { |
406 | 0 | FIBITMAP *bitmap = FreeImage_LoadFromHandle(fif, &io, (fi_handle)handle, flags); |
407 | |
|
408 | 0 | fclose(handle); |
409 | |
|
410 | 0 | return bitmap; |
411 | 0 | } else { |
412 | 0 | FreeImage_OutputMessageProc((int)fif, "FreeImage_Load: failed to open file %s", filename); |
413 | 0 | } |
414 | | |
415 | 0 | return NULL; |
416 | 0 | } |
417 | | |
418 | | FIBITMAP * DLL_CALLCONV |
419 | 0 | FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags) { |
420 | 0 | FreeImageIO io; |
421 | 0 | SetDefaultIO(&io); |
422 | | #ifdef _WIN32 |
423 | | FILE *handle = _wfopen(filename, L"rb"); |
424 | | |
425 | | if (handle) { |
426 | | FIBITMAP *bitmap = FreeImage_LoadFromHandle(fif, &io, (fi_handle)handle, flags); |
427 | | |
428 | | fclose(handle); |
429 | | |
430 | | return bitmap; |
431 | | } else { |
432 | | FreeImage_OutputMessageProc((int)fif, "FreeImage_LoadU: failed to open input file"); |
433 | | } |
434 | | #endif |
435 | 0 | return NULL; |
436 | 0 | } |
437 | | |
438 | | BOOL DLL_CALLCONV |
439 | 0 | FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags) { |
440 | | // cannot save "header only" formats |
441 | 0 | if(FreeImage_HasPixels(dib) == FALSE) { |
442 | 0 | FreeImage_OutputMessageProc((int)fif, "FreeImage_SaveToHandle: cannot save \"header only\" formats"); |
443 | 0 | return FALSE; |
444 | 0 | } |
445 | | |
446 | 0 | if ((fif >= 0) && (fif < FreeImage_GetFIFCount())) { |
447 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
448 | | |
449 | 0 | if (node) { |
450 | 0 | if(node->m_plugin->save_proc != NULL) { |
451 | 0 | void *data = FreeImage_Open(node, io, handle, FALSE); |
452 | | |
453 | 0 | BOOL result = node->m_plugin->save_proc(io, dib, handle, -1, flags, data); |
454 | | |
455 | 0 | FreeImage_Close(node, io, handle, data); |
456 | | |
457 | 0 | return result; |
458 | 0 | } |
459 | 0 | } |
460 | 0 | } |
461 | | |
462 | 0 | return FALSE; |
463 | 0 | } |
464 | | |
465 | | |
466 | | BOOL DLL_CALLCONV |
467 | 0 | FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags) { |
468 | 0 | FreeImageIO io; |
469 | 0 | SetDefaultIO(&io); |
470 | | |
471 | 0 | FILE *handle = fopen(filename, "w+b"); |
472 | | |
473 | 0 | if (handle) { |
474 | 0 | BOOL success = FreeImage_SaveToHandle(fif, dib, &io, (fi_handle)handle, flags); |
475 | |
|
476 | 0 | fclose(handle); |
477 | |
|
478 | 0 | return success; |
479 | 0 | } else { |
480 | 0 | FreeImage_OutputMessageProc((int)fif, "FreeImage_Save: failed to open file %s", filename); |
481 | 0 | } |
482 | | |
483 | 0 | return FALSE; |
484 | 0 | } |
485 | | |
486 | | BOOL DLL_CALLCONV |
487 | 0 | FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags) { |
488 | 0 | FreeImageIO io; |
489 | 0 | SetDefaultIO(&io); |
490 | | #ifdef _WIN32 |
491 | | FILE *handle = _wfopen(filename, L"w+b"); |
492 | | |
493 | | if (handle) { |
494 | | BOOL success = FreeImage_SaveToHandle(fif, dib, &io, (fi_handle)handle, flags); |
495 | | |
496 | | fclose(handle); |
497 | | |
498 | | return success; |
499 | | } else { |
500 | | FreeImage_OutputMessageProc((int)fif, "FreeImage_SaveU: failed to open output file"); |
501 | | } |
502 | | #endif |
503 | 0 | return FALSE; |
504 | 0 | } |
505 | | |
506 | | // ===================================================================== |
507 | | // Plugin construction + enable/disable functions |
508 | | // ===================================================================== |
509 | | |
510 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
511 | 0 | FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format, const char *description, const char *extension, const char *regexpr) { |
512 | 0 | return s_plugins->AddNode(proc_address, NULL, format, description, extension, regexpr); |
513 | 0 | } |
514 | | |
515 | | #ifdef _WIN32 |
516 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
517 | | FreeImage_RegisterExternalPlugin(const char *path, const char *format, const char *description, const char *extension, const char *regexpr) { |
518 | | if (path != NULL) { |
519 | | HINSTANCE instance = LoadLibrary(path); |
520 | | |
521 | | if (instance != NULL) { |
522 | | FARPROC proc_address = GetProcAddress(instance, "_Init@8"); |
523 | | |
524 | | FREE_IMAGE_FORMAT result = s_plugins->AddNode((FI_InitProc)proc_address, (void *)instance, format, description, extension, regexpr); |
525 | | |
526 | | if (result == FIF_UNKNOWN) |
527 | | FreeLibrary(instance); |
528 | | |
529 | | return result; |
530 | | } |
531 | | } |
532 | | |
533 | | return FIF_UNKNOWN; |
534 | | } |
535 | | #endif // _WIN32 |
536 | | |
537 | | int DLL_CALLCONV |
538 | 0 | FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable) { |
539 | 0 | if (s_plugins != NULL) { |
540 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
541 | |
|
542 | 0 | if (node != NULL) { |
543 | 0 | BOOL previous_state = node->m_enabled; |
544 | |
|
545 | 0 | node->m_enabled = enable; |
546 | |
|
547 | 0 | return previous_state; |
548 | 0 | } |
549 | 0 | } |
550 | | |
551 | 0 | return -1; |
552 | 0 | } |
553 | | |
554 | | int DLL_CALLCONV |
555 | 0 | FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif) { |
556 | 0 | if (s_plugins != NULL) { |
557 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
558 | |
|
559 | 0 | return (node != NULL) ? node->m_enabled : FALSE; |
560 | 0 | } |
561 | | |
562 | 0 | return -1; |
563 | 0 | } |
564 | | |
565 | | // ===================================================================== |
566 | | // Plugin Access Functions |
567 | | // ===================================================================== |
568 | | |
569 | | int DLL_CALLCONV |
570 | 24.7k | FreeImage_GetFIFCount() { |
571 | 24.7k | return (s_plugins != NULL) ? s_plugins->Size() : 0; |
572 | 24.7k | } |
573 | | |
574 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
575 | 0 | FreeImage_GetFIFFromFormat(const char *format) { |
576 | 0 | if (s_plugins != NULL) { |
577 | 0 | PluginNode *node = s_plugins->FindNodeFromFormat(format); |
578 | |
|
579 | 0 | return (node != NULL) ? (FREE_IMAGE_FORMAT)node->m_id : FIF_UNKNOWN; |
580 | 0 | } |
581 | | |
582 | 0 | return FIF_UNKNOWN; |
583 | 0 | } |
584 | | |
585 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
586 | 0 | FreeImage_GetFIFFromMime(const char *mime) { |
587 | 0 | if (s_plugins != NULL) { |
588 | 0 | PluginNode *node = s_plugins->FindNodeFromMime(mime); |
589 | |
|
590 | 0 | return (node != NULL) ? (FREE_IMAGE_FORMAT)node->m_id : FIF_UNKNOWN; |
591 | 0 | } |
592 | | |
593 | 0 | return FIF_UNKNOWN; |
594 | 0 | } |
595 | | |
596 | | const char * DLL_CALLCONV |
597 | 0 | FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif) { |
598 | 0 | if (s_plugins != NULL) { |
599 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
600 | |
|
601 | 0 | return (node != NULL) ? (node->m_format != NULL) ? node->m_format : node->m_plugin->format_proc() : NULL; |
602 | 0 | } |
603 | | |
604 | 0 | return NULL; |
605 | 0 | } |
606 | | |
607 | | const char * DLL_CALLCONV |
608 | 0 | FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif) { |
609 | 0 | if (s_plugins != NULL) { |
610 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
611 | |
|
612 | 0 | return (node != NULL) ? (node->m_plugin != NULL) ? ( node->m_plugin->mime_proc != NULL )? node->m_plugin->mime_proc() : NULL : NULL : NULL; |
613 | 0 | } |
614 | | |
615 | 0 | return NULL; |
616 | 0 | } |
617 | | |
618 | | const char * DLL_CALLCONV |
619 | 0 | FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif) { |
620 | 0 | if (s_plugins != NULL) { |
621 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
622 | |
|
623 | 0 | return (node != NULL) ? (node->m_extension != NULL) ? node->m_extension : (node->m_plugin->extension_proc != NULL) ? node->m_plugin->extension_proc() : NULL : NULL; |
624 | 0 | } |
625 | | |
626 | 0 | return NULL; |
627 | 0 | } |
628 | | |
629 | | const char * DLL_CALLCONV |
630 | 0 | FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif) { |
631 | 0 | if (s_plugins != NULL) { |
632 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
633 | |
|
634 | 0 | return (node != NULL) ? (node->m_description != NULL) ? node->m_description : (node->m_plugin->description_proc != NULL) ? node->m_plugin->description_proc() : NULL : NULL; |
635 | 0 | } |
636 | | |
637 | 0 | return NULL; |
638 | 0 | } |
639 | | |
640 | | const char * DLL_CALLCONV |
641 | 0 | FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif) { |
642 | 0 | if (s_plugins != NULL) { |
643 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
644 | |
|
645 | 0 | return (node != NULL) ? (node->m_regexpr != NULL) ? node->m_regexpr : (node->m_plugin->regexpr_proc != NULL) ? node->m_plugin->regexpr_proc() : NULL : NULL; |
646 | 0 | } |
647 | | |
648 | 0 | return NULL; |
649 | 0 | } |
650 | | |
651 | | BOOL DLL_CALLCONV |
652 | 0 | FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif) { |
653 | 0 | if (s_plugins != NULL) { |
654 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
655 | |
|
656 | 0 | return (node != NULL) ? node->m_plugin->load_proc != NULL : FALSE; |
657 | 0 | } |
658 | | |
659 | 0 | return FALSE; |
660 | 0 | } |
661 | | |
662 | | BOOL DLL_CALLCONV |
663 | 0 | FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif) { |
664 | 0 | if (s_plugins != NULL) { |
665 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
666 | |
|
667 | 0 | return (node != NULL) ? node->m_plugin->save_proc != NULL : FALSE ; |
668 | 0 | } |
669 | | |
670 | 0 | return FALSE; |
671 | 0 | } |
672 | | |
673 | | BOOL DLL_CALLCONV |
674 | 0 | FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int depth) { |
675 | 0 | if (s_plugins != NULL) { |
676 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
677 | |
|
678 | 0 | return (node != NULL) ? |
679 | 0 | (node->m_plugin->supports_export_bpp_proc != NULL) ? |
680 | 0 | node->m_plugin->supports_export_bpp_proc(depth) : FALSE : FALSE; |
681 | 0 | } |
682 | | |
683 | 0 | return FALSE; |
684 | 0 | } |
685 | | |
686 | | BOOL DLL_CALLCONV |
687 | 0 | FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type) { |
688 | 0 | if (s_plugins != NULL) { |
689 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
690 | |
|
691 | 0 | return (node != NULL) ? |
692 | 0 | (node->m_plugin->supports_export_type_proc != NULL) ? |
693 | 0 | node->m_plugin->supports_export_type_proc(type) : FALSE : FALSE; |
694 | 0 | } |
695 | | |
696 | 0 | return FALSE; |
697 | 0 | } |
698 | | |
699 | | BOOL DLL_CALLCONV |
700 | 0 | FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif) { |
701 | 0 | if (s_plugins != NULL) { |
702 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
703 | |
|
704 | 0 | return (node != NULL) ? |
705 | 0 | (node->m_plugin->supports_icc_profiles_proc != NULL) ? |
706 | 0 | node->m_plugin->supports_icc_profiles_proc() : FALSE : FALSE; |
707 | 0 | } |
708 | | |
709 | 0 | return FALSE; |
710 | 0 | } |
711 | | |
712 | | BOOL DLL_CALLCONV |
713 | 0 | FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif) { |
714 | 0 | if (s_plugins != NULL) { |
715 | 0 | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
716 | |
|
717 | 0 | return (node != NULL) ? |
718 | 0 | (node->m_plugin->supports_no_pixels_proc != NULL) ? |
719 | 0 | node->m_plugin->supports_no_pixels_proc() : FALSE : FALSE; |
720 | 0 | } |
721 | | |
722 | 0 | return FALSE; |
723 | 0 | } |
724 | | |
725 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
726 | 0 | FreeImage_GetFIFFromFilename(const char *filename) { |
727 | 0 | if (filename != NULL) { |
728 | 0 | const char *extension; |
729 | | |
730 | | // get the proper extension if we received a filename |
731 | |
|
732 | 0 | char *place = strrchr((char *)filename, '.'); |
733 | 0 | extension = (place != NULL) ? ++place : filename; |
734 | | |
735 | | // look for the extension in the plugin table |
736 | |
|
737 | 0 | for (int i = 0; i < FreeImage_GetFIFCount(); ++i) { |
738 | |
|
739 | 0 | if (s_plugins->FindNodeFromFIF(i)->m_enabled) { |
740 | | |
741 | | // compare the format id with the extension |
742 | |
|
743 | 0 | if (FreeImage_stricmp(FreeImage_GetFormatFromFIF((FREE_IMAGE_FORMAT)i), extension) == 0) { |
744 | 0 | return (FREE_IMAGE_FORMAT)i; |
745 | 0 | } else { |
746 | | // make a copy of the extension list and split it |
747 | |
|
748 | 0 | char *copy = (char *)malloc(strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)) + 1); |
749 | 0 | memset(copy, 0, strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)) + 1); |
750 | 0 | memcpy(copy, FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i), strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i))); |
751 | | |
752 | | // get the first token |
753 | |
|
754 | 0 | char *token = strtok(copy, ","); |
755 | |
|
756 | 0 | while (token != NULL) { |
757 | 0 | if (FreeImage_stricmp(token, extension) == 0) { |
758 | 0 | free(copy); |
759 | |
|
760 | 0 | return (FREE_IMAGE_FORMAT)i; |
761 | 0 | } |
762 | | |
763 | 0 | token = strtok(NULL, ","); |
764 | 0 | } |
765 | | |
766 | | // free the copy of the extension list |
767 | | |
768 | 0 | free(copy); |
769 | 0 | } |
770 | 0 | } |
771 | 0 | } |
772 | 0 | } |
773 | | |
774 | 0 | return FIF_UNKNOWN; |
775 | 0 | } |
776 | | |
777 | | FREE_IMAGE_FORMAT DLL_CALLCONV |
778 | 0 | FreeImage_GetFIFFromFilenameU(const wchar_t *filename) { |
779 | | #ifdef _WIN32 |
780 | | if (filename == NULL) return FIF_UNKNOWN; |
781 | | |
782 | | // get the proper extension if we received a filename |
783 | | wchar_t *place = wcsrchr((wchar_t *)filename, '.'); |
784 | | if (place == NULL) return FIF_UNKNOWN; |
785 | | // convert to single character - no national chars in extensions |
786 | | char *extension = (char *)malloc(wcslen(place)+1); |
787 | | unsigned int i=0; |
788 | | for(; i < wcslen(place); i++) // convert 16-bit to 8-bit |
789 | | extension[i] = (char)(place[i] & 0x00FF); |
790 | | // set terminating 0 |
791 | | extension[i]=0; |
792 | | FREE_IMAGE_FORMAT fRet = FreeImage_GetFIFFromFilename(extension); |
793 | | free(extension); |
794 | | |
795 | | return fRet; |
796 | | #else |
797 | 0 | return FIF_UNKNOWN; |
798 | 0 | #endif // _WIN32 |
799 | 0 | } |
800 | | |
801 | | BOOL DLL_CALLCONV |
802 | 902k | FreeImage_ValidateFIF(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle) { |
803 | 902k | if (s_plugins != NULL) { |
804 | 902k | BOOL validated = FALSE; |
805 | | |
806 | 902k | PluginNode *node = s_plugins->FindNodeFromFIF(fif); |
807 | | |
808 | 902k | if (node) { |
809 | 902k | long tell = io->tell_proc(handle); |
810 | | |
811 | 902k | validated = (node != NULL) ? (node->m_enabled) ? (node->m_plugin->validate_proc != NULL) ? node->m_plugin->validate_proc(io, handle) : FALSE : FALSE : FALSE; |
812 | | |
813 | 902k | io->seek_proc(handle, tell, SEEK_SET); |
814 | 902k | } |
815 | | |
816 | 902k | return validated; |
817 | 902k | } |
818 | | |
819 | 0 | return FALSE; |
820 | 902k | } |