mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-16 23:10:54 +00:00
Use the new tinyexr API for memory load/save instead of manual additions
This commit is contained in:
@@ -200,23 +200,30 @@ ReplayCreateStatus IMG_CreateReplayDevice(const char *logfile, IReplayDriver **d
|
||||
// make sure the file is a type we recognise before going further
|
||||
if(is_exr_file(f))
|
||||
{
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
const char *err = NULL;
|
||||
|
||||
float *data = NULL;
|
||||
int dummy;
|
||||
FileIO::fseek64(f, 0, SEEK_END);
|
||||
uint64_t size = FileIO::ftell64(f);
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
int ret = LoadEXRFP(&data, &dummy, &dummy, f, &err);
|
||||
std::vector<byte> buffer;
|
||||
buffer.resize((size_t)size);
|
||||
|
||||
if(data) free(data);
|
||||
FileIO::fread(&buffer[0], 1, buffer.size(), f);
|
||||
|
||||
EXRImage exrImage;
|
||||
InitEXRImage(&exrImage);
|
||||
|
||||
int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err);
|
||||
|
||||
FreeEXRImage(&exrImage);
|
||||
|
||||
// could be an unsupported form of EXR, like deep image or other
|
||||
if(ret != 0)
|
||||
{
|
||||
FileIO::fclose(f);
|
||||
|
||||
RDCERR("EXR file detected, but couldn't load with LoadEXR %d: '%s'", ret, err);
|
||||
RDCERR("EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", ret, err);
|
||||
return eReplayCreate_APIUnsupported;
|
||||
}
|
||||
}
|
||||
@@ -355,20 +362,77 @@ void ImageViewer::RefreshFile()
|
||||
if(is_exr_file(f))
|
||||
{
|
||||
texDetails.format = rgba32_float;
|
||||
|
||||
|
||||
FileIO::fseek64(f, 0, SEEK_END);
|
||||
uint64_t size = FileIO::ftell64(f);
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
std::vector<byte> buffer;
|
||||
buffer.resize((size_t)size);
|
||||
|
||||
FileIO::fread(&buffer[0], 1, buffer.size(), f);
|
||||
|
||||
FileIO::fclose(f);
|
||||
|
||||
EXRImage exrImage;
|
||||
InitEXRImage(&exrImage);
|
||||
|
||||
const char *err = NULL;
|
||||
|
||||
int ret = LoadEXRFP((float **)&data, (int *)&texDetails.width, (int *)&texDetails.height, f, &err);
|
||||
datasize = texDetails.width*texDetails.height*4*sizeof(float);
|
||||
int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err);
|
||||
|
||||
// could be an unsupported form of EXR, like deep image or other
|
||||
if(ret != 0)
|
||||
{
|
||||
if(data) free(data);
|
||||
RDCERR("EXR file detected, but couldn't load with LoadEXR %d: '%s'", ret, err);
|
||||
FileIO::fclose(f);
|
||||
RDCERR("EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", ret, err);
|
||||
return;
|
||||
}
|
||||
|
||||
texDetails.width = exrImage.width;
|
||||
texDetails.height = exrImage.height;
|
||||
|
||||
datasize = texDetails.width*texDetails.height*4*sizeof(float);
|
||||
data = (byte *)malloc(datasize);
|
||||
|
||||
for(int i=0; i < exrImage.num_channels; i++)
|
||||
exrImage.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
|
||||
|
||||
ret = LoadMultiChannelEXRFromMemory(&exrImage, &buffer[0], &err);
|
||||
|
||||
int channels[4] = { -1, -1, -1, -1 };
|
||||
for(int i=0; i < exrImage.num_channels; i++)
|
||||
{
|
||||
switch(exrImage.channel_names[i][0])
|
||||
{
|
||||
case 'R': channels[0] = i; break;
|
||||
case 'G': channels[1] = i; break;
|
||||
case 'B': channels[2] = i; break;
|
||||
case 'A': channels[3] = i; break;
|
||||
}
|
||||
}
|
||||
|
||||
float *rgba = (float *)data;
|
||||
float **src = (float **)exrImage.images;
|
||||
|
||||
for(uint32_t i=0; i < texDetails.width*texDetails.height; i++)
|
||||
{
|
||||
for(int c=0; c < 4; c++)
|
||||
{
|
||||
if(channels[c] >= 0)
|
||||
rgba[i*4 + c] = src[ channels[c] ][i];
|
||||
else if(c < 3) // RGB channels default to 0
|
||||
rgba[i*4 + c] = 0.0f;
|
||||
else // alpha defaults to 1
|
||||
rgba[i*4 + c] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
FreeEXRImage(&exrImage);
|
||||
|
||||
// shouldn't get here but let's be safe
|
||||
if(ret != 0)
|
||||
{
|
||||
free(data);
|
||||
RDCERR("EXR file detected, but couldn't load with LoadEXRFromMemory %d: '%s'", ret, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,7 +1045,20 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
}
|
||||
else if(sd.destType == eFileType_HDR || sd.destType == eFileType_EXR)
|
||||
{
|
||||
float *fldata = new float[td.width*td.height*4];
|
||||
float *fldata = NULL;
|
||||
float *bgra[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
if(sd.destType == eFileType_HDR)
|
||||
{
|
||||
fldata = new float[td.width*td.height*4];
|
||||
}
|
||||
else
|
||||
{
|
||||
bgra[0] = new float[td.width*td.height];
|
||||
bgra[1] = new float[td.width*td.height];
|
||||
bgra[2] = new float[td.width*td.height];
|
||||
bgra[3] = new float[td.width*td.height];
|
||||
}
|
||||
|
||||
byte *srcData = subdata[0];
|
||||
|
||||
@@ -1124,10 +1137,20 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
r = g = b = a; a = 1.0f;
|
||||
}
|
||||
|
||||
fldata[(y*td.width + x) * 4 + 0] = r;
|
||||
fldata[(y*td.width + x) * 4 + 1] = g;
|
||||
fldata[(y*td.width + x) * 4 + 2] = b;
|
||||
fldata[(y*td.width + x) * 4 + 3] = a;
|
||||
if(fldata)
|
||||
{
|
||||
fldata[(y*td.width + x) * 4 + 0] = r;
|
||||
fldata[(y*td.width + x) * 4 + 1] = g;
|
||||
fldata[(y*td.width + x) * 4 + 2] = b;
|
||||
fldata[(y*td.width + x) * 4 + 3] = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
bgra[0][(y*td.width + x)] = b;
|
||||
bgra[1][(y*td.width + x)] = g;
|
||||
bgra[2][(y*td.width + x)] = r;
|
||||
bgra[3][(y*td.width + x)] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,13 +1162,46 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
else if(sd.destType == eFileType_EXR)
|
||||
{
|
||||
const char *err = NULL;
|
||||
int ret = SaveEXRFP(fldata, (int)td.width, (int)td.height, f, &err);
|
||||
success = (ret == 0);
|
||||
if(!success)
|
||||
|
||||
EXRImage exrImage;
|
||||
InitEXRImage(&exrImage);
|
||||
|
||||
int pixTypes[4] = { TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT };
|
||||
int reqTypes[4] = { TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF };
|
||||
const char *bgraNames[4] = { "B", "G", "R", "A" };
|
||||
|
||||
exrImage.num_channels = 4;
|
||||
exrImage.channel_names = bgraNames;
|
||||
exrImage.images = (unsigned char**)bgra;
|
||||
exrImage.width = td.width;
|
||||
exrImage.height = td.height;
|
||||
exrImage.pixel_types = pixTypes;
|
||||
exrImage.requested_pixel_types = reqTypes;
|
||||
|
||||
unsigned char *mem = NULL;
|
||||
|
||||
size_t ret = SaveMultiChannelEXRToMemory(&exrImage, &mem, &err);
|
||||
|
||||
success = (ret > 0);
|
||||
if(success)
|
||||
FileIO::fwrite(mem, 1, ret, f);
|
||||
else
|
||||
RDCERR("Error saving EXR file %d: '%s'", ret, err);
|
||||
|
||||
free(mem);
|
||||
}
|
||||
|
||||
delete[] fldata;
|
||||
if(fldata)
|
||||
{
|
||||
delete[] fldata;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] bgra[0];
|
||||
delete[] bgra[1];
|
||||
delete[] bgra[2];
|
||||
delete[] bgra[3];
|
||||
}
|
||||
}
|
||||
|
||||
FileIO::fclose(f);
|
||||
|
||||
Reference in New Issue
Block a user