bool HDRWriter::writeRLE(const osg::Image *img, std::ostream &fout) { int scanline_width = img->s(); int num_scanlines = img->t(); unsigned char rgbe[4]; unsigned char *buffer; if ((scanline_width < MINELEN) || (scanline_width > MAXELEN)) // run length encoding is not allowed so write flat return writeNoRLE(fout, img); buffer = (unsigned char*)malloc(sizeof(unsigned char) * 4 * scanline_width); if (buffer == NULL) // no buffer space so write flat return writeNoRLE(fout, img); for (int row = 0; row < num_scanlines; ++row) { float *data = (float*) img->data(0, row); rgbe[0] = 2; rgbe[1] = 2; rgbe[2] = scanline_width >> 8; rgbe[3] = scanline_width & 0xFF; fout.write(reinterpret_cast<const char*>(rgbe), sizeof(rgbe)); /* if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) { free(buffer); return rgbe_error(rgbe_write_error,NULL); } */ for (int i = 0; i < scanline_width; i++) { float2rgbe(rgbe, data[R], data[G], data[B]); buffer[i] = rgbe[0]; buffer[i + scanline_width] = rgbe[1]; buffer[i + 2 * scanline_width] = rgbe[2]; buffer[i + 3 * scanline_width] = rgbe[3]; data += RGBE_DATA_SIZE; } /* 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++) { if (writeBytesRLE(fout, &buffer[i * scanline_width], scanline_width) != true) { free(buffer); return false; } } } free(buffer); return true; }
/* These routines can be made faster by allocating a larger buffer and fread-ing and iwrite-ing the data in larger chunks */ int RGBE_WritePixels(float *data, int numpixels) { unsigned char rgbe[4]; while (numpixels-- > 0) { float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); data += RGBE_DATA_SIZE; if (iwrite(rgbe, sizeof(rgbe), 1) < 1) return IL_FALSE; } return IL_TRUE; }
/* These routines can be made faster by allocating a larger buffer and fread-ing and fwrite-ing the data in larger chunks */ static int rgbe_write_pixels(struct img_io *io, float *data, int numpixels) { unsigned char rgbe[4]; while(numpixels-- > 0) { float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]); data += RGBE_DATA_SIZE; if(io->write(rgbe, sizeof(rgbe), io->uptr) < 1) return rgbe_error(rgbe_write_error, NULL); } return RGBE_RETURN_SUCCESS; }
/* These routines can be made faster by allocating a larger buffer and fread-ing and fwrite-ing the data in larger chunks */ int RGBE_WritePixels(FILE *fp, float *data, int numpixels) { unsigned char rgbe[4]; while (numpixels-- > 0) { float2rgbe(rgbe,data[RGBE_DATA_RED], data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); data += RGBE_DATA_SIZE; if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) return rgbe_error(rgbe_write_error,NULL); } return RGBE_RETURN_SUCCESS; }
//-------------------------------------------------------------------------------------- // write uncompressed .HDR data // //-------------------------------------------------------------------------------------- void HDR_WritePixels(FILE *fp, float32 *a_RawData, int32 a_NumPixels) { uint8 RGBEData[4]; int32 i; float32 *rawDataPtr; rawDataPtr = a_RawData; for(i=0; i<a_NumPixels; i++) { float2rgbe(RGBEData, rawDataPtr[0], rawDataPtr[1], rawDataPtr[2]); rawDataPtr += 3; fwrite(RGBEData, sizeof(RGBEData), 1, fp); } }
int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width, int num_scanlines) { unsigned char rgbe[4]; unsigned char *buffer; int i, err; if ((scanline_width < 8)||(scanline_width > 0x7fff)) /* run length encoding is not allowed so write flat*/ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines); buffer = (unsigned char *)malloc(sizeof(unsigned char)*4*scanline_width); if (buffer == NULL) /* no buffer space so write flat */ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines); while(num_scanlines-- > 0) { rgbe[0] = 2; rgbe[1] = 2; rgbe[2] = scanline_width >> 8; rgbe[3] = scanline_width & 0xFF; if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) { free(buffer); return rgbe_error(rgbe_write_error,NULL); } for(i=0; i<scanline_width; i++) { float2rgbe(rgbe,data[RGBE_DATA_RED], data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); buffer[i] = rgbe[0]; buffer[i+scanline_width] = rgbe[1]; buffer[i+2*scanline_width] = rgbe[2]; buffer[i+3*scanline_width] = rgbe[3]; data += RGBE_DATA_SIZE; } /* write out each of the four channels separately run length encoded */ /* first red, then green, then blue, then exponent */ for(i=0; i<4; i++) { if ((err = RGBE_WriteBytes_RLE(fp,&buffer[i*scanline_width], scanline_width)) != RGBE_RETURN_SUCCESS) { free(buffer); return err; } } } free(buffer); return RGBE_RETURN_SUCCESS; }
/* These routines can be made faster by allocating a larger buffer and fread-ing and fwrite-ing the data in larger chunks */ bool HDRWriter::writeNoRLE( std::ostream& fout, const osg::Image* img) { unsigned char rgbe[4]; for(int row=0; row<img->t(); ++row) { float* data = (float*)img->data(0,row); for(int column=0; column<img->s(); ++column) { float2rgbe( rgbe, data[R], data[G], data[B] ); data += RGBE_DATA_SIZE; fout.write(reinterpret_cast<const char*>(rgbe), sizeof(rgbe)); } } return true; }
// Internal function used to save the Hdr. ILboolean iSaveHdrInternal() { ILimage *TempImage; rgbe_header_info stHeader; unsigned char rgbe[4]; ILubyte *buffer; ILfloat *data; ILuint i; ILboolean bRet; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } stHeader.exposure = 0; stHeader.gamma = 0; stHeader.programtype[0] = 0; stHeader.valid = 0; if (iCurImage->Format != IL_UNSIGNED_BYTE) { TempImage = iConvertImage(iCurImage, IL_RGB, IL_FLOAT); if (TempImage == NULL) return IL_FALSE; } else TempImage = iCurImage; if (!RGBE_WriteHeader(TempImage->Width, TempImage->Height, &stHeader)) return IL_FALSE; if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) iFlipBuffer(TempImage->Data,TempImage->Depth,TempImage->Bps,TempImage->Height); data = (ILfloat*)TempImage->Data; if ((TempImage->Width < 8)||(TempImage->Width > 0x7fff)) { /* run length encoding is not allowed so write flat*/ bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height); if (iCurImage != TempImage) ilCloseImage(TempImage); return bRet; } buffer = (ILubyte*)ialloc(sizeof(ILubyte)*4*TempImage->Width); if (buffer == NULL) { /* no buffer space so write flat */ bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height); if (iCurImage != TempImage) ilCloseImage(TempImage); return bRet; } while(TempImage->Height-- > 0) { rgbe[0] = 2; rgbe[1] = 2; rgbe[2] = TempImage->Width >> 8; rgbe[3] = TempImage->Width & 0xFF; if (iwrite(rgbe, sizeof(rgbe), 1) < 1) { free(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_FALSE; } for(i=0;i<TempImage->Width;i++) { float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); buffer[i] = rgbe[0]; buffer[i+TempImage->Width] = rgbe[1]; buffer[i+2*TempImage->Width] = rgbe[2]; buffer[i+3*TempImage->Width] = rgbe[3]; data += RGBE_DATA_SIZE; } /* write out each of the four channels separately run length encoded */ /* first red, then green, then blue, then exponent */ for(i=0;i<4;i++) { if (RGBE_WriteBytes_RLE(&buffer[i*TempImage->Width],TempImage->Width) != IL_TRUE) { ifree(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_FALSE; } } } ifree(buffer); if (iCurImage != TempImage) ilCloseImage(TempImage); return IL_TRUE; }