Shift operations

Last updated at 20 February 2021 at 9:00am


A few weeks ago I got bored and decided to do some bitmap file IO. Through this awesome Wikipedia page, I was able to understand the file format and created a small C++ library bmp.

This fun project led me to learn about shift operations. In this article I will share what I learned.

A bitmap image stores its image data as either 32 bits or 24 bits per pixel. That is, red, green and blue values for 24 bit and an additional alpha value for 32 bit image.

The first task I had was to come up with a data structure that would represent the bitmap in memory. Below is what I initially went with.

struct pixel_t
{
    unsigned char b;
    unsigned char g;
    unsigned char r;
    unsigned char a;
};

struct bmp32_t
{
    ...
    pixel_t * pixels;
};

pixel_t represents a 32 bit pixel, with blue, green, red and alpha values as an unsigned char. bmp32_t is the bitmap data structure that has an array of pixel_t.

This approach worked well. Then I learned about bitwise operators, and I was immediately disappointed with myself. Then I found out that there was another way to represent a pixel using one data type.

This other way was using bitwise operations to manipulate bits in an integer. Bitwise operations are one of those things you know exists but you don’t really know how to use them like templates :'(.

The bitwise operation that I used was the shift operation.

Shifting

Shifting in simple terms is moving bits left or right.

For example :

Number Shift left Shift right
0100 (4) 1000 (8) 0010 (2)
1011 (11) 0110 (6) 0101 (5)

C++ has two operators that allows you to accomplish this task.

  • >> Shift right
  • << Shift left

For example :

1
2
3
4
int a = 0x01;
a << 1;
a << 2;
a >> 4;

Line 2 shifts the integer once to the left, line 3 shifts to the left 2 times, and line 4 shifts to the right 4 times.

Implementation

Since a pixel color ranges from zero (0x00) to 255(0xff) for blue, green, red and alpha, we store the data in a 32 bit integer.

Pixel value 0xff0032ff would mean that :

  • blue - 0xff(255),
  • green - 0x43(67),
  • red - 0x32(50),
  • alpha - 0xff(255),

To manipulate the data we can use shift operations to get and set different values.

To get the value green value :

uint32_t pixel = 0xff4332ff;
green = (pixel << 8) > 24;

First shift the value left 8 times, then shift again 24 times to the right. As shown by the illustration below.

To set the b,g,r,a values :

pixel = 0;
pixel = b;
pixel = (pixel << 8);
pixel += g;
pixel = (pixel << 8);
pixel += r;
pixel = (pixel << 8);
pixel += a;

First set the blue value, then create space for green, add green, do the same for the rest.


I hope this sheds some light on how you can usea shift operator. While you are at it you can also research on BIT MASKING which is another concept that relies on bitwise operations.