Digging around the cutting edge A5 source of al_convert_mask_to_alpha (https://github.com/liballeg/allegro5/blob/634fdc89807c91be8174190ad5cf9e0bc55a25c2/src/bitmap.c#L253): This function is OS-independent, and it is, like my handwritten Lix recoloring, a high-level pixel-by-pixel loop.
void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)
{
ALLEGRO_LOCKED_REGION *lr;
int x, y;
ALLEGRO_COLOR pixel;
ALLEGRO_COLOR alpha_pixel;
ALLEGRO_STATE state;
if (!(lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, 0))) {
ALLEGRO_ERROR("Couldn't lock bitmap.");
return;
}
al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP);
al_set_target_bitmap(bitmap);
alpha_pixel = al_map_rgba(0, 0, 0, 0);
for (y = 0; y < bitmap->h; y++) {
for (x = 0; x < bitmap->w; x++) {
pixel = al_get_pixel(bitmap, x, y);
if (memcmp(&pixel, &mask_color, sizeof(ALLEGRO_COLOR)) == 0) {
al_put_pixel(x, y, alpha_pixel);
}
}
}
al_unlock_bitmap(bitmap);
al_restore_state(&state);
}
One possible method of attack: Investigate how C memcmp can fail to recognize two pixel structs as identical even though both are pink. A5 color structs contain 4 floats without padding:
typedef struct ALLEGRO_COLOR ALLEGRO_COLOR;
struct ALLEGRO_COLOR
{
float r, g, b, a;
};
Now, for IEEE floats, the C language considers +0 == −0 when we compare them with ==, but memcmp(+0, −0) will not consider them equal. (Perhaps even +1 won't memcmp-equal some other representation of +1, but I doubt it.) Then memcmp will fail. I'll ask on A5 what they think about memcmp here. Comparing floats with equality is a can of worms in general, I have no good immediate fix to offer.
I don't want to scare away other Mac users with technicialities. Who has a Mac? :lix-grin:
-- Simon