|
Don't worry, I have the freedom to ignore any messages that don't interest me.
|
|
|
|
|
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
|
|
|
|
|
Richard I have it working. Now on to saving.
phil, leon thanks guys.
|
|
|
|
|
I fount a class to read and write bitmaps, it`s old source code that uses MFC. it uses CFile to read and write, when I try to compile I get a Quote: WINDOWS.H already included message. Is there a way to work around the problem?
modified 11-Mar-20 13:07pm.
|
|
|
|
|
fearless_ wrote: Is there a way to work around the problem? Yes, remove the duplicate include statement.
|
|
|
|
|
thanks, with a simple tweak at headers it worked
|
|
|
|
|
Would you mind helping me further? I loaded the bitmap, however when I check the values from the array into which the bitmap is loaded they show up as 0 (null).
modified 12-Mar-20 4:05am.
|
|
|
|
|
Really. And we are supposed to guess what code and where the error occurs?
|
|
|
|
|
here is my code
StringCchPrintfA(pszFilename,1024,"hello.bmp");
if( !cf.Open( pszFilename, CFile::modeRead ) )
{
StringCchPrintfA(message,1024,"error reading file");
MessageBox(NULL, message, "Textures.exe", MB_OK);
return( FALSE );
}
DWORD dwDibSize= cf.GetLength() - sizeof( BITMAPFILEHEADER );
int bsize =0;
bsize= cf.GetLength() - sizeof( BITMAPFILEHEADER );
StringCchPrintfA(message,1024,"bitmap size %d",bsize);
MessageBox(NULL, message, "Textures.exe", MB_OK);
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
{
StringCchPrintfA(message,1024,"error allocating array ");
MessageBox(NULL, message, "Textures.exe", MB_OK);
return( FALSE );
}
BITMAPFILEHEADER BFH;
try{
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||
BFH.bfType != 'MB' ||
cf.Read( pDib, dwDibSize ) != dwDibSize )
{
StringCchPrintfA(message,1024,"error processing the file ");
MessageBox(NULL, message, "Textures.exe", MB_OK);
delete [] pDib;
return( FALSE );
}
}
modified 12-Mar-20 8:41am.
|
|
|
|
|
And what is the problem and where does it occur?
And please use proper <pre> tags so your code is formatted properly. The code button at the top of the edit box provides proper formatting for most languages.
|
|
|
|
|
At the end of code posted above I try to do this:
StringCchPrintfA(message,1024,"dib at 34 %d",pDib[34]);
MessageBox(NULL, message, "Textures.exe", MB_OK);
I expect pDib[34] to be 255 since the bitmap is 10 white pixels ( in a row) 40 bytes in total.
|
|
|
|
|
|
yeah I was a bit in a hurry, I was expecting to find pixels right after the first header.
|
|
|
|
|
|
I was only using a part of the bitmap processing code I was using as reference. I don`t need the palette part so I trimmed out a bit too much.
m_pDib = pDib;
m_dwDibSize = dwDibSize;
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
m_width = m_pBIH->biWidth;
m_height = m_pBIH->biHeight;
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
I know I must go past the bitmapinfoheader to get to the pixels
modified 13-Mar-20 14:06pm.
|
|
|
|
|
Please use proper <pre> tags around code blocks (and proper indentation), not Quoted text. The following code sample is preceded by
<pre lang="c++">
and followed by
</pre>
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
Much more readable.
|
|
|
|
|
I`m having trouble understanding how this code works. The problem is I`m not a c expert.
cf.Read( &BFH, sizeof( BITMAPFILEHEADER )
For instance how does the portion of data read from my file fits into a structure. It`s not a structure of identical items BITMAPFILEHEADER is a mix of WORDs and DWORDS
|
|
|
|
|
The sizeof operator gives the number of bytes in the object referred to. So in your case it will be the size of a BITMAPFILEHEADER , and the read operation will read the correct number of bytes into the structure. When complete each field of the structure should be correctly aligned*.
*There are conditions where this may not be true, so beware if you have a structure containing single byte elements. You may ignore that for the moment.
|
|
|
|
|
thanks that makes sense. In the code above do I need m_nPaletteEntries at all? Is used to calculate the offset at which individual pixels are stored?
|
|
|
|
|
|
I have to take a short break. Your insight (last post included) is priceless Richard, thanks
`DreamLand Page` is my projects facebook page.
|
|
|
|
|
Sorry to disappoint you, but my 'insight' is actually just a matter of reading the documentation.
|
|
|
|
|
the code you quoted is the bit that throws me into fog. What does the line that has the overload operator do?
|
|
|
|
|
fearless_ wrote: What does the line that has the overload operator do? What line?
|
|
|
|
|
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
|
|
|
|