Archived

This topic is now archived and is closed to further replies.

more fstream confusion.

This topic is 5310 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, the code below has 2 different methods of reading in the same data (it''s just a bitmap header). When I run the first method (read in the whole header) I get one set of data, when I run the second I get a different set of data.
  	std::fstream fs;
	
	fs.exceptions(std::ios::badbit|std::ios::failbit);
	try	
	{	
		fs.open(fn.c_str(),std::ios::in|std::ios::binary);

		// Load bitmap fileheader & infoheader


//Method 1 - Only use 1 of the 2 methods at a time


//		fs.read ((char*)&bmp->FileData,sizeof (BITMAPFILEHEADER));


//Method 2 - Only use 1 of the 2 methods at a time

		fs.read ((char*)&bmp->FileData.bfType,sizeof (short));
		fs.read ((char*)&bmp->FileData.bfSize,sizeof (int));
		fs.read ((char*)&bmp->FileData.bfReserved1,sizeof (short));
		fs.read ((char*)&bmp->FileData.bfReserved2,sizeof (short));
		fs.read ((char*)&bmp->FileData.bfOffBits,sizeof (int));


		printf("Type %i\n",bmp->FileData.bfType);
		printf("Size %i\n",bmp->FileData.bfSize);
		printf("Reserved1 %i\n",bmp->FileData.bfReserved1);
		printf("Reserved2 %i\n",bmp->FileData.bfReserved2);
		printf("Offset Bits %i\n",bmp->FileData.bfOffBits);

		fs.read ((char*)&bmp->Header,sizeof (BITMAPINFOHEADER));

		//Are the bytes being read in in the correct order ?

		if (bmp->FileData.bfType!=19778)
			printf("Not a Bitmap %i\n",''BM'');

		//Calculate if a Colour Table is needed, if so create it and Load it in

		//As a Vector of Quads


		//Read the Data into a Vector of RGBA Quads

		//Sorting it for size on input


	}
	catch(std::ios::failure e)
	{
		const int test = fs.exceptions();

		if (test&std::ios_base::badbit)
		printf ("BadBit Exception Thrown.\nType = %i\n",test);

		if (test&std::ios_base::failbit)
		printf ("failbit Exception Thrown.\nType = %i\n",test);

		if (test&std::ios_base::eofbit)
		printf ("eofbit Exception Thrown.\nType = %i\n",test);
	}
	
	fs.close();
}
Neither of these sets of data is right. (though the second set is closer to what I am after.) in Hex, the real data is; 42 4d de 17 00 00 00 00 00 00 3e 00 00 00 Method 1 (Reads it all in 1 go) 4d 42 00 00 00 00 00 00 3e 00 28 00 00 00 Method 2 (Reads it all in 1 go) 4d 42 00 00 17 de 00 00 00 00 00 00 00 3e Now I can see frm method 2 that all my data is there, just each block of data is inverted. But why doesn''t the first one read in the same block of data, either with each block inverted, or withthe whole thing inverted ? This is driving me mad, so any ideas will be greatfully recieved. TIA, Bp.

Share this post


Link to post
Share on other sites
OK, following further investigation of the above problem,
if I do a sizeof(BITMAPFILEHEADER) I am getting 16.
if I manually count the size of the variables I get 14 (the right value).
So why does by Typedef struct have an extra 2 bytes added to it ?

Bp.

Share this post


Link to post
Share on other sites
Padding. The compiler can pad out your structs to sit nicely on 4-byte boundaries. Your other issues appear to be down to ''endianness'' as you realised in your other post. However it''s not down to individual compilers but down to the processor you run on.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
OK, so if the compiler is padding, I need to go with my initial method and load in the data a piece at a time, or can I force no padding ?

On second thoughts, as I need to reverse some of the bytes, I may just read in a 14 byte string, and then manipulate that into my structure.

As to the endian, I am using a generic PC, and MS NT4 at work.
At home I have a cyrix processor and 98, and I am pretty sure that this works differently there. I guess I need to detect if I am using Big or Little endian, and decide if I need to convert the data or not.

Thanks,
Bp.

Share this post


Link to post
Share on other sites
quote:
Original post by Bagpuss
OK, so if the compiler is padding, I need to go with my initial method and load in the data a piece at a time, or can I force no padding ?
Not standard, I think, but try #pragma pack().

Look here for details: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_predir_pack.asp

[edited by - CWizard on June 5, 2003 6:12:59 AM]

Share this post


Link to post
Share on other sites