From 76c82116532223f8be75816786d7031c25af090e Mon Sep 17 00:00:00 2001 From: BlueCube3310 <53150244+BlueCube3310@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:22:11 +0200 Subject: [PATCH] Image: Add a method for detecting signed values --- core/io/image.cpp | 27 ++++++++++++++++++++++++++ core/io/image.h | 2 ++ modules/betsy/image_compress_betsy.cpp | 27 +------------------------- modules/cvtt/image_compress_cvtt.cpp | 12 +----------- 4 files changed, 31 insertions(+), 37 deletions(-) diff --git a/core/io/image.cpp b/core/io/image.cpp index 003646d095f..f6065d984b9 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -3824,6 +3824,33 @@ void Image::bump_map_to_normal_map(float bump_scale) { data = result_image; } +bool Image::detect_signed(bool p_include_mips) const { + ERR_FAIL_COND_V(is_compressed(), false); + + if (format >= Image::FORMAT_RH && format <= Image::FORMAT_RGBAH) { + const uint16_t *img_data = reinterpret_cast(data.ptr()); + const uint64_t img_size = p_include_mips ? (data.size() / 2) : (width * height * get_format_pixel_size(format) / 2); + + for (uint64_t i = 0; i < img_size; i++) { + if ((img_data[i] & 0x8000) != 0 && (img_data[i] & 0x7fff) != 0) { + return true; + } + } + + } else if (format >= Image::FORMAT_RF && format <= Image::FORMAT_RGBAF) { + const uint32_t *img_data = reinterpret_cast(data.ptr()); + const uint64_t img_size = p_include_mips ? (data.size() / 4) : (width * height * get_format_pixel_size(format) / 4); + + for (uint64_t i = 0; i < img_size; i++) { + if ((img_data[i] & 0x80000000) != 0 && (img_data[i] & 0x7fffffff) != 0) { + return true; + } + } + } + + return false; +} + void Image::srgb_to_linear() { if (data.size() == 0) { return; diff --git a/core/io/image.h b/core/io/image.h index 8d09a0b40b8..4461ae71a6e 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -391,6 +391,8 @@ public: Ref get_image_from_mipmap(int p_mipmap) const; void bump_map_to_normal_map(float bump_scale = 1.0); + bool detect_signed(bool p_include_mips = true) const; + void blit_rect(const Ref &p_src, const Rect2i &p_src_rect, const Point2i &p_dest); void blit_rect_mask(const Ref &p_src, const Ref &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest); void blend_rect(const Ref &p_src, const Rect2i &p_src_rect, const Point2i &p_dest); diff --git a/modules/betsy/image_compress_betsy.cpp b/modules/betsy/image_compress_betsy.cpp index 6a0862e7290..7f723826d16 100644 --- a/modules/betsy/image_compress_betsy.cpp +++ b/modules/betsy/image_compress_betsy.cpp @@ -49,31 +49,6 @@ static int get_next_multiple(int n, int m) { return n + (m - (n % m)); } -static bool is_image_signed(const Image *r_img) { - if (r_img->get_format() >= Image::FORMAT_RH && r_img->get_format() <= Image::FORMAT_RGBAH) { - const uint16_t *img_data = reinterpret_cast(r_img->ptr()); - const uint64_t img_size = r_img->get_data_size() / 2; - - for (uint64_t i = 0; i < img_size; i++) { - if ((img_data[i] & 0x8000) != 0 && (img_data[i] & 0x7fff) != 0) { - return true; - } - } - - } else if (r_img->get_format() >= Image::FORMAT_RF && r_img->get_format() <= Image::FORMAT_RGBAF) { - const uint32_t *img_data = reinterpret_cast(r_img->ptr()); - const uint64_t img_size = r_img->get_data_size() / 4; - - for (uint64_t i = 0; i < img_size; i++) { - if ((img_data[i] & 0x80000000) != 0 && (img_data[i] & 0x7fffffff) != 0) { - return true; - } - } - } - - return false; -} - Error _compress_betsy(BetsyFormat p_format, Image *r_img) { uint64_t start_time = OS::get_singleton()->get_ticks_msec(); @@ -125,7 +100,7 @@ Error _compress_betsy(BetsyFormat p_format, Image *r_img) { case BETSY_FORMAT_BC6: { err = compute_shader->parse_versions_from_text(bc6h_shader_glsl); - if (is_image_signed(r_img)) { + if (r_img->detect_signed(true)) { dest_format = Image::FORMAT_BPTC_RGBF; version = "signed"; } else { diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 6b905c5ea11..2087dde2a1b 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -174,17 +174,7 @@ void image_compress_cvtt(Image *p_image, Image::UsedChannels p_channels) { p_image->convert(Image::FORMAT_RGBH); } - const uint8_t *rb = p_image->get_data().ptr(); - - const uint16_t *source_data = reinterpret_cast(&rb[0]); - int pixel_element_count = w * h * 3; - for (int i = 0; i < pixel_element_count; i++) { - if ((source_data[i] & 0x8000) != 0 && (source_data[i] & 0x7fff) != 0) { - is_signed = true; - break; - } - } - + is_signed = p_image->detect_signed(); target_format = is_signed ? Image::FORMAT_BPTC_RGBF : Image::FORMAT_BPTC_RGBFU; } else { p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert