summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorK. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>2022-06-19 18:55:47 -0700
committerK. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>2022-06-23 08:53:15 -0700
commitce42ee790c2cc1164414d451d8a3f4f8eda84123 (patch)
tree4d6c41701d7a881f0f25aba6c4ab6c675be3029d
parentd1dac8427a6a41e8fc0a76807887a57a8fe6fd10 (diff)
For in-engine processing allow saving openexr to a buffer.
-rw-r--r--core/io/image.cpp9
-rw-r--r--core/io/image.h3
-rw-r--r--modules/tinyexr/image_saver_tinyexr.cpp33
-rw-r--r--modules/tinyexr/image_saver_tinyexr.h1
-rw-r--r--modules/tinyexr/register_types.cpp1
5 files changed, 36 insertions, 11 deletions
diff --git a/core/io/image.cpp b/core/io/image.cpp
index a945d3e6cd..97a46c29db 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -85,6 +85,7 @@ SaveJPGFunc Image::save_jpg_func = nullptr;
SaveEXRFunc Image::save_exr_func = nullptr;
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
+SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr;
SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr;
SaveWebPFunc Image::save_webp_func = nullptr;
@@ -2323,6 +2324,13 @@ Error Image::save_exr(const String &p_path, bool p_grayscale) const {
return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
}
+Vector<uint8_t> Image::save_exr_to_buffer() const {
+ if (save_exr_buffer_func == nullptr) {
+ return Vector<uint8_t>();
+ }
+ return save_exr_buffer_func(Ref<Image>((Image *)this), false);
+}
+
Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const {
if (save_webp_func == nullptr) {
return ERR_UNAVAILABLE;
@@ -3180,6 +3188,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("save_jpg", "path", "quality"), &Image::save_jpg, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("save_exr_to_buffer", "grayscale"), &Image::save_exr_to_buffer, DEFVAL(false));
ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f));
ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f));
diff --git a/core/io/image.h b/core/io/image.h
index 229103f792..10c1156dae 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -52,6 +52,7 @@ typedef Error (*SaveWebPFunc)(const String &p_path, const Ref<Image> &p_img, con
typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const bool p_lossy, const float p_quality);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
+typedef Vector<uint8_t> (*SaveEXRBufferFunc)(const Ref<Image> &p_img, bool p_grayscale);
class Image : public Resource {
GDCLASS(Image, Resource);
@@ -61,6 +62,7 @@ public:
static SaveJPGFunc save_jpg_func;
static SaveEXRFunc save_exr_func;
static SavePNGBufferFunc save_png_buffer_func;
+ static SaveEXRBufferFunc save_exr_buffer_func;
static SaveJPGBufferFunc save_jpg_buffer_func;
static SaveWebPFunc save_webp_func;
static SaveWebPBufferFunc save_webp_buffer_func;
@@ -292,6 +294,7 @@ public:
Error save_jpg(const String &p_path, float p_quality = 0.75) const;
Vector<uint8_t> save_png_to_buffer() const;
Vector<uint8_t> save_jpg_to_buffer(float p_quality = 0.75) const;
+ Vector<uint8_t> save_exr_to_buffer() const;
Error save_exr(const String &p_path, bool p_grayscale) const;
Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const;
Vector<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const;
diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp
index 5fa6ace827..661fe343af 100644
--- a/modules/tinyexr/image_saver_tinyexr.cpp
+++ b/modules/tinyexr/image_saver_tinyexr.cpp
@@ -141,13 +141,14 @@ static int get_channel_count(Image::Format p_format) {
}
}
-Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale) {
+Vector<uint8_t> save_exr_buffer(const Ref<Image> &p_img, bool p_grayscale) {
Image::Format format = p_img->get_format();
if (!is_supported_format(format)) {
// Format not supported
print_error("Image format not supported for saving as EXR. Consider saving as PNG.");
- return ERR_UNAVAILABLE;
+
+ return Vector<uint8_t>();
}
EXRHeader header;
@@ -175,15 +176,15 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
};
int channel_count = get_channel_count(format);
- ERR_FAIL_COND_V(channel_count < 0, ERR_UNAVAILABLE);
- ERR_FAIL_COND_V(p_grayscale && channel_count != 1, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(channel_count < 0, Vector<uint8_t>());
+ ERR_FAIL_COND_V(p_grayscale && channel_count != 1, Vector<uint8_t>());
int target_pixel_type = get_target_pixel_type(format);
- ERR_FAIL_COND_V(target_pixel_type < 0, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(target_pixel_type < 0, Vector<uint8_t>());
int target_pixel_type_size = get_pixel_type_size(target_pixel_type);
- ERR_FAIL_COND_V(target_pixel_type_size < 0, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(target_pixel_type_size < 0, Vector<uint8_t>());
SrcPixelType src_pixel_type = get_source_pixel_type(format);
- ERR_FAIL_COND_V(src_pixel_type == SRC_UNSUPPORTED, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(src_pixel_type == SRC_UNSUPPORTED, Vector<uint8_t>());
const int pixel_count = p_img->get_width() * p_img->get_height();
const int *channel_mapping = channel_mappings[channel_count - 1];
@@ -270,15 +271,25 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
const char *err = nullptr;
size_t bytes = SaveEXRImageToMemory(&image, &header, &mem, &err);
+ if (err && *err != OK) {
+ return Vector<uint8_t>();
+ }
+ Vector<uint8_t> buffer;
+ buffer.resize(bytes);
+ memcpy(buffer.ptrw(), mem, bytes);
+ free(mem);
+ return buffer;
+}
- if (bytes == 0) {
- print_error(String("Saving EXR failed. Error: {0}").format(varray(err)));
+Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale) {
+ const Vector<uint8_t> buffer = save_exr_buffer(p_img, p_grayscale);
+ if (buffer.size() == 0) {
+ print_error(String("Saving EXR failed."));
return ERR_FILE_CANT_WRITE;
} else {
Ref<FileAccess> ref = FileAccess::open(p_path, FileAccess::WRITE);
ERR_FAIL_COND_V(ref.is_null(), ERR_FILE_CANT_WRITE);
- ref->store_buffer(mem, bytes);
- free(mem);
+ ref->store_buffer(buffer.ptr(), buffer.size());
}
return OK;
diff --git a/modules/tinyexr/image_saver_tinyexr.h b/modules/tinyexr/image_saver_tinyexr.h
index 5bf95b265e..8f97f55408 100644
--- a/modules/tinyexr/image_saver_tinyexr.h
+++ b/modules/tinyexr/image_saver_tinyexr.h
@@ -34,5 +34,6 @@
#include "core/os/os.h"
Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
+Vector<uint8_t> save_exr_buffer(const Ref<Image> &p_img, bool p_grayscale);
#endif // IMAGE_SAVER_TINYEXR_H
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index d49ac23fea..c5897f37c3 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -44,6 +44,7 @@ void initialize_tinyexr_module(ModuleInitializationLevel p_level) {
ImageLoader::add_image_format_loader(image_loader_tinyexr);
Image::save_exr_func = save_exr;
+ Image::save_exr_buffer_func = save_exr_buffer;
}
void uninitialize_tinyexr_module(ModuleInitializationLevel p_level) {