FreeImage is a popular, open source library for reading and writing images. In this post I go over how to disable unused plugins to improve compile times and reduce library sizes.

FreeImage is a popular, open source library for reading and writing common image formats from C/C++ applications (and many other applications through the many available wrappers). However, the full FreeImage library support over 30 different file formats, which results in long compile times, big binaries and, presumably, longer link times.

Many pieces of software using FreeImage really only require a handful of the image formats available. Fortunately, the underlying plugin structure of FreeImage makes it fairly easy to remove the unused code. From a recent set of builds, reducing the formats FreeImage supports to just the 6 we actually use, reduced our static library size from 20.5Mb/4MB (Debug/Release) to 6Mb/1.4MB. As all of the plugins are required at run-time, just incase they are used, it’s fairly reasonable to assume this would also strip 2.6Mb from the resulting binary - as well as reducing link times I would imagine.

Overview: Disabling / Removing a FreeImage Plugin

  1. Remove the relevant ‘Source/FreeImage/PluginXXX.cpp’ file and related files from your project/make file.
  2. Edit ‘Source/FreeImage/Plugin.cpp’ and comment out the relevant s_plugins->AddNode lines for your plugins.
  3. Edit ‘Source/FreeImage/FreeImage.h’ and re-adjust the FREE_IMAGE_FORMAT enum to account for the missing plugins.

Example: Removing the EXR FreeImage Plugin

Step 1. Removing the Files

Whether you are using CMake, Visual Studio, Xcode or Makefiles - you will want to remove the file ‘Source/FreeImage/PluginEXR.cpp’ from your project, so that it will no longer compile.

It’s also relatively easy to remove all of the files related to the EXR file format, as the EXR format relies on OpenEXR. If you’re using CMake, you can just comment out all of the .cpp/.h files that exist in ‘Source/OpenEXR’. This removes about 60-70 .cpp files from the project.

Step 2. Don’t Initialise the Plugin

In the file ‘Source/FreeImage/Plugin.cpp’, find the function ‘FreeImage_Initialise’. It will contains some code that looks something like the following;

if (s_plugins) {
    s_plugins->AddNode(InitBMP);
    s_plugins->AddNode(InitICO);
    s_plugins->AddNode(InitJPEG);
    ...

Each “AddNode” statement adds a new plugin to FreeImage. If you are removing just one or two modules, you can simply comment them out. If you are removing a whole bunch, you might want to move all of the ones you comment out to the bottom of the file, so that you can easily see which modules are left for Step 3.

Step 3. Fix the FREE_IMAGE_FORMAT enum

The FREE_IMAGE_FORMAT enum needs to match up with the list of nodes/plugins that you added exactly. For instance, in the example above, InitBMP relates to FIF_BMP at index 0 in the enum. Essentially, the list of plugins and the list of AddNode statements and the list of formats should be of the same size and contain all of the same entries.

As an example, if we had removed the ICO image format above, we would have…

if (s_plugins) {
    s_plugins->AddNode(InitBMP);
    // s_plugins->AddNode(InitICO);
    s_plugins->AddNode(InitJPEG);
    ...

And then the enum would become…

FI_ENUM(FREE_IMAGE_FORMAT) {
    FIF_UNKNOWN = -1,
    FIF_BMP 	= 0,
    // FIF_ICO 	= 1,
    FIF_JPEG	= 1,
    ...
}

Hope this helps!