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

📄 ximawnd.cpp

📁 用Cximage 库显示各种格式图片小程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// xImaWnd.cpp : Windows functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
 * CxImage version 6.0.0 02/Feb/2008
 */

#include "ximage.h"

#include "ximaiter.h" 
#include "ximabmp.h"

////////////////////////////////////////////////////////////////////////////////
#if defined (_WIN32_WCE)

#ifndef DEFAULT_GUI_FONT
#define DEFAULT_GUI_FONT 17
#endif

#ifndef PROOF_QUALITY
#define PROOF_QUALITY 2
#endif

struct DIBINFO : public BITMAPINFO
{
	RGBQUAD    arColors[255];    // Color table info - adds an extra 255 entries to palette
	operator LPBITMAPINFO()          { return (LPBITMAPINFO) this; }
	operator LPBITMAPINFOHEADER()    { return &bmiHeader;          }
	RGBQUAD* ColorTable()            { return bmiColors;           }
};

int BytesPerLine(int nWidth, int nBitsPerPixel)
{
    return ( (nWidth * nBitsPerPixel + 31) & (~31) ) / 8;
}

int NumColorEntries(int nBitsPerPixel, int nCompression, DWORD biClrUsed)
{
	int nColors = 0;
	switch (nBitsPerPixel)
	{
	case 1:
		nColors = 2;  break;
	case 2:
		nColors = 4;  break;   // winCE only
	case 4:
		nColors = 16; break;
	case 8:
		nColors =256; break;
	case 24:
		nColors = 0;  break;
	case 16:
	case 32:
		nColors = 3;  break; // I've found that PocketPCs need this regardless of BI_RGB or BI_BITFIELDS
	default:
		ASSERT(FALSE);
	}
	// If biClrUsed is provided, and it is a legal value, use it
	if (biClrUsed > 0 && biClrUsed <= (DWORD)nColors)
		return biClrUsed;
	
	return nColors;
}

int GetDIBits(
  HDC hdc,           // handle to DC
  HBITMAP hbmp,      // handle to bitmap
  UINT uStartScan,   // first scan line to set
  UINT cScanLines,   // number of scan lines to copy
  LPVOID lpvBits,    // array for bitmap bits
  LPBITMAPINFO lpbi, // bitmap data buffer
  UINT uUsage        // RGB or palette index
)
{
	UINT	iColorTableSize = 0;

	if (!hbmp)
		return 0;

	// Get dimensions of bitmap
	BITMAP bm;
	if (!::GetObject(hbmp, sizeof(bm),(LPVOID)&bm))
		return 0;

	//3. Creating new bitmap and receive pointer to it's bits.
	HBITMAP hTargetBitmap;
	void *pBuffer;
	
	//3.1 Initilize DIBINFO structure
	DIBINFO  dibInfo;
	dibInfo.bmiHeader.biBitCount = 24;
	dibInfo.bmiHeader.biClrImportant = 0;
	dibInfo.bmiHeader.biClrUsed = 0;
	dibInfo.bmiHeader.biCompression = 0;
	dibInfo.bmiHeader.biHeight = bm.bmHeight;
	dibInfo.bmiHeader.biPlanes = 1;
	dibInfo.bmiHeader.biSize = 40;
	dibInfo.bmiHeader.biSizeImage = bm.bmHeight*BytesPerLine(bm.bmWidth,24);
	dibInfo.bmiHeader.biWidth = bm.bmWidth;
	dibInfo.bmiHeader.biXPelsPerMeter = 3780;
	dibInfo.bmiHeader.biYPelsPerMeter = 3780;
	dibInfo.bmiColors[0].rgbBlue = 0;
	dibInfo.bmiColors[0].rgbGreen = 0;
	dibInfo.bmiColors[0].rgbRed = 0;
	dibInfo.bmiColors[0].rgbReserved = 0;

	//3.2 Create bitmap and receive pointer to points into pBuffer
	HDC hDC = ::GetDC(NULL);
	ASSERT(hDC);
	hTargetBitmap = CreateDIBSection(
		hDC,
		(const BITMAPINFO*)dibInfo,
		DIB_RGB_COLORS,
		(void**)&pBuffer,
		NULL,
		0);

	::ReleaseDC(NULL, hDC);

	//4. Copy source bitmap into the target bitmap.

	//4.1 Create 2 device contexts
	HDC memDc = CreateCompatibleDC(NULL);
	if (!memDc) {
		ASSERT(FALSE);
	}
	
	HDC targetDc = CreateCompatibleDC(NULL);
	if (!targetDc) {
		ASSERT(FALSE);
	}

	//4.2 Select source bitmap into one DC, target into another
	HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject(memDc, hbmp);
	HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject(targetDc, hTargetBitmap);

	//4.3 Copy source bitmap into the target one
	BitBlt(targetDc, 0, 0, bm.bmWidth, bm.bmHeight, memDc, 0, 0, SRCCOPY);

	//4.4 Restore device contexts
	::SelectObject(memDc, hOldBitmap1);
	::SelectObject(targetDc, hOldBitmap2);
	DeleteDC(memDc);
	DeleteDC(targetDc);

	//Here we can bitmap bits: pBuffer. Note:
	// 1. pBuffer contains 3 bytes per point
	// 2. Lines ane from the bottom to the top!
	// 3. Points in the line are from the left to the right
	// 4. Bytes in one point are BGR (blue, green, red) not RGB
	// 5. Don't delete pBuffer, it will be automatically deleted
	//    when delete hTargetBitmap
	lpvBits = pBuffer;

	DeleteObject(hbmp);
	//DeleteObject(hTargetBitmap);

	return 1;
}
#endif 

////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINDOWS
////////////////////////////////////////////////////////////////////////////////
long CxImage::Blt(HDC pDC, long x, long y)
{
	if((pDib==0)||(pDC==0)||(!info.bEnabled)) return 0;

    HBRUSH brImage = CreateDIBPatternBrushPt(pDib, DIB_RGB_COLORS);
    POINT pt;
    SetBrushOrgEx(pDC,x,y,&pt); //<RT>
    HBRUSH brOld = (HBRUSH) SelectObject(pDC, brImage);
    PatBlt(pDC, x, y, head.biWidth, head.biHeight, PATCOPY);
    SelectObject(pDC, brOld);
    SetBrushOrgEx(pDC,pt.x,pt.y,NULL);
    DeleteObject(brImage);
    return 1;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Transfer the image in a global bitmap handle (clipboard copy)
 */
HANDLE CxImage::CopyToHandle()
{
	HANDLE hMem=NULL;
	if (pDib){
		hMem= GlobalAlloc(GHND, GetSize());
		if (hMem){
			BYTE* pDst=(BYTE*)GlobalLock(hMem);
			if (pDst){
				memcpy(pDst,pDib,GetSize());
			}
			GlobalUnlock(hMem);
		}
	}
	return hMem;
}
////////////////////////////////////////////////////////////////////////////////
/**
 * Global object (clipboard paste) constructor
 * \param hMem: source bitmap object, the clipboard format must be CF_DIB
 * \return true if everything is ok
 */
bool CxImage::CreateFromHANDLE(HANDLE hMem)
{
	if (!Destroy())
		return false;

	DWORD dwSize = GlobalSize(hMem);
	if (!dwSize) return false;

	BYTE *lpVoid;						//pointer to the bitmap
	lpVoid = (BYTE *)GlobalLock(hMem);
	BITMAPINFOHEADER *pHead;			//pointer to the bitmap header
	pHead = (BITMAPINFOHEADER *)lpVoid;
	if (lpVoid){

		//CxMemFile hFile(lpVoid,dwSize);

		//copy the bitmap header
		memcpy(&head,pHead,sizeof(BITMAPINFOHEADER));
		//check if it's a top-down bitmap
		bool bTopDownDib = head.biHeight<0;
		if (bTopDownDib) head.biHeight=-head.biHeight;
		//create the image
		if(!Create(head.biWidth,head.biHeight,head.biBitCount)){
			GlobalUnlock(lpVoid);
			return false;
		}
		//preserve DPI
		SetXDPI((long)floor(head.biXPelsPerMeter * 254.0 / 10000.0 + 0.5));
		SetYDPI((long)floor(head.biYPelsPerMeter * 254.0 / 10000.0 + 0.5));

		/*//copy the pixels (old way)
		if((pHead->biCompression != BI_RGB) || (pHead->biBitCount == 32)){ //<J鰎gen Alfredsson>
			// BITFIELD case
			// set the internal header in the dib
			memcpy(pDib,&head,sizeof(head));
			// get the bitfield masks
			DWORD bf[3];
			memcpy(bf,lpVoid+pHead->biSize,12);
			// transform into RGB
			Bitfield2RGB(lpVoid+pHead->biSize+12,bf[0],bf[1],bf[2],(BYTE)pHead->biBitCount);
		} else { //normal bitmap
			memcpy(pDib,lpVoid,GetSize());
		}*/

		// <Michael Gandyra>
		// fill in color map
		bool bIsOldBmp = (head.biSize == sizeof(BITMAPCOREHEADER));
		RGBQUAD *pRgb = GetPalette();
		if (pRgb) {
			// number of colors to fill in
			int nColors = DibNumColors(pHead);
			if (bIsOldBmp) {
				/* get pointer to BITMAPCOREINFO (old style 1.x) */
				LPBITMAPCOREINFO lpbmc = (LPBITMAPCOREINFO)lpVoid;
				for (int i = nColors - 1; i >= 0; i--) {
					pRgb[i].rgbRed      = lpbmc->bmciColors[i].rgbtRed;
					pRgb[i].rgbGreen    = lpbmc->bmciColors[i].rgbtGreen;
					pRgb[i].rgbBlue     = lpbmc->bmciColors[i].rgbtBlue;
					pRgb[i].rgbReserved = (BYTE)0;
				}
			} else {
				/* get pointer to BITMAPINFO (new style 3.x) */
				LPBITMAPINFO lpbmi = (LPBITMAPINFO)lpVoid;
				for (int i = nColors - 1; i >= 0; i--) {
					pRgb[i].rgbRed      = lpbmi->bmiColors[i].rgbRed;
					pRgb[i].rgbGreen    = lpbmi->bmiColors[i].rgbGreen;
					pRgb[i].rgbBlue     = lpbmi->bmiColors[i].rgbBlue;
					pRgb[i].rgbReserved = (BYTE)0;
				}
			}
		}

		// <Michael Gandyra>
		DWORD dwCompression = pHead->biCompression;
		// compressed bitmap ?
		if(dwCompression!=BI_RGB || pHead->biBitCount==32 || pHead->biBitCount ==16) {
			// get the bitmap bits
			LPSTR lpDIBBits = (LPSTR)((BYTE*)pHead + *(DWORD*)pHead + (WORD)(GetNumColors() * sizeof(RGBQUAD)));
			// decode and copy them to our image
			switch (pHead->biBitCount) {
			case 32 :
				{
					// BITFIELD case
					if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB) {
						// get the bitfield masks
						DWORD bf[3];
						memcpy(bf,lpVoid+pHead->biSize,12);
						// transform into RGB
						Bitfield2RGB(lpVoid+pHead->biSize+12,bf[0],bf[1],bf[2],(BYTE)pHead->biBitCount);
					} else {
						// "unknown compression";
						GlobalUnlock(lpVoid);
						return false;
					}
				}
				break;
			case 16 :
				{
					// get the bitfield masks
					long offset=0;
					DWORD bf[3];
					if (dwCompression == BI_BITFIELDS) {
						memcpy(bf,lpVoid+pHead->biSize,12);
						offset= 12;
					} else {
						bf[0] = 0x7C00;
						bf[1] = 0x3E0;
						bf[2] = 0x1F; // RGB555
					}
					// copy the pixels
					memcpy(info.pImage, lpDIBBits + offset, head.biHeight*((head.biWidth+1)/2)*4);
					// transform into RGB
					Bitfield2RGB(info.pImage, bf[0], bf[1], bf[2], 16);
				}
				break;
			case 8 :
			case 4 :
			case 1 :
				{
					switch (dwCompression) {
					case BI_RLE4:
						{
							BYTE status_byte = 0;
							BYTE second_byte = 0;
							int scanline = 0;
							int bits = 0;
							BOOL low_nibble = FALSE;
							CImageIterator iter(this);

							for (BOOL bContinue = TRUE; bContinue; ) {
								status_byte = *(lpDIBBits++);
								switch (status_byte) {
								case RLE_COMMAND :
									status_byte = *(lpDIBBits++);
									switch (status_byte) {
									case RLE_ENDOFLINE :
										bits = 0;
										scanline++;
										low_nibble = FALSE;
										break;
									case RLE_ENDOFBITMAP :
										bContinue = FALSE;
										break;
									case RLE_DELTA :
										{
											// read the delta values
											BYTE delta_x;
											BYTE delta_y;
											delta_x = *(lpDIBBits++);
											delta_y = *(lpDIBBits++);
											// apply them
											bits       += delta_x / 2;

⌨️ 快捷键说明

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