Thread: Problems with bmp-reading program

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    3

    Problems with bmp-reading program

    I'm having trouble finding the bitmap offset info in the file header, and the size info is a bit unreliable at the moment.

    I've made a 10x10 pixel 24-bit image in paint in WinXP and that's the file I'm testing with.

    If I increase the size so it goes over the size of an unsigned short int it doesn't show the correct size and I was wondering how to fix this. If I increase the size of bmpFileHeader.size to unsigned long int it doesn't work at all.

    The second problem is the bitmap offset, it doesn't show any meaningful value at all.



    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    struct bmpFileHeader {
        unsigned short int type;            //specifies the file type
        unsigned short int size;             //specifies the size in bytes of the bitmap file
        unsigned short int reserved1;       //reserved; must be 0
        unsigned short int reserved2;       //reserved; must be 0
        unsigned long int bitmapOffset;     //specifies the offset in bytes from the bitmapfileheader to the bitmap bits
    };
    
    int main(int argc, char *argv[])
    {
        bmpFileHeader fh;
        
        //Open file as read only, binary
        ifstream bmpstream("test.bmp", ios::in | ios:: binary);
        
        
        //Verifying that open file succeeded
        if(!bmpstream) {
            cout << "Error opening file.\n";
            system("PAUSE");
            return EXIT_FAILURE;
        }
        
        
        //Read bitmap file header
        bmpstream.read((char *) &fh, sizeof(bmpFileHeader));
        
        
        //Temporary debug feedback
        cout << "Filetype: " << hex << fh.type << endl;
        cout << "Filesize: " << dec << fh.size << endl;
        cout << "Reserved 1: " << fh.reserved1 << endl;
        cout << "Reserved 2: " << fh.reserved2 << endl;
        cout << "Bitmap Offset: " << fh.bitmapOffset << endl;
        
        
        //Verifying that file is .BMP by checking first 2 bytes in the file header.
        if (fh.type !=0x4D42) {
            bmpstream.close();
            return EXIT_FAILURE;
        } 
        
        
        
        //Close file
        bmpstream.close();
        
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The sizes go 2, 4, 2, 2, 4. You have 2, 2, 2, 2, 4.

    Check this out. http://www.wotsit.org/refer.asp?url=...l&sc=246550348
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Which OS/Compiler are you using here?

    The further you step away from a 16-bit Microsoft / X86 implementation, the less likely reading directly into a structure is to work as desired.

    Binary structures are beset with all sorts of endian and alignment problems.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    3
    dwks: Ya, I know. I had it like that first, but it only worked with the size when I changed it to 2, 2, 2, 2, 4.

    Salem: I'm using Windows XP and using Dev-C++.

    Any ideas on what to do?

    btw, I like your avatar Salem

    Edit: I forgot my manners, thanks for your answers!
    Last edited by Amanita; 10-24-2007 at 01:53 PM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The reason it sort of works with your modified struct is that the compiler will enforce alignment on double-words [such as int] when it builds the struct. This means:
    2,4,2,2,4 becomes 2,[2,]4,2,2,4 where the [2,] is a filler padding the next 4 bytes to be aligned to a 4 byte boundary.

    You can use some sort of mechanism to change the alignment of the struct, so that it's not padded out [aka "packing the struct"] the data structure - I think MS uses
    Code:
    #pragma pack(1)
    .

    Or you could read each little bit at a time.

    Unfortunatley, there's really no consistant and portable way to use "structure packing". gcc uses __attribute__(something), if I remember correctly.

    --
    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.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    dwks: Ya, I know. I had it like that first, but it only worked with the size when I changed it to 2, 2, 2, 2, 4.
    In that case, your structure padding might be messing things up. Try changing them to the sizes I suggested and reading in each structure member individually. For example, after changing size to a long, this works for me:
    Code:
        bmpstream.read((char *) &fh.type, sizeof(fh.type));
        bmpstream.read((char *) &fh.size, sizeof(fh.size));
        // ...
    Of course, that's a pain to write out.

    Or mess with your compiler's structure padding settings if you feel like it.

    [edit] Also see matsp's post. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Oct 2007
    Posts
    3
    Woah! It works!

    This padding was news to me. I'm not exactly an experienced programmer, just doing it for fun.

    I've struggled with it for quite some time, I thought I would figure it out for myself but it seems it's hard to find something you don't know you should look for.

    I greatly appreciate your help.

  8. #8

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Even "#pragma(pack)" can only do so much. On a different architecture, even the basic types may have different sizes, and then there is the whole endian problem to be solved.

    The only portable way is to read one byte at a time, and manually write the code to position that data in the proper place in the struct.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-28-2008, 03:07 AM
  2. Calling external program and reading its output.
    By Dragoon_42 in forum C++ Programming
    Replies: 3
    Last Post: 10-18-2007, 05:34 AM
  3. Problem reading BMP
    By Mortissus in forum C Programming
    Replies: 4
    Last Post: 02-02-2006, 06:32 AM
  4. Having problems reading a text file.
    By newbie543 in forum C Programming
    Replies: 9
    Last Post: 08-28-2005, 11:52 PM
  5. problems reading in from text
    By requiem in forum C++ Programming
    Replies: 5
    Last Post: 04-25-2003, 12:13 AM