// ==========================================================
// EXR Loader and writer
//
// Design and implementation by 
// - Hervé Drolon (drolon@infonie.fr)
// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================

#include "FreeImage.h"
#include "Utilities.h"

#ifdef _MSC_VER
// OpenEXR has many problems with MSVC warnings (why not just correct them ?), just ignore one of them
#pragma warning (disable : 4800) // ImfVersion.h - 'const int' : forcing value to bool 'true' or 'false' (performance warning)
#endif 
#include "third_party/openexr/IlmImf/ImfIO.h"
#include "third_party/ilmbase/Iex/Iex.h"
#include "third_party/openexr/IlmImf/ImfOutputFile.h"
#include "third_party/openexr/IlmImf/ImfInputFile.h"
#include "third_party/openexr/IlmImf/ImfRgbaFile.h"
#include "third_party/openexr/IlmImf/ImfChannelList.h"
#include "third_party/openexr/IlmImf/ImfRgba.h"
#include "third_party/openexr/IlmImf/ImfArray.h"
#include "third_party/openexr/IlmImf/ImfPreviewImage.h"
#include "third_party/ilmbase/Half/half.h"


// ==========================================================
// Plugin Interface
// ==========================================================

static int s_format_id;

// ----------------------------------------------------------

/**
FreeImage input stream wrapper
@see Imf_2_2::IStream
*/
class C_IStream : public Imf::IStream {
private:
    FreeImageIO *_io;
	fi_handle _handle;

public:
	C_IStream (FreeImageIO *io, fi_handle handle) : 
	  Imf::IStream(""), _io (io), _handle(handle) {
	}

	virtual bool read (char c[/*n*/], int n) {
		return ((unsigned)n != _io->read_proc(c, 1, n, _handle));
	}

	virtual Imath::Int64 tellg() {
		return _io->tell_proc(_handle);
	}

	virtual void seekg(Imath::Int64 pos) {
		_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
	}

	virtual void clear() {
	}
};

// ----------------------------------------------------------

/**
FreeImage output stream wrapper
@see Imf_2_2::OStream
*/
class C_OStream : public Imf::OStream {
private:
    FreeImageIO *_io;
	fi_handle _handle;

public:
	C_OStream (FreeImageIO *io, fi_handle handle) : 
	  Imf::OStream(""), _io (io), _handle(handle) {
	}

	virtual void write(const char c[/*n*/], int n) {
		if((unsigned)n != _io->write_proc((void*)&c[0], 1, n, _handle)) {
			Iex::throwErrnoExc();
		}
	}

	virtual Imath::Int64 tellp() {
		return _io->tell_proc(_handle);
	}

	virtual void seekp(Imath::Int64 pos) {
		_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
	}
};

// ----------------------------------------------------------


// ==========================================================
// Plugin Implementation
// ==========================================================

static const char * DLL_CALLCONV
Format() {
	return "EXR";
}

static const char * DLL_CALLCONV
Description() {
	return "ILM OpenEXR";
}

static const char * DLL_CALLCONV
Extension() {
	return "exr";
}

static const char * DLL_CALLCONV
RegExpr() {
	return NULL;
}

static const char * DLL_CALLCONV
MimeType() {
	return "image/x-exr";
}

static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	BYTE exr_signature[] = { 0x76, 0x2F, 0x31, 0x01 };
	BYTE signature[] = { 0, 0, 0, 0 };

	io->read_proc(signature, 1, 4, handle);
	return (memcmp(exr_signature, signature, 4) == 0);
}

static BOOL DLL_CALLCONV
SupportsExportDepth(int depth) {
	return FALSE;
}

static BOOL DLL_CALLCONV 
SupportsExportType(FREE_IMAGE_TYPE type) {
	return (
		(type == FIT_FLOAT) ||
		(type == FIT_RGBF)  ||
		(type == FIT_RGBAF)
	);
}

static BOOL DLL_CALLCONV
SupportsNoPixels() {
	return TRUE;
}

// --------------------------------------------------------------------------

static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	bool bUseRgbaInterface = false;
	FIBITMAP *dib = NULL;	

	if(!handle) {
		return NULL;
	}

	try {
		BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

		// save the stream starting point
		const long stream_start = io->tell_proc(handle);

		// wrap the FreeImage IO stream
		C_IStream istream(io, handle);

		// open the file
		Imf::InputFile file(istream);

		// get file info			
		const Imath::Box2i &dataWindow = file.header().dataWindow();
		int width  = dataWindow.max.x - dataWindow.min.x + 1;
		int height = dataWindow.max.y - dataWindow.min.y + 1;

		//const Imf::Compression &compression = file.header().compression();

		const Imf::ChannelList &channels = file.header().channels();

		// check the number of components and check for a coherent format

		std::string exr_color_model;
		Imf::PixelType pixel_type = Imf::HALF;
		FREE_IMAGE_TYPE image_type = FIT_UNKNOWN;
		int components = 0;
		bool bMixedComponents = false;

		for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
			components++;
			if(components == 1) {
				exr_color_model += i.name();
				pixel_type = i.channel().type;
			} else {
				exr_color_model += "/";
				exr_color_model += i.name();
				if (i.channel().type != pixel_type) {
					bMixedComponents = true;
				}
			}
		}

		if(bMixedComponents) {
			bool bHandled = false;
			// we may have a RGBZ or RGBAZ image ... 
			if(components > 4) {
				if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B") && channels.findChannel("A")) {
					std::string msg = "Warning: converting color model " + exr_color_model + " to RGBA color model";
					FreeImage_OutputMessageProc(s_format_id, msg.c_str());
					bHandled = true;
				}
			}
			else if(components > 3) {
				if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
					std::string msg = "Warning: converting color model " + exr_color_model + " to RGB color model";
					FreeImage_OutputMessageProc(s_format_id, msg.c_str());
					bHandled = true;
				}
			}
			if(!bHandled) {
				THROW (Iex::InputExc, "Unable to handle mixed component types (color model = " << exr_color_model << ")");
			} 
		}

		switch(pixel_type) {
			case Imf::UINT:
				THROW (Iex::InputExc, "Unsupported format: UINT");
				break;
			case Imf::HALF:
			case Imf::FLOAT:
			default:
				break;
		}

		// check for supported image color models
		// --------------------------------------------------------------

		if((components == 1) || (components == 2)) {				
			// if the image is gray-alpha (YA), ignore the alpha channel
			if((components == 1) && channels.findChannel("Y")) {
				image_type = FIT_FLOAT;
				components = 1;
			} else {
				std::string msg = "Warning: loading color model " + exr_color_model + " as Y color model";
				FreeImage_OutputMessageProc(s_format_id, msg.c_str());
				image_type = FIT_FLOAT;
				// ignore the other channel
				components = 1;
			}
		} else if(components == 3) {
			if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
				image_type = FIT_RGBF;
			}
			else if(channels.findChannel("BY") && channels.findChannel("RY") && channels.findChannel("Y")) {
				image_type = FIT_RGBF;
				bUseRgbaInterface = true;
			}
		} else if(components >= 4) {
			if(channels.findChannel("R") && channels.findChannel("G") && channels.findChannel("B")) {
				if(channels.findChannel("A")) {
					if(components > 4) {
						std::string msg = "Warning: converting color model " + exr_color_model + " to RGBA color model";
						FreeImage_OutputMessageProc(s_format_id, msg.c_str());
					}
					image_type = FIT_RGBAF;
					// ignore other layers if there is more than one alpha layer
					components = 4;
				} else {
					std::string msg = "Warning: converting color model " + exr_color_model + " to RGB color model";
					FreeImage_OutputMessageProc(s_format_id, msg.c_str());

					image_type = FIT_RGBF;
					// ignore other channels
					components = 3;					
				}
			}
		}

		if(image_type == FIT_UNKNOWN) {
			THROW (Iex::InputExc, "Unsupported color model: " << exr_color_model);
		}

		// allocate a new dib
		dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, 0);
		if(!dib) THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);

		// try to load the preview image
		// --------------------------------------------------------------

		if(file.header().hasPreviewImage()) {
			const Imf::PreviewImage& preview = file.header().previewImage();
			const unsigned thWidth = preview.width();
			const unsigned thHeight = preview.height();
			
			FIBITMAP* thumbnail = FreeImage_Allocate(thWidth, thHeight, 32);
			if(thumbnail) {
				const Imf::PreviewRgba *src_line = preview.pixels();
				BYTE *dst_line = FreeImage_GetScanLine(thumbnail, thHeight - 1);
				const unsigned dstPitch = FreeImage_GetPitch(thumbnail);
				
				for (unsigned y = 0; y < thHeight; ++y) {
					const Imf::PreviewRgba *src_pixel = src_line;
					RGBQUAD* dst_pixel = (RGBQUAD*)dst_line;
					
					for(unsigned x = 0; x < thWidth; ++x) {
						dst_pixel->rgbRed = src_pixel->r;
						dst_pixel->rgbGreen = src_pixel->g;
						dst_pixel->rgbBlue = src_pixel->b;
						dst_pixel->rgbReserved = src_pixel->a;				
						src_pixel++;
						dst_pixel++;
					}
					src_line += thWidth;
					dst_line -= dstPitch;
				}
				FreeImage_SetThumbnail(dib, thumbnail);
				FreeImage_Unload(thumbnail);
			}
		}

		if(header_only) {
			// header only mode
			return dib;
		}

		// load pixels
		// --------------------------------------------------------------

		const BYTE *bits = FreeImage_GetBits(dib);			// pointer to our pixel buffer
		const size_t bytespp = sizeof(float) * components;	// size of our pixel in bytes
		const unsigned pitch = FreeImage_GetPitch(dib);		// size of our yStride in bytes

		Imf::PixelType pixelType = Imf::FLOAT;	// load as float data type;
		
		if(bUseRgbaInterface) {
			// use the RGBA interface (used when loading RY BY Y images )

			const int chunk_size = 16;

			BYTE *scanline = (BYTE*)bits;

			// re-open using the RGBA interface
			io->seek_proc(handle, stream_start, SEEK_SET);
			Imf::RgbaInputFile rgbaFile(istream);

			// read the file in chunks
			Imath::Box2i dw = dataWindow;
			Imf::Array2D<Imf::Rgba> chunk(chunk_size, width);
			while (dw.min.y <= dw.max.y) {
				// read a chunk
				rgbaFile.setFrameBuffer (&chunk[0][0] - dw.min.x - dw.min.y * width, 1, width);
				rgbaFile.readPixels (dw.min.y, MIN(dw.min.y + chunk_size - 1, dw.max.y));
				// fill the dib
				const int y_max = ((dw.max.y - dw.min.y) <= chunk_size) ? (dw.max.y - dw.min.y) : chunk_size;
				for(int y = 0; y < y_max; y++) {
					FIRGBF *pixel = (FIRGBF*)scanline;
					const Imf::Rgba *half_rgba = chunk[y];
					for(int x = 0; x < width; x++) {
						// convert from half to float
						pixel[x].red = half_rgba[x].r;
						pixel[x].green = half_rgba[x].g;
						pixel[x].blue = half_rgba[x].b;
					}
					// next line
					scanline += pitch;
				}
				// next chunk
				dw.min.y += chunk_size;
			}

		} else {
			// use the low level interface

			// build a frame buffer (i.e. what we want on output)
			Imf::FrameBuffer frameBuffer;

			// allow dataWindow with minimal bounds different form zero
			size_t offset = - dataWindow.min.x * bytespp - dataWindow.min.y * pitch;

			if(components == 1) {
				frameBuffer.insert ("Y",	// name
					Imf::Slice (pixelType,	// type
					(char*)(bits + offset), // base
					bytespp,				// xStride
					pitch,					// yStride
					1, 1,					// x/y sampling
					0.0));					// fillValue
			} else if((components == 3) || (components == 4)) {
				const char *channel_name[4] = { "R", "G", "B", "A" };

				for(int c = 0; c < components; c++) {
					frameBuffer.insert (
						channel_name[c],					// name
						Imf::Slice (pixelType,				// type
						(char*)(bits + c * sizeof(float) + offset), // base
						bytespp,							// xStride
						pitch,								// yStride
						1, 1,								// x/y sampling
						0.0));								// fillValue
				}
			}

			// read the file
			file.setFrameBuffer(frameBuffer);
			file.readPixels(dataWindow.min.y, dataWindow.max.y);
		}

		// lastly, flip dib lines
		FreeImage_FlipVertical(dib);

	}
	catch(Iex::BaseExc & e) {
		if(dib != NULL) {
			FreeImage_Unload(dib);
		}
		FreeImage_OutputMessageProc(s_format_id, e.what());
		return NULL;
	}

	return dib;
}

/**
Set the preview image using the dib embedded thumbnail
*/
static BOOL
SetPreviewImage(FIBITMAP *dib, Imf::Header& header) {
	if(!FreeImage_GetThumbnail(dib)) {
		return FALSE;
	}
	FIBITMAP* thumbnail = FreeImage_GetThumbnail(dib);

	if((FreeImage_GetImageType(thumbnail) != FIT_BITMAP) || (FreeImage_GetBPP(thumbnail) != 32)) {
		// invalid thumbnail - ignore it
		FreeImage_OutputMessageProc(s_format_id, FI_MSG_WARNING_INVALID_THUMBNAIL);
	} else {
		const unsigned thWidth = FreeImage_GetWidth(thumbnail);
		const unsigned thHeight = FreeImage_GetHeight(thumbnail);
		
		Imf::PreviewImage preview(thWidth, thHeight);

		// copy thumbnail to 32-bit RGBA preview image
		
		const BYTE* src_line = FreeImage_GetScanLine(thumbnail, thHeight - 1);
		Imf::PreviewRgba* dst_line = preview.pixels();
		const unsigned srcPitch = FreeImage_GetPitch(thumbnail);
		
		for (unsigned y = 0; y < thHeight; y++) {
			const RGBQUAD* src_pixel = (RGBQUAD*)src_line;
			Imf::PreviewRgba* dst_pixel = dst_line;
			
			for(unsigned x = 0; x < thWidth; x++) {
				dst_pixel->r = src_pixel->rgbRed;
				dst_pixel->g = src_pixel->rgbGreen;
				dst_pixel->b = src_pixel->rgbBlue;
				dst_pixel->a = src_pixel->rgbReserved;
				
				src_pixel++;
				dst_pixel++;
			}
			
			src_line -= srcPitch;
			dst_line += thWidth;
		}
		
		header.setPreviewImage(preview);
	}

	return TRUE;
}

/**
Save using EXR_LC compression (works only with RGB[A]F images)
*/
static BOOL 
SaveAsEXR_LC(C_OStream& ostream, FIBITMAP *dib, Imf::Header& header, int width, int height) {
	int x, y;
	Imf::RgbaChannels rgbaChannels;

	try {

		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);

		// convert from float to half
		Imf::Array2D<Imf::Rgba> pixels(height, width);
		switch(image_type) {
			case FIT_RGBF:
				rgbaChannels = Imf::WRITE_YC;
				for(y = 0; y < height; y++) {
					FIRGBF *src_bits = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
					for(x = 0; x < width; x++) {
						Imf::Rgba &dst_bits = pixels[y][x];
						dst_bits.r = src_bits[x].red;
						dst_bits.g = src_bits[x].green;
						dst_bits.b = src_bits[x].blue;
					}
				}
				break;
			case FIT_RGBAF:
				rgbaChannels = Imf::WRITE_YCA;
				for(y = 0; y < height; y++) {
					FIRGBAF *src_bits = (FIRGBAF*)FreeImage_GetScanLine(dib, height - 1 - y);
					for(x = 0; x < width; x++) {
						Imf::Rgba &dst_bits = pixels[y][x];
						dst_bits.r = src_bits[x].red;
						dst_bits.g = src_bits[x].green;
						dst_bits.b = src_bits[x].blue;
						dst_bits.a = src_bits[x].alpha;
					}
				}
				break;
			default:
				THROW (Iex::IoExc, "Bad image type");
				break;
		}

		// write the data
		Imf::RgbaOutputFile file(ostream, header, rgbaChannels);
		file.setFrameBuffer (&pixels[0][0], 1, width);
		file.writePixels (height);

		return TRUE;

	} catch(Iex::BaseExc & e) {
		FreeImage_OutputMessageProc(s_format_id, e.what());

		return FALSE;
	}

}

static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	const char *channel_name[4] = { "R", "G", "B", "A" };
	BOOL bIsFlipped = FALSE;
	half *halfData = NULL;

	if(!dib || !handle) return FALSE;

	try {
		// check for EXR_LC compression and verify that the format is RGB
		if((flags & EXR_LC) == EXR_LC) {
			FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
			if(((image_type != FIT_RGBF) && (image_type != FIT_RGBAF)) || ((flags & EXR_FLOAT) == EXR_FLOAT)) {
				THROW (Iex::IoExc, "EXR_LC compression is only available with RGB[A]F images");
			}
			if((FreeImage_GetWidth(dib) % 2) || (FreeImage_GetHeight(dib) % 2)) {
				THROW (Iex::IoExc, "EXR_LC compression only works when the width and height are a multiple of 2");
			}
		}

		// wrap the FreeImage IO stream
		C_OStream ostream(io, handle);

		// compression
		Imf::Compression compress;
		if((flags & EXR_NONE) == EXR_NONE) {
			// no compression
			compress = Imf::NO_COMPRESSION;
		} else if((flags & EXR_ZIP) == EXR_ZIP) {
			// zlib compression, in blocks of 16 scan lines
			compress = Imf::ZIP_COMPRESSION;
		} else if((flags & EXR_PIZ) == EXR_PIZ) {
			// piz-based wavelet compression
			compress = Imf::PIZ_COMPRESSION;
		} else if((flags & EXR_PXR24) == EXR_PXR24) {
			// lossy 24-bit float compression
			compress = Imf::PXR24_COMPRESSION;
		} else if((flags & EXR_B44) == EXR_B44) {
			// lossy 44% float compression
			compress = Imf::B44_COMPRESSION;
		} else {
			// default value
			compress = Imf::PIZ_COMPRESSION;
		}

		// create the header
		int width  = FreeImage_GetWidth(dib);
		int height = FreeImage_GetHeight(dib);
		int dx = 0, dy = 0;

		Imath::Box2i dataWindow (Imath::V2i (0, 0), Imath::V2i (width - 1, height - 1));
		Imath::Box2i displayWindow (Imath::V2i (-dx, -dy), Imath::V2i (width - dx - 1, height - dy - 1));

		Imf::Header header = Imf::Header(displayWindow, dataWindow, 1, 
			Imath::V2f(0,0), 1, 
			Imf::INCREASING_Y, compress);        		

		// handle thumbnail
		SetPreviewImage(dib, header);
		
		// check for EXR_LC compression
		if((flags & EXR_LC) == EXR_LC) {
			return SaveAsEXR_LC(ostream, dib, header, width, height);
		}

		// output pixel type
		Imf::PixelType pixelType;
		if((flags & EXR_FLOAT) == EXR_FLOAT) {
			pixelType = Imf::FLOAT;	// save as float data type
		} else {
			// default value
			pixelType = Imf::HALF;	// save as half data type
		}

		// check the data type and number of channels
		int components = 0;
		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
		switch(image_type) {
			case FIT_FLOAT:
				components = 1;
				// insert luminance channel
				header.channels().insert ("Y", Imf::Channel(pixelType));
				break;
			case FIT_RGBF:
				components = 3;
				for(int c = 0; c < components; c++) {
					// insert R, G and B channels
					header.channels().insert (channel_name[c], Imf::Channel(pixelType));
				}
				break;
			case FIT_RGBAF:
				components = 4;
				for(int c = 0; c < components; c++) {
					// insert R, G, B and A channels
					header.channels().insert (channel_name[c], Imf::Channel(pixelType));
				}
				break;
			default:
				THROW (Iex::ArgExc, "Cannot save: invalid data type.\nConvert the image to float before saving as OpenEXR.");
		}

		// build a frame buffer (i.e. what we have on input)
		Imf::FrameBuffer frameBuffer;

		BYTE *bits = NULL;	// pointer to our pixel buffer
		size_t bytespp = 0;	// size of our pixel in bytes
		size_t bytespc = 0;	// size of our pixel component in bytes
		unsigned pitch = 0;	// size of our yStride in bytes


		if(pixelType == Imf::HALF) {
			// convert from float to half
			halfData = new(std::nothrow) half[width * height * components];
			if(!halfData) {
				THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);
			}

			for(int y = 0; y < height; y++) {
				float *src_bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
				half *dst_bits = halfData + y * width * components;
				for(int x = 0; x < width; x++) {
					for(int c = 0; c < components; c++) {
						dst_bits[c] = src_bits[c];
					}
					src_bits += components;
					dst_bits += components;
				}
			}
			bits = (BYTE*)halfData;
			bytespc = sizeof(half);
			bytespp = sizeof(half) * components;
			pitch = sizeof(half) * width * components;
		} else if(pixelType == Imf::FLOAT) {
			// invert dib scanlines
			bIsFlipped = FreeImage_FlipVertical(dib);
		
			bits = FreeImage_GetBits(dib);
			bytespc = sizeof(float);
			bytespp = sizeof(float) * components;
			pitch = FreeImage_GetPitch(dib);
		}

		if(image_type == FIT_FLOAT) {
			frameBuffer.insert ("Y",	// name
				Imf::Slice (pixelType,	// type
				(char*)(bits),			// base
				bytespp,				// xStride
				pitch));				// yStride
		} else if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF)) {			
			for(int c = 0; c < components; c++) {
				char *channel_base = (char*)(bits) + c*bytespc;
				frameBuffer.insert (channel_name[c],// name
					Imf::Slice (pixelType,			// type
					channel_base,					// base
					bytespp,	// xStride
					pitch));	// yStride
			}
		}

		// write the data
		Imf::OutputFile file (ostream, header);
		file.setFrameBuffer (frameBuffer);
		file.writePixels (height);

		if(halfData != NULL) {
			delete[] halfData;
		}
		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		return TRUE;

	} catch(Iex::BaseExc & e) {
		if(halfData != NULL) {
			delete[] halfData;
		}
		if(bIsFlipped) {
			// invert dib scanlines
			FreeImage_FlipVertical(dib);
		}

		FreeImage_OutputMessageProc(s_format_id, e.what());

		return FALSE;
	}	
}

// ==========================================================
//   Init
// ==========================================================

void DLL_CALLCONV
InitEXR(Plugin *plugin, int format_id) {
	s_format_id = format_id;

	// initialize the OpenEXR library
	// note that this OpenEXR function produce so called "false memory leaks"
	// see http://lists.nongnu.org/archive/html/openexr-devel/2013-11/msg00000.html
	Imf::staticInitialize();

	plugin->format_proc = Format;
	plugin->description_proc = Description;
	plugin->extension_proc = Extension;
	plugin->regexpr_proc = RegExpr;
	plugin->open_proc = NULL;
	plugin->close_proc = NULL;
	plugin->pagecount_proc = NULL;
	plugin->pagecapability_proc = NULL;
	plugin->load_proc = Load;
	plugin->save_proc = Save;
	plugin->validate_proc = Validate;
	plugin->mime_proc = MimeType;
	plugin->supports_export_bpp_proc = SupportsExportDepth;
	plugin->supports_export_type_proc = SupportsExportType;
	plugin->supports_icc_profiles_proc = NULL;
	plugin->supports_no_pixels_proc = SupportsNoPixels;
}
