Skip to content

Commit dd47d91

Browse files
committed
Image: Improve is_invisible function
1 parent 7598b08 commit dd47d91

File tree

1 file changed

+50
-22
lines changed

1 file changed

+50
-22
lines changed

core/io/image.cpp

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,47 +2438,75 @@ void Image::initialize_data(const char **p_xpm) {
24382438
}
24392439

24402440
bool Image::is_invisible() const {
2441-
if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) {
2442-
return false;
2443-
}
2444-
2445-
int64_t len = data.size();
2441+
int w, h;
2442+
int64_t len;
2443+
_get_mipmap_offset_and_size(1, len, w, h);
24462444

24472445
if (len == 0) {
24482446
return true;
24492447
}
24502448

2451-
int w, h;
2452-
_get_mipmap_offset_and_size(1, len, w, h);
2453-
2454-
const uint8_t *r = data.ptr();
2455-
const unsigned char *data_ptr = r;
2456-
2457-
bool detected = false;
2458-
24592449
switch (format) {
24602450
case FORMAT_LA8: {
2461-
for (int i = 0; i < (len >> 1); i++) {
2462-
DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]);
2463-
}
2451+
const int pixel_count = len / 2;
2452+
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
24642453

2454+
for (int i = 0; i < pixel_count; i++) {
2455+
if ((pixeldata[i] & 0xFF00) != 0) {
2456+
return false;
2457+
}
2458+
}
24652459
} break;
24662460
case FORMAT_RGBA8: {
2467-
for (int i = 0; i < (len >> 2); i++) {
2468-
DETECT_NON_ALPHA(data_ptr[(i << 2) + 3])
2461+
const int pixel_count = len / 4;
2462+
const uint32_t *pixeldata = reinterpret_cast<const uint32_t *>(data.ptr());
2463+
2464+
for (int i = 0; i < pixel_count; i++) {
2465+
if ((pixeldata[i] & 0xFF000000) != 0) {
2466+
return false;
2467+
}
24692468
}
2469+
} break;
2470+
case FORMAT_RGBA4444: {
2471+
const int pixel_count = len / 2;
2472+
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
24702473

2474+
for (int i = 0; i < pixel_count; i++) {
2475+
if ((pixeldata[i] & 0x000F) != 0) {
2476+
return false;
2477+
}
2478+
}
24712479
} break;
2480+
case FORMAT_RGBAH: {
2481+
// The alpha mask accounts for the sign bit.
2482+
const int pixel_count = len / 4;
2483+
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
24722484

2473-
case FORMAT_DXT3:
2474-
case FORMAT_DXT5: {
2475-
detected = true;
2485+
for (int i = 0; i < pixel_count; i += 4) {
2486+
if ((pixeldata[i + 3] & 0x7FFF) != 0) {
2487+
return false;
2488+
}
2489+
}
2490+
} break;
2491+
case FORMAT_RGBAF: {
2492+
// The alpha mask accounts for the sign bit.
2493+
const int pixel_count = len / 4;
2494+
const uint32_t *pixeldata = reinterpret_cast<const uint32_t *>(data.ptr());
2495+
2496+
for (int i = 0; i < pixel_count; i += 4) {
2497+
if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) {
2498+
return false;
2499+
}
2500+
}
24762501
} break;
24772502
default: {
2503+
// Formats that are compressed or don't support alpha channels are presumed to be visible.
2504+
return false;
24782505
}
24792506
}
24802507

2481-
return !detected;
2508+
// Every pixel has been checked, the image is invisible.
2509+
return true;
24822510
}
24832511

24842512
Image::AlphaMode Image::detect_alpha() const {

0 commit comments

Comments
 (0)