Loading a bitmap

This is a discussion on Loading a bitmap within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by brewbuck This is why you should not use sizeof() on a struct to load packed binary data ...

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by brewbuck View Post
    This is why you should not use sizeof() on a struct to load packed binary data from a file. It ignores alignment and endian issues.

    You can't just imagine that the struct overlays perfectly on a section of file data. Things don't work that way.
    And removing sizeof() will solve exactly which part of the problem? I'm sure you mean the right thing, but sizeof() itself is not a culprit in this case - the struct itself holds 16 bit and 32 bit data intermixed in ways that cause the compiler to add padding - in the middle of the struct. So alignment is very much the issue here.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    Quote Originally Posted by matsp View Post
    And removing sizeof() will solve exactly which part of the problem? I'm sure you mean the right thing, but sizeof() itself is not a culprit in this case - the struct itself holds 16 bit and 32 bit data intermixed in ways that cause the compiler to add padding - in the middle of the struct. So alignment is very much the issue here.

    --
    Mats
    I didn't say that sizeof() was the problem. I (implicitly) was saying that the whole concept of taking a struct, laying it out like some portion of a file format, then using sizeof() to compute its size and read it as a single chunk, is wrong.

    Further, if you follow the rule "never use sizeof() while reading a file format" then you eliminate a whole class of errors, like the aforementioned, as well as assuming a particular endianness and integer width. Without sizeof(), you are forced to read a single byte at a time, which forces you to deal with endianness and width from the very outset instead of ignoring them.
    Last edited by brewbuck; 11-05-2007 at 10:47 AM.

  3. #18
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    These are the structs provided by Microsoft.
    Code:
    typedef struct tagBITMAPFILEHEADER { 
      WORD    bfType; 
      DWORD   bfSize; 
      WORD    bfReserved1; 
      WORD    bfReserved2; 
      DWORD   bfOffBits; 
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER{
      DWORD  biSize; 
      LONG   biWidth; 
      LONG   biHeight; 
      WORD   biPlanes; 
      WORD   biBitCount; 
      DWORD  biCompression; 
      DWORD  biSizeImage; 
      LONG   biXPelsPerMeter; 
      LONG   biYPelsPerMeter; 
      DWORD  biClrUsed; 
      DWORD  biClrImportant; 
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    Which equal:
    Code:
    typedef struct tagBITMAPFILEHEADER { 
      unsigned short bfType; 
      unsigned long  bfSize; 
      unsigned short bfReserved1; 
      unsigned short bfReserved2; 
      unsigned long  bfOffBits; 
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER{
      unsigned long  biSize; 
      long           biWidth; 
      long           biHeight; 
      unsigned short biPlanes; 
      unsigned short biBitCount; 
      unsigned long  biCompression; 
      unsigned long  biSizeImage; 
      long           biXPelsPerMeter; 
      long           biYPelsPerMeter; 
      unsigned long  biClrUsed; 
      unsigned long  biClrImportant; 
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    I remember I have used these once to read bitmap files. Microsoft itself uses this way too...

    And GameDev has this as a tutorial too: http://www.gamedev.net/reference/art...rticle1966.asp
    Last edited by maxorator; 11-05-2007 at 12:08 PM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  4. #19
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    So, your argument is "If Microsoft does it, it must be right?"

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And by the way, MS also does:
    Code:
    #include <pshpack2.h>
    typedef struct tagBITMAPFILEHEADER {
    ....
    pshpack2.h in turn does:
    #pragma pack(2)

    [It's a bit more complex than that - it tests for differnet compiler versions and a bunch of other #if type things before it does this, but that's what it amounts to].

    You would have seen that if you read the line just above the header you copied and pasted from WinGDI.h - or did you just copy'n'paste from some other place that doesn't show the context of the structure definition?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Loading a bitmap (Without using glaux)
    By Shamino in forum Game Programming
    Replies: 7
    Last Post: 03-16-2006, 09:43 AM
  2. OpenGL -- Bitmaps
    By HQSneaker in forum Game Programming
    Replies: 14
    Last Post: 09-06-2004, 05:04 PM
  3. Loading a Bitmap resource for OpenGL Texture[x]
    By the dead tree in forum Game Programming
    Replies: 4
    Last Post: 08-26-2004, 02:12 PM
  4. Loading bitmap in dll
    By Mithoric in forum Windows Programming
    Replies: 2
    Last Post: 12-22-2003, 01:53 PM
  5. No one can seem to help me, loading bitmap
    By Shadow12345 in forum C++ Programming
    Replies: 7
    Last Post: 12-28-2002, 01:22 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21