This question led to a nice discussion on the allegro forums Credits to Dizzy Egg for working out this example in full detail. I'll summarize the answer here for future reference.
A solution with al_tinted_bitmap is definitely possible, but I'd choose the get_pixel / put_pixel approach as you have a bit more control. It's not hard to replace pixels of one color with pixels of another color. Just loop over each pixel in the bitmap and do this:
color = al_get_pixel(snake_white, x, y);
if(color.r == 1.0 && color.g == 1.0 && color.b == 1.0) {
al_put_pixel(x, y, al_map_rgb(50, 255, 50)); //Choose your own colour!
}
else {
al_put_pixel(x, y, color);
}
The problem in this case is that you don't have just one color (white) but also shades of grey, due to anti-aliasing on the outlines of the snake. So what we can do instead, is check each pixel if the r, g, and b component are all non-zero. If they're all non-zero, then it's neither black, nor red (the tongue) nor yellow (the eyes). Then we multiply the grey-values with r,g,b components of our own choosing.
color = al_get_pixel(snake_white, x, y);
if(color.r >= 0.01 && color.g >= 0.01 && color.b >= 0.01) {
al_put_pixel(x, y, al_map_rgba_f(new_color.r * color.r, new_color.g * color.g, new_color.b * color.b, color.a));
}
else {
al_put_pixel(x, y, color);
}
You could make it smarter in a lot of ways, but it works well for the snake image. See the linked forum thread for the full code.