24-Bit Bitmaps

Problem #86

Tags: computing instructional

Who solved this?

Previous:Polynomial Derivatives Next:Product Rule and Trigonometric Derivatives


A simple 24-bit bitmap with 8 pixels (enlarged here for visiblity). Click on the image to download it, then try to open it in a text editor like Notepad to follow along below.

On computers, all data is ultimately stored as 1s or 0s. But how do we start with something like an image, reduce it down into 1s and 0s to be able to send it over the internet, the be able to reconstruct that image on some user's computer? There are many formats available for storing image data, but in this problem we will take a look at 24-Bit Bitmap files.

If you try to open up a .bmp file in a text editor to look at its contents however, you might be greeted with a sight like this:

bmp raw text

So what's going on here? The data is stored as hexadecimal byte data, but the text editor is incorrectly trying to interpret each byte as a character of ASCII text. Let's convert it back to the hex bytes, then.

42 4d 4e 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 04 00 00 00 02 00 00 00 01 00 18 00 00 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 00 ff ff ff 00 ff ff ff ff 00 00 00 ff 00 00 00 ff

There are three main sections in the data: the File Header, the DIB Header, and the Pixel Data. The final section is where the actual image is defined, mapping each pixel color by bit (hence the name). Let's walk through each section one at a time.

File Header

The first fourteen bytes of data contains the file header. In our example it is these bytes:

42 4d        // file type
4e 00 00 00  // file size
00 00        // reseved 1
00 00        // reseved 2
36 00 00 00  // pixel data location

There are five pieces of data in the File Header, separated above for visual clarity.

DIB Header

The next forty bytes of data containst the file header. In our example it is these bytes:

28 00 00 00  // header size in bytes
04 00 00 00  // image width in pixels
02 00 00 00  // image height in pixels
01 00        // color planes
18 00        // bits per pixel
00 00 00 00  // compression
18 00 00 00  // pixel data size in bytes
00 00 00 00  // horizontal pixels per meter
00 00 00 00  // vertical pixels per meter
00 00 00 00  // colors used
00 00 00 00  // important colors

There are eleven pieces of data in the File Header, separated above by line for visual clarity.

Pixel Data

The remaining bytes will then describe the color of each pixel, starting from the botton-leftmost pixel and then listing each pixel left-to-right in each row. Each pixel is described by three bytes in BGR format, listing Blue intensity first, then Green, then Red. In our example we have eight pixels with color values:

00 00 00 ... black
00 ff ff ... yellow
ff 00 ff ... magenta
ff ff 00 ... cyan
ff ff ff ... white
ff 00 00 ... blue
00 ff 00 ... green
00 00 ff ... red

A note on Pixel Data - each row of pixels must contain a quantity of bytes divisible by four. So for example if we have an image that is three pixels wide, and each pixel uses three bytes of color data, then that's only nine bytes per row. The next-greatest number divisible by four is twelve, and so three "padding bytes" of 00 will be added to the each row. These "padding bytes" should be tracked and ignored when parsing the data.

Problem Statement

You will be given a set of byte data corresponding to a real 24-bit bitmap image file. You will then be asked to examine the color values of specific pixels from the image.

Input Data
First will be N hexadecimal byte values separated by spaces. For visual clarity, bytes will be separated by newlines in groups of sixteen bytes per line. Note that the final line may contain less than sixteen bytes if the total quantity of bytes is not divisible by sixteen.
Also note that the values are not space-separated as in our examples so far.

After the byte data, the next line will be a decimal integer Q, the quantity of testcases.
Q lines will then follow, each having three space-separated values X Y C, being the Row, Column, and Color intensity value of a certain pixel (either B, G, or R). Note that Row and Column values are 0-indexed.

Answer
Should be Q space-separated integers, corresponding to the color intensity of the listed pixels in the given bitmap data.
List all intensities as the decimal representations, rather than the hex values.

Examples

Here is an example using the image we've been walking through above.

input data:
424d4e00000000000000360000002800
00000400000002000000010018000000
00001800000000000000000000000000
00000000000000000000ffffff00ffff
ff00ffffffff000000ff000000ff
3
0 0 R
0 1 G
1 1 B

answer:
0 255 255

Here is another example using an image five pixels wide and two pixels tall. Note the padding byte appearing at the end of each row.

input data:
424d5600000000000000360000002800
00000500000002000000010018000000
00002000000000000000000000000000
0000000000001595aa8e2c7c808b8d31
3f7410c76b001920cbfab398dff5ac55
9407fbc84600
3
0 0 R
0 3 G
1 4 B

answer:
170 139 251

Be aware that the Bitmap data in the actual testcase will be much larger than the above examples.

You need to login to get test data and submit solution.