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

📄 zgraphdib.cpp

📁 Symbian手机智能操作系统下的源码,图像查看软件,支持十几种图形格式.
💻 CPP
字号:
#include "zGraphDib.h"

const RGBQUAD StandardColorTable16[] = {
	{ 0x00, 0x00, 0x00, 0x00 }, 
	{ 0x00, 0x00, 0x80, 0x00 },
	{ 0x00, 0x80, 0x00, 0x00 },
	{ 0x00, 0x80, 0x80, 0x00 },
	{ 0x80, 0x00, 0x00, 0x00 },
	{ 0x80, 0x00, 0x80, 0x00 },
	{ 0x80, 0x80, 0x00, 0x00 },
	{ 0xC0, 0xC0, 0xC0, 0x00 },
	{ 0x80, 0x80, 0x80, 0x00 },
	{ 0x00, 0x00, 0xFF, 0x00 },
	{ 0x00, 0xFF, 0x00, 0x00 },
	{ 0x00, 0xFF, 0xFF, 0x00 },
	{ 0xFF, 0x00, 0x00, 0x00 },
	{ 0xFF, 0x00, 0xFF, 0x00 },
	{ 0xFF, 0xFF, 0x00, 0x00 },
	{ 0xFF, 0xFF, 0xFF, 0x00 }
};

// R G B
const DWORD StandardMask555[] =  { 0x007C00, 0x0003E0, 0x00001F };
const DWORD StandardMask565[] =  { 0x00F800, 0x0007E0, 0x00001F };
const DWORD StandardMask888[] =  { 0xFF0000, 0x00FF00, 0x0000FF };

const BYTE Shift1bpp[] = { 7,     6,     5,     4,     3,     2,     1,     0     };
const BYTE Mask1bpp [] = { ~0x80, ~0x40, ~0x20, ~0x10, ~0x08, ~0x04, ~0x02, ~0x01 };
const BYTE Shift2bpp[] = { 6,     4,     2,     0     };
const BYTE Mask2bpp [] = { ~0xC0, ~0x30, ~0x0C, ~0x03 };
const BYTE Shift4bpp[] = { 4, 0 };
const BYTE Mask4bpp [] = { ~0xF0, ~0x0F };

zGraphDib::zGraphDib()
{
	b_create	   = false;
	m_pBMI         = NULL;
	m_pBits        = NULL;
	m_Flags		   = 0;

	m_nWidth       = 0;
	m_nHeight      = 0;
	m_nPlanes      = 1;
	m_nBitCount    = 1;
	m_nColorDepth  = 1;
	m_nImageSize   = 0;
	m_nImageFormat = DIB_1BPP;

	m_pRGBTRIPLE   = NULL;
	m_pRGBQUAD	   = NULL;
}

zGraphDib::~zGraphDib()
{
	ReleaseDIB();
}

void zGraphDib::zGraphDibInfo::SetFormat(int width, int height, int bitcount, int compression)
{
	//设置文件格式信息
	memset(&m_dibinfo, 0, sizeof(m_dibinfo));

	m_dibinfo.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
	m_dibinfo.bmiHeader.biWidth       = width;
	m_dibinfo.bmiHeader.biHeight      = height;
	m_dibinfo.bmiHeader.biPlanes      = 1;
	m_dibinfo.bmiHeader.biBitCount    = bitcount;
	m_dibinfo.bmiHeader.biCompression = compression;

	//设置标准调色板
	switch ( bitcount )
	{
		case 2:		//2色
			m_dibinfo.bmiColors[0].rgbRed   = 0;	// 黑	
			m_dibinfo.bmiColors[0].rgbGreen = 0;
			m_dibinfo.bmiColors[0].rgbBlue  = 0;
			m_dibinfo.bmiColors[1].rgbRed   = 0xFF; // 白
			m_dibinfo.bmiColors[1].rgbGreen = 0xFF;
			m_dibinfo.bmiColors[1].rgbBlue  = 0xFF;

		case 4:		//设置标准16色调色板
			memcpy(m_dibinfo.bmiColors, StandardColorTable16, 16 * sizeof(RGBQUAD));
			break;

		case 8:		//设置标准256色调色板(windows:40 + 216)
		{
			for (int blue =0; blue <6; blue ++)
			{
				for (int green=0; green<6; green++)
				{
					for (int red  =0; red  <6; red  ++)
					{
						int i = (blue * 6 + green) * 6 + red;
						m_dibinfo.bmiColors[i].rgbRed   = red   * 55;
						m_dibinfo.bmiColors[i].rgbGreen = green * 55;
						m_dibinfo.bmiColors[i].rgbBlue  = blue  * 55;
					}
				}
			}
			break;
		}

		case 16:	//设置16位色的rgb分量掩码
			if ( compression==BI_BITFIELDS )
				memcpy(m_dibinfo.bmiColors, StandardMask555, sizeof(StandardMask555));
			break;

		case 32:	//设置32位色的rgb分量掩码
			if ( compression==BI_BITFIELDS )
				memcpy(m_dibinfo.bmiColors, StandardMask888, sizeof(StandardMask888));
			break;
	}
}

void zGraphDib::zGraphDibInfo::SetGrayScale(DWORD mask)
{
	int nColor = 1 << m_dibinfo.bmiHeader.biBitCount;

	for (int i=0; i<nColor; i++)
	{
		m_dibinfo.bmiColors[i].rgbRed		= i & GetRValue(mask);
		m_dibinfo.bmiColors[i].rgbGreen		= i & GetGValue(mask);
		m_dibinfo.bmiColors[i].rgbBlue		= i & GetBValue(mask);
		m_dibinfo.bmiColors[i].rgbReserved  = 0;
	}		
}

BITMAPINFO *zGraphDib::zGraphDibInfo::GetBMI() const
{
	return (BITMAPINFO *) & m_dibinfo;
}

BITMAPINFO *zGraphDib::zGraphDibInfo::CopyBMI() const
{
	int nColor;

	if ( m_dibinfo.bmiHeader.biCompression==BI_BITFIELDS )
	{
		nColor = 3;
	}else if ( m_dibinfo.bmiHeader.biBitCount <= 8 )
	{
		nColor = 1 << m_dibinfo.bmiHeader.biBitCount;
	}else
	{
		nColor = 0;
	}
	int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColor;

	BITMAPINFO * pBMI = (BITMAPINFO *) new BYTE[nSize];
	if (pBMI)
	{
		memcpy(pBMI, & m_dibinfo, nSize);
	}

	return pBMI;
}

bool zGraphDib::AttachDIB(BITMAPINFO *pDIB, BYTE *pBits, int flags)
{
	if ( IsBadReadPtr(pDIB, sizeof(BITMAPCOREHEADER)) )
	{
		return false;
	}

	ReleaseDIB();
	
	m_pBMI      = pDIB;
	m_Flags     = flags;

	DWORD size = * (DWORD *) pDIB;	//获取信息头尺寸

	int compression;
	//根据信息头大小判断版本
	switch ( size )
	{
		case sizeof(BITMAPCOREHEADER):	//OS2信息头
		{
			BITMAPCOREHEADER * pHeader = (BITMAPCOREHEADER *) pDIB;

			m_nWidth    = pHeader->bcWidth;
			m_nHeight   = pHeader->bcHeight;
			m_nPlanes   = pHeader->bcPlanes;
			m_nBitCount = pHeader->bcBitCount;
			m_nImageSize= 0;
			compression = BI_RGB;

			if ( m_nBitCount <= 8 )
			{
				m_nClrUsed   = 1 << m_nBitCount;
				m_nClrImpt   = m_nClrUsed;
				m_pRGBTRIPLE = (RGBTRIPLE *) ((BYTE *) m_pBMI + size);

				m_pBits      = (BYTE *) & m_pRGBTRIPLE[m_nClrUsed];
			}
			else
				m_pBits      = (BYTE *) m_pBMI + size;
			break;
		}

		case sizeof(BITMAPINFOHEADER):
//		case sizeof(BITMAPV4HEADER):
//		case sizeof(BITMAPV5HEADER):		//位图信息头,V4,V5版本统当作一般信息头处理.
		{
			BITMAPINFOHEADER * pHeader = & m_pBMI->bmiHeader;

			m_nWidth    = pHeader->biWidth;
			m_nHeight   = pHeader->biHeight;
			m_nPlanes   = pHeader->biPlanes;
			m_nBitCount = pHeader->biBitCount;
			m_nImageSize= pHeader->biSizeImage;
			compression = pHeader->biCompression;

			m_nClrUsed  = pHeader->biClrUsed;
			m_nClrImpt  = pHeader->biClrImportant;

			if ( m_nBitCount<=8 )
			{
				if ( m_nClrUsed==0 )	
				{
					//全颜色表
					m_nClrUsed = 1 << m_nBitCount;
				}
			}
			if ( m_nClrUsed )	// 有一个颜色表
			{
				if ( m_nClrImpt==0 )	// 全都使用了
				{
					m_nClrImpt = m_nClrUsed;
				}
				if ( compression==BI_BITFIELDS )
				{
					m_pBitFields = (DWORD *) ((BYTE *)pDIB+size);
					m_pRGBQUAD = (RGBQUAD *) ((BYTE *)pDIB+size + 3*sizeof(DWORD));
				}else
				{
					m_pRGBQUAD = (RGBQUAD *) ((BYTE *)pDIB+size);
				}
				m_pBits = (BYTE *) & m_pRGBQUAD[m_nClrUsed];
			}else
			{
				if ( compression==BI_BITFIELDS )
				{
					m_pBitFields = (DWORD *) ((BYTE *)pDIB+size);
					m_pBits      = (BYTE *) m_pBMI + size + 3 * sizeof(DWORD);
				}else
				{
					m_pBits      = (BYTE *) m_pBMI + size;
				}
			}
			break;
		}

		default:
			return false;
	}

	//像素指针
	if ( pBits )
	{
		m_pBits = pBits;	//如果直接指定了像素位
	}

	//颜色深度
	m_nColorDepth = m_nPlanes * m_nBitCount;
	//DWORD对齐后的大小
	m_nBPS		  = (m_nWidth * m_nBitCount + 31) / 32 * 4;

	//高度,行差,起始位置
	if (m_nHeight < 0 )		//上下形式位图
	{
		m_nHeight = - m_nHeight;	//高度
		m_nDelta  = m_nBPS;			//行差
		m_pOrigin = m_pBits;		//从前向后 0...n
	}else					//下上形式位图
	{
		m_nDelta  = - m_nBPS;		//设定行差
		m_pOrigin = m_pBits + (m_nHeight-1) * m_nBPS * m_nPlanes;	//从后向前 n..0
	}

	//图像大小
	if ( m_nImageSize==0 )
	{
		m_nImageSize = m_nBPS * m_nPlanes * m_nHeight;
	}

	//图像格式
	switch ( m_nBitCount )
	{
		case 0:
//			if ( compression==BI_JPEG )
//			{
//				m_nImageFormat = DIB_JPEG;
//			}else if ( compression==BI_PNG )
//			{
//				m_nImageFormat = DIB_PNG;
//			}else
			{
				return false;
			}
			break;
		case 1:
			m_nImageFormat = DIB_1BPP;
			break;

		case 2:
			m_nImageFormat = DIB_2BPP;
			break;

		case 4:
//			if ( compression==BI_RLE4 )
//			{
//				m_nImageFormat = DIB_4BPPRLE;
//			}else
			{
				m_nImageFormat = DIB_4BPP;
			}
			break;

		case 8:
//			if ( compression==BI_RLE8 )
//			{
//				m_nImageFormat = DIB_8BPPRLE;
//			}else
			{
				m_nImageFormat = DIB_8BPP;
			}
			break;
		
		case 16:
			if ( compression==BI_BITFIELDS )
			{
				m_nImageFormat = DIB_16RGBbitfields;
			}else
			{
				m_nImageFormat = DIB_16RGB555; 
			}
			break;
		
		case 24:
			m_nImageFormat = DIB_24RGB888;
			break;

		case 32:
			if ( compression == BI_BITFIELDS )
			{
				m_nImageFormat = DIB_32RGBbitfields;
			}else
			{
				m_nImageFormat = DIB_32RGB888; 
			}
			break;

		default:
			return false;
	}

	if ( compression==BI_BITFIELDS )
	{
		DWORD red   = m_pBitFields[0];
		DWORD green = m_pBitFields[1];
		DWORD blue  = m_pBitFields[2];

		if (      (blue==0x001F) && (green==0x03E0) && (red==0x7C00) )
		{
			m_nImageFormat = DIB_16RGB555;
		}else if ( (blue==0x001F) && (green==0x07E0) && (red==0xF800) )
		{
			m_nImageFormat = DIB_16RGB565;
		}else if ( (blue==0x00FF) && (green==0xFF00) && (red==0xFF0000) )
		{
			m_nImageFormat = DIB_32RGB888;
		}
	}

	//建立标记
	b_create = true;

	return true;
}


bool zGraphDib::LoadBitmap(HMODULE hModule, LPCTSTR pBitmapName)
{
	//从资源载入位图
	HRSRC   hRes = FindResource(hModule, pBitmapName, RT_BITMAP);

	if ( hRes==NULL )
		return false;

	HGLOBAL hGlb = LoadResource(hModule, hRes);

	if ( hGlb==NULL )
		return false;

	BITMAPINFO * pDIB = (BITMAPINFO *) LockResource(hGlb);

	if ( pDIB==NULL )
		return false;

	return AttachDIB(pDIB, NULL, DIB_BMI_READONLY | DIB_BITS_READONLY);
}

bool zGraphDib::Create(int width, int height, int bitcount)
{
	//建立指定位图

	zGraphDibInfo dibinfo;
	dibinfo.SetFormat(width, height, bitcount, BI_RGB);

	int nBitsSize = ( width * bitcount + 31 ) /32 * 4 * height;
	BYTE * pBits = new BYTE[nBitsSize];
	
	if ( pBits )
	{
		return AttachDIB(dibinfo.CopyBMI(), pBits, 0);
	}else
	{
		return FALSE;
	}
}

void zGraphDib::ReleaseDIB()
{
	b_create = false;

	if (m_pBMI != NULL)
	{
		if ( m_Flags & DIB_BMI_NEEDFREE )
		{
			delete [] (BYTE *) m_pBMI;
			m_Flags &= ~ DIB_BMI_NEEDFREE;
			m_pBMI   = NULL;
		}
	}
	if (m_pBits != NULL)
	{
		if ( m_Flags & DIB_BITS_NEEDFREE )
		{
			delete [] m_pBits;
			m_Flags &= ~ DIB_BITS_NEEDFREE;
			m_pBits = NULL;
		}	
	}
}


bool zGraphDib::IsCompressed() const
{
	return (m_nImageFormat == DIB_4BPPRLE) || (m_nImageFormat == DIB_8BPPRLE) || 
	    	(m_nImageFormat == DIB_JPEG) || (m_nImageFormat == DIB_PNG);
}


int zGraphDib::DrawDib(HDC hDC, int dx, int dy, int dw, int dh, int sx, int sy, int sw, int sh, DWORD rop)
{
	if ( m_pBMI )
	{
		return ::StretchDIBits(hDC, dx, dy, dw, dh, sx, sy, sw, sh,m_pBits, m_pBMI, DIB_RGB_COLORS, rop);
	}else
	{
		return GDI_ERROR;
	}
}

int zGraphDib::GetDIBColorCount(const BITMAPINFOHEADER &bmih)
{
	if ( bmih.biBitCount <= 8 )
	{	
		if ( bmih.biClrUsed )
		{	
			return bmih.biClrUsed;
		}else
		{
			return 1 << bmih.biBitCount;
		}
	}else if ( bmih.biCompression==BI_BITFIELDS )
	{
		return 3 + bmih.biClrUsed;
	}else
	{
		return bmih.biClrUsed;
	}
}

int zGraphDib::GetDIBPixelSize(const BITMAPINFOHEADER &bmih)
{
	if ( bmih.biSizeImage )
	{
		return bmih.biSizeImage;
	}else
	{
		return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
	}
}

DWORD zGraphDib::GetPixelIndex(int x, int y) const
{
	if ( (x<0) || (x>=m_nWidth) )
		return -1;

	if ( (y<0) || (y>=m_nHeight) )
		return -1;

	BYTE * pPixel = m_pOrigin + y * m_nDelta;

	switch ( m_nImageFormat )
	{
		case DIB_1BPP:
			return ( pPixel[x/8] >> Shift1bpp[x%8] ) & 0x01;

		case DIB_2BPP:
			return ( pPixel[x/4] >> Shift2bpp[x%4] ) & 0x03;

		case DIB_4BPP:
			return ( pPixel[x/2] >> Shift4bpp[x%4] ) & 0x0F;

		case DIB_8BPP:
			return pPixel[x];

		case DIB_16RGB555:
		case DIB_16RGB565:
			return ((WORD *)pPixel)[x];

		case DIB_24RGB888:
			pPixel += x * 3;
			return (pPixel[0]) | (pPixel[1] << 8) | (pPixel[2] << 16);
		
		case DIB_32RGB888:
		case DIB_32RGBA8888:
			return ((DWORD *)pPixel)[x];
	}

	return -1;
}

BOOL  zGraphDib::SetPixelIndex(int x, int y, DWORD index)
{
	if ( (x<0) || (x>=m_nWidth) )
		return FALSE;

	if ( (y<0) || (y>=m_nHeight) )
		return FALSE;

	BYTE * pPixel = m_pOrigin + y * m_nDelta;
	
	switch ( m_nImageFormat )
	{
		case DIB_1BPP:
			pPixel[x/8] = (BYTE) ( ( pPixel[x/8] & Mask1bpp[x%8] ) | ( (index & 1) << Shift1bpp[x%8] ) );
			break;

		case DIB_2BPP:
			pPixel[x/4] = (BYTE) ( ( pPixel[x/4] & Mask2bpp[x%4] ) | ( (index & 3) << Shift2bpp[x%4] ) );
			break;

		case DIB_4BPP:
			pPixel[x/2] = (BYTE) ( ( pPixel[x/2] & Mask4bpp[x%2] ) | ( (index & 15) << Shift4bpp[x%2] ) );
			break;

		case DIB_8BPP:
			pPixel[x] = (BYTE) index;
			break;

		case DIB_16RGB555:
		case DIB_16RGB565:
			((WORD *)pPixel)[x] = (WORD) index;
			break;

		case DIB_24RGB888:
			((RGBTRIPLE *)pPixel)[x] = * ((RGBTRIPLE *) & index);
			break;

		case DIB_32RGB888:
		case DIB_32RGBA8888:
			((DWORD *)pPixel)[x] = index;
			break;

		default:
			return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

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