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:
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.
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.
The first two bytes hold the File Type, which is always 42 4d for bitmap files (corresponding to the ASCII charactes B and M signifying a BitMap).
The next four bytes hold the File Size describing the total bytes in the file. Our example has seventy-eight bytes, or 4e in hex. We should note that the bytes are "tail-endian", meaning that the "least significant" byte is placed to the right. In this way the bytes 01 00 mean one in demical, rather than two-hundred fifty-six. However understand that each two-digit byte is still in normal order, so seventy-eight is still 4e in hex.
The next two pairs of two bytes each are Reserved for application-dependent use, and are typically left at 0.
The final four bytes describe at which byte the actual image Pixel Data starts in the file after both headers. In our example it starts at byte fifty-four, or 36 in hex.
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.
The first four bytes are the size of the DIB Header, which is always forty, or 28 in hex.
The next four bytes are the width of the image in pixels.
The next four bytes are the height of the image in pixels.
The next two bytes are the number of "color planes", which will always be set to 01 00.
The next two bytes indicate the number of bits we are using for each pixel of color data. Since we are using twenty-four-bit data, this value is 18 00 00 00.
The next four bytes indicate compression, which we will not use for this problem and so these will always be set to zero.
The next four bytes indicate the length of the Pixel Data, in bytes, including any additional padding bytes required (more on padding bytes mentioned below).
The next sixteen bytes are often set to zero, and we'll ignore them for this problem.
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.
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.