Cannot load BMP file for some reason.

For some reason the function DEBUGLoadBMP() (day 37) doesn't work for me, when I launch the EXE I don't see any bitmap. Moreover VS debugger return weird values for the header struct:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
FileType        2624998722	unsigned __int64
FileSize        3538944	unsigned int
Reserved1       28147497673687040	unsigned __int64
Reserved2       281474983264256	unsigned __int64
BitmapOffset	32	unsigned int
Size	        0	unsigned int
Width	        185729024	int
Height	        185729024	int
Planes	        0	unsigned __int64
BitsPerPixel	18446742974197923840	unsigned __int64
Compression     4294967295	unsigned int
SizeOfBitmap	4294967295	unsigned int
HorzResolution	-1	int
VertResolution	-1	int
ColorsUsed      4294967295	unsigned int
ColorsImportant	4294967295	unsigned int
RedMask         4294967295	unsigned int
GreenMask       4294967295	unsigned int
BlueMask        4294967295	unsigned int


For example, HxW should be 100x100. And yes, I used #pragma pack(push, 1)/#pragma pack(pop) on
bitmap_header.

For completness I also include the DEBUGLoadBMP() code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
internal loaded_bitmap
DEBUGLoadBMP(thread_context *Thread, debug_platform_read_entire_file *ReadEntireFile, char *FileName)
{
   loaded_bitmap Result = {};
   // NOTE(casey): Byte order in memory is AA BB GG RR, bottom up.
   // In little endian -> 0xRRGGBBAA

   debug_read_file_result ReadResult = ReadEntireFile(Thread, FileName);
   if(ReadResult.ContentsSize != 0)
   {
      bitmap_header *Header = (bitmap_header *)ReadResult.Contents;
      uint32 *Pixels = (uint32 *)((uint8 *)ReadResult.Contents + Header->BitmapOffset);
      Result.Pixels = Pixels;
      Result.Width = Header->Width;
      Result.Height = Header->Height;

      uint32 *SourceDest = Pixels;

      for (int32 Y = 0; Y < Header->Height; ++Y) {
         for (int32 X = 0; X < Header->Width; ++X) {
            /* 0xRRGGBBAA -> 0xAARRGGBB*/
            *SourceDest = (*SourceDest >> 8) | (*SourceDest << 24);
            ++SourceDest;
         }
      }
   }
   return(Result);
}


Any clue?
Thanks in advance.
I also had a very tough time getting it to work the first time.
The most basic thing you can do is go to the memory address of ReadResult.Contents and read from there.
The first two bytes should be always be 'B' and 'M'.

Can you read this (and possibly more) data from ReadResult.Contents' memory?
the first number you read is 2624998722 in hex that is, 9c 76 4d 42 that is much larger than the 2 bytes you should have been reading. The lowest significant bytes (those come first in little endian) are 42 and 4d which matches with the BM that is expected.

In other words you messed up the offsets in the header struct.
ratchetfreak
In other words you messed up the offsets in the header struct.


Yes, this is my suspect too. According to video lesson the pack() statement should avoid this, any idea why it doesn't work?
dgiglio


Yes, this is my suspect too. According to video lesson the pack() statement should avoid this, any idea why it doesn't work?


double check the type of each field. "FileType 2624998722 unsigned __int64" the __int64 bit is very suspicious
ratchetfreak

double check the type of each field. "FileType 2624998722 unsigned __int64" the __int64 bit is very suspicious


My problem is that I don't know a tecnique to show in VS a portion of memory, my idea was to start fom the address returned by ReadResult.Contents and move forward word by word.
I'm not sure if you correctly understood what ratchetfreak tried to tell you.

The pack is not an issue. The issue is data type. FileType should be 16-bit number. But debugger shows that you have declared it as 64-bit integer. If you are reading data for structure as a one read, or doing memcpy to sizeof member - this will read wrong data. You need to read just 2 bytes for FileType.

What do you mean by "show in VS a portion of memory"? VS debugger has memory view - Alt+6. There you can write any address, or arbitrary expression involving variables (like &Header->FileType) and it will show contents of raw memory.

Edited by Mārtiņš Možeiko on
mmozeiko

The pack is not an issue. The issue is data type. FileType should be 16-bit number. But debugger shows that you have declared it as 64-bit integer.


Ok, but I've declared it as a 16-bit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#pragma pack(push, 1)
struct bitmap_header
{
   uint16 FileType;
   uint32 FileSize;
...
   uint32 BitmapOffset;
   uint32 Size;
   int32  Width;
   int32  Height;
...
};
#pragma pack(pop)
And are you sure uint16 is correct typedef?
mmozeiko
And are you sure uint16 is correct typedef?


DOH!
Yes, there was a typo in my typedef.