Thread: Me again.. this time: how does C/C++ store struct/class info in a file anyway??

  1. #1
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113

    Me again.. this time: how does C/C++ store struct/class info in a file anyway??

    Hi, I'm back again, I haven't been away from lack of coding, I've just been quite busy and haven't run into any interesting problems lately
    Anyway, I did a little while ago, but then got busy enough I never had a chance to ask it, so here goes.

    How does c/c++ store classes in binary format in a file anyway?

    The main reason I ask this is because I want to load a bitmap into a DOS-based app. I know, SDL is better, etc; don't worry, I'll get to that, but first I want to try doing it myself. It has always been easier for me to learn things from the ground up, even if it seems a tad unneccessarry(I am sure I spelled that wrong but it's late..)
    So the big thing is this. I tried loading up a bitmap into this working graphics shell I (finally) managed to hack together from various sites using the old code from those graphics tutorials by.. uhmm.. whatsisname.. that were done (originally) in pascal.
    The compiler I'm using is DJGPP(which I don't normally use)
    I put in the code from this website, under the faq, entry about "how do i load a bitmap into my dos program?" I modified it *very* slightly to fit my graphics shell.
    I created a test graphic in Windows Paint, and attempted loading it. It gave me the error "this is not a valid bitmap".
    After a bit of poking, I found that the bfType was loading in properly (value is 19778), but everything after that seems to be screwed up.
    The big question is - what order are the bytes in a class or struct's member variables stored on a file?
    Is djgpp somehow loading them in a different order than they were saved in?
    And if so, how can I fix it?

    Also, as extra info, I don't remember exactly what I did since it's actually been a couple months since I was messing around with it, but if I remember I also did the following:

    loaded the values of the BITMAP struct with various values and saved it to a file, then loaded it back, with both djgpp and MSVC++ 6.0: both times it worked fine.
    (also used fstream.read and fstream.write to write a class which was the same as the struct for bitmap, and had the exact same results)

    Also compiled code to load a bitmap in MSVC++, and had the same results as in DJGPP (i.e. everything after the BM is screwed)

    I also tried using Paint Shop Pro and Photoshop to create bitmaps, both with the same results as Windows Paint

    it *seems* like somehow the code I write is loading the values, but somehow switching the order of the bytes(or nibbles) in the values it loads;

    I've also read from *quite* a few different sources on how to load bitmaps, and they all have the same code as is in the FAQ here at cprogramming.

    I'm totally stumped on this one.. and I don't really want to write some fancy translation code to un-screw-up all the values I load, since I'm probably just missing something simple.. I hope ^.^
    Any help will be greatly appreciated.. especially if I learn something real good from it
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Chances are you are reading old bitmap formats into modern programs. Either that or the image originated on one type of machine and are loading it to another, like moterola to intel for instance. Old bitmap formats only support 8 bit (256) colors, and the header is probably slightly different. Do a google on file formats and narrow it to bitmap, you'll get several sites that will spell out for you the information to write and thus read back for viewing.

    Anyway, C/C++ compilers store information like any other program written in any other language for that platform. You just have to be patient and read the complete documentation before writing s program to deal with it...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113
    Chances are you are reading old bitmap formats into modern programs. Either that or the image originated on one type of machine and are loading it to another, like moterola to intel for instance.
    I don't think so, as I created the image last night on the same machine I used to load it. I also created two more bitmaps this morning, one made in Paint Shop Pro 7.01, another made in Photoshop 6.0: interestingly enough, the values my program loaded from the bitmaps from psp and ps ,atched each other; however they didn't match the one I made in paint. This may be because of the large number of various options you can specify for bitmap files, and I may have chosen something different in psp and ps than I did in paint.


    Old bitmap formats only support 8 bit (256) colors, and the header is probably slightly different.
    I am using 256 colour bitmaps, and I am using code to load them.

    Do a google on file formats and narrow it to bitmap, you'll get several sites that will spell out for you the information to write and thus read back for viewing.
    I did wotsit.org was just one of them, and every site I did find contained exactly the same information on bitmaps, old and new; they detailed how to load bitmaps wether they were 24bit or 8bit or in-betweeen, and each of them said that the header is the same; it's just the actual data area of the file that differs. But I am having trouble loading the header itself! which is why it seems odd.. anyway I will continue to look into it. Thanks for the pointers though

    Anyway, C/C++ compilers store information like any other program written in any other language for that platform. You just have to be patient and read the complete documentation before writing s program to deal with it...
    okie dokie, I'll keep looking around.
    oh, btw, sorry for making my post so long, it's just that I've been trying to figure this out for awhile now, and I am still totally flabbergasted ^.^ so I figured I'd give as much info as I could. Anyway, chow for now, I'll off to see if I can figure anything out and check back here again later!
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

  4. #4
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113
    Well, an hour looking around on MSDN didn't help alot, as I didn't find anything at all on how MSVC++ (6.) stores classes/structs to file, however, after messing around myself, I found something out;
    something that is very odd and mystifying.
    sizeof(unsigned short) on my computer (using either djgpp or MSVC++ 6) is 2.
    However, when I save the following struct to file:
    Code:
    struct TMP {
      long l;
      unsigned short s;
      int i;
    } tmp;
    ofstream o;
    o.open("dump.txt", ios::out | ios::binary);
    o.write((char*)&tmp, sizeof(tmp))
    (of course I snipped a bit..)
    it seems that it is padding the value of the short with two extra bytes.
    I tried filling a Bitmap header struct with values that a normal one would contain, and saving it to a file as well;
    It padded the first short in the struct (which is supposed to contain (dec)19778 (hex)4d42 (char)MB which will be swapped to make (char)BM once it hits the text file) with another two bytes.
    In a normal bitmap file (created with any of the three programs I used, at least..) the short is *not* padded with the extra two bytes, so I have absolutely no idea why it would be padding mine, however if it also attempts to pad the short when it is loading, and doesn't find it padded in a normal bitmap file, then it's no wonder it's messing everything up.. but why??
    The worst part is, there are two other unsigned short values in the bitmap header, and it doesn't pad either of those !!
    I am really getting confused, and a couple hours of messing with hex editor and searching through MSDN hasn't helped.
    It seems, though, that a program compiled either in djgpp or in MSVC, and using struct or class, and using fstream or the fopen() functions, still thinks that the third and fourth bytes in the bitmap file belong to the first unsigned short in the struct/class, which they don't. (they belong to the second member variable in the class, which is a long.)

    Does anyone have any idea what I'm doing wrong?!?!

    p.s. about the fact that the MS Paint bitmap I created was loading differently than the other two, I doscovered that the MS Paint one was a 24bit bitmap, so that's why it was different. However, regardless of whether the bitmap is 24 or 8 bit the header still remains the same.

    p.p.s don't you think we should make it so the graphic smileys don't appear inside [code] brackets?

    --edit--
    p.p.p.s it also seems that VC++ at least, stores the short values with a pad after them even in memory - *if* the next value in the class/struct is a 4-byte value; i.e. two shorts beside each other are not padded, while one short with a long after it is, and so is a short if it is the last member variable in the struct. somehow all of this seems needlessly complicated to me?!? how in the world do paint, and photoshop, and paint shop pro, and windows for that matter, still load bitmaps?
    Last edited by Cobras2; 03-03-2003 at 04:20 PM.
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

  5. #5
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113
    Ok, I think I have it figured out now. Partially..
    According to a guy who answered the question that I posted at experts-echange, modern compilers, by default, pad the values in a struct/class so that they align to 32bit boundaries;
    i.e. if there is a short(2bytes on my system) and then a long(4bytes on my system) it adds 2 bytes of garbage after the short(which it then proceeds to not use), however if there are two shorts beside each other they line up, so it doesn't bother to pad them. He said it's a optimization. My question's are;
    1) Why is this optimization needed? Does it have to do with processor speed? Because to me it just looks like a waste of memory(and disk space, if you save it to a file)

    [edit]
    nevermind question 1 - the guy at experts-exchange explained that the reason for the padding is since modern CPUs are for the most part 32bit, it's alot better speed if you pad the members of a struct to align to 32bit fields.. which makes perfect sense.. although this answer just reinforces the question in #2
    [/edit]

    2) Why have I not found any notes on this at any of the sites where I read up on the bitmap file format? Are they all just hopelessly outdated and no-one bothered to mention it?
    Last edited by Cobras2; 03-05-2003 at 02:56 PM.
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

  6. #6
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113
    Ok, makes sense as well.. but again, if that's the best way to do it, why is it that I haven't run into it before? It's just not generally something that comes up..?

    [edit]
    oh and we might also want to get someone to update that faq a bit.. or at least make note that it's probably outdated:
    http://faq.cprogramming.com/cgi-bin/...&id=1043284392
    [/edit]
    Last edited by Cobras2; 03-05-2003 at 05:38 PM.
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM