diff --git a/core/io/image.cpp b/core/io/image.cpp index 199871ba970..cce9d98b2fb 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -2438,47 +2438,75 @@ void Image::initialize_data(const char **p_xpm) { } bool Image::is_invisible() const { - if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) { - return false; - } - - int64_t len = data.size(); + int w, h; + int64_t len; + _get_mipmap_offset_and_size(1, len, w, h); if (len == 0) { return true; } - int w, h; - _get_mipmap_offset_and_size(1, len, w, h); - - const uint8_t *r = data.ptr(); - const unsigned char *data_ptr = r; - - bool detected = false; - switch (format) { case FORMAT_LA8: { - for (int i = 0; i < (len >> 1); i++) { - DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]); - } + const int pixel_count = len / 2; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0xFF00) != 0) { + return false; + } + } } break; case FORMAT_RGBA8: { - for (int i = 0; i < (len >> 2); i++) { - DETECT_NON_ALPHA(data_ptr[(i << 2) + 3]) + const int pixel_count = len / 4; + const uint32_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0xFF000000) != 0) { + return false; + } } - } break; + case FORMAT_RGBA4444: { + const int pixel_count = len / 2; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); - case FORMAT_DXT3: - case FORMAT_DXT5: { - detected = true; + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0x000F) != 0) { + return false; + } + } + } break; + case FORMAT_RGBAH: { + // The alpha mask accounts for the sign bit. + const int pixel_count = len / 4; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i += 4) { + if ((pixeldata[i + 3] & 0x7FFF) != 0) { + return false; + } + } + } break; + case FORMAT_RGBAF: { + // The alpha mask accounts for the sign bit. + const int pixel_count = len / 4; + const uint32_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i += 4) { + if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) { + return false; + } + } } break; default: { + // Formats that are compressed or don't support alpha channels are presumed to be visible. + return false; } } - return !detected; + // Every pixel has been checked, the image is invisible. + return true; } Image::AlphaMode Image::detect_alpha() const {