Search code examples
c++graphicsbitmapbitwise-operatorsmask

Can image masking be done efficiently using only bit operations?


I have a bitmap that I need to use as an image mask when compositing a number of layers together into one target bitmap. The image mask is a black & white image where black specifies pixels that should not be drawn and white draws the pixels from the source bitmap.

The pixels are all in 32-bit ARGB format.

As indicated above, the pixels in the mask are either black (0xFF000000) or white (0xFFFFFFFF).

I'm trying to think of a quick and efficient way to combine the mask pixels with the pixels from the bitmap to be drawn using only bit operations. It would be trivial if the black pixels for clipping had an alpha value of 0 -- then I could just do an AND with the mask pixel and the bitmap pixel.

Is there any sort of bit saturation instruction, or something similar? I was thinking something along the lines of:

uint mask = maskPixel & 0x00FFFFFF;
saturate(mask); 
// If the maskPixel was black, mask will be all 0s, so the result of saturation is still all 0s. 
// If the maskPixel was white, mask will be 0x00FFFFFF, so the saturation will result in 0xFFFFFFFF

Any ideas?


Solution

  • The get_mask function below extends the low bit into an entire unsigned int value. This should be adequate if only black or white pixels are present.

    #include <iostream>
    #include <iomanip>
    
    unsigned int get_mask(unsigned int pixel) {
        return ~((pixel & 1)-1);
    }
    
    int main() {
        const unsigned int white = 0x00ffffff;
        const unsigned int black = 0x00000000;
        std::cout << std::hex << std::setfill('0');
        std::cout << std::setw(8) << white << " => " << std::setw(8) << get_mask(white) << "\n";
        std::cout << std::setw(8) << black << " => " << std::setw(8) << get_mask(black) << "\n";
    }