diff options
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginHDR.cpp')
-rw-r--r-- | plugins/AdvaImg/src/FreeImage/PluginHDR.cpp | 722 |
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; -} |