/************************************************* * dibpal.cpp * * * * Copyright (C) 1995-1999 Microsoft Inc. * * * *************************************************/ // dibpal.cpp : implementation file // #include "stdafx.h" #include "dibpal.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDIBPal CDIBPal::CDIBPal() { } CDIBPal::~CDIBPal() { } // Create a palette from the color table in a DIB BOOL CDIBPal::Create(CDIB *pDIB) { DWORD dwColors = pDIB->GetNumClrEntries(); // Check the DIB has a color table if (! dwColors) { TRACE("No color table"); return FALSE; } // get a pointer to the RGB quads in the color table RGBQUAD * pRGB = pDIB->GetClrTabAddress(); // allocate a log pal and fill it with the color table info LOGPALETTE *pPal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE) + dwColors * sizeof(PALETTEENTRY)); if (!pPal) { TRACE("Out of memory for logpal"); return FALSE; } pPal->palVersion = 0x300; // Windows 3.0 pPal->palNumEntries = (WORD) dwColors; // table size for (DWORD dw=0; dwpalPalEntry[dw].peRed = pRGB[dw].rgbRed; pPal->palPalEntry[dw].peGreen = pRGB[dw].rgbGreen; pPal->palPalEntry[dw].peBlue = pRGB[dw].rgbBlue; pPal->palPalEntry[dw].peFlags = 0; } BOOL bResult = CreatePalette(pPal); free (pPal); return bResult; } ///////////////////////////////////////////////////////////////////////////// // CDIBPal commands int CDIBPal::GetNumColors() { int iColors = 0; if (!GetObject(sizeof(iColors), &iColors)) { TRACE("Failed to get num pal colors"); return 0; } return iColors; } void CDIBPal::Draw(CDC *pDC, CRect *pRect, BOOL bBkgnd) { int iColors = GetNumColors(); CPalette *pOldPal = pDC->SelectPalette(this, bBkgnd); pDC->RealizePalette(); int i, j, top, left, bottom, right; for (j=0, top=0; j<16 && iColors; j++, top=bottom) { bottom = (j+1) * pRect->bottom / 16 + 1; for(i=0, left=0; i<16 && iColors; i++, left=right) { right = (i+1) * pRect->right / 16 + 1; CBrush br (PALETTEINDEX(j * 16 + i)); CBrush *brold = pDC->SelectObject(&br); pDC->Rectangle(left-1, top-1, right, bottom); pDC->SelectObject(brold); iColors--; } } pDC->SelectPalette(pOldPal, FALSE); } BYTE Color16[16][3] = {{0,0,0},{128,0,0},{0,128,0},{128,128,0}, {0,0,128},{128,0,128},{0,128,128},{192,192,192}, {128,128,128},{255,0,0},{0,255,0},{255,255,0}, {0,0,255},{255,0,255},{0,255,255},{255,255,255}}; BOOL CDIBPal::SetSysPalColors() { BOOL bResult = FALSE; int i, iSysColors, iPalEntries; HPALETTE hpalOld; int nColorMode; // Get a screen DC to work with HWND hwndActive = ::GetActiveWindow(); HDC hdcScreen = ::GetDC(hwndActive); ASSERT(hdcScreen); // Make sure we are on a palettized device if (!(GetDeviceCaps(hdcScreen, RASTERCAPS) & RC_PALETTE)) { TRACE("Not a palettized device"); goto abort; } // Get the number of system colors and the number of palette entries // Note that on a palletized device the number of colors is the // number of guaranteed colors. I.e. the number of reserved system colors iSysColors = GetDeviceCaps(hdcScreen, NUMCOLORS); iPalEntries = GetDeviceCaps(hdcScreen, SIZEPALETTE); if (iSysColors > 256) goto abort; if (iSysColors == -1) nColorMode = 16; else if (iPalEntries == 0) nColorMode = 4; else nColorMode = 8; SetSystemPaletteUse(hdcScreen, SYSPAL_NOSTATIC); SetSystemPaletteUse(hdcScreen, SYSPAL_STATIC); hpalOld = ::SelectPalette(hdcScreen, (HPALETTE)m_hObject, // our hpal FALSE); ::RealizePalette(hdcScreen); ::SelectPalette(hdcScreen, hpalOld, FALSE); PALETTEENTRY pe[256]; switch (nColorMode) { case 4: { iPalEntries = 16; for (i = 0; i >%d:%d:%d\n",i,pe[i].peRed,pe[i].peGreen,pe[i].peBlue); // } bResult = TRUE; abort: ::ReleaseDC(hwndActive, hdcScreen); return bResult; } // Load a palette from a named file BOOL CDIBPal::Load(char *pszFileName) { CString strFile; if ((pszFileName == NULL) || (strlen(pszFileName) == 0)) { // Show an open file dialog to get the name CFileDialog dlg (TRUE, // open NULL, // no default extension NULL, // no initial file name OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "Palette files (*.PAL)|*.PAL|All files (*.*)|*.*||"); if (dlg.DoModal() == IDOK) { strFile = dlg.GetPathName(); } else { return FALSE; } } else { // copy the supplied file path strFile = pszFileName; } // Try to open the file for read access CFile file; if (! file.Open(strFile, CFile::modeRead | CFile::shareDenyWrite)) { AfxMessageBox("Failed to open file"); return FALSE; } BOOL bResult = Load(&file); file.Close(); if (!bResult) AfxMessageBox("Failed to load file"); return bResult; } // Load a palette from an open CFile object BOOL CDIBPal::Load(CFile *fp) { return Load(fp->m_hFile); } // Load a palette from an open file handle BOOL CDIBPal::Load(UINT_PTR hFile) { HMMIO hmmio; MMIOINFO info; memset(&info, 0, sizeof(info)); info.adwInfo[0] = (DWORD)hFile; hmmio = mmioOpen(NULL, &info, MMIO_READ | MMIO_ALLOCBUF); if (!hmmio) { TRACE("mmioOpen failed"); return FALSE; } BOOL bResult = Load(hmmio); mmioClose(hmmio, MMIO_FHOPEN); return bResult; } // Load a palette from an open MMIO handle BOOL CDIBPal::Load(HMMIO hmmio) { // Check it's a RIFF PAL file MMCKINFO ckFile; ckFile.fccType = mmioFOURCC('P','A','L',' '); if (mmioDescend(hmmio, &ckFile, NULL, MMIO_FINDRIFF) != 0) { TRACE("Not a RIFF or PAL file"); return FALSE; } // Find the 'data' chunk MMCKINFO ckChunk; ckChunk.ckid = mmioFOURCC('d','a','t','a'); if (mmioDescend(hmmio, &ckChunk, &ckFile, MMIO_FINDCHUNK) != 0) { TRACE("No data chunk in file"); return FALSE; } // allocate some memory for the data chunk int iSize = ckChunk.cksize; void *pdata = malloc(iSize); if (!pdata) { TRACE("No mem for data"); return FALSE; } // read the data chunk if (mmioRead(hmmio, (char *)pdata, iSize) != iSize) { TRACE("Failed to read data chunk"); free(pdata); return FALSE; } // The data chunk should be a LOGPALETTE structure // which we can create a palette from LOGPALETTE* pLogPal = (LOGPALETTE*)pdata; if (pLogPal->palVersion != 0x300) { TRACE("Invalid version number"); free(pdata); return FALSE; } // Get the number of entries int iColors = pLogPal->palNumEntries; if (iColors <= 0) { TRACE("No colors in palette"); free(pdata); return FALSE; } return CreatePalette(pLogPal); } // Save a palette to an open CFile object BOOL CDIBPal::Save(CFile *fp) { return Save(fp->m_hFile); } // Save a palette to an open file handle BOOL CDIBPal::Save(UINT_PTR hFile) { HMMIO hmmio; MMIOINFO info; memset(&info, 0, sizeof(info)); info.adwInfo[0] = (DWORD)hFile; hmmio = mmioOpen(NULL, &info, MMIO_WRITE | MMIO_CREATE | MMIO_ALLOCBUF); if (!hmmio) { TRACE("mmioOpen failed"); return FALSE; } BOOL bResult = Save(hmmio); mmioClose(hmmio, MMIO_FHOPEN); return bResult; } // Save a palette to an open MMIO handle BOOL CDIBPal::Save(HMMIO hmmio) { // Create a RIFF chunk for a PAL file MMCKINFO ckFile; ckFile.cksize = 0; // corrected later ckFile.fccType = mmioFOURCC('P','A','L',' '); if (mmioCreateChunk(hmmio, &ckFile, MMIO_CREATERIFF) != 0) { TRACE("Failed to create RIFF-PAL chunk"); return FALSE; } // create the LOGPALETTE data which will become // the data chunk int iColors = GetNumColors(); ASSERT(iColors > 0); int iSize = sizeof(LOGPALETTE) + (iColors-1) * sizeof(PALETTEENTRY); LOGPALETTE* plp = (LOGPALETTE*) malloc(iSize); ASSERT(plp); plp->palVersion = 0x300; plp->palNumEntries = (unsigned short) iColors; GetPaletteEntries(0, iColors, plp->palPalEntry); // create the data chunk MMCKINFO ckData; ckData.cksize = iSize; ckData.ckid = mmioFOURCC('d','a','t','a'); if (mmioCreateChunk(hmmio, &ckData, 0) != 0) { TRACE("Failed to create data chunk"); return FALSE; } // write the data chunk if (mmioWrite(hmmio, (char*)plp, iSize) != iSize) { TRACE("Failed to write data chunk"); free(plp); return FALSE; } free(plp); // Ascend from the data chunk which will correct the length mmioAscend(hmmio, &ckData, 0); // Ascend from the RIFF/PAL chunk mmioAscend(hmmio, &ckFile, 0); return TRUE; }