2

I am trying to write a code to read a BMP file so I am trying to read BMP header(s). I am using a test image from some code library but it looks, like the structure doesn't correspond with the information about BMP image structure on Wikipedia Wikipedia BMP structure , especially in part, where should be offset stored ("The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found. ") in the table on Wikipedia as the start of the image looks like following:

00000000: 424d ea88 0000 0000 0000 3604 0000 2800  BM........6...(.
00000010: 0000 e300 0000 9500 0000 0100 0800 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0001  ................
00000030: 0000 0000 0000 2c2a 2c00 4c8f 6900 252e  ......,*,.L.i.%.
00000040: 9900 385b 4700 4c54 9700 98c9 a000 7a8c  ..8[G.LT......z.

So there is clear that the image starts on 36h and not 436h as is should look like according to Wikipedia - looks for me like the valid information has 1 Byte, not 4 Bytes. So I tried to find another source of the information about the header and I've found only the same information as is described in the mentioned article.

I thought that I have wrong image stored, so I decided to open it via Gimp and store it as the new-one, but it looks like the header has the same structure, just start of the image is moved.

00000000: 424d 2e89 0000 0000 0000 7a04 0000 6c00  BM........z...l.
00000010: 0000 e300 0000 9500 0000 0100 0800 0000  ................
00000020: 0000 b484 0000 130b 0000 130b 0000 0001  ................
00000030: 0000 0001 0000 4247 5273 0000 0000 0000  ......BGRs......
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0200 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 2c2a 2c00 4c8f  ..........,*,.L.
00000080: 6900 252e 9900 385b 4700 4c54 9700 98c9  i.%...8[G.LT....

So not only that Gimp reads the header with no issue, but it even creates header of the same type. But according to the documentation it looks like the binary part should be stored on 436h, respective 47Ah as there should be little endian used. I am clearly missing something there but I can't get the point as the different sources fastgraph.com BMP header docs.fileformat.com BMP structure shows the same offsets but reality differs here for some reason. Can you move me forward here?

PS: I would paste here original image, but it looks like the image is automatically exported to png format.

noname
  • 21
  • 4
  • Does this answer your question? [BMP image header](https://stackoverflow.com/questions/14478778/bmp-image-header) – user14063792468 Apr 10 '22 at 13:50
  • What makes you think the 'binary part' starts at 36? "BGRs" doesn't look like bitmap data. In fact, given that the "Size of header" field is 108, I expect you're looking at a BITMAPV4HEADER (not a BITMAPINFOHEADER), which should help you parse out the rest of that data. – David Wohlferd Apr 10 '22 at 19:03
  • The reason why i think that there starts the bitmap data is because I've checked the first pixel value in the image in Gimp. The first three values looks like the value of the first pixel. If I tried to check the pixel that should be on the offset 436h, that value would differ. Thanks for the point regarding to the headers, I will check it now. – noname Apr 10 '22 at 22:17
  • @David Wohlferd - Thank you again with the good points, you are probably correct with the second image, where is the value 108, as you write. I am trying to understand this quickly, but I have to check it later in greater detail to fully understand the situation. But as far as I can check the sample of the first image, it looks for me still like BITMAPINFOHEADER as there is value 28h in the place where offset should be. I will try check the images again later with fresh head to understand this better as I am still not clear about all columns in both cases. Thanks for the good point! – noname Apr 10 '22 at 22:47
  • Just a note, the value that was part of the question wasn't in BITMAPINFOHEADER or BITMAPV4HEADER, but in Bitmap File Header, on 0A prefix, so although I will be very happy to check the DIB Headers as they interests me as well, the core issue is in Bitmap File Header on 0A prefix, where the offset should be written. Maybe just a note - if I will try to create image in Gimp directly without opening the file first, the Bitmap File Header looks exactly as one would expect. Not sure why the re-exported file uses the header. – noname Apr 10 '22 at 23:14
  • 1
    In monochrome, 16- and 256-color BMP files, the color table follows the header. 24-bit Bitmaps do not have such a table. The color table has a length of 8 bytes for monochrome, 0x40 bytes for 16-color and 0x400 bytes for 256-color bitmaps. Because the first example is obiously a 256-color BMP file, the color table starts at offset 36h and ends at offset 435h. The bitmap data starts at offset 436h. – Martin Rosenau Apr 11 '22 at 12:31
  • @Martin Rosenau, Thanks for the perfect explanation, now I am getting it. I will need to check it a bit deeper to fully understand the topic, but now I understand, where I made the mistake. Your comment was really useful +1 – noname Apr 11 '22 at 16:51

2 Answers2

1

tl;dr: In your image there's a color table. When there's a color table, it comes after the DIB header, and the pixel data is after that. Since the color table runs from 0x36 to 0x435, the pixel data itself is indeed at 0x436.

The last time I used it, the Wikipedia article on the BMP format was correct and more thorough and better presented than most other sources.

A BMP file has a file header and then a bitmap info header (sometimes called the DIB header). The pixel data might start immediately after the info header, but there may be additional color information and/or padding. The pixel data is after that.

Based on your first hex dump, you are correct that the file header says the pixel data starts at 0x0436. You don't show enough of the file to see whether the pixel data actually starts at 0x0436, but we can inspect the DIB header to see if it's consistent.

The DIB header is more complex because there are many versions. Starting at offset 0x0E, we can read that size of the DIB header is 0x28 (or 40 decimal). That tells us it's a vanilla BITMAPINFOHEADER.

The bitmap size is 227x149 pixels. (Watch out, because odd widths can be tricky to get just right.)

The pixel format is 8 bits per pixel and BI_RGB is the compression value. So there will be a color table (palette) after the headers and before the pixel data. In fact, the header explicitly says there will be 256 color table entries.

So the color table starts at 0x36. Each entry in the color table is four bytes (RGBQUAD), so the table length is 256 colors * 4 bytes/color = 1024 bytes. Thus the table runs from 0x36 to 0x435.

The pixel data can come anywhere after the color table as long as it's aligned to a 4-byte boundary. Since 0x0436 is a multiple of 4, that's the first possible address available. It's also exactly where the file header said the pixel data would be.

(When you saved the image with Gimp, Gimp chose to save it using a different version of the bitmap info header that's 0x6C bytes long and it uses a different pixel format, so it's not surprising that the pixel data starts at a larger offset.)

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
-1

Thanks for all replies!

After all responses it looks that I did mistake because I have thought that start of bitmap palette is start of the image, because the color on the start looked like the color in the first pixel of the image. All replies were useful for me as they helped me understand the topic better. After there was comment from Martin Rosenau read, which helped me to understand my mistake, was also helpful http://libertybasicuniversity.com/lbnews/nl100/format.htm article.

noname
  • 21
  • 4
  • This is not an answer, but only a comment. Please take the [tour] again - this is not a board/forum/chat. – AmigoJack Jun 26 '22 at 22:50