Thread: How can I do the following..

  1. #1
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802

    How can I do the following..

    I have CDib Class here which loads DIBs (device independant bitmaps) It has a member funtion ::Load(const char *pszFilename) which takes a filename and loads the DIB from it.
    I'm trying to modify the class to include a function ::LoadIndirect(const char *pszData) to load bitmaps based on character data sent.

    The load function uses the following expression:
    cf.Read( &BFH, sizeof( BITMAPFILEHEADER );
    Where cf is of type CFile and BFH is BITMAPFILEHEADER.
    How is it doing this, or shall I say, how can I do this with a chunk of data instead of a file?

    It opens the file, and reads data in to the address of BFH. Alright. So I tried:

    Code:
    	BITMAPFILEHEADER BFH;
    	unsigned char *pBFHTemp = new unsigned char[sizeof(BITMAPFILEHEADER)];
    	for (int i = 0; i < sizeof(BITMAPFILEHEADER); i++)
    	{
    		pBFHTemp += pszData[i];
    	}
    	&BFH = pBFHTemp;
    	delete[] pBFHTemp;
    But I get the following error: DIB.cpp(188) : error C2440: '=' : cannot convert from 'unsigned char *' to 'struct tagBITMAPFILEHEADER *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


    All I want to do is take data, and place it at the address of BFH, how can I do this?
    Last edited by Dual-Catfish; 04-29-2002 at 06:25 PM.

  2. #2
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    the best i can come up with, with the information you provided, is a syntax error. chances are high it's not this, but it's all i could think of.
    1) can char* be +=?
    and btw, what is pszdata?
    2) does &BFH = pBFHTemp work?

  3. #3
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    1) can char* be +=?
    and btw, what is pszdata?
    2) does &BFH = pBFHTemp work?

    1) That was a typo, it's actually string.
    2) pszData is a bitmap file, passed to the function. It's just unsigned char, which I have to parse and load.
    3) No, &BFH = pBFHTemp is the line that generates the error

  4. #4
    Registered User
    Join Date
    Sep 2001
    Location
    Fiji
    Posts
    212
    I thought I read this already. Or has it changed since last time?

    Anywayz

    &BFH = pBFHTemp

    is the operator overloaded? And how come the reference is at the front there?

    kwigibo

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    200
    Are you sure that &BFH is an lvalue?
    I go to encounter for the millionth time the reality of experience and to forge in the smithy of my soul the uncreated conscience of my race.

    Windows XP consists of 32 bit extensions and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company, that can't stand 1 bit of competition.

  6. #6
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    why not just make a pointer of type BITMAPFILEHEADER and use that instead of BFH?

  7. #7
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    >is the operator overloaded?
    I'm not sure.. I assume so, seeing as I get no error...
    >And how come the reference is at the front there?
    Because I wan't to put the data at 'the address of' BFH. Simply assigning it wouldn't work, as it has many member variables.

    The data is structured in such a way, that if I could insert it into the memory space of BFH, all the member variables would get the correct value... but I've tried different variations of this and I cannot get this working

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    	BITMAPFILEHEADER *BFH;
    	unsigned char *pBFHTemp = new unsigned char[sizeof(BITMAPFILEHEADER)];
    	for (int i = 0; i < sizeof(BITMAPFILEHEADER); i++)
    	{
    		pBFHTemp += pszData[i];
    	}
    	BFH = (BITMAPFILEHEADER *) pBFHTemp;
    And the call would be:

    cf.Read( BFH, sizeof( BITMAPFILEHEADER ));

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well I dont know much about the BITMAPWHATEVERHEADER struct but you cannot do:

    &BFH = pBFHTemp;

    ...because (a) that is an illegal assignment and (b) BFH is a structure ( or perhaps a typedef for a pointer to one ) and pBFHTemp is a char pointer!

    So if it is the data ( the "chars" ) you want, then simply look at the definition of the BITMAPWHATEVERHEADER structure where you will most certainly find a "char *" ( or LPSTR, or similar ) which points directly to the data!

    Now if the originators of windows were sensible folk, this variable would be named something like "unsigned char *data", but seeing how this is not usually the case, it will probably be named "LPSTR lCmfsHddlDibHerKraut" or similar.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    >cf.Read( BFH, sizeof( BITMAPFILEHEADER ));
    But that's not the call :/
    The call is cf.Read( &BFH, sizeof(BITMAPFILEHEADER));
    The definition of BITMAPFILEHEADER can be found here:
    http://msdn.microsoft.com/library/de...tmaps_62uq.asp

    I have no idea how cf.Read() does it :/

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    That's because it takes a pointer to a BITMAPFILEHEADER. Since:
    BITMAPFILEHEADER *BFH;
    is already a pointer to a BITMAPFILEHEADER, then:

    cf.Read( BFH, sizeof( BITMAPFILEHEADER ));

  12. #12
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    This is MY load function..
    In the other load function, BFH was not a pointer, and it was used as cf.Read(&BFH, sizeof(BFH));

    In my function, I need to replicate this behavior.. read data from a larger chunk of data, the size of BFH and store it at the address of BFH.

    Allow me to post code..

    Code:
    BOOL CDib::Load( const char *pszFilename )
    {
    
    	CFile cf;
    
    	// Attempt to open the Dib file for reading.
    	if( !cf.Open( pszFilename, CFile::modeRead ) )
    		return( FALSE );
    
    	// Get the size of the file and store
    	// in a local variable. Subtract the
    	// size of the BITMAPFILEHEADER structure
    	// since we won't keep that in memory.
    	DWORD dwDibSize;
    	dwDibSize =
    		cf.GetLength() - sizeof( BITMAPFILEHEADER );
    
    	// Attempt to allocate the Dib memory.
    	unsigned char *pDib;
    	pDib = new unsigned char [dwDibSize];
    	if( pDib == NULL )
    		return( FALSE );
    
    	BITMAPFILEHEADER BFH;
    
    	// Read in the Dib header and data.
    	try{
    
    		// Did we read in the entire BITMAPFILEHEADER?
    		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 ){
    
    			// Delete the memory if we had any
    			// errors and return FALSE.
    			delete [] pDib;
    			return( FALSE );
    			}
    		}
    
    	// If we catch an exception, delete the
    	// exception, the temporary Dib memory,
    	// and return FALSE.
    	catch( CFileException *e ){
    		e->Delete();
    		delete [] pDib;
    		return( FALSE );
    		}
    	
    	// If we got to this point, the Dib has been
    	// loaded. If a Dib was already loaded into
    	// this class, we must now delete it.
    	if( m_pDib != NULL )
    		delete m_pDib;
    
    	// Store the local Dib data pointer and
    	// Dib size variables in the class member
    	// variables.
    	m_pDib = pDib;
    	m_dwDibSize = dwDibSize;
    
    	// Pointer our BITMAPINFOHEADER and RGBQUAD
    	// variables to the correct place in the Dib data.
    	m_pBIH = (BITMAPINFOHEADER *) m_pDib;
    	m_pPalette =
    		(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
    
    	// Calculate the number of palette entries.
    	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;
    
    	// Point m_pDibBits to the actual Dib bits data.
    	m_pDibBits =
    		&m_pDib[sizeof(BITMAPINFOHEADER)+
    			m_nPaletteEntries*sizeof(RGBQUAD)];
    
    	// If we have a valid palette, delete it.
    	if( m_Palette.GetSafeHandle() != NULL )
    		m_Palette.DeleteObject();
    
    	// If there are palette entries, we'll need
    	// to create a LOGPALETTE then create the
    	// CPalette palette.
    	if( m_nPaletteEntries != 0 ){
    
    		// Allocate the LOGPALETTE structure.
    		LOGPALETTE *pLogPal = (LOGPALETTE *) new char
    				[sizeof(LOGPALETTE)+
    				m_nPaletteEntries*sizeof(PALETTEENTRY)];
    
    		if( pLogPal != NULL ){
    
    			// Set the LOGPALETTE to version 0x300
    			// and store the number of palette
    			// entries.
    			pLogPal->palVersion = 0x300;
    			pLogPal->palNumEntries = m_nPaletteEntries;
    
    			// Store the RGB values into each
    			// PALETTEENTRY element.
    			for( int i=0; i<m_nPaletteEntries; i++ ){
    				pLogPal->palPalEntry[i].peRed =
    					m_pPalette[i].rgbRed;
    				pLogPal->palPalEntry[i].peGreen =
    					m_pPalette[i].rgbGreen;
    				pLogPal->palPalEntry[i].peBlue =
    					m_pPalette[i].rgbBlue;
    				}
    
    			// Create the CPalette object and
    			// delete the LOGPALETTE memory.
    			m_Palette.CreatePalette( pLogPal );
    			delete [] pLogPal;
    			}
    		}
    	
    	return( TRUE );
    
    }
    My (not working) Load funtion..

    Code:
    BOOL CDib::LoadIndirect(const char *pszData)
    {
    	if (pszData == NULL)
    	{
    		return (FALSE);
    	}
    
    	// Get the size of the file and store
    	// in a local variable. Subtract the
    	// size of the BITMAPFILEHEADER structure
    	// since we won't keep that in memory.
    
    	DWORD dwDibSize;
    	dwDibSize = strlen(pszData) - sizeof(BITMAPFILEHEADER);
    
    	unsigned char *pDib;
    	pDib = new unsigned char [dwDibSize];	// Attempt to allocate the Dib memory.
    
    	if (pDib == NULL)
    	{
    		return (FALSE);
    	}
    	BITMAPFILEHEADER BFH;
    
    	string sBmpHeader;
    	for (int i = 0; i < sizeof(BITMAPFILEHEADER); i++)
    	{
    		sBmpHeader += pszData[i];
    	}
    	BFH = sBmpHeader;
    
    	string sBmpData;
    	for (i = sizeof(BITMAPFILEHEADER); i < strlen(pszData); i++)
    	{
    		sBmpData += pszData[i];
    	}
    	pDib = sBmpData.c_str();
    
    	if (strlen(sBmpData) != dwDibSize || sBmpHeader != sizeof(BITMAPFILEHEADER) || BFH.bfType != 'MB')
    	{
    		delete [] pDib;
    		return (FALSE);
    	}
    
    	// If we got to this point, the Dib has been
    	// loaded. If a Dib was already loaded into
    	// this class, we must now delete it.
    	if (m_pDib != NULL)
    	{
    		delete m_pDib;
    	}
    
    	// Store the local Dib data pointer and
    	// Dib size variables in the class member
    	// variables.
    	m_pDib = pDib;
    	m_dwDibSize = dwDibSize;
    
    	// Pointer our BITMAPINFOHEADER and RGBQUAD
    	// variables to the correct place in the Dib data.
    	m_pBIH = (BITMAPINFOHEADER *) m_pDib;
    	m_pPalette =
    		(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
    
    	// Calculate the number of palette entries.
    	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;
    
    	// Point m_pDibBits to the actual Dib bits data.
    	m_pDibBits =
    		&m_pDib[sizeof(BITMAPINFOHEADER)+
    			m_nPaletteEntries*sizeof(RGBQUAD)];
    
    	// If we have a valid palette, delete it.
    	if( m_Palette.GetSafeHandle() != NULL )
    		m_Palette.DeleteObject();
    
    	// If there are palette entries, we'll need
    	// to create a LOGPALETTE then create the
    	// CPalette palette.
    	if( m_nPaletteEntries != 0 ){
    
    		// Allocate the LOGPALETTE structure.
    		LOGPALETTE *pLogPal = (LOGPALETTE *) new char
    				[sizeof(LOGPALETTE)+
    				m_nPaletteEntries*sizeof(PALETTEENTRY)];
    
    		if( pLogPal != NULL ){
    
    			// Set the LOGPALETTE to version 0x300
    			// and store the number of palette
    			// entries.
    			pLogPal->palVersion = 0x300;
    			pLogPal->palNumEntries = m_nPaletteEntries;
    
    			// Store the RGB values into each
    			// PALETTEENTRY element.
    			for( int i=0; i<m_nPaletteEntries; i++ ){
    				pLogPal->palPalEntry[i].peRed =
    					m_pPalette[i].rgbRed;
    				pLogPal->palPalEntry[i].peGreen =
    					m_pPalette[i].rgbGreen;
    				pLogPal->palPalEntry[i].peBlue =
    					m_pPalette[i].rgbBlue;
    				}
    
    			// Create the CPalette object and
    			// delete the LOGPALETTE memory.
    			m_Palette.CreatePalette( pLogPal );
    			delete [] pLogPal;
    			}
    		}
    	
    	return( TRUE );
    
    
    }

  13. #13
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    I'm thinking this would work:
    Code:
    	BITMAPFILEHEADER *BFH;
    
    	string sBmpHeader;
    	for (int i = 0; i < sizeof(BITMAPFILEHEADER); i++)
    	{
    		sBmpHeader += pszData[i];
    	}
    	BFH = (BITMAPHEADER *) sBmpHeader.c_str();
    
    	string sBmpData;
    	for (i = sizeof(BITMAPFILEHEADER); i < strlen(pszData); i++)
    	{
    		sBmpData += pszData[i];
    	}
    	pDib = sBmpData.c_str();
    
    	if (strlen(sBmpData) != dwDibSize || sBmpHeader != sizeof(BITMAPFILEHEADER) || BFH -> bfType != 'MB')

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > if (strlen(sBmpData) != dwDibSize || sBmpHeader != sizeof(BITMAPFILEHEADER) || BFH -> bfType != 'MB')

    This part of the if() statement looks questionable though:
    sBmpHeader != sizeof(BITMAPFILEHEADER)

    sBmpHeader is a string, so you need the string length of sBmpHeader, right?

  15. #15
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    Just ignore that part for now, it doesn't work yet, as I can't get get the data in the correct places anyway ;(

    Once I can replicate the behaviour of that line, I'll be on my way... but until then, I'll sit and cry about it.

Popular pages Recent additions subscribe to a feed