diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-11-15 16:25:40 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-11-15 16:25:40 +0100 |
commit | 4935493f720b0c4e925b0643960b5949bedae0c7 (patch) | |
tree | 5b8ce90433e95536b610a8bd50349af9f0696f2a /modules | |
parent | 7b3c1a0a83edfe9448b93f9bd3c832134d8d4ddd (diff) | |
parent | da132f32665244a42f58bb4abb555c2202688cce (diff) |
Merge pull request #67948 from DeeJayLSP/split_webp
Overhaul WebP packer and split compression options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/webp/webp_common.cpp | 50 | ||||
-rw-r--r-- | modules/webp/webp_common.h | 2 |
2 files changed, 20 insertions, 32 deletions
diff --git a/modules/webp/webp_common.cpp b/modules/webp/webp_common.cpp index af98788420..572a33653e 100644 --- a/modules/webp/webp_common.cpp +++ b/modules/webp/webp_common.cpp @@ -41,40 +41,21 @@ namespace WebPCommon { Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) { ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>()); - Ref<Image> img = p_image->duplicate(); - if (img->detect_alpha()) { - img->convert(Image::FORMAT_RGBA8); - } else { - img->convert(Image::FORMAT_RGB8); - } - - Size2 s(img->get_width(), img->get_height()); - Vector<uint8_t> data = img->get_data(); - const uint8_t *r = data.ptr(); - - uint8_t *dst_buff = nullptr; - size_t dst_size = 0; - if (img->get_format() == Image::FORMAT_RGB8) { - dst_size = WebPEncodeRGB(r, s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff); - } else { - dst_size = WebPEncodeRGBA(r, s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff); - } - - ERR_FAIL_COND_V(dst_size == 0, Vector<uint8_t>()); - Vector<uint8_t> dst; - dst.resize(dst_size); - uint8_t *w = dst.ptrw(); - memcpy(w, dst_buff, dst_size); - WebPFree(dst_buff); - - return dst; + return _webp_packer(p_image, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), false); } Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) { ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>()); - int compression_level = GLOBAL_GET("rendering/textures/lossless_compression/webp_compression_level"); - compression_level = CLAMP(compression_level, 0, 9); + float compression_factor = GLOBAL_GET("rendering/textures/webp_compression/lossless_compression_factor"); + compression_factor = CLAMP(compression_factor, 0.0f, 100.0f); + + return _webp_packer(p_image, compression_factor, true); +} + +Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless) { + int compression_method = GLOBAL_GET("rendering/textures/webp_compression/compression_method"); + compression_method = CLAMP(compression_method, 0, 6); Ref<Image> img = p_image->duplicate(); if (img->detect_alpha()) { @@ -87,16 +68,21 @@ Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) { Vector<uint8_t> data = img->get_data(); const uint8_t *r = data.ptr(); - // we need to use the more complex API in order to access the 'exact' flag... + // we need to use the more complex API in order to access specific flags... WebPConfig config; WebPPicture pic; - if (!WebPConfigInit(&config) || !WebPConfigLosslessPreset(&config, compression_level) || !WebPPictureInit(&pic)) { + if (!WebPConfigInit(&config) || !WebPPictureInit(&pic)) { ERR_FAIL_V(Vector<uint8_t>()); } WebPMemoryWriter wrt; - config.exact = 1; + if (p_lossless) { + config.lossless = 1; + config.exact = 1; + } + config.method = compression_method; + config.quality = p_quality; pic.use_argb = 1; pic.width = s.width; pic.height = s.height; diff --git a/modules/webp/webp_common.h b/modules/webp/webp_common.h index 11bef40256..23b433ad79 100644 --- a/modules/webp/webp_common.h +++ b/modules/webp/webp_common.h @@ -37,6 +37,8 @@ namespace WebPCommon { // Given an image, pack this data into a WebP file. Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality); Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image); +// Helper function for those above. +Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless); // Given a WebP file, unpack it into an image. Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer); Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len); |