While debugging a JPEG saving issue, I encountered a critical lack of error handling in the core plugin routing logic: In FreeImage_SaveToHandle (and the underlying PluginNode::Save calls), the code calls DoSave even if DoOpen fails to initialize the data structures (returning nullptr). See the code snippet:
bool Save(FIBITMAP* dib, FreeImageIO* io, fi_handle handle, int page, int flags) {
void* data = DoOpen(io, handle, false); // Returns nullptr for certain plugins or failures
const bool result = DoSave(dib, io, handle, page, flags, data); // 'data' is passed without check
DoClose(io, handle, data);
return result;
}
In my specific case with the JPEG Plugin, saving a 32-bit BMP as a JPEG results in a 0-byte file being created on disk. While the plugin correctly identifies the bit-depth incompatibility and returns FALSE, the architecture's failure to validate the I/O state (data) makes debugging significantly harder and leads to inconsistent file system states.
Users get a FALSE return value but are left with an empty 0-byte file on the disk because the file was opened but never written to, while passing a null data pointer to plugins that expect a valid state structure is a potential source of crashes.