summaryrefslogtreecommitdiff
path: root/modules/tinyexr/image_loader_tinyexr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/tinyexr/image_loader_tinyexr.cpp')
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 49a4db237a..0abefe11ee 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "image_loader_tinyexr.h"
#include "os/os.h"
@@ -47,6 +48,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 +74,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 +108,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 +141,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 +165,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;
}