parsing bitmap files (2)
-
I think I almost got it right. I have a question about the two file reads
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||// Is the type 'MB'? BFH.bfType != 'MB' || // Did we read in the remaining data? cf.Read( pDib, dwDibSize ) != dwDibSize )
first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included
-
I think I almost got it right. I have a question about the two file reads
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||// Is the type 'MB'? BFH.bfType != 'MB' || // Did we read in the remaining data? cf.Read( pDib, dwDibSize ) != dwDibSize )
first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included
-
I think I almost got it right. I have a question about the two file reads
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||// Is the type 'MB'? BFH.bfType != 'MB' || // Did we read in the remaining data? cf.Read( pDib, dwDibSize ) != dwDibSize )
first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included
You are confused there are two headers one after another you need to read them both before deciding whether to do step 3 and I have put a few hints what you need to do 1.) Read BITMAPFILEHEADER check for "BM", hold offset to bitmap data 2.) Read BITMAPINFOHEADER calc DWORD line stride width from bitmap width and bitdepth, see if you have a palette if so do step 3 else step 4 3.) Read the index palette if the BMP has one 4.) Jump to file offset from step 1 that is your bitmap data. Now you need to remember each line is DWORD (4 byte aligned) that means if you multiply the bytes per each line pixel * bitmap width it has to equal 4. So lets give you an example if you bitmap is 24Bit so each pixel is 3 bytes. So if your image was one pixel in width the first line is the first 3 bytes then there is a pad of one dummy byte and the second line starts at the 4th byte. So there can be 0 to 3 extra bytes per line because each new line must start on a DWORD boundary. So the amount of data you need to read for a line can be a couple bytes more than the just multiplying the bitmpap width * bytes per pixel. The dummy bytes are usually zero but some smart people worked out long ago if you make all your images odd so you have the extra bytes you can put a hidden watermark, or play spy and put secret messsages in the dummy bytes :-)
In vino veritas
-
I think I almost got it right. I have a question about the two file reads
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||// Is the type 'MB'? BFH.bfType != 'MB' || // Did we read in the remaining data? cf.Read( pDib, dwDibSize ) != dwDibSize )
first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included
Richard I have it working. Now on to saving. phil, leon thanks guys.
-
No, the second read will start from the byte following the position where the previous read stopped. That is normal file IO operations. It will only re-read the header if you rewind the file after the first operation.
This is my write attempt.
BITMAPFILEHEADER BFH;
BITMAPINFOHEADER BIH;
RGBQUAD Palette;
RGBQUAD * Pixels = new RGBQUAD[10];cf.Read( &BFH, sizeof( BITMAPFILEHEADER )); cf.Read( &BIH, sizeof( BITMAPINFOHEADER )); for(int i =0; i<10; i++) { cf.Read(&Pixels\[i\],sizeof(RGBQUAD)); } StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); CFile fileWrite; Pixels\[0\].rgbBlue = 100; Pixels\[0\].rgbGreen = 100; Pixels\[0\].rgbRed = 50; // Attempt to create the file. if( !fileWrite.Open( pszFilename, CFile::modeCreate | CFile::modeWrite ) ) return( FALSE ); fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) ); fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) ); for(int i =0;i<10; i++) { fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) ); }
when I start my program again I expect the values of the first pixel to be updated but they aren`t
-
This is my write attempt.
BITMAPFILEHEADER BFH;
BITMAPINFOHEADER BIH;
RGBQUAD Palette;
RGBQUAD * Pixels = new RGBQUAD[10];cf.Read( &BFH, sizeof( BITMAPFILEHEADER )); cf.Read( &BIH, sizeof( BITMAPINFOHEADER )); for(int i =0; i<10; i++) { cf.Read(&Pixels\[i\],sizeof(RGBQUAD)); } StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); CFile fileWrite; Pixels\[0\].rgbBlue = 100; Pixels\[0\].rgbGreen = 100; Pixels\[0\].rgbRed = 50; // Attempt to create the file. if( !fileWrite.Open( pszFilename, CFile::modeCreate | CFile::modeWrite ) ) return( FALSE ); fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) ); fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) ); for(int i =0;i<10; i++) { fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) ); }
when I start my program again I expect the values of the first pixel to be updated but they aren`t
-
you`re right, if I try to create the file under a new name it works.
-
This is my write attempt.
BITMAPFILEHEADER BFH;
BITMAPINFOHEADER BIH;
RGBQUAD Palette;
RGBQUAD * Pixels = new RGBQUAD[10];cf.Read( &BFH, sizeof( BITMAPFILEHEADER )); cf.Read( &BIH, sizeof( BITMAPINFOHEADER )); for(int i =0; i<10; i++) { cf.Read(&Pixels\[i\],sizeof(RGBQUAD)); } StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen); MessageBox(NULL, message, "Textures.exe", MB\_OK); StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue); MessageBox(NULL, message, "Textures.exe", MB\_OK); CFile fileWrite; Pixels\[0\].rgbBlue = 100; Pixels\[0\].rgbGreen = 100; Pixels\[0\].rgbRed = 50; // Attempt to create the file. if( !fileWrite.Open( pszFilename, CFile::modeCreate | CFile::modeWrite ) ) return( FALSE ); fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) ); fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) ); for(int i =0;i<10; i++) { fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) ); }
when I start my program again I expect the values of the first pixel to be updated but they aren`t
-
I have just tried a similar exercise and the changes are correctly made to the output file.
I will run into other C related issues, you`re not getting rid of me.
-
I will run into other C related issues, you`re not getting rid of me.