What do bitwise operations mean for colors?

Date:November 13, 2006 / year-entry #382
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20061113-11/?p=29033
Comments:    9
Summary:Someday, you're going to pass a raster operation to the BitBlt function that entails bit manipulation. Something like SRCAND perhaps, or possibly the dreaded SRCINVERT. These bitwise operations make perfect sense for monochrome bitmaps, since those are one bit per pixel anyway. But what does it mean for color bitmaps? What do you get when...

Someday, you're going to pass a raster operation to the BitBlt function that entails bit manipulation. Something like SRCAND perhaps, or possibly the dreaded SRCINVERT. These bitwise operations make perfect sense for monochrome bitmaps, since those are one bit per pixel anyway. But what does it mean for color bitmaps? What do you get when you "and" together forest green (#228B22) and hot pink (#FF69B4)?

The bitwise operations are performed in the pixel space of the destination. If the destination is a non-palettized bitmap format (higher than 8bpp), then the pixel values are red, blue and green components packed together (in various ways depending on the format). Those values are "and"ed together as integers to produce the result. For example, in a 565-format bitmap, the color forest green is represented as the value 0x2464 (0y00100`100011`00100) and hot pink is 0xFB56 (0y11111`011010`10110). The bitwise "and" of these two values is 0x2044, which is a very dark purple.

With palettized bitmaps, the results are much less predictable since the values in the bitmap are not colors but color indices. For example, if a pixel has the value 6, that means that the color of the pixel is determined by the entry in slot 6 of the bitmap's color table, and that color could be anything. There is no rule that even requires that color 0 be black and that the highest available color be white, though most bitmaps adhere to this by convention.

On an 8bpp bitmap, then, the question of what you get when you "and" together forest green and hot pink is underdetermined. If the color table for example happened to put forest green in slot 6 and hot pink in slot 18, the result of the "and" operation would be 6 & 18 = 2, and the result pixel would therefore be whatever color was in slot 2 of the bitmap's color table.

What does this mean for you, adventuresome blitter?

If you're going to use raster operations that involve bitwise operations, one of the pixels involved in the operation should be black or white (zero or all-bits-set) in order to obtain predictable results. You can then use identities like "x and black = black" and "x xor black = x" to predict the result, assuming the bitmap follows the convention for black and white noted above. But if you're going to be xor'ing with forest green, then the results could be anything.


Comments (9)
  1. Tom says:

    Bit-wise operations on color DDBs is like a box of chocolates — you never know what you’re gonna get.  But I must say that, using a palletized DDB just seems wrong.  I can understand a DDB using differing bits per color per pixel as the BPCPP must match the display hardware for effective bltting, but doesn’t using a palettized DDB make blitting hard or (gasp!) less efficient?  Do they even make palettized DDBs?

    [I think you’ll enjoy Wednesday’s entry. -Raymond]
  2. KJK::Hyperion says:

    Superkoko, you can use it as an obfuscated way to perform calculations. You can implement a Vernam cipher very "handily" with BitBlt, and since you can make up your own logic operations by providing an arbitrary truth table, there’s no limit to how hard you can obfuscate something as simple as a XOR. A more benign use is to XOR a bitmap with itself to blacken it, or NOT XOR to whiten. And once you get hooked up to PatBlt, there’s no going back…

  3. Mike Dimmick says:

    I’m using a custom blit to paint text from a custom font bitmap. We’re doing this because it is significantly harder to create a custom TrueType font, Windows CE only supports either TrueType or bitmap fonts (chosen at platform build time), and the OEM suppliers (and Microsoft for Windows Mobile) have already made the choice of TrueType.

    The ternary raster operation opcode is 0x00B8074A and I leave it as an exercise to the reader to work out how it works ;) As a hint, the background colour of the font bitmap is white and the foreground colour is black.

    Moving to a custom blit (i.e. one not declared in WinGDI.h) saved two blits per character, a screen-compatible DC, and a screen-compatible bitmap selected into that DC. Thanks, Raymond, for the hint that this was even possible.

  4. Jack Mathews says:

    An "interesting" effect with bitwise and?  Simulating palettization (or heat stroke) by anding off the low bits one by one.

  5. Dan McCarty says:

    AND’ing forest green with anything is always tricky, and the lesson is don’t make the classic mistake of not seeing the Forest for the Green!

    (Thanks folks, I’ll be here all week except Tuesday.  Make sure you try the Mahi Mahi.)

  6. SuperKoko says:

    I remember that I once used he AND bitwise operation of an homogen source (with a function functionally equivalent to PatBlt) on an RGB 24 bits image destination.

    The homogen source pixels had values such as RGB(-4,-4,-4) or RGB(-2**n, -2**n, -2**n).

    The final effect is to decrease the number of colors of the image by rounding down colors.

    The effect is interesting.

    However, I don’t think that AND-ing a 24 bits image with another 24 bits image could make sense. At least, I’ve never used it.

  7. Charlie says:

    Given the stories I’ve heard about NES/Super NES development, I’m not fazed at all by the idea of XORing colors. People came up with cool graphical effects based on weird bitwise magic all the time.

    The Super Nintendo’s graphics processor, in particular, had some truly bizarre features.

  8. kokorozashi says:

    One thing I’d like to see covered (and yes I know this is the wrong place for suggestions, but for this suggestion I suspect Raymond’s suggestion box is also the wrong place) is a discussion of why such operations don’t seem to be present at all in GDI+ and what one is supposed to do instead. I have some vague ideas but no practical experience. I recently wrote my own blitter to do what I used to know on the Mac as deep masking, but I have a feeling that was not the best approach.

  9. Cheong says:

    So, this is why System.Drawing.Graphics object is not applicable to System.Drawing.Image of indexed image formats like GIF.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index