BOOL WINAPI CreateDIBPalette(HDIB hDIB, CPalette* pPal) { LPLOGPALETTE lpPal; // pointer to a logical palette HANDLE hLogPal; // handle to a logical palette HPALETTE hPal = NULL; // handle to a palette int i; // loop index WORD wNumColors; // number of colors in color table LPSTR lpbi; // pointer to packed-DIB LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0) LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (old) BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB BOOL bResult = FALSE; /* if handle to DIB is invalid, return FALSE */ if (hDIB == NULL) return FALSE; lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); /* get pointer to BITMAPINFO (Win 3.0) */ lpbmi = (LPBITMAPINFO)lpbi; /* get pointer to BITMAPCOREINFO (old 1.x) */ lpbmc = (LPBITMAPCOREINFO)lpbi; /* get the number of colors in the DIB */ wNumColors = ::DIBNumColors(lpbi); if (wNumColors != 0) { /* allocate memory block for logical palette */ hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wNumColors); /* if not enough memory, clean up and return NULL */ if (hLogPal == 0) { ::GlobalUnlock((HGLOBAL) hDIB); return FALSE; } lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); /* set version and number of palette entries */ lpPal->palVersion = PALVERSION; lpPal->palNumEntries = (WORD)wNumColors; /* is this a Win 3.0 DIB? */ bWinStyleDIB = IS_WIN30_DIB(lpbi); for (i = 0; i < (int)wNumColors; i++) { if (bWinStyleDIB) { lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; } else { lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; lpPal->palPalEntry[i].peFlags = 0; } } /* create the palette and get handle to it */ bResult = pPal->CreatePalette(lpPal); ::GlobalUnlock((HGLOBAL) hLogPal); ::GlobalFree((HGLOBAL) hLogPal); } ::GlobalUnlock((HGLOBAL) hDIB); return bResult; }
// --- Effect : This function creates a palette from a DIB by allocating memory for the // logical palette, reading and storing the colors from the DIB's color table // into the logical palette, creating a palette from this logical palette, // and then returning the palette's handle. This allows the DIB to be // displayed using the best possible colors (important for DIBs with 256 or // more colors). // --- static BOOL InitPalette( LPSTR lpbi, HPALETTE *hPalette ) { LPLOGPALETTE lpPal; // pointer to a logical palette HANDLE hLogPal; // handle to a logical palette int i; // loop index WORD wNumColors; // number of colors in color table LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0) LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (old) BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB BOOL bResult = TRUE; // Initialized with TRUE because when NumColors returns ZERO // ie. when reading a TRUE COLOR DIB, NumColors returns ZERO // and then InitPalette succeedes because there is no need // for a palette. *hPalette = NULL; // if handle to DIB is invalid, return FALSE if ( lpbi == NULL ) return FALSE; // get pointer to BITMAPINFO (Win 3.0) lpbmi = (LPBITMAPINFO)lpbi; // get pointer to BITMAPCOREINFO (old 1.x) lpbmc = (LPBITMAPCOREINFO)lpbi; // get the number of colors in the DIB wNumColors = ::GetNumColors( lpbi ); if ( wNumColors != 0 ) { // allocate memory block for logical palette hLogPal = ::GlobalAlloc(GPTR, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wNumColors); // if not enough memory, clean up and return NULL if (hLogPal == 0) return FALSE; lpPal = (LPLOGPALETTE)hLogPal; // set version and number of palette entries lpPal->palVersion = PALVERSION; lpPal->palNumEntries = (WORD)wNumColors; // is this a Win 3.0 DIB? bWinStyleDIB = IS_WIN30_DIB(lpbi); for (i = 0; i < (int)wNumColors; i++) { if (bWinStyleDIB) { lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; } else { lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; lpPal->palPalEntry[i].peFlags = 0; } } // create the palette and get handle to it *hPalette = ::CreatePalette( lpPal ); ::GlobalFree((HGLOBAL) hLogPal); } return bResult; }
HPALETTE FAR CreateDIBPalette(HDIB hDIB) { LPLOGPALETTE lpPal; // pointer to a logical palette HANDLE hLogPal; // handle to a logical palette HPALETTE hPal = NULL; // handle to a palette int i, wNumColors; // loop index, number of colors in color table LPSTR lpbi; // pointer to packed-DIB LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0) LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2) BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB /* if handle to DIB is invalid, return NULL */ if (!hDIB) return NULL; /* lock DIB memory block and get a pointer to it */ lpbi = GlobalLock(hDIB); /* get pointer to BITMAPINFO (Win 3.0) */ lpbmi = (LPBITMAPINFO)lpbi; /* get pointer to BITMAPCOREINFO (OS/2 1.x) */ lpbmc = (LPBITMAPCOREINFO)lpbi; /* get the number of colors in the DIB */ wNumColors = DIBNumColors(lpbi); /* is this a Win 3.0 DIB? */ bWinStyleDIB = IS_WIN30_DIB(lpbi); if (wNumColors) { /* allocate memory block for logical palette */ hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wNumColors); /* if not enough memory, clean up and return NULL */ if (!hLogPal) { GlobalUnlock(hDIB); return NULL; } /* lock memory block and get pointer to it */ lpPal = (LPLOGPALETTE)GlobalLock(hLogPal); /* set version and number of palette entries */ lpPal->palVersion = PALVERSION; lpPal->palNumEntries = wNumColors; /* store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB) * into palette */ for (i = 0; i < wNumColors; i++) { if (bWinStyleDIB) { lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; } else { lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; lpPal->palPalEntry[i].peFlags = 0; } } /* create the palette and get handle to it */ hPal = CreatePalette(lpPal); /* if error getting handle to palette, clean up and return NULL */ if (!hPal) { GlobalUnlock(hLogPal); GlobalFree(hLogPal); return NULL; } } /* clean up */ GlobalUnlock(hLogPal); GlobalFree(hLogPal); GlobalUnlock(hDIB); /* return handle to DIB's palette */ return hPal; }
BOOL WINAPI ReplaceColorPal(LPSTR lpDIB, BYTE * bpColorsTable) { // 循环变量 int i; // 颜色表中的颜色数目 WORD wNumColors; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFO lpbmi; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREINFO lpbmc; // 表明是否是Win3.0 DIB的标记 BOOL bWinStyleDIB; // 创建结果 BOOL bResult = FALSE; // 获取指向BITMAPINFO结构的指针(Win3.0) lpbmi = (LPBITMAPINFO)lpDIB; // 获取指向BITMAPCOREINFO结构的指针 lpbmc = (LPBITMAPCOREINFO)lpDIB; // 获取DIB中颜色表中的颜色数目 wNumColors =DIBNumColors(lpDIB); // 判断颜色数目是否是256色 if (wNumColors == 256) { // 判断是否是WIN3.0的DIB bWinStyleDIB = IS_WIN30_DIB(lpDIB); // 读取伪彩色编码,更新DIB调色板 for (i = 0; i < (int)wNumColors; i++) { if (bWinStyleDIB) { // 更新DIB调色板红色分量 lpbmi->bmiColors[i].rgbRed = bpColorsTable[i * 4]; // 更新DIB调色板绿色分量 lpbmi->bmiColors[i].rgbGreen = bpColorsTable[i * 4 + 1]; // 更新DIB调色板蓝色分量 lpbmi->bmiColors[i].rgbBlue = bpColorsTable[i * 4 + 2]; // 更新DIB调色板保留位 lpbmi->bmiColors[i].rgbReserved = 0; } else { // 更新DIB调色板红色分量 lpbmc->bmciColors[i].rgbtRed = bpColorsTable[i * 4]; // 更新DIB调色板绿色分量 lpbmc->bmciColors[i].rgbtGreen = bpColorsTable[i * 4 + 1]; // 更新DIB调色板蓝色分量 lpbmc->bmciColors[i].rgbtBlue = bpColorsTable[i * 4 + 2]; } } } // 返回 return bResult; }