summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage/PluginHDR.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginHDR.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginHDR.cpp722
1 files changed, 0 insertions, 722 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/PluginHDR.cpp b/plugins/AdvaImg/src/FreeImage/PluginHDR.cpp
deleted file mode 100644
index 28ce1a5768..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginHDR.cpp
+++ /dev/null
@@ -1,722 +0,0 @@
-// ==========================================================
-// HDR Loader and writer
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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"
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// RGBE library
-// ==========================================================
-
-// ----------------------------------------------------------
-
-// maximum size of a line in the header
-#define HDR_MAXLINE 256
-
-// flags indicating which fields in an rgbeHeaderInfo are valid
-#define RGBE_VALID_PROGRAMTYPE 0x01
-#define RGBE_VALID_COMMENT 0x02
-#define RGBE_VALID_GAMMA 0x04
-#define RGBE_VALID_EXPOSURE 0x08
-
-// offsets to red, green, and blue components in a data (float) pixel
-#define RGBE_DATA_RED 0
-#define RGBE_DATA_GREEN 1
-#define RGBE_DATA_BLUE 2
-
-// ----------------------------------------------------------
-#ifdef _WIN32
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif
-
-typedef struct tagHeaderInfo {
- int valid; // indicate which fields are valid
- char programtype[16]; // listed at beginning of file to identify it after "#?". defaults to "RGBE"
- char comment[HDR_MAXLINE]; // comment beginning with "# "
- float gamma; // image has already been gamma corrected with given gamma. defaults to 1.0 (no correction)
- float exposure; // a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0
-} rgbeHeaderInfo;
-
-#ifdef _WIN32
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif
-
-typedef enum {
- rgbe_read_error,
- rgbe_write_error,
- rgbe_format_error,
- rgbe_memory_error
-} rgbe_error_code;
-
-// ----------------------------------------------------------
-// Prototypes
-// ----------------------------------------------------------
-
-static BOOL rgbe_Error(rgbe_error_code error_code, const char *msg);
-static BOOL rgbe_GetLine(FreeImageIO *io, fi_handle handle, char *buffer, int length);
-static inline void rgbe_FloatToRGBE(BYTE rgbe[4], FIRGBF *rgbf);
-static inline void rgbe_RGBEToFloat(FIRGBF *rgbf, BYTE rgbe[4]);
-static BOOL rgbe_ReadHeader(FreeImageIO *io, fi_handle handle, unsigned *width, unsigned *height, rgbeHeaderInfo *header_info);
-static BOOL rgbe_WriteHeader(FreeImageIO *io, fi_handle handle, unsigned width, unsigned height, rgbeHeaderInfo *info);
-static BOOL rgbe_ReadPixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels);
-static BOOL rgbe_WritePixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels);
-static BOOL rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanline_width, unsigned num_scanlines);
-static BOOL rgbe_WriteBytes_RLE(FreeImageIO *io, fi_handle handle, BYTE *data, int numbytes);
-static BOOL rgbe_WritePixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned scanline_width, unsigned num_scanlines);
-static BOOL rgbe_ReadMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info);
-static BOOL rgbe_WriteMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info);
-
-// ----------------------------------------------------------
-
-/**
-Default error routine. change this to change error handling
-*/
-static BOOL
-rgbe_Error(rgbe_error_code error_code, const char *msg) {
- switch (error_code) {
- case rgbe_read_error:
- FreeImage_OutputMessageProc(s_format_id, "RGBE read error");
- break;
- case rgbe_write_error:
- FreeImage_OutputMessageProc(s_format_id, "RGBE write error");
- break;
- case rgbe_format_error:
- FreeImage_OutputMessageProc(s_format_id, "RGBE bad file format: %s\n", msg);
- break;
- default:
- case rgbe_memory_error:
- FreeImage_OutputMessageProc(s_format_id, "RGBE error: %s\n",msg);
- }
-
- return FALSE;
-}
-
-/**
-Get a line from a ASCII io stream
-*/
-static BOOL
-rgbe_GetLine(FreeImageIO *io, fi_handle handle, char *buffer, int length) {
- int i;
- memset(buffer, 0, length);
- for(i = 0; i < length; i++) {
- if(!io->read_proc(&buffer[i], 1, 1, handle))
- return FALSE;
- if(buffer[i] == 0x0A)
- break;
- }
-
- return (i < length) ? TRUE : FALSE;
-}
-
-/**
-Standard conversion from float pixels to rgbe pixels.
-Note: you can remove the "inline"s if your compiler complains about it
-*/
-static inline void
-rgbe_FloatToRGBE(BYTE rgbe[4], FIRGBF *rgbf) {
- float v;
- int e;
-
- v = rgbf->red;
- if (rgbf->green > v) v = rgbf->green;
- if (rgbf->blue > v) v = rgbf->blue;
- if (v < 1e-32) {
- rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
- }
- else {
- v = (float)(frexp(v, &e) * 256.0 / v);
- rgbe[0] = (BYTE) (rgbf->red * v);
- rgbe[1] = (BYTE) (rgbf->green * v);
- rgbe[2] = (BYTE) (rgbf->blue * v);
- rgbe[3] = (BYTE) (e + 128);
- }
-}
-
-/**
-Standard conversion from rgbe to float pixels.
-Note: Ward uses ldexp(col+0.5,exp-(128+8)).
-However we wanted pixels in the range [0,1] to map back into the range [0,1].
-*/
-static inline void
-rgbe_RGBEToFloat(FIRGBF *rgbf, BYTE rgbe[4]) {
- if (rgbe[3]) { // nonzero pixel
- float f = (float)(ldexp(1.0, rgbe[3] - (int)(128+8)));
- rgbf->red = rgbe[0] * f;
- rgbf->green = rgbe[1] * f;
- rgbf->blue = rgbe[2] * f;
-
- }
- else {
- rgbf->red = rgbf->green = rgbf->blue = 0;
- }
-}
-
-/**
-Minimal header reading. Modify if you want to parse more information
-*/
-static BOOL
-rgbe_ReadHeader(FreeImageIO *io, fi_handle handle, unsigned *width, unsigned *height, rgbeHeaderInfo *header_info) {
- char buf[HDR_MAXLINE];
- float tempf;
- int i;
- BOOL bFormatFound = FALSE;
- BOOL bHeaderFound = FALSE;
-
- header_info->valid = 0;
- header_info->programtype[0] = 0;
- header_info->gamma = 1.0;
- header_info->exposure = 1.0;
-
- // get the first line
- if(!rgbe_GetLine(io, handle, buf, HDR_MAXLINE))
- return rgbe_Error(rgbe_read_error, NULL);
-
- // check the signature
-
- if ((buf[0] != '#')||(buf[1] != '?')) {
- // if you don't want to require the magic token then comment the next line
- return rgbe_Error(rgbe_format_error,"bad initial token");
- }
- else {
- header_info->valid |= RGBE_VALID_PROGRAMTYPE;
- for(i = 0; i < sizeof(header_info->programtype) - 1; i++) {
- if((buf[i+2] == 0) || isspace(buf[i+2]))
- break;
- header_info->programtype[i] = buf[i+2];
- }
- header_info->programtype[i] = 0;
- }
-
- for(;;) {
- // get next line
- if(!rgbe_GetLine(io, handle, buf, HDR_MAXLINE))
- return rgbe_Error(rgbe_read_error, NULL);
-
- if((buf[0] == 0) || (buf[0] == '\n')) {
- // end of header so break out of loop
- bHeaderFound = TRUE;
- break;
- }
- else if(strcmp(buf,"FORMAT=32-bit_rle_rgbe\n") == 0) {
- bFormatFound = TRUE;
- }
- else if(sscanf(buf, "GAMMA=%g", &tempf) == 1) {
- header_info->gamma = tempf;
- header_info->valid |= RGBE_VALID_GAMMA;
- }
- else if(sscanf(buf,"EXPOSURE=%g",&tempf) == 1) {
- header_info->exposure = tempf;
- header_info->valid |= RGBE_VALID_EXPOSURE;
- }
- else if((buf[0] == '#') && (buf[1] == 0x20)) {
- header_info->valid |= RGBE_VALID_COMMENT;
- strcpy(header_info->comment, buf);
- }
- }
- if(!bHeaderFound || !bFormatFound) {
- return rgbe_Error(rgbe_format_error, "invalid header");
- }
-
- // get next line
- if(!rgbe_GetLine(io, handle, buf, HDR_MAXLINE))
- return rgbe_Error(rgbe_read_error, NULL);
-
- // get the image width & height
- if(sscanf(buf,"-Y %d +X %d", height, width) < 2) {
- if(sscanf(buf,"+X %d +Y %d", height, width) < 2) {
- return rgbe_Error(rgbe_format_error, "missing image size specifier");
- }
- }
-
- return TRUE;
-}
-
-/**
- default minimal header. modify if you want more information in header
-*/
-static BOOL
-rgbe_WriteHeader(FreeImageIO *io, fi_handle handle, unsigned width, unsigned height, rgbeHeaderInfo *info) {
- char buffer[HDR_MAXLINE];
-
- const char *programtype = "RADIANCE";
-
- if(info && (info->valid & RGBE_VALID_PROGRAMTYPE)) {
- programtype = info->programtype;
- }
- // The #? is to identify file type, the programtype is optional
- sprintf(buffer, "#?%s\n", programtype);
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- sprintf(buffer, "%s\n", info->comment);
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- sprintf(buffer, "FORMAT=32-bit_rle_rgbe\n");
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- if(info && (info->valid & RGBE_VALID_GAMMA)) {
- sprintf(buffer, "GAMMA=%g\n", info->gamma);
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- }
- if(info && (info->valid & RGBE_VALID_EXPOSURE)) {
- sprintf(buffer,"EXPOSURE=%g\n", info->exposure);
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- }
- sprintf(buffer, "\n-Y %d +X %d\n", height, width);
- if(io->write_proc(buffer, 1, (unsigned int)strlen(buffer), handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
-
- return TRUE;
-}
-
-static BOOL
-rgbe_ReadMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info) {
- return TRUE;
-}
-static BOOL
-rgbe_WriteMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info) {
- header_info->gamma = 1;
- header_info->valid |= RGBE_VALID_GAMMA;
- header_info->exposure = 0;
- header_info->valid |= RGBE_VALID_EXPOSURE;
-
- return TRUE;
-}
-
-/**
-Simple read routine. Will not correctly handle run length encoding
-*/
-static BOOL
-rgbe_ReadPixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels) {
- BYTE rgbe[4];
-
- for(unsigned x = 0; x < numpixels; x++) {
- if(io->read_proc(rgbe, 1, sizeof(rgbe), handle) < 1) {
- return rgbe_Error(rgbe_read_error, NULL);
- }
- rgbe_RGBEToFloat(&data[x], rgbe);
- }
-
- return TRUE;
-}
-
-/**
- Simple write routine that does not use run length encoding.
- These routines can be made faster by allocating a larger buffer and
- fread-ing and fwrite-ing the data in larger chunks.
-*/
-static BOOL
-rgbe_WritePixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels) {
- BYTE rgbe[4];
-
- for(unsigned x = 0; x < numpixels; x++) {
- rgbe_FloatToRGBE(rgbe, &data[x]);
- if(io->write_proc(rgbe, sizeof(rgbe), 1, handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- }
-
- return TRUE;
-}
-
-static BOOL
-rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanline_width, unsigned num_scanlines) {
- BYTE rgbe[4], *scanline_buffer, *ptr, *ptr_end;
- int i, count;
- BYTE buf[2];
-
- if ((scanline_width < 8)||(scanline_width > 0x7fff)) {
- // run length encoding is not allowed so read flat
- return rgbe_ReadPixels(io, handle, data, scanline_width * num_scanlines);
- }
- scanline_buffer = NULL;
- // read in each successive scanline
- while(num_scanlines > 0) {
- if(io->read_proc(rgbe, 1, sizeof(rgbe), handle) < 1) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_read_error,NULL);
- }
- if((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) {
- // this file is not run length encoded
- rgbe_RGBEToFloat(data, rgbe);
- data ++;
- free(scanline_buffer);
- return rgbe_ReadPixels(io, handle, data, scanline_width * num_scanlines - 1);
- }
- if((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_format_error,"wrong scanline width");
- }
- if(scanline_buffer == NULL) {
- scanline_buffer = (BYTE*)malloc(sizeof(BYTE) * 4 * scanline_width);
- if(scanline_buffer == NULL) {
- return rgbe_Error(rgbe_memory_error, "unable to allocate buffer space");
- }
- }
-
- ptr = &scanline_buffer[0];
- // read each of the four channels for the scanline into the buffer
- for(i = 0; i < 4; i++) {
- ptr_end = &scanline_buffer[(i+1)*scanline_width];
- while(ptr < ptr_end) {
- if(io->read_proc(buf, 1, 2 * sizeof(BYTE), handle) < 1) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_read_error, NULL);
- }
- if(buf[0] > 128) {
- // a run of the same value
- count = buf[0] - 128;
- if((count == 0) || (count > ptr_end - ptr)) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_format_error, "bad scanline data");
- }
- while(count-- > 0)
- *ptr++ = buf[1];
- }
- else {
- // a non-run
- count = buf[0];
- if((count == 0) || (count > ptr_end - ptr)) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_format_error, "bad scanline data");
- }
- *ptr++ = buf[1];
- if(--count > 0) {
- if(io->read_proc(ptr, 1, sizeof(BYTE) * count, handle) < 1) {
- free(scanline_buffer);
- return rgbe_Error(rgbe_read_error, NULL);
- }
- ptr += count;
- }
- }
- }
- }
- // now convert data from buffer into floats
- for(i = 0; i < scanline_width; i++) {
- rgbe[0] = scanline_buffer[i];
- rgbe[1] = scanline_buffer[i+scanline_width];
- rgbe[2] = scanline_buffer[i+2*scanline_width];
- rgbe[3] = scanline_buffer[i+3*scanline_width];
- rgbe_RGBEToFloat(data, rgbe);
- data ++;
- }
-
- num_scanlines--;
- }
-
- free(scanline_buffer);
-
- return TRUE;
-}
-
-/**
- The code below is only needed for the run-length encoded files.
- Run length encoding adds considerable complexity but does
- save some space. For each scanline, each channel (r,g,b,e) is
- encoded separately for better compression.
- @return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-rgbe_WriteBytes_RLE(FreeImageIO *io, fi_handle handle, BYTE *data, int numbytes) {
- static const int MINRUNLENGTH = 4;
- int cur, beg_run, run_count, old_run_count, nonrun_count;
- BYTE buf[2];
-
- cur = 0;
- while(cur < numbytes) {
- beg_run = cur;
- // find next run of length at least 4 if one exists
- run_count = old_run_count = 0;
- while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
- beg_run += run_count;
- old_run_count = run_count;
- run_count = 1;
- while((beg_run + run_count < numbytes) && (run_count < 127) && (data[beg_run] == data[beg_run + run_count])) {
- run_count++;
- }
- }
- // if data before next big run is a short run then write it as such
- if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) {
- buf[0] = (BYTE)(128 + old_run_count); // write short run
- buf[1] = data[cur];
- if(io->write_proc(buf, 2 * sizeof(BYTE), 1, handle) < 1)
- return rgbe_Error(rgbe_write_error, NULL);
- cur = beg_run;
- }
- // write out bytes until we reach the start of the next run
- while(cur < beg_run) {
- nonrun_count = beg_run - cur;
- if (nonrun_count > 128)
- nonrun_count = 128;
- buf[0] = (BYTE)nonrun_count;
- if(io->write_proc(buf, sizeof(buf[0]), 1, handle) < 1)
- return rgbe_Error(rgbe_write_error,NULL);
- if(io->write_proc(&data[cur], sizeof(data[0]) * nonrun_count, 1, handle) < 1)
- return rgbe_Error(rgbe_write_error,NULL);
- cur += nonrun_count;
- }
- // write out next run if one was found
- if (run_count >= MINRUNLENGTH) {
- buf[0] = (BYTE)(128 + run_count);
- buf[1] = data[beg_run];
- if(io->write_proc(buf, sizeof(buf[0]) * 2, 1, handle) < 1)
- return rgbe_Error(rgbe_write_error,NULL);
- cur += run_count;
- }
- }
-
- return TRUE;
-}
-
-static BOOL
-rgbe_WritePixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned scanline_width, unsigned num_scanlines) {
- BYTE rgbe[4];
- BYTE *buffer;
-
- if ((scanline_width < 8)||(scanline_width > 0x7fff)) {
- // run length encoding is not allowed so write flat
- return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines);
- }
- buffer = (BYTE*)malloc(sizeof(BYTE) * 4 * scanline_width);
- if (buffer == NULL) {
- // no buffer space so write flat
- return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines);
- }
- while(num_scanlines-- > 0) {
- rgbe[0] = (BYTE)2;
- rgbe[1] = (BYTE)2;
- rgbe[2] = (BYTE)(scanline_width >> 8);
- rgbe[3] = (BYTE)(scanline_width & 0xFF);
- if(io->write_proc(rgbe, sizeof(rgbe), 1, handle) < 1) {
- free(buffer);
- return rgbe_Error(rgbe_write_error, NULL);
- }
- for(unsigned x = 0; x < scanline_width; x++) {
- rgbe_FloatToRGBE(rgbe, data);
- buffer[x] = rgbe[0];
- buffer[x+scanline_width] = rgbe[1];
- buffer[x+2*scanline_width] = rgbe[2];
- buffer[x+3*scanline_width] = rgbe[3];
- data ++;
- }
- // write out each of the four channels separately run length encoded
- // first red, then green, then blue, then exponent
- for(int i = 0; i < 4; i++) {
- BOOL bOK = rgbe_WriteBytes_RLE(io, handle, &buffer[i*scanline_width], scanline_width);
- if(!bOK) {
- free(buffer);
- return bOK;
- }
- }
- }
- free(buffer);
-
- return TRUE;
-}
-
-
-// ----------------------------------------------------------
-
-
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "HDR";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "High Dynamic Range Image";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "hdr";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return NULL;
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/vnd.radiance";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- BYTE hdr_signature[] = { '#', '?' };
- BYTE signature[] = { 0, 0 };
-
- io->read_proc(signature, 1, 2, handle);
-
- return (memcmp(hdr_signature, signature, 2) == 0);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (type == FIT_RGBF) ? TRUE : FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
- return TRUE;
-}
-
-// --------------------------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- FIBITMAP *dib = NULL;
-
- if(!handle) {
- return NULL;
- }
-
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- try {
-
- rgbeHeaderInfo header_info;
- unsigned width, height;
-
- // Read the header
- if(rgbe_ReadHeader(io, handle, &width, &height, &header_info) == FALSE) {
- return NULL;
- }
-
- // allocate a RGBF image
- dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBF, width, height);
- if(!dib) {
- throw FI_MSG_ERROR_MEMORY;
- }
-
- // set the metadata as comments
- rgbe_ReadMetadata(dib, &header_info);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // read the image pixels and fill the dib
-
- for(unsigned y = 0; y < height; y++) {
- FIRGBF *scanline = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
- if(!rgbe_ReadPixels_RLE(io, handle, scanline, width, 1)) {
- FreeImage_Unload(dib);
- return NULL;
- }
- }
-
- }
- catch(const char *text) {
- if(dib != NULL) {
- FreeImage_Unload(dib);
- }
- FreeImage_OutputMessageProc(s_format_id, text);
- }
-
- return dib;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- if(!dib) return FALSE;
-
- FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
- if(src_type != FIT_RGBF) {
- FreeImage_OutputMessageProc(s_format_id, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, FIT_RGBF);
- return FALSE;
- }
-
- unsigned width = FreeImage_GetWidth(dib);
- unsigned height = FreeImage_GetHeight(dib);
-
- // write the header
-
- rgbeHeaderInfo header_info;
- memset(&header_info, 0, sizeof(rgbeHeaderInfo));
- // fill the header with correct gamma and exposure
- rgbe_WriteMetadata(dib, &header_info);
- // fill a comment
- sprintf(header_info.comment, "# Made with FreeImage %s", FreeImage_GetVersion());
- if(!rgbe_WriteHeader(io, handle, width, height, &header_info)) {
- return FALSE;
- }
-
- // write each scanline
-
- for(unsigned y = 0; y < height; y++) {
- FIRGBF *scanline = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
- if(!rgbe_WritePixels_RLE(io, handle, scanline, width, 1)) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitHDR(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- 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;
-}