thpthp
thpthp

Reputation: 93

Get a value in a function with bit manipulation

In a particular graphic library one represents pixels with 32-bit values consisting of four bytes for representing the four components RED, GREEN, BLUE and Alpha. The following definitions are available:

typedef unsigned int Uint32;
typedef unsigned char byte;
enum Color { RED = 0, GREEN = 1, BLUE = 2, ALPHA = 3 };

One now needs two free functions:

Byte getColorComponent (Uint32 pixel, Color color);

which, by means of bit manipulation, retrieves and returns the value of the one of the four color components shown in the color argument; and

void setColorComponent (Uint32 & pixel, Byte value, Color color);

which takes stops in the Byte value in the right place (according to the color argument) in the pixel.

The answer is:

Byte getColorComponent(Uint32 pixel, Color color){   return (pixel >> (3-color)*8) & 0xFF; } 
void setColorComponent(Uint32& pixel, Byte value, Color color){   pixel &= ~(0xFF << (3-color) * 8);   pixel |= value << (3-color) * 8; }

I need help to understand the answer.

Upvotes: 1

Views: 71

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409404

A good way to help figure out this sort of problems, is to use ordinary pen and paper. Pick values for one or more variables, substitute them inside the expression. Continue substituting sub-expressions until there's a result.

Much like you simplify mathematical expressions.

For example with getColorComponent:

Pick the color GREEN (with value 1).

Pick the pixel value 0x8a2be200 (which is an opaque blue-violet color, assuming RGBA).

Original expression (pixel >> (3 - color) * 8) & 0xff

Substitution chain

  1. (0x8a2be200 >> (3 - 1) * 8) & 0xff
  2. (0x8a2be200 >> 2 * 8) & 0xff
  3. (0x8a2be200 >> 16) & 0xff
  4. 0x8a2b & 0xff
  5. 0x2b

With color == GREEN it extracts the GREEN color component of a 32-bit RGBA color value.

If you use any of the other color enumeration values (RED, BLUE or ALPHA) doing the same thing, you will see that it extracts those components from the RGBA color value as well.

I leave it as an exercise for the readers to use this technique to figure out what setColorComponent is doing.


As an alternative, to use with computers and debuggers, split up a complicated expression into its smallest sub-expressions, assigning the results to temporary variables. Then use a debugger to step through the code line by line, to see the results come together.

With this the expression (pixel >> (3 - color) * 8) & 0xff would become the statements

auto t1 = 3 - color;     // 3 - color
auto t2 = t1 * 8;        // (3 - color) * 8
auto t3 = pixel >> t2;   // pixel >> (3 - color) * 8
auto t4 = t3 & 0xff;     // (pixel >> (3 - color) * 8) &0xff

Upvotes: 1

Related Questions