Coverage Report

Created: 2026-07-16 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}