Image: Improve is_invisible function

This commit is contained in:
BlueCube3310 2025-03-28 22:42:37 +01:00
parent 7598b08ec2
commit dd47d9173e

View file

@ -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<const uint16_t *>(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<const uint32_t *>(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<const uint16_t *>(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<const uint16_t *>(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<const uint32_t *>(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 {