diff options
Diffstat (limited to 'modules/webp')
-rw-r--r-- | modules/webp/SCsub | 238 | ||||
-rw-r--r-- | modules/webp/image_loader_webp.cpp | 2 | ||||
-rw-r--r-- | modules/webp/image_loader_webp.h | 2 | ||||
-rw-r--r-- | modules/webp/register_types.cpp | 11 | ||||
-rw-r--r-- | modules/webp/resource_saver_webp.cpp | 6 | ||||
-rw-r--r-- | modules/webp/webp_common.cpp | 54 | ||||
-rw-r--r-- | modules/webp/webp_common.h | 2 |
7 files changed, 156 insertions, 159 deletions
diff --git a/modules/webp/SCsub b/modules/webp/SCsub index 80d62400c8..72ad1ea5e4 100644 --- a/modules/webp/SCsub +++ b/modules/webp/SCsub @@ -12,123 +12,129 @@ thirdparty_obj = [] if env["builtin_libwebp"]: thirdparty_dir = "#thirdparty/libwebp/" thirdparty_sources = [ - "dec/alpha_dec.c", - "dec/buffer_dec.c", - "dec/frame_dec.c", - "dec/idec_dec.c", - "dec/io_dec.c", - "dec/quant_dec.c", - "dec/tree_dec.c", - "dec/vp8_dec.c", - "dec/vp8l_dec.c", - "dec/webp_dec.c", - "demux/anim_decode.c", - "demux/demux.c", - "dsp/alpha_processing.c", - "dsp/alpha_processing_mips_dsp_r2.c", - "dsp/alpha_processing_neon.c", - "dsp/alpha_processing_sse2.c", - "dsp/alpha_processing_sse41.c", - "dsp/cost.c", - "dsp/cost_mips32.c", - "dsp/cost_mips_dsp_r2.c", - "dsp/cost_neon.c", - "dsp/cost_sse2.c", - "dsp/cpu.c", - "dsp/dec.c", - "dsp/dec_clip_tables.c", - "dsp/dec_mips32.c", - "dsp/dec_mips_dsp_r2.c", - "dsp/dec_msa.c", - "dsp/dec_neon.c", - "dsp/dec_sse2.c", - "dsp/dec_sse41.c", - "dsp/enc.c", - "dsp/enc_mips32.c", - "dsp/enc_mips_dsp_r2.c", - "dsp/enc_msa.c", - "dsp/enc_neon.c", - "dsp/enc_sse2.c", - "dsp/enc_sse41.c", - "dsp/filters.c", - "dsp/filters_mips_dsp_r2.c", - "dsp/filters_msa.c", - "dsp/filters_neon.c", - "dsp/filters_sse2.c", - "dsp/lossless.c", - "dsp/lossless_enc.c", - "dsp/lossless_enc_mips32.c", - "dsp/lossless_enc_mips_dsp_r2.c", - "dsp/lossless_enc_msa.c", - "dsp/lossless_enc_neon.c", - "dsp/lossless_enc_sse2.c", - "dsp/lossless_enc_sse41.c", - "dsp/lossless_mips_dsp_r2.c", - "dsp/lossless_msa.c", - "dsp/lossless_neon.c", - "dsp/lossless_sse2.c", - "dsp/lossless_sse41.c", - "dsp/rescaler.c", - "dsp/rescaler_mips32.c", - "dsp/rescaler_mips_dsp_r2.c", - "dsp/rescaler_msa.c", - "dsp/rescaler_neon.c", - "dsp/rescaler_sse2.c", - "dsp/ssim.c", - "dsp/ssim_sse2.c", - "dsp/upsampling.c", - "dsp/upsampling_mips_dsp_r2.c", - "dsp/upsampling_msa.c", - "dsp/upsampling_neon.c", - "dsp/upsampling_sse2.c", - "dsp/upsampling_sse41.c", - "dsp/yuv.c", - "dsp/yuv_mips32.c", - "dsp/yuv_mips_dsp_r2.c", - "dsp/yuv_neon.c", - "dsp/yuv_sse2.c", - "dsp/yuv_sse41.c", - "enc/alpha_enc.c", - "enc/analysis_enc.c", - "enc/backward_references_cost_enc.c", - "enc/backward_references_enc.c", - "enc/config_enc.c", - "enc/cost_enc.c", - "enc/filter_enc.c", - "enc/frame_enc.c", - "enc/histogram_enc.c", - "enc/iterator_enc.c", - "enc/near_lossless_enc.c", - "enc/picture_csp_enc.c", - "enc/picture_enc.c", - "enc/picture_psnr_enc.c", - "enc/picture_rescale_enc.c", - "enc/picture_tools_enc.c", - "enc/predictor_enc.c", - "enc/quant_enc.c", - "enc/syntax_enc.c", - "enc/token_enc.c", - "enc/tree_enc.c", - "enc/vp8l_enc.c", - "enc/webp_enc.c", - "mux/anim_encode.c", - "mux/muxedit.c", - "mux/muxinternal.c", - "mux/muxread.c", - "utils/bit_reader_utils.c", - "utils/bit_writer_utils.c", - "utils/color_cache_utils.c", - "utils/filters_utils.c", - "utils/huffman_encode_utils.c", - "utils/huffman_utils.c", - "utils/quant_levels_dec_utils.c", - "utils/quant_levels_utils.c", - "utils/random_utils.c", - "utils/rescaler_utils.c", - "utils/thread_utils.c", - "utils/utils.c", + "sharpyuv/sharpyuv.c", + "sharpyuv/sharpyuv_csp.c", + "sharpyuv/sharpyuv_dsp.c", + "sharpyuv/sharpyuv_gamma.c", + "sharpyuv/sharpyuv_neon.c", + "sharpyuv/sharpyuv_sse2.c", + "src/dec/alpha_dec.c", + "src/dec/buffer_dec.c", + "src/dec/frame_dec.c", + "src/dec/idec_dec.c", + "src/dec/io_dec.c", + "src/dec/quant_dec.c", + "src/dec/tree_dec.c", + "src/dec/vp8_dec.c", + "src/dec/vp8l_dec.c", + "src/dec/webp_dec.c", + "src/demux/anim_decode.c", + "src/demux/demux.c", + "src/dsp/alpha_processing.c", + "src/dsp/alpha_processing_mips_dsp_r2.c", + "src/dsp/alpha_processing_neon.c", + "src/dsp/alpha_processing_sse2.c", + "src/dsp/alpha_processing_sse41.c", + "src/dsp/cost.c", + "src/dsp/cost_mips32.c", + "src/dsp/cost_mips_dsp_r2.c", + "src/dsp/cost_neon.c", + "src/dsp/cost_sse2.c", + "src/dsp/cpu.c", + "src/dsp/dec.c", + "src/dsp/dec_clip_tables.c", + "src/dsp/dec_mips32.c", + "src/dsp/dec_mips_dsp_r2.c", + "src/dsp/dec_msa.c", + "src/dsp/dec_neon.c", + "src/dsp/dec_sse2.c", + "src/dsp/dec_sse41.c", + "src/dsp/enc.c", + "src/dsp/enc_mips32.c", + "src/dsp/enc_mips_dsp_r2.c", + "src/dsp/enc_msa.c", + "src/dsp/enc_neon.c", + "src/dsp/enc_sse2.c", + "src/dsp/enc_sse41.c", + "src/dsp/filters.c", + "src/dsp/filters_mips_dsp_r2.c", + "src/dsp/filters_msa.c", + "src/dsp/filters_neon.c", + "src/dsp/filters_sse2.c", + "src/dsp/lossless.c", + "src/dsp/lossless_enc.c", + "src/dsp/lossless_enc_mips32.c", + "src/dsp/lossless_enc_mips_dsp_r2.c", + "src/dsp/lossless_enc_msa.c", + "src/dsp/lossless_enc_neon.c", + "src/dsp/lossless_enc_sse2.c", + "src/dsp/lossless_enc_sse41.c", + "src/dsp/lossless_mips_dsp_r2.c", + "src/dsp/lossless_msa.c", + "src/dsp/lossless_neon.c", + "src/dsp/lossless_sse2.c", + "src/dsp/lossless_sse41.c", + "src/dsp/rescaler.c", + "src/dsp/rescaler_mips32.c", + "src/dsp/rescaler_mips_dsp_r2.c", + "src/dsp/rescaler_msa.c", + "src/dsp/rescaler_neon.c", + "src/dsp/rescaler_sse2.c", + "src/dsp/ssim.c", + "src/dsp/ssim_sse2.c", + "src/dsp/upsampling.c", + "src/dsp/upsampling_mips_dsp_r2.c", + "src/dsp/upsampling_msa.c", + "src/dsp/upsampling_neon.c", + "src/dsp/upsampling_sse2.c", + "src/dsp/upsampling_sse41.c", + "src/dsp/yuv.c", + "src/dsp/yuv_mips32.c", + "src/dsp/yuv_mips_dsp_r2.c", + "src/dsp/yuv_neon.c", + "src/dsp/yuv_sse2.c", + "src/dsp/yuv_sse41.c", + "src/enc/alpha_enc.c", + "src/enc/analysis_enc.c", + "src/enc/backward_references_cost_enc.c", + "src/enc/backward_references_enc.c", + "src/enc/config_enc.c", + "src/enc/cost_enc.c", + "src/enc/filter_enc.c", + "src/enc/frame_enc.c", + "src/enc/histogram_enc.c", + "src/enc/iterator_enc.c", + "src/enc/near_lossless_enc.c", + "src/enc/picture_csp_enc.c", + "src/enc/picture_enc.c", + "src/enc/picture_psnr_enc.c", + "src/enc/picture_rescale_enc.c", + "src/enc/picture_tools_enc.c", + "src/enc/predictor_enc.c", + "src/enc/quant_enc.c", + "src/enc/syntax_enc.c", + "src/enc/token_enc.c", + "src/enc/tree_enc.c", + "src/enc/vp8l_enc.c", + "src/enc/webp_enc.c", + "src/mux/anim_encode.c", + "src/mux/muxedit.c", + "src/mux/muxinternal.c", + "src/mux/muxread.c", + "src/utils/bit_reader_utils.c", + "src/utils/bit_writer_utils.c", + "src/utils/color_cache_utils.c", + "src/utils/filters_utils.c", + "src/utils/huffman_encode_utils.c", + "src/utils/huffman_utils.c", + "src/utils/quant_levels_dec_utils.c", + "src/utils/quant_levels_utils.c", + "src/utils/random_utils.c", + "src/utils/rescaler_utils.c", + "src/utils/thread_utils.c", + "src/utils/utils.c", ] - thirdparty_sources = [thirdparty_dir + "src/" + file for file in thirdparty_sources] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_webp.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "src/"]) diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index 778d562278..dd387db554 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -48,7 +48,7 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) { return img; } -Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) { Vector<uint8_t> src_image; uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h index 9a5dc6cd7c..0522e4ef91 100644 --- a/modules/webp/image_loader_webp.h +++ b/modules/webp/image_loader_webp.h @@ -35,7 +35,7 @@ class ImageLoaderWebP : public ImageFormatLoader { public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderWebP(); }; diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp index 29f633743e..e523f43cfe 100644 --- a/modules/webp/register_types.cpp +++ b/modules/webp/register_types.cpp @@ -33,7 +33,7 @@ #include "image_loader_webp.h" #include "resource_saver_webp.h" -static ImageLoaderWebP *image_loader_webp = nullptr; +static Ref<ImageLoaderWebP> image_loader_webp; static Ref<ResourceSaverWebP> resource_saver_webp; void initialize_webp_module(ModuleInitializationLevel p_level) { @@ -41,9 +41,10 @@ void initialize_webp_module(ModuleInitializationLevel p_level) { return; } - image_loader_webp = memnew(ImageLoaderWebP); - resource_saver_webp.instantiate(); + image_loader_webp.instantiate(); ImageLoader::add_image_format_loader(image_loader_webp); + + resource_saver_webp.instantiate(); ResourceSaver::add_resource_format_saver(resource_saver_webp); } @@ -52,7 +53,9 @@ void uninitialize_webp_module(ModuleInitializationLevel p_level) { return; } - memdelete(image_loader_webp); + ImageLoader::remove_image_format_loader(image_loader_webp); + image_loader_webp.unref(); + ResourceSaver::remove_resource_format_saver(resource_saver_webp); resource_saver_webp.unref(); } diff --git a/modules/webp/resource_saver_webp.cpp b/modules/webp/resource_saver_webp.cpp index bd71c2869a..56ff8097b4 100644 --- a/modules/webp/resource_saver_webp.cpp +++ b/modules/webp/resource_saver_webp.cpp @@ -38,8 +38,8 @@ Error ResourceSaverWebP::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<ImageTexture> texture = p_resource; - ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as WEBP."); - ERR_FAIL_COND_V_MSG(!texture->get_width(), ERR_INVALID_PARAMETER, "Can't save empty texture as WEBP."); + ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as WebP."); + ERR_FAIL_COND_V_MSG(!texture->get_width(), ERR_INVALID_PARAMETER, "Can't save empty texture as WebP."); Ref<Image> img = texture->get_image(); @@ -52,7 +52,7 @@ Error ResourceSaverWebP::save_image(const String &p_path, const Ref<Image> &p_im Vector<uint8_t> buffer = save_image_to_buffer(p_img, p_lossy, p_quality); Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); - ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save WEBP at path: '%s'.", p_path)); + ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save WebP at path: '%s'.", p_path)); const uint8_t *reader = buffer.ptr(); diff --git a/modules/webp/webp_common.cpp b/modules/webp/webp_common.cpp index 8657a98853..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 = ProjectSettings::get_singleton()->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; @@ -139,7 +125,7 @@ Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer) { ERR_FAIL_COND_V(r[0] != 'R' || r[1] != 'I' || r[2] != 'F' || r[3] != 'F' || r[8] != 'W' || r[9] != 'E' || r[10] != 'B' || r[11] != 'P', Ref<Image>()); WebPBitstreamFeatures features; if (WebPGetFeatures(r, size, &features) != VP8_STATUS_OK) { - ERR_FAIL_V_MSG(Ref<Image>(), "Error unpacking WEBP image."); + ERR_FAIL_V_MSG(Ref<Image>(), "Error unpacking WebP image."); } Vector<uint8_t> dst_image; @@ -183,7 +169,7 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p ERR_FAIL_COND_V_MSG(errdec, ERR_FILE_CORRUPT, "Failed decoding WebP image."); - p_image->create(features.width, features.height, false, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image); + p_image->set_data(features.width, features.height, false, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image); return OK; } 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); |