Add image saving code.
This commit is contained in:
parent
7f3cee4db9
commit
872c61e1d1
@ -55,8 +55,8 @@ namespace nv
|
|||||||
static Image * loadFreeImage(FREE_IMAGE_FORMAT fif, Stream & s);
|
static Image * loadFreeImage(FREE_IMAGE_FORMAT fif, Stream & s);
|
||||||
static FloatImage * loadFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s);
|
static FloatImage * loadFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s);
|
||||||
|
|
||||||
static bool saveFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const Image * img, const ImageMetaData * tags/*=NULL*/);
|
static bool saveFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const Image * img, const ImageMetaData * tags);
|
||||||
static bool saveFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const FloatImage * img);
|
static bool saveFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const FloatImage * img, uint base_component, uint num_components);
|
||||||
|
|
||||||
#else // defined(HAVE_FREEIMAGE)
|
#else // defined(HAVE_FREEIMAGE)
|
||||||
|
|
||||||
@ -148,15 +148,14 @@ bool nv::ImageIO::save(const char * fileName, Stream & s, const Image * img, con
|
|||||||
nvDebugCheck(s.isSaving());
|
nvDebugCheck(s.isSaving());
|
||||||
nvDebugCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
const char * extension = Path::extension(fileName);
|
|
||||||
|
|
||||||
#if defined(HAVE_FREEIMAGE)
|
#if defined(HAVE_FREEIMAGE)
|
||||||
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName);
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName);
|
||||||
if (fif != FIF_UNKNOWN && FreeImage_FIFSupportsWriting(fif)) {
|
if (fif != FIF_UNKNOWN && FreeImage_FIFSupportsWriting(fif)) {
|
||||||
#pragma message(NV_FILE_LINE "TODO: implement saveFreeImage")
|
return saveFreeImage(fif, s, img, tags);
|
||||||
//return saveFreeImage(fif, s, img, tags);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
const char * extension = Path::extension(fileName);
|
||||||
|
|
||||||
if (strCaseCmp(extension, ".tga") == 0) {
|
if (strCaseCmp(extension, ".tga") == 0) {
|
||||||
return saveTGA(s, img);
|
return saveTGA(s, img);
|
||||||
}
|
}
|
||||||
@ -224,30 +223,23 @@ FloatImage * nv::ImageIO::loadFloat(const char * fileName, Stream & s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nv::ImageIO::saveFloat(const char * fileName, Stream & s, const FloatImage * fimage, uint baseComponent, uint componentCount)
|
||||||
bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components)
|
|
||||||
{
|
{
|
||||||
const char * extension = Path::extension(fileName);
|
if (componentCount == 0)
|
||||||
|
{
|
||||||
|
componentCount = fimage->componentNum() - baseComponent;
|
||||||
|
}
|
||||||
|
if (baseComponent + componentCount < fimage->componentNum())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_FREEIMAGE)
|
#if defined(HAVE_FREEIMAGE)
|
||||||
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName);
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName);
|
||||||
if (fif != FIF_UNKNOWN && FreeImage_FIFSupportsWriting(fif)) {
|
if (fif != FIF_UNKNOWN && FreeImage_FIFSupportsWriting(fif)) {
|
||||||
#pragma message(NV_FILE_LINE "TODO: Implement saveFloatFreeImage")
|
return saveFloatFreeImage(fif, s, fimage, baseComponent, componentCount);
|
||||||
//return saveFloatFreeImage(fif, s);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#else // defined(HAVE_FREEIMAGE)
|
#else // defined(HAVE_FREEIMAGE)
|
||||||
#if defined(HAVE_OPENEXR)
|
|
||||||
if (strCaseCmp(extension, ".exr") == 0) {
|
|
||||||
return saveFloatEXR(fileName, fimage, base_component, num_components);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_TIFF)
|
|
||||||
if (strCaseCmp(extension, ".tif") == 0 || strCaseCmp(extension, ".tiff") == 0) {
|
|
||||||
return saveFloatTIFF(fileName, fimage, base_component, num_components);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//if (num_components == 3 || num_components == 4)
|
//if (num_components == 3 || num_components == 4)
|
||||||
if (num_components <= 4)
|
if (num_components <= 4)
|
||||||
{
|
{
|
||||||
@ -272,20 +264,51 @@ bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, ui
|
|||||||
return ImageIO::save(fileName, image.ptr());
|
return ImageIO::save(fileName, image.ptr());
|
||||||
}
|
}
|
||||||
#endif // defined(HAVE_FREEIMAGE)
|
#endif // defined(HAVE_FREEIMAGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nv::ImageIO::saveFloat(const char * fileName, const FloatImage * fimage, uint baseComponent, uint componentCount)
|
||||||
|
{
|
||||||
|
const char * extension = Path::extension(fileName);
|
||||||
|
|
||||||
|
#if !defined(HAVE_FREEIMAGE)
|
||||||
|
#if defined(HAVE_OPENEXR)
|
||||||
|
if (strCaseCmp(extension, ".exr") == 0) {
|
||||||
|
return saveFloatEXR(fileName, fimage, baseComponent, componentCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_TIFF)
|
||||||
|
if (strCaseCmp(extension, ".tif") == 0 || strCaseCmp(extension, ".tiff") == 0) {
|
||||||
|
return saveFloatTIFF(fileName, fimage, baseComponent, componentCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // defined(HAVE_FREEIMAGE)
|
||||||
|
|
||||||
|
StdInputStream stream(fileName);
|
||||||
|
|
||||||
|
if (stream.isError()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return saveFloat(fileName, stream, fimage, baseComponent, componentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_FREEIMAGE)
|
#if defined(HAVE_FREEIMAGE)
|
||||||
|
|
||||||
unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle)
|
static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle)
|
||||||
{
|
{
|
||||||
Stream * s = (Stream *) handle;
|
Stream * s = (Stream *) handle;
|
||||||
s->serialize(buffer, size * count);
|
s->serialize(buffer, size * count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin)
|
static unsigned DLL_CALLCONV WriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle)
|
||||||
|
{
|
||||||
|
Stream * s = (Stream *) handle;
|
||||||
|
s->serialize(buffer, size * count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin)
|
||||||
{
|
{
|
||||||
Stream * s = (Stream *) handle;
|
Stream * s = (Stream *) handle;
|
||||||
|
|
||||||
@ -303,7 +326,7 @@ int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long DLL_CALLCONV TellProc(fi_handle handle)
|
static long DLL_CALLCONV TellProc(fi_handle handle)
|
||||||
{
|
{
|
||||||
Stream * s = (Stream *) handle;
|
Stream * s = (Stream *) handle;
|
||||||
return s->tell();
|
return s->tell();
|
||||||
@ -472,6 +495,90 @@ FloatImage * nv::ImageIO::loadFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s)
|
|||||||
return floatImage;
|
return floatImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nv::ImageIO::saveFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const Image * img, const ImageMetaData * tags)
|
||||||
|
{
|
||||||
|
nvCheck(!s.isError());
|
||||||
|
|
||||||
|
FreeImageIO io;
|
||||||
|
io.read_proc = NULL;
|
||||||
|
io.write_proc = WriteProc;
|
||||||
|
io.seek_proc = SeekProc;
|
||||||
|
io.tell_proc = TellProc;
|
||||||
|
|
||||||
|
const uint w = img->width();
|
||||||
|
const uint h = img->height();
|
||||||
|
|
||||||
|
FIBITMAP * bitmap = FreeImage_Allocate(w, h, 32);
|
||||||
|
|
||||||
|
for (uint i = 0; i < h; i++)
|
||||||
|
{
|
||||||
|
uint8 * scanline = FreeImage_GetScanLine(bitmap, i);
|
||||||
|
memcpy(scanline, img->scanline(h - i - 1), w * sizeof(Color32));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags != NULL)
|
||||||
|
{
|
||||||
|
#pragma message(NV_FILE_LINE "TODO: Save image metadata")
|
||||||
|
//FreeImage_SetMetadata(
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = FreeImage_SaveToHandle(fif, bitmap, &io, (fi_handle)&s, 0);
|
||||||
|
|
||||||
|
FreeImage_Unload(bitmap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nv::ImageIO::saveFloatFreeImage(FREE_IMAGE_FORMAT fif, Stream & s, const FloatImage * img, uint baseComponent, uint componentCount)
|
||||||
|
{
|
||||||
|
nvCheck(!s.isError());
|
||||||
|
|
||||||
|
FreeImageIO io;
|
||||||
|
io.read_proc = NULL;
|
||||||
|
io.write_proc = WriteProc;
|
||||||
|
io.seek_proc = SeekProc;
|
||||||
|
io.tell_proc = TellProc;
|
||||||
|
|
||||||
|
const uint w = img->width();
|
||||||
|
const uint h = img->height();
|
||||||
|
|
||||||
|
FREE_IMAGE_TYPE type;
|
||||||
|
if (componentCount == 1)
|
||||||
|
{
|
||||||
|
type = FIT_FLOAT;
|
||||||
|
}
|
||||||
|
else if (componentCount == 3)
|
||||||
|
{
|
||||||
|
type = FIT_RGBF;
|
||||||
|
}
|
||||||
|
else if (componentCount == 4)
|
||||||
|
{
|
||||||
|
type = FIT_RGBAF;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIBITMAP * bitmap = FreeImage_AllocateT(type, w, h);
|
||||||
|
|
||||||
|
for (uint y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
float * scanline = (float *)FreeImage_GetScanLine(bitmap, y);
|
||||||
|
|
||||||
|
for (uint x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
for (uint c = 0; c < componentCount; c++)
|
||||||
|
{
|
||||||
|
scanline[x * componentCount + c] = img->pixel(x, y, baseComponent + c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = FreeImage_SaveToHandle(fif, bitmap, &io, (fi_handle)&s, 0);
|
||||||
|
|
||||||
|
FreeImage_Unload(bitmap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else // defined(HAVE_FREEIMAGE)
|
#else // defined(HAVE_FREEIMAGE)
|
||||||
|
|
||||||
/// Load TGA image.
|
/// Load TGA image.
|
||||||
|
@ -27,9 +27,11 @@ namespace nv
|
|||||||
NVIMAGE_API FloatImage * loadFloat(const char * fileName);
|
NVIMAGE_API FloatImage * loadFloat(const char * fileName);
|
||||||
NVIMAGE_API FloatImage * loadFloat(const char * fileName, Stream & s);
|
NVIMAGE_API FloatImage * loadFloat(const char * fileName, Stream & s);
|
||||||
|
|
||||||
NVIMAGE_API bool save(const char * fileName, Stream & s, const Image * img, const ImageMetaData * tags=NULL);
|
|
||||||
NVIMAGE_API bool save(const char * fileName, const Image * img, const ImageMetaData * tags=NULL);
|
NVIMAGE_API bool save(const char * fileName, const Image * img, const ImageMetaData * tags=NULL);
|
||||||
NVIMAGE_API bool saveFloat(const char * fileName, const FloatImage * fimage, uint base_component, uint num_components);
|
NVIMAGE_API bool save(const char * fileName, Stream & s, const Image * img, const ImageMetaData * tags=NULL);
|
||||||
|
|
||||||
|
NVIMAGE_API bool saveFloat(const char * fileName, const FloatImage * fimage, uint baseComponent, uint componentCount);
|
||||||
|
NVIMAGE_API bool saveFloat(const char * fileName, Stream & s, const FloatImage * fimage, uint baseComponent, uint componentCount);
|
||||||
|
|
||||||
} // ImageIO namespace
|
} // ImageIO namespace
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user