PDA

Click to See Complete Forum and Search --> : Bitmap header 2 bytes too big!


ChuckB
Sep 13th, 2002, 11:49 PM
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;


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

ChuckB
Sep 14th, 2002, 12:42 AM
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

Zaei
Sep 14th, 2002, 12:48 AM
I think that you are confusing the BITMAPFILEHEADER with the BITMAPINFO structures. (this is just from doing size comparisons in MSDN =).

Z.

parksie
Sep 14th, 2002, 06:34 AM
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...

ChuckB
Sep 14th, 2002, 12:49 PM
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

riis
Sep 15th, 2002, 01:38 AM
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!

ChuckB
Sep 15th, 2002, 10:16 PM
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

Zaei
Sep 15th, 2002, 10:22 PM
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.

ChuckB
Sep 15th, 2002, 10:51 PM
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

Zaei
Sep 15th, 2002, 11:21 PM
Yep, 32 bit textures. I use a file converter, that takes a source image, and an alpha mask, and outputs the new texture =).

Z.

ChuckB
Sep 15th, 2002, 11:34 PM
Ok,
I can write a file filter now that I finally have a clue. ;-)
Regards,
ChuckB

transcendental
Sep 17th, 2002, 07:12 AM
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.:D

jim mcnamara
Sep 17th, 2002, 09:13 AM
file size - one way: use stat()


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

Zaei
Sep 17th, 2002, 10:43 AM
I usually use an fseek(..., 0, SEEK_END);, followed by an ftell(...), which is another way to do it =).

Z.

ChuckB
Sep 17th, 2002, 01:32 PM
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.


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

jim mcnamara
Sep 17th, 2002, 02:42 PM
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.

jim mcnamara
Sep 17th, 2002, 02:46 PM
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

ChuckB
Sep 17th, 2002, 08:51 PM
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

parksie
Sep 18th, 2002, 06:43 AM
stat() is ANSI C, so therefore is also ANSI C++ :)

ChuckB
Sep 18th, 2002, 12:03 PM
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


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

parksie
Sep 18th, 2002, 12:05 PM
FileTimeToSystemTime() is from the Win32 API...

ChuckB
Sep 18th, 2002, 01:13 PM
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...


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]

Zaei
Sep 18th, 2002, 03:00 PM
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.

jim mcnamara
Sep 18th, 2002, 03:27 PM
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 -

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.

parksie
Sep 18th, 2002, 04:04 PM
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?

CornedBee
Sep 18th, 2002, 05:12 PM
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.

ChuckB
Sep 19th, 2002, 10:01 AM
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

Zaei
Sep 19th, 2002, 10:30 AM
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.

parksie
Sep 19th, 2002, 10:36 AM
/me likes some of the Boost classes

Pity I don't have enough need for them right now, though :(

Zaei
Sep 19th, 2002, 10:50 AM
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.