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

📄 hgico.c

📁 HGui4.1.rar
💻 C
字号:
//---------------------------------------------------------------------------------
// Copyright (c) Haisoft 2006-9-1
// Copyright jinhailiao 2008-2010
// E-mail:   jinhailiao@163.com
// Project:			HGui
// File:			hgico.h
// Description:		
//-------------------------------------------------------------
// Reversion Histroy:
//-------------------------------------------------------------
// Version		date		operations				by who
// 3.0.0		2008-03-20	cteate					Kingsea
//---------------------------------------------------------------------------------
#include "haitype.h"
#include "haihandle.h"
#include "haimem.h"
#include "_haigdi.h"
#include "haipic.h"


typedef struct tagIconDirectoryEntry
{
	S_BYTE  bWidth;
	S_BYTE  bHeight;
	S_BYTE  bColorCount;
	S_BYTE  bReserved;
	S_WORD  wPlanes;
	S_WORD  wBitCount;
	S_DWORD dwBytesInRes;
	S_DWORD dwImageOffset;
}
S_ICONDIRENTRY, *SP_ICONDIRENTRY;

typedef struct tagIconHead
{
	S_WORD idReserved;
	S_WORD idType;
	S_WORD idCount;
}
S_ICONHEADER, *SP_ICONHEADER;


S_DWORD _hai_ReadBitmapInfo(S_BYTE *pBmpData, BITMAPINFOHEADER *pbih);


S_BYTE hai_GetIcoFrameTotal(S_VOID *pIcoData)
{
	S_BYTE *picoData = pIcoData;
	S_ICONHEADER IconHeader;
	
	if (pIcoData == S_NULL)
		return 0;

	IconHeader.idReserved = HAI_MAKEWORD(picoData+0);
	IconHeader.idType  = HAI_MAKEWORD(picoData+2);
	IconHeader.idCount = HAI_MAKEWORD(picoData+4);

	// check an icon or a cursor
	if (IconHeader.idReserved==0 && (IconHeader.idType==1||IconHeader.idType==2))
		return (S_BYTE)IconHeader.idCount;
	else
		return 0;
}

SH_ICON hai_IcoDecode(S_VOID *pIcoData, S_BYTE frame)
{
	S_WORD i, j, c;
	S_DWORD WidthBytes;
	S_BYTE *picoData = pIcoData;
	S_BYTE *pDst, *pSrc;
	RGBQUAD *pPalette = S_NULL;
	_SP_ICON pIcon = S_NULL;
	S_ICONHEADER IconHeader;
	S_ICONDIRENTRY IconDir;
	BITMAPINFOHEADER bih;
	
	if (pIcoData == S_NULL)
		return S_NULL;

	IconHeader.idReserved = HAI_MAKEWORD(picoData+0);
	IconHeader.idType  = HAI_MAKEWORD(picoData+2);
	IconHeader.idCount = HAI_MAKEWORD(picoData+4);
	picoData += 6;

	// check an icon or a cursor
	if (!(IconHeader.idReserved==0 && (IconHeader.idType==1||IconHeader.idType==2)))
		return S_NULL;
	if (frame > IconHeader.idCount)
		return S_NULL;
	frame -= 1;
	picoData += frame*sizeof(S_ICONDIRENTRY);
	memcpy(&IconDir, picoData, sizeof(S_ICONDIRENTRY));

	picoData = (S_BYTE *)pIcoData + IconDir.dwImageOffset;
	//read bih;
	picoData += _hai_ReadBitmapInfo(picoData, &bih);
	//
	if (bih.biPlanes != 1 || bih.biCompression != BI_RGB)
		return S_NULL;

	// read the palette
	if (bih.biBitCount <= 8)
	{
		pPalette = hai_MemAlloc((1<<bih.biBitCount)*sizeof(RGBQUAD));
		if (pPalette == S_NULL)
			return S_NULL;
		memcpy(pPalette, picoData, (1<<bih.biBitCount)*sizeof(RGBQUAD));
	}
	
	WidthBytes = BITMAP_WIDTHBYTES(bih.biWidth, 24);
	pIcon = hai_MemAlloc(sizeof(*pIcon)+WidthBytes*bih.biWidth+MASKWIDTH(bih.biWidth)*bih.biWidth+4);
	if (pIcon == S_NULL)
		goto ICONDECODEERROR;

	HAI_SETHDLTYPE(pIcon, HT_ICON);
	pIcon->width     = (S_WORD)bih.biWidth;
	pIcon->height    = (S_WORD)bih.biWidth;
	pIcon->BitsPixel = 24;
	pIcon->WidthBytes = (S_WORD)WidthBytes;
	pIcon->lpImage = ((S_BYTE *)pIcon)+sizeof(*pIcon);
	pIcon->lpMask = ((S_BYTE *)pIcon)+sizeof(*pIcon)+WidthBytes*bih.biWidth;
	
	//read the icon
	picoData += (1<<bih.biBitCount)*sizeof(RGBQUAD);
	WidthBytes = BITMAP_WIDTHBYTES(bih.biWidth, bih.biBitCount);
	switch (bih.biBitCount)	{
		case 32 :
			for (i = 0; i < pIcon->height; i++)
			{
				pDst = ((S_BYTE*)pIcon->lpImage)+i*pIcon->WidthBytes;
				pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
				j = (bih.biWidth+7)>>3;
				switch (bih.biWidth % 8)
				{
				case 0:do{*pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 7:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 6:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 5:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 4:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 3:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 2:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
				case 1:     *pDst++ = *pSrc++;*pDst++ = *pSrc++;*pDst++ = *pSrc++;pSrc++;
						}while (--j);
				}
			}
			break;
		case 24 :
			memcpy(pIcon->lpImage, picoData, pIcon->WidthBytes*pIcon->height);
			break;
		case 16 :
			for (i = 0; i < pIcon->height; i++)
			{
				pDst = ((S_BYTE*)pIcon->lpImage)+i*pIcon->WidthBytes;
				pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
				j = (bih.biWidth+7)>>3;
				switch (bih.biWidth % 8)
				{
				case 0:do{c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 7:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 6:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 5:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 4:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 3:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 2:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
				case 1:     c=HAI_MAKEWORD(pSrc);pSrc+=2;*pDst++=(S_BYTE)((c&0x1F)<<3);*pDst++=(S_BYTE)((c&0x3E0)>>2);*pDst++=(S_BYTE)((c&0x7C00)>>7);
						}while (--j);
				}
			}
			break;
		case 8:
			for (i = 0; i < pIcon->height; i++)
			{
				pDst = ((S_BYTE*)pIcon->lpImage)+i*pIcon->WidthBytes;
				pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
				j = (bih.biWidth+7)>>3;
				switch (bih.biWidth % 8)
				{
				case 0:do{c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 7:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 6:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 5:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 4:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 3:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 2:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
				case 1:     c=*pSrc++;*pDst++=pPalette[c].rgbRed;*pDst++=pPalette[c].rgbGreen;*pDst++=pPalette[c].rgbBlue;
						}while (--j);
				}
			}
			break;
		case 4:
			for (i = 0; i < pIcon->height; i++)
			{
				pDst = ((S_BYTE*)pIcon->lpImage)+i*pIcon->WidthBytes;
				pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
				j = (S_WORD)bih.biWidth;
				while (j >= 2){
					j -= 2;
					c = *pSrc++;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbRed;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbGreen;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbBlue;
					*pDst++ = pPalette[c&0X0F].rgbRed;
					*pDst++ = pPalette[c&0X0F].rgbGreen;
					*pDst++ = pPalette[c&0X0F].rgbBlue;
				}
				if (j == 1){
					c = *pSrc++;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbRed;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbGreen;
					*pDst++ = pPalette[(c>>4)&0X0F].rgbBlue;
				}
			}
			break;
		case 1:
			for (i = 0; i < pIcon->height; i++)
			{
				pDst = ((S_BYTE*)pIcon->lpImage)+i*pIcon->WidthBytes;
				pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
				j = (S_WORD)bih.biWidth;
				while (j >= 8){
					j -= 8;
					c = *pSrc++;
					*pDst++ = pPalette[(c>>7)&0X01].rgbRed;*pDst++ = pPalette[(c>>7)&0X01].rgbGreen;*pDst++ = pPalette[(c>>7)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>6)&0X01].rgbRed;*pDst++ = pPalette[(c>>6)&0X01].rgbGreen;*pDst++ = pPalette[(c>>6)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>5)&0X01].rgbRed;*pDst++ = pPalette[(c>>5)&0X01].rgbGreen;*pDst++ = pPalette[(c>>5)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>4)&0X01].rgbRed;*pDst++ = pPalette[(c>>4)&0X01].rgbGreen;*pDst++ = pPalette[(c>>4)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>3)&0X01].rgbRed;*pDst++ = pPalette[(c>>3)&0X01].rgbGreen;*pDst++ = pPalette[(c>>3)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>2)&0X01].rgbRed;*pDst++ = pPalette[(c>>2)&0X01].rgbGreen;*pDst++ = pPalette[(c>>2)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>1)&0X01].rgbRed;*pDst++ = pPalette[(c>>1)&0X01].rgbGreen;*pDst++ = pPalette[(c>>1)&0X01].rgbBlue;
					*pDst++ = pPalette[(c>>0)&0X01].rgbRed;*pDst++ = pPalette[(c>>0)&0X01].rgbGreen;*pDst++ = pPalette[(c>>0)&0X01].rgbBlue;
				}
				if (j)
				{
					S_SHORT w = (S_SHORT)j;
					c = *pSrc++;
					{*pDst++ = pPalette[(c>>7)&0X01].rgbRed;*pDst++ = pPalette[(c>>7)&0X01].rgbGreen;*pDst++ = pPalette[(c>>7)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>6)&0X01].rgbRed;*pDst++ = pPalette[(c>>6)&0X01].rgbGreen;*pDst++ = pPalette[(c>>6)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>5)&0X01].rgbRed;*pDst++ = pPalette[(c>>5)&0X01].rgbGreen;*pDst++ = pPalette[(c>>5)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>4)&0X01].rgbRed;*pDst++ = pPalette[(c>>4)&0X01].rgbGreen;*pDst++ = pPalette[(c>>4)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>3)&0X01].rgbRed;*pDst++ = pPalette[(c>>3)&0X01].rgbGreen;*pDst++ = pPalette[(c>>3)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>2)&0X01].rgbRed;*pDst++ = pPalette[(c>>2)&0X01].rgbGreen;*pDst++ = pPalette[(c>>2)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>1)&0X01].rgbRed;*pDst++ = pPalette[(c>>1)&0X01].rgbGreen;*pDst++ = pPalette[(c>>1)&0X01].rgbBlue;}
					if (--w > 0)
						{*pDst++ = pPalette[(c>>0)&0X01].rgbRed;*pDst++ = pPalette[(c>>0)&0X01].rgbGreen;*pDst++ = pPalette[(c>>0)&0X01].rgbBlue;}
				}
			}
			break;
		default:
			goto ICONDECODEERROR;
	}

	// read mask
	picoData += WidthBytes*pIcon->height;
	WidthBytes = MASKWIDTH(pIcon->width);
	for (i = 0; i < pIcon->height; i++)
	{
		pDst = ((S_BYTE*)pIcon->lpMask)+i*WidthBytes;
		pSrc = picoData+(pIcon->height-i-1)*WidthBytes;
		memcpy(pDst, pSrc, WidthBytes);
	}

	if (pPalette)
		hai_MemFree(pPalette);
	return (SH_ICON)pIcon;
ICONDECODEERROR:
	if (pPalette)
		hai_MemFree(pPalette);
	if (pIcon)
		hai_MemFree(pIcon);
	return S_NULL;
}



⌨️ 快捷键说明

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