⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdib.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (numwritten != sizeof(hdr)) 
	{
		RETAILMSG(CDIB_ERROR_MSG, (TEXT("CDIB: Save: Failed to write BITMAPFILEHEADER.\r\n")));
	    	return FALSE;
	}
	// Write the DIB header
	numwritten = fwrite( (void *)lpbi, sizeof(BYTE), dwBitmapInfoSize, pFile );
	if (numwritten != dwBitmapInfoSize) 
	{
		RETAILMSG(CDIB_ERROR_MSG, (TEXT("CDIB: Save: Failed to write BitmapInfoSize.\r\n")));
	    	return FALSE;
	}

	// Write DIB bits
	numwritten = fwrite( GetDIBits(), sizeof(BYTE), lpbi->biSizeImage, pFile );
	if (numwritten != lpbi->biSizeImage) 
	{
		RETAILMSG(CDIB_ERROR_MSG, (TEXT("CDIB: Save: Failed to write bits.\r\n")));
	    	return FALSE;
	}	

	fclose(pFile);
	
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
//
// CDIB palette stuff
//
// --- In?: nNumColors - number of colors to set
//           pColors - array of RGBQUAD's containing colors to set
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Sets the colors used by the image. Only works if # colors <= 256
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::SetColorTable(UINT nNumColors, RGBQUAD *pColors)
{
    if (!m_hBitmap ||!pColors || !nNumColors || m_iColorTableSize == 0 || nNumColors > 256)
        return FALSE;

    LPRGBQUAD pColorTable = GetColorTable();
    ASSERT(pColorTable);

    int nCount = min(m_iColorTableSize, nNumColors);
    ::memset(pColorTable, 0, m_iColorTableSize*sizeof(RGBQUAD));
    ::memcpy(pColorTable, pColors, nCount*sizeof(RGBQUAD));

    return TRUE;
}


// --- In?:
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Creates the palette from the DIBSection's color table. Assumes 
//              m_iColorTableSize has been set and the DIBsection m_hBitmap created
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::CreatePalette()
{
    //m_hPal DeleteObject();

    if (!m_hBitmap)
        return FALSE;

    // Create a 256 color halftone palette if there is no color table in the DIBSection
    if (m_iColorTableSize == 0)
        return CreateHalftonePalette(m_hPal, 256);

    // Get space for the color entries
    RGBQUAD *pRGB = new RGBQUAD[m_iColorTableSize];
    if (!pRGB)
        return CreateHalftonePalette(m_hPal, m_iColorTableSize);

    HDC hDC = ::GetDC(NULL);
    if (!hDC)
    {
        delete [] pRGB;
        return FALSE;
    }

    // Create a memory DC compatible with the current DC
    HDC hMemDC = CreateCompatibleDC(hDC);
    if (!hMemDC)
    {
        delete [] pRGB;
		ReleaseDC(NULL, hDC);
        return CreateHalftonePalette(m_hPal, m_iColorTableSize);
    }
    ReleaseDC(NULL, hDC);
    
    HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemDC, m_hBitmap);
    if (!hOldBitmap)
    {
        delete [] pRGB;
        return CreateHalftonePalette(m_hPal, m_iColorTableSize);
    }

    // Get the colors used. WinCE does not support GetDIBColorTable so if you
    // are using this on a CE device with palettes, then you need to replace
    // the call with code that manually gets the color table from the m_DIBinfo structure.
    int nColors = CEGetDIBColorTable(hDC, 0, m_iColorTableSize, pRGB);

    // Clean up
    SelectObject(hMemDC, hOldBitmap);

    if (!nColors)   // No colors retrieved => the bitmap in the DC is not a DIB section
    {
        delete [] pRGB;
        return CreateHalftonePalette(m_hPal, m_iColorTableSize);
    }   
    
    // Create and fill a LOGPALETTE structure with the colors used.
    PALETTEINFO PaletteInfo;
    PaletteInfo.palNumEntries = m_iColorTableSize;
                        
    for (int ii = 0; ii < nColors; ii++)
    {
        PaletteInfo.palPalEntry[ii].peRed   = pRGB[ii].rgbRed;
        PaletteInfo.palPalEntry[ii].peGreen = pRGB[ii].rgbGreen;
        PaletteInfo.palPalEntry[ii].peBlue  = pRGB[ii].rgbBlue;
        PaletteInfo.palPalEntry[ii].peFlags = 0;
    }

    delete [] pRGB;

    // Create Palette!
	m_hPal = ::CreatePalette( &PaletteInfo );
    return (NULL != m_hPal);
}

// --- In?: pPalette - new palette to use
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Sets the current palette used by the image from the supplied CPalette,
//              and sets the color table in the DIBSection
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::SetPalette(HPALETTE hPal)
{
    // m_Palette.DeleteObject();

    if (!hPal)
        return FALSE;

	WORD nColors;
	::GetObject(hPal, sizeof(WORD), &nColors);

    if (nColors <= 0 || nColors > 256)
        return FALSE;

    // Get palette entries
    PALETTEINFO pi;
    pi.palNumEntries = (WORD) ::GetPaletteEntries(hPal, 0, nColors, (LPPALETTEENTRY) pi);                          
    return SetLogPalette(&pi);
}

// --- In?: pLogPalette - new palette to use
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Sets the current palette used by the image from the supplied LOGPALETTE
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::SetLogPalette(LOGPALETTE* pLogPalette)
{
    if (!pLogPalette)
    {
        CreatePalette();
        return FALSE;
    }

    ASSERT(pLogPalette->palVersion == (WORD) 0x300);

    UINT nColors = pLogPalette->palNumEntries;
    if (nColors <= 0 || nColors > 256)
    {
        CreatePalette();
        return FALSE;
    }

    // Create new palette
	DeleteObject( m_hPal );
	m_hPal = ::CreatePalette(pLogPalette);
	if (!m_hPal)
    {
        CreatePalette();
        return FALSE;
    }

    if (m_iColorTableSize == 0)
        return TRUE;

    // Set the DIB colors
    RGBQUAD RGBquads[256]; 
    for (UINT i = 0; i < nColors; i++)
    {
        RGBquads[i].rgbRed   = pLogPalette->palPalEntry[i].peRed;
        RGBquads[i].rgbGreen = pLogPalette->palPalEntry[i].peGreen;
        RGBquads[i].rgbBlue  = pLogPalette->palPalEntry[i].peBlue;
        RGBquads[i].rgbReserved = 0;
    }
    
    return FillDIBColorTable(nColors, RGBquads);
}

// --- In?: nNumColors - number of colors to set
//           pRGB - colors to fill
// --- Out :
// --- Returns : Returns TRUE on success
// --- Effect : Sets the colors used by the image. Only works if # colors <= 256
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::FillDIBColorTable(UINT nNumColors, RGBQUAD *pRGB)
{
    if (!pRGB || !nNumColors || !m_iColorTableSize || nNumColors > 256)
        return FALSE;

    // get the number of colors to return per BITMAPINFOHEADER docs
    UINT nColors;
    LPBITMAPINFOHEADER pBmih = GetBitmapInfoHeader();
    if (pBmih->biClrUsed)
        nColors = pBmih->biClrUsed;
    else
        nColors = 1 << (pBmih->biBitCount*pBmih->biPlanes);

    // Initialize the loop variables
    nColors = min(nNumColors, nColors);

    LPRGBQUAD pColorTable = GetColorTable();
    for (UINT iColor = 0; iColor < nColors; iColor++)
    {
        pColorTable[iColor].rgbReserved = 0;
        pColorTable[iColor].rgbBlue     = pRGB[iColor].rgbBlue;
        pColorTable[iColor].rgbRed      = pRGB[iColor].rgbRed;
        pColorTable[iColor].rgbGreen    = pRGB[iColor].rgbGreen;
    }

    return TRUE;
}

//#endif // DIBSECTION_NO_PALETTE


// --- In?: hdc     - the Device Context in which the DIBSection is selected
//           hBitmap - the bitmap whose solor entries are to be queried
//           lpbi    - a pointer to a BITMAPINFO structure that will have it's
//                     color table filled.
// --- Out :
// --- Returns : the number of colors placed in the color table
// --- Effect : This function is a replacement for GetDIBits, in that it retrieves 
//              (or synthesizes) the color table from the given bitmap, and stores 
//              the values in the BITMAPINFO structure supplied.
//
///////////////////////////////////////////////////////////////////////////////

UINT CDIB::GetColorTableEntries(HDC hdc, HBITMAP hBitmap)
{
    if (!m_iColorTableSize)
        return 0;

    // Fill the color table with the colors from the bitmap's color table
    LPRGBQUAD pColorTable = GetColorTable();
    
    // Get the color table from the HBITMAP and copy them over.
    UINT nCount;
    RGBQUAD* pRGB = new RGBQUAD[m_iColorTableSize];
    if (pRGB)
    {
        HBITMAP hOldBitmap = (HBITMAP) SelectObject(hdc, hBitmap);
        nCount = CEGetDIBColorTable(hdc, 0, m_iColorTableSize, pRGB);
        SelectObject(hdc, hOldBitmap);
        if (nCount)
        {
            // m_iColorTableSize = nCount;
            memcpy(pColorTable, pRGB, nCount*sizeof(RGBQUAD));
        }
    }
    delete [] pRGB;

    // Didn't work - so synthesize one.
    if (!nCount)
    {       
        nCount = min( m_iColorTableSize, sizeof(ms_StdColors) / sizeof(ms_StdColors[0]) );
        memcpy(pColorTable, ms_StdColors, nCount*sizeof(RGBQUAD));
    }

    return nCount;
}


///////////////////////////////////////////////////////////////////////////////
//
// This function is from the MS KB article "HOWTO: Get the Color Table of 
//  DIBSection in Windows CE".
// 
// PARAMETERS:
// HDC - the Device Context in which the DIBSection is selected
/// UINT - the index of the first color table entry to retrieve
// UINT - the number of color table entries to retrieve
// RGBQUAD - a buffer large enough to hold the number of RGBQUAD
// entries requested
//
// RETURNS:
// UINT - the number of colors placed in the buffer
//
//
///////////////////////////////////////////////////////////////////////////////

UINT CEGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors)
{   
    if (pColors == NULL)
        return 0;                       // No place to put them, fail
    
    // Get a description of the DIB Section
    HBITMAP hDIBSection = (HBITMAP) GetCurrentObject( hdc, OBJ_BITMAP );

    DIBSECTION ds;
    DWORD dwSize = GetObject( hDIBSection, sizeof(DIBSECTION), &ds );
    
    if (dwSize != sizeof(DIBSECTION))
        return 0;                      // Must not be a DIBSection, fail
    
    if (ds.dsBmih.biBitCount > 8)
        return 0;                      // Not Palettized, fail
    
    // get the number of colors to return per BITMAPINFOHEADER docs
    UINT cColors;
    if (ds.dsBmih.biClrUsed)
        cColors = ds.dsBmih.biClrUsed;
    else
        cColors = 1 << (ds.dsBmih.biBitCount * ds.dsBmih.biPlanes);
    
    // Create a mask for the palette index bits for 1, 2, 4, and 8 bpp
    WORD wIndexMask = (0xFF << (8 - ds.dsBmih.biBitCount)) & 0x00FF;
    
    // Get the pointer to the image bits
    LPBYTE pBits = (LPBYTE) ds.dsBm.bmBits;
    
    // Initialize the loop variables
    cColors = min( cColors, cEntries );
    BYTE OldPalIndex = *pBits;
 
    UINT TestPixelY;
    if (ds.dsBmih.biHeight > 0 )
        // If button up DIB, pBits points to last row
        TestPixelY = ds.dsBm.bmHeight-1;
    else
        // If top down DIB, pBits points to first row
        TestPixelY = 0;
    
    for (UINT iColor = uStartIndex; iColor < cColors; iColor++)
    {
        COLORREF    rgbColor;
        
        // Set the palette index for the test pixel,
        // modifying only the bits for one pixel
        *pBits = (iColor << (8 - ds.dsBmih.biBitCount)) | (*pBits & ~wIndexMask);
        
        // now get the resulting color
        rgbColor = GetPixel( hdc, 0, TestPixelY );
        
        pColors[iColor - uStartIndex].rgbReserved = 0;
        pColors[iColor - uStartIndex].rgbBlue = GetBValue(rgbColor);
        pColors[iColor - uStartIndex].rgbRed = GetRValue(rgbColor);
        pColors[iColor - uStartIndex].rgbGreen = GetGValue(rgbColor);
    }
    
    // Restore the test pixel
    *pBits = OldPalIndex;
    
    return cColors;
}


///////////////////////////////////////////////////////////////////////////////
//
// --- In?: pDC - device context to use when calling CreateCompatibleDC
//           bSelectPalette - if TRUE, the current palette will be preselected
// --- Out :
// --- Returns : A pointer to a memory DC
// --- Effect : Creates a memory DC and selects in the current bitmap so it can be
//              modified using the GDI functions. Only one memDC can be created for
//              a given CDIB object. If you have a memDC but wish to recreate it
//              as compatible with a different DC, then call ReleaseMemoryDC first.
//              If the memory DC has already been created then it will be recycled.
//              Note that if using this in an environment where the color depth of
//              the screen may change, then you will need to set "m_bReuseMemDC" to FALSE
//
///////////////////////////////////////////////////////////////////////////////

HDC CDIB::GetMemoryDC(HDC hDC /*=NULL*/, BOOL bSelectPalette /*=TRUE*/)
{
#ifdef DIBSECTION_NO_MEMDC_REUSE
    ReleaseMemoryDC(TRUE);
#else
    if (!m_bReuseMemDC)
	{
        ReleaseMemoryDC(TRUE);
	}
    else if (m_hMemDC)   // Already created?
    {
        return m_hMemDC;
    }
#endif // DIBSECTION_NO_MEMDC_REUSE

    // Create a memory DC compatible with the given DC
	m_hMemDC = CreateCompatibleDC(hDC);
    if (!m_hMemDC)
        return NULL;

    // Select in the bitmap
    m_hOldBitmap = (HBITMAP) ::SelectObject(m_hMemDC, m_hBitmap);

    // Select in the palette
    if (bSelectPalette && UsesPalette(m_hMemDC))
    {
        // Palette should already have been created - but just in case...
        if (!m_hPal)
            CreatePalette();

        m_hOldPal = SelectPalette( m_hMemDC, m_hPal, FALSE );
        RealizePalette( m_hMemDC );
    }
    else
        m_hOldPal = NULL;

    return m_hMemDC;
}


///////////////////////////////////////////////////////////////////////////////
//
// --- In?: bForceRelease - if TRUE, then the memory DC is forcibly released
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Selects out the current bitmap and deletes the mem dc. If bForceRelease 
//              is FALSE, then the DC release will not actually occur. This is provided 
//              so you can have
//
//                 GetMemoryDC(...)
//                 ... do something
//                 ReleaseMemoryDC()
//
//               bracketed calls. If m_bReuseMemDC is subsequently set to FALSE, then 
//               the same code fragment will still work.
//
///////////////////////////////////////////////////////////////////////////////

BOOL CDIB::ReleaseMemoryDC(BOOL bForceRelease /*=FALSE*/)
{
    if ( !m_hMemDC
#ifndef DIBSECTION_NO_MEMDC_REUSE
        || (m_bReuseMemDC && !bForceRelease) 
#endif // DIBSECTION_NO_MEMDC_REUSE
        )
        return TRUE; // Nothing to do

    // Select out the current bitmap
    if (m_hOldBitmap)
        ::SelectObject(m_hMemDC, m_hOldBitmap);

    m_hOldBitmap = NULL;

#ifndef DIBSECTION_NO_PALETTE
    // Select out the current palette
    if (m_hOldPal)
        SelectPalette(m_hMemDC, m_hOldPal, FALSE);

    m_hOldPal = NULL;
#endif // DIBSECTION_NO_PALETTE

    // Delete the memory DC
    return DeleteDC(m_hMemDC);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -