Thread: Setting the palette on a BITMAPINFO struct

  1. #1
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273

    Angry Setting the palette on a BITMAPINFO struct

    Hi,
    I'm trying to code an 8-bit image loader/displayer, and I'm trying to fill out the bmiColors of the BITMAPINFO struct for use with the CreateDIBitmap function. However, the bmiColors array has only 1 entry instead of 256, so how do I get my RGBQUAD array of 256 entries to be "attached" to it?

  2. #2
    Registered User Esss's Avatar
    Join Date
    Aug 2001
    Posts
    133
    > so how do I get my RGBQUAD array of 256 entries to be "attached" to it?

    The array is represented by an area of memory immediately after the header, thus:

    LPBITMAPINFO lpbi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));

    You can then fill in the bmiColors array as if it were 256 entries long.
    Ess
    Like a rat in a maze who says,
    "Watch me choose my own direction"
    Are you under the illusion
    The path is winding your way?
    - Rush

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    My code currently looks like this:-
    Code:
    HBITMAP ReadFrame(unsigned char *Image, unsigned char Palette[3][256], HPALETTE hPalReturn)
    {
    	int i;
    	LPBITMAPINFO lpbmpinfo = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    	HBITMAP hBitmap;
    	HDC hScreenDC;
    	HPALETTE hPal, hOldPal;
    
    	for(i=0;i<256;i++)
    	{
    		lpbmpinfo->bmiColors[i].rgbRed = Palette[0][i];
    		lpbmpinfo->bmiColors[i].rgbGreen = Palette[1][i];
    		lpbmpinfo->bmiColors[i].rgbBlue = Palette[2][i];
    		lpbmpinfo->bmiColors[i].rgbReserved = 0;
    	}
    	lpbmpinfo->bmiHeader.biSize = sizeof(lpbmpinfo->bmiHeader);
    	lpbmpinfo->bmiHeader.biBitCount = 8;
    	lpbmpinfo->bmiHeader.biCompression = BI_RGB;
    	lpbmpinfo->bmiHeader.biHeight = -240;
    	lpbmpinfo->bmiHeader.biPlanes = 1;
    	lpbmpinfo->bmiHeader.biWidth = 320;
    	hScreenDC = GetDC(NULL);
    	hPal = CreateDIBPalette(lpbmpinfo);
    	hOldPal = SelectPalette(hScreenDC, hPal, FALSE);
    	RealizePalette(hScreenDC);
    	hBitmap = CreateDIBitmap(hScreenDC, &lpbmpinfo->bmiHeader, CBM_INIT, Image, lpbmpinfo, DIB_RGB_COLORS);
    	SelectPalette(hScreenDC, hOldPal, FALSE);
    	ReleaseDC(NULL, hScreenDC);
    	hPalReturn = hPal;
    
    	return hBitmap;
    }
    CreateDIBPalette simply makes a GDI palette object from the palette stored in lpbmpinfo.

    However, when I run this, CreateDIBitmap does not appear to work and an Access Violation error occurs. I'm porting this code from VB, and it works there (although not without modification to the BITMAPINFO struct to have 256 entries (as there is no pointer support)). I'm stumped...

  4. #4
    Registered User Esss's Avatar
    Join Date
    Aug 2001
    Posts
    133
    Well, I note that you're not clearing the BITMAPINFOHEADER to zero, so things like biSizeImage will be unknown. Either use calloc or memset.

    Other than that, check to make sure the pointer to the bitmap data is valid and points to the right quantity of data.
    Ess
    Like a rat in a maze who says,
    "Watch me choose my own direction"
    Are you under the illusion
    The path is winding your way?
    - Rush

  5. #5
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    I ZeroMemory'ed the lpbmpinfo->bmiHeader struct after, to no avail.
    However, when I commented out the "hPal = CreateDIBPalette(lpbmpinfo);" line, it worked fine. Looks like I have a problem somewhere here:-
    Code:
    HPALETTE CreateDIBPalette(LPBITMAPINFO lpbmi)
    {
        int i;
    	LOGPALETTE pal;
        
        pal.palVersion = 0x300;
        pal.palNumEntries = 256;
        for (i=0;i<256;i++)
    	{
            pal.palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
            pal.palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
            pal.palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
            pal.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
    	}
        return CreatePalette(&pal);
    }

  6. #6
    Registered User Esss's Avatar
    Join Date
    Aug 2001
    Posts
    133
    Oh, silly me. I assumed you'd used a debugger and therefore knew it was CreateDIBitmap that crashed.

    LOGPALETTE uses the same technique for a variable-length palette:

    Code:
    LPLOGPALETTE lpPalette = (LPLOGPALETTE)malloc(sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY));
    Ess
    Like a rat in a maze who says,
    "Watch me choose my own direction"
    Are you under the illusion
    The path is winding your way?
    - Rush

  7. #7
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273

    Red face

    Bah, that function was left VB-style and I didn't even notice...
    It works now, thanx

    P.S.: I did use a debugger, but skirted round the parts I thought were right. I suppose learning how to debug properly is half the battle for solid code :P

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  2. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  3. Search Engine - Binary Search Tree
    By Gecko2099 in forum C Programming
    Replies: 9
    Last Post: 04-17-2005, 02:56 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM