![]() |
| | #1 |
| Registered User Join Date: Oct 2009
Posts: 4
| Manually Loading Bitmap Files Here is the code i have to read a bitmap, admitedly it is not complete as it only opens the file and reads in to my "custom" BitmapFileHeader and BitmapInfoHeader structures. Code: //structure to contain bitmap file header information. It is the same as the win32 version except its my own.. if that makes sense
struct BitmapFileHeader {
unsigned short Type;
unsigned int Size;
unsigned short Reserved1;
unsigned short Reserved2;
unsigned int OffBits;
};
struct BitmapInfoHeader {
unsigned int Size;
long Width;
long Height;
unsigned short Planes;
unsigned short BitCount;
unsigned int Compression;
unsigned int SizeImage;
long XPelsPerMeter;
long YPelsPerMeter;
unsigned int ClrUsed;
unsigned int ClrImrportant;
};
// Read bitmap file
void Bitmap::Read( const char* file )
{
// open file for reading
std::ifstream f( file, std::ios::binary );
if ( !f.is_open( ) )
{
std::cout << "Error: File not found.";
f.close( );
}
// read in the file and info headers
f.read( reinterpret_cast<char*>(&mFileHeader), sizeof( BitmapFileHeader ) );
f.read( reinterpret_cast<char*>(&mInfoHeader), sizeof( BitmapInfoHeader ) );
}
mFileHeader.Type = 19778 < (Thats probably the only value that looks correct to me.. when cast into char* it produces "BM") mFileHeader.Size = 0 mFileHeader.Reserved1 = 0 mFileHeader.Reserved2 = 54 mFileHeader.OffBits = 2621440 mInfoHeader.Size = 131072 mInfoHeader.Width = 131072 mInfoHeader.Height = 65536 mInfoHeader.Planes = 24 mInfoHeader.BitCount = 0 mInfoHeader.Compression = 1048576 mInfoHeader.SizeImage = 0 mInfoHeader.XPelsPerMeter = 0 mInfoHeader.YPelsPerMeter = 0 mInfoHeader.ClrUsed = 0 mInfoHeader.ClrImrportant = 0 Im not sure but i think the compression might be the problem, however i did try another type of .bmp that had compression 0 but still had the same problems so maybe not (and im guessing compression only deals with the actual data, not the headers). Anywho, Thanks in advance. ~CC PS: The image I am loading is a simple 2x2 24-bit .bmp created with windows 7 version of paint. Unless im a mistaken the mInfoHeader.Width/Height should be 2 x 2 not 131072x65536, you get my point :P Last edited by CodeCriminal; 10-30-2009 at 02:12 PM. |
| CodeCriminal is offline | |
| | #2 |
| Guest Join Date: Aug 2001
Posts: 4,923
| Post your code. |
| Sebastiani is offline | |
| | #3 |
| Senior software engineer Join Date: Mar 2007 Location: Portland, OR
Posts: 5,381
| You are trying the "newbie method" of reading an on-disk binary data structure. The problem is that the data structure on disk contains no padding, whereas the compiler struct does. For instance: Code: struct BitmapFileHeader {
unsigned short Type;
unsigned int Size;
unsigned short Reserved1;
unsigned short Reserved2;
unsigned int OffBits;
};
The correct method is to individually load the values and put them, one by one, into the structure members.
__________________ "Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot |
| brewbuck is offline | |
| | #4 |
| Registered User Join Date: Oct 2009
Posts: 4
| Ah.. well thats disappointing.. ill give it whirl thanks. EDIT: Ok so that works, ill try to remember that for the future still though, it is kind of disapointing that i have the read each member of the structs individually is there not another way around that? Last edited by CodeCriminal; 10-30-2009 at 02:32 PM. |
| CodeCriminal is offline | |
| | #5 | |
| Guest Join Date: Aug 2001
Posts: 4,923
| Quote:
Code: #pragma pack(push, 1) // the '1' means 'byte boundary' // structure(s) defined here #pragma pack(pop) | |
| Sebastiani is offline | |
| | #6 |
| Registered User Join Date: Oct 2009
Posts: 4
| Hmm, Ive never used "packing directives" before, perhaps its time a take a look at em. Thanks |
| CodeCriminal is offline | |
| | #7 | |
| Senior software engineer Join Date: Mar 2007 Location: Portland, OR
Posts: 5,381
| Quote:
On some platforms, it's REQUIRED that certain data types have certain alignments, and on those architectures, forcing the compiler to omit the padding can actually cause crashing.
__________________ "Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot | |
| brewbuck is offline | |
| | #8 |
| Guest Join Date: Aug 2001
Posts: 4,923
| True on both points, but nonetheless it is a fairly common practice and generally safe to do on most systems. That said, there are plenty of C++ tricks that be used to achieve a portable solution with minimal effort: Code:
#include <iostream>
#include <fstream>
#include <stdexcept>
struct read_binary_file_helper
{
read_binary_file_helper( std::istream& in )
: in( in )
{ }
template < typename Type >
bool operator ( ) ( Type& value, bool throw_on_error = true )
{
if( in.read( ( char* )&value, sizeof( value ) ) )
return true;
if( throw_on_error )
throw std::runtime_error( "read_binary_file_helper: file read error" );
return false;
}
template < typename Type >
inline operator Type ( void )
{
Type
value;
( *this )( value );
return value;
}
std::istream&
in;
};
struct BitmapFileHeader {
unsigned short Type;
unsigned int Size;
unsigned short Reserved1;
unsigned short Reserved2;
unsigned int OffBits;
};
struct BitmapInfoHeader {
unsigned int Size;
long Width;
long Height;
unsigned short Planes;
unsigned short BitCount;
unsigned int Compression;
unsigned int SizeImage;
long XPelsPerMeter;
long YPelsPerMeter;
unsigned int ClrUsed;
unsigned int ClrImrportant;
};
template < typename Type >
void print( char const* text, Type const& value )
{
std::cout << text << ": " << std::hex << "0x" << value << std::endl;
}
int main( int, char** argv )
{
using namespace
std;
while( *( ++argv ) )
{
cout << "File: '" << *argv << "'" << endl;
try
{
ifstream
in( *argv, ios::binary );
if( !in )
throw std::runtime_error( "cannot open file" );
BitmapFileHeader
bfh;
BitmapInfoHeader
bih;
read_binary_file_helper
rbh( in );
print( "bfh.Type", bfh.Type = rbh );
print( "bfh.Size", bfh.Size = rbh );
print( "bfh.Reserved1", bfh.Reserved1 = rbh );
print( "bfh.Reserved2", bfh.Reserved2 = rbh );
print( "bfh.OffBits", bfh.OffBits = rbh );
print( "bih.Size", bih.Size = rbh );
print( "bih.Width", bih.Width = rbh );
print( "bih.Height", bih.Height = rbh );
print( "bih.Planes", bih.Planes = rbh );
print( "bih.BitCount", bih.BitCount = rbh );
print( "bih.Compression", bih.Compression = rbh );
print( "bih.SizeImage", bih.SizeImage = rbh );
print( "bih.XPelsPerMeter", bih.XPelsPerMeter = rbh );
print( "bih.YPelsPerMeter", bih.YPelsPerMeter = rbh );
print( "bih.ClrUsed", bih.ClrUsed = rbh );
print( "bih.ClrImrportant", bih.ClrImrportant = rbh );
}
catch( exception const& error )
{
cerr << "Error: " << error.what( ) << endl;
}
}
return 0;
}
Isn't C++ great? |
| Sebastiani is offline | |
![]() |
| Tags |
| code |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Loading multiple files | SanDiego619SDSU | C Programming | 4 | 10-29-2006 01:37 AM |
| Loading Bitmap Problem | loopshot | Game Programming | 1 | 04-15-2005 12:26 PM |
| OpenGL -- Bitmaps | HQSneaker | Game Programming | 14 | 09-06-2004 04:04 PM |
| Loading X Files with DirectX 8 ?? | MrWizard | Game Programming | 2 | 07-24-2002 02:48 AM |
| Loading all files in a directory | steve_i83 | Windows Programming | 2 | 08-26-2001 02:18 PM |