TinyEXR: Fix EXR header when parsing pixels encoded as HALF
Also free the header and image properly after usage. Fixes #13490.
This commit is contained in:
parent
0036019e67
commit
7d9f14e9e4
1 changed files with 20 additions and 5 deletions
|
@ -47,6 +47,11 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
|
||||
f->close();
|
||||
|
||||
// Re-implementation of tinyexr's LoadEXRFromMemory using Godot types to store the Image data
|
||||
// and Godot's error codes.
|
||||
// When debugging after updating the thirdparty library, check that we're still in sync with
|
||||
// their API usage in LoadEXRFromMemory.
|
||||
|
||||
EXRVersion exr_version;
|
||||
EXRImage exr_image;
|
||||
EXRHeader exr_header;
|
||||
|
@ -68,6 +73,13 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
return ERR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// Read HALF channel as FLOAT. (GH-13490)
|
||||
for (int i = 0; i < exr_header.num_channels; i++) {
|
||||
if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
|
||||
exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
InitEXRImage(&exr_image);
|
||||
ret = LoadEXRImageFromMemory(&exr_image, &exr_header, w.ptr(), src_image_len, &err);
|
||||
if (ret != TINYEXR_SUCCESS) {
|
||||
|
@ -95,23 +107,25 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
}
|
||||
|
||||
if (idxR == -1) {
|
||||
ERR_PRINT("R channel not found");
|
||||
ERR_PRINT("TinyEXR: R channel not found.");
|
||||
// @todo { free exr_image }
|
||||
return ERR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
if (idxG == -1) {
|
||||
ERR_PRINT("G channel not found\n")
|
||||
ERR_PRINT("TinyEXR: G channel not found.")
|
||||
// @todo { free exr_image }
|
||||
return ERR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
if (idxB == -1) {
|
||||
ERR_PRINT("B channel not found\n")
|
||||
ERR_PRINT("TinyEXR: B channel not found.")
|
||||
// @todo { free exr_image }
|
||||
return ERR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// EXR image data loaded, now parse it into Godot-friendly image data
|
||||
|
||||
PoolVector<uint8_t> imgdata;
|
||||
Image::Format format;
|
||||
|
||||
|
@ -126,7 +140,6 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
}
|
||||
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write wd = imgdata.write();
|
||||
uint16_t *iw = (uint16_t *)wd.ptr();
|
||||
|
||||
|
@ -151,11 +164,13 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
}
|
||||
}
|
||||
|
||||
print_line("EXR w: " + itos(exr_image.width) + " h:" + itos(exr_image.height) + " format " + Image::get_format_name(format));
|
||||
p_image->create(exr_image.width, exr_image.height, false, format, imgdata);
|
||||
|
||||
w = PoolVector<uint8_t>::Write();
|
||||
|
||||
FreeEXRHeader(&exr_header);
|
||||
FreeEXRImage(&exr_image);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue