summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage/PluginEXR.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginEXR.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginEXR.cpp773
1 files changed, 0 insertions, 773 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/PluginEXR.cpp b/plugins/AdvaImg/src/FreeImage/PluginEXR.cpp
deleted file mode 100644
index b286430380..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginEXR.cpp
+++ /dev/null
@@ -1,773 +0,0 @@
-// ==========================================================
-// 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 "../OpenEXR/IlmImf/ImfIO.h"
-#include "../OpenEXR/Iex/Iex.h"
-#include "../OpenEXR/IlmImf/ImfOutputFile.h"
-#include "../OpenEXR/IlmImf/ImfInputFile.h"
-#include "../OpenEXR/IlmImf/ImfRgbaFile.h"
-#include "../OpenEXR/IlmImf/ImfChannelList.h"
-#include "../OpenEXR/IlmImf/ImfRgba.h"
-#include "../OpenEXR/IlmImf/ImfArray.h"
-#include "../OpenEXR/IlmImf/ImfPreviewImage.h"
-#include "../OpenEXR/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;
-}