Results 1 to 30 of 30

Thread: Bitmap header 2 bytes too big!

  1. #1

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157

    Bitmap header 2 bytes too big!

    Hi,
    I was trying to create my own structures and typedefs for the bitmap file and info headers. I have written a 'console' program to display all of the specs for a selected bitmap (.bmp) file. However, the size of the file header for my program ends up at 16 bytes. When I comment out my header file and place #include <windows.h> everything is okay. I am trying to do this without reference to windows.h for my learning experience.

    So...why is this file header structure missing two bytes? By the way, I am getting this 16 bytes by doing this command....

    sizeof header;

    Code:
    typedef unsigned char BYTE;
    typedef unsigned short WORD;
    typedef unsigned long DWORD;
    
    typedef struct _BITMAPFILEHEADER
    {
      WORD bfType;              //2 bytes
      DWORD bfSize;             //4 bytes
      WORD bfReserved1;     //2 bytes
      WORD bfReserved2;     //2 bytes
      DWORD bfOffBits;         //4 bytes
    } BITMAPFILEHEADER;
    I get 14 bytes. Any explanation or thoughts would be appreciated.

    Regards,
    ChuckB

  2. #2

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi,
    I may have mistated this description.
    I am attaching the project and files. Please take a look if you get time and tell me if you see the problem with my code. The problem is I cannot get the 32x32 out of this with my "bitmap_def.h" file,but windows.h works okay.

    Regards,
    ChuckB
    Attached Files Attached Files

  3. #3
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    I think that you are confusing the BITMAPFILEHEADER with the BITMAPINFO structures. (this is just from doing size comparisons in MSDN =).

    Z.

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Try setting the structure packing (in MSVC, look up #pragma pack).

    The problem is, each element in the structure starts on a 4-byte boundary. Therefore, the WORDs actually end up being 4 bytes.


    At least, that's what MS say...
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi,
    Parksie, I will look into this 'packing' that you are talking about.

    Z, each sample I have studied to read bitmaps reference a BITMAPFILEHEADER and BITMAPINFOHEADER.

    Then after opening a file to read the samples do something like this.

    fread(&bitmapfileheader,sizeof bitmapfileheader, 1, fp);
    fread(&bitmapinfoheader, sizeof bitmapinfoheader, 1,fp);

    After this, each piece of the color info is loaded into an array.

    So I have built these structures and even defined the various 'typedefs' and get results different from what 'windows.h' provides. Sooo...I think there is something else that must be done. I will spend much of today trying to work this out.


    Regards,
    ChuckB

  6. #6
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    I haven't ever meddled with those windows structures, but am capable of to read bmp-files the hard way
    But, as far as I know, the bmp-header is 54 bytes large, and if there's a color palette, it will be another 1024 bytes.

    It's quite easy to find out, when you draw a bitmap (actually a whole lot) yourself, and look at it in a hex viewer.

    Anyways, i do have a text file with some info (don't know where I got it from). I'll attach it, maybe it will help.

    Good luck!
    Attached Files Attached Files

  7. #7

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi Riis,
    I have seen the zipped file before. Of course, it didn't make much sense then. I am now able to read a bitmap file and use it as a texture for a polygon. Whew!

    Of course, I got myself confused. I tried reading a BMP so I can display it to the screen...somewhere in between I started working with texture stuff in OpenGL...then I realized I was trying to solve two different problems. Started from scratch and now can load texture. Of course I am using windows.h for now. However, I will build some structures based upon the BMP spec....then again I thought I had done that so I must dig some more.

    Nonetheless...I can load textures. :-)

    Regards,
    ChuckB

  8. #8
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Nice, Chuck =). I have the easiest texture format in the world =). Raw pixel data. Just find the file length, divide by 4, and take the square root to get the height and width (since hardware textures can only be square powers of two...), then just read the data =).

    Z.

  9. #9

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Z,
    Divide by 4? I guess that means 4 bytes per pixel...RGBA. Yes?
    I can buid a bitmap editor for stuff like 32x32, 64x64, etc. and save as raw bytes. However, I have built my own paintbrush program in the past...I could modify it so it reads the pixels from the drawing area and load that into a file...with alpha defaulting to 1.

    Regards,
    ChuckB

  10. #10
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Yep, 32 bit textures. I use a file converter, that takes a source image, and an alpha mask, and outputs the new texture =).

    Z.

  11. #11

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Ok,
    I can write a file filter now that I finally have a clue. ;-)
    Regards,
    ChuckB

  12. #12
    Hyperactive Member
    Join Date
    Sep 2001
    Posts
    396
    Originally posted by Zaei
    Nice, Chuck =). I have the easiest texture format in the world =). Raw pixel data. Just find the file length, divide by 4, and take the square root to get the height and width (since hardware textures can only be square powers of two...), then just read the data =).

    Z.
    How to get the correct file size? Does windows tell u the exact number of bytes?

    If this method works, I think I'm going to write my own simple bitmap editor.

  13. #13
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    file size - one way: use stat()

    Code:
    struct stat a;
    if(stat(filename,&a)==0){
       printf("file length is:%u",a.st_size);
    }else{
      printf("cannot stat file");
    }

  14. #14
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    I usually use an fseek(..., 0, SEEK_END);, followed by an ftell(...), which is another way to do it =).

    Z.

  15. #15

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi,
    This struct stat has really got my attention. I looked up the stat.h file to see what other elements were available for stat. I wrote a short routine. Here is the output excerpt.

    Code:
        cout << "accessed date: " << a.st_atime << endl;    
        cout << "modified time: " << a.st_mtime << endl;    
        cout << "created time: " << a.st_ctime << endl;    
        cout << "file length: " << a.st_size << endl;    
        cout << "mode: " << a.st_mode << endl;
    Results in this display from the console...

    accessed date: 1032285769
    modified time: 1031595155
    created time: 1031581347
    file length: 4134
    mode: 33206

    Any idea on how to convert the date/time into meaningful info? I thought I could do a binary AND with mode to find out file stats but it didn't like ... a.st_mode & 0x0001

    Any help would be appreciated. My books and ebooks are not helping.

    Regards,
    ChuckB

  16. #16
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Those times are FILETIME structs (two longs)
    a 64 bit number --

    Use FileTimeToSystemTime() to convert to a SYSTEMTIME struct which has year, day, month, etc.

  17. #17
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Mode is a series of bit _S_IFDIR is set if it's a directory, _S_IFREG is set if not.

    Look up _stat in MSDN

  18. #18

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    HI,
    I'll look into that. I think that is a Windows function, isn't it? I am trying to stay 100% ANSI C++. So, it requires that I figure out how Windows does it and then write a C++ function.

    Regards,
    ChuckB

  19. #19
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    stat() is ANSI C, so therefore is also ANSI C++
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  20. #20

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi,
    Parksie, DevC++ doesn't recognize FileTimeToSystemTime(). I don't think that this is a ANSI C++ function...meaning a linux or mac compiler would not recognize it....I think that is what ANSI C++ means...though I have been wrong several times before.

    I did find this German link that provides sample code...which I used below. http://www.informatik.uni-halle.de/lehre/c/c_file.html

    Code:
      struct stat s;
      if(stat("bitmap1.cpp",&s)==0){
        printf("%-40s : %d\n", "Filesize:", s.st_size);
        printf("%-40s : %s\n", 
               "Date of last modification:", ctime(&s.st_mtime));
        printf("%-40s : %s\n", 
               "Date of creation:", ctime(&s.st_ctime));
        printf("%-40s : %s\n", 
               "Date last accessed:", ctime(&s.st_atime));
        printf("%-40s : %ud\n", "File Attribute:", s.st_mode);
      }
    I still need to decipher the File Attributes from s.st_mode. Also, I would like to display with 'cout' in the proper format. Still learning.


    Regards,
    ChuckB

  21. #21
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    FileTimeToSystemTime() is from the Win32 API...
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  22. #22

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi Parksie, Win32, MFC, STL, ANSI...it is a bit mind numbing getting this stuff straight in my head. I am curious....

    Is this correct? The Win32 API is a huge library of functions written by Microsoft to support its operating system and/or VC++ development software.....or is it an industry standard library supported by all other operating systems? Sorry to be so dense, but just when I think I get some particular thing figured out...bam! My world crumbles. ;-) If you say Win32 is supported by Linux and other OS's then I say I can use the API...just like I do GLUT and OpenGL...and still maintain software that is easily ported to another OS.

    Incidently, I can get the date info with 'cout' formatted correctly with...

    Code:
      cout << "Modified time: " << ctime(&s.st_mtime) << endl;
      cout << "Creation time: " << ctime(&s.st_ctime) << endl;
      cout << "Access time: " << ctime(&s.st_atime) << endl;
    Regards,
    ChuckB


    [/CODE]

  23. #23
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Win32 is essentially the Windows Runtime. It is ONLY suported on Windows. Linux has its own runtimes, etc. That is why, if portability is a big deal, you wont find and system specific calls scattered through a program, they will simply be wrapped, so they can be modified in as little time as possible.

    Z.

  24. #24
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Soory I caused this mess. Those times are time_t values.
    time_t is ANSI standard. But, what time_t is, may be different.
    I told you it was a 64 bit number, which in Windows it is.
    For TURBO C under DOS it's a long (32 bit), for HPUX 11.0 it's either depending on whether 32 or 64 bit is implemented.

    BUT. localtime() and other ANSI calls take a time_t variable and create a struct tm as a result

    - ie, months, years, days, seconds.

    asctime(localtime(time_t )) takes time_t and turns it into what you see with the unix date command (date & time).

    There are two base time data structures:
    time_t - some kind of big number
    struct tm -
    Code:
        struct tm {
            int tm_sec;     /* second (0-61, allows for leap seconds) */
            int tm_min;     /* minute (0-59) */
            int tm_hour;    /* hour (0-23) */
            int tm_mday;    /* day of the month (1-31) */
            int tm_mon;     /* month (0-11) */
            int tm_year;    /* years since 1900 */
            int tm_wday;    /* day of the week (0-6) */
            int tm_yday;    /* day of the year (0-365) */
            int tm_isdst;   /* non-0 if daylight savings time is in effect */
         };
    Whether the values are int, long, or short depends on the system & compiler you develop under. Each one work correctly with the same code. If you don't make assumptions about struct tm datatypes.

  25. #25
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by ChuckB
    Hi Parksie, Win32, MFC, STL, ANSI...it is a bit mind numbing getting this stuff straight in my head. I am curious....
    Win32: The API for Microsoft Windows 9x/NT. It's basically the base layer for those OSs, and can be more efficient if you're not planning on porting it.

    MFC: Microsoft's almost-OO wrapper around the Win32 API, again only Windows, and betrays a lot of its heritage. I don't like it because it's bloated and platform-dependent. However, I will admit that for Windows development, there's no faster way.

    STL: Standard Template Library. Now merged into the Standard C++ Library; it's one of the most powerful tools a C++ programmer has, and there's not much that they don't do. The Standard Library is pretty much an extension of the Standard C Library (which is included within the C++ Library).

    ANSI: American National Standards Institute. Their working groups decide on the general, and accepted, standards for all sorts of things, character sets, OS APIs, languages, you name it. ISO (International Standards Organisation) is the international equivalent.

    In a semi-equivalent capacity to Win32, there's the POSIX (portable operating system) APIs, which basically means any Unix system (Irix, Solaris, BSD, Linux, etc.). Very useful to know, and large proportions of it are included in the Standard C Library (POSIX is entirely C -- see the history of Unix for more details on why).


    Wow, long post. Hopefully it's been helpful Jim, anything I've missed?
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  26. #26
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    In extension to parksie's post:
    CRT (if you come across it): The C runtime library, it is the collection of all these functions that we know so well, the functions in stdlib.h, stdio.h, ctype.h, math.h, all those things. The CRT is standardized by ANSI.

    ANSI C: Your code is ANSI C-compliant if it only uses features of the core C language as standardized by the ANSI C standard. This means no compiler-specific language extensions, only functions of the ANSI CRT etc.

    ANSI C++: like ANSI C, but with C++.
    Note: to be ANSI C++, you need to use the .h-less headers like <vector>

    See the GNU C library docs (http://www.gnu.org) for information on how to decipher the file attributes and modes. But watch out that you don't confuse POSIX and ANSI, they are not seperated well in the manual.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  27. #27

    Thread Starter
    Addicted Member ChuckB's Avatar
    Join Date
    Jul 2002
    Location
    South Carolina, USA
    Posts
    157
    Hi,
    Thank you everyone. You confirmed what I needed to know to keep things straight. Here is my big picture reason to learn ANSI C++ as well as possible, including this STL stuff.

    Let's say I apply for a position as a C++ programmer and I know Win32 stuff really well. I show up, find out that Windows is out and that Linux is in...then the question becomes "Do I know enough ANSI C++ well enough to program without dependency upon Win32?

    I think from what I read that C++ is far more powerful and flexible then most introductory college courses or books on the market reveal. After reading "The C++ Standard Library", I realize I could spend several years learning to utilize all of its functionality and features.

    I think it is possible to be good at C++ and Win32 like most of you guys. But for a newbie, I want to focus on ANSI C++. Frankly, the Win32 API makes a lot of stuff very easy to do...which is why it exists...but it does take away from C++ knowledge.

    So, that is why I was looking for a pure ANSI C++ alternative to FileTimeToSystemTime().

    I hope this makes sense. Feel free to tell me how ridiculous it is. I am always willing to entertain a different perspective.

    As always, I really appreciate your input.
    Regards,
    ChuckB

  28. #28
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    I agree, Chuck. It is why I spent a good chunk of time writing my own set of Matrix functions, instead of using the D3DX Library.

    Z.

  29. #29
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    /me likes some of the Boost classes

    Pity I don't have enough need for them right now, though
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  30. #30
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    I wrote my own string_tokenizer class =). Probably the most useful class ive ever written. Next is a property_map class =).

    Need to get boost though, and take a look at some of the other classes availible.

    Need to work on something big to use a bunch of the classes =).

    Z.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width