|
#define ICON_SIZE 32

static int _HBitmapToBmp32Bits(HBITMAP hBitmap, U8 *out, int out_len)
  {
 /**//*
* 注意:
* 該函數(shù)代碼部分參考csdn。向原作者致敬!
*/
// 設(shè)備描述表
HDC hDC;
//位圖中每個(gè)像素所占字節(jié)數(shù)
WORD wBitCount;
// 定義調(diào)色板大小,位圖中像素字節(jié)大小,位圖文件大小,寫入文件字節(jié)數(shù)
DWORD dwBmBitsSize;
//位圖屬性結(jié)構(gòu)
BITMAP Bitmap;
//位圖信息頭結(jié)構(gòu)
BITMAPINFOHEADER bi;
// 定義文件,分配內(nèi)存句柄,調(diào)色板句柄
// 計(jì)算位圖文件每個(gè)像素所占字節(jié)數(shù)
HANDLE hPal, hOldPal = NULL;

// 設(shè)置位圖信息頭結(jié)構(gòu)
wBitCount = 32;
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
 if (Bitmap.bmWidth != ICON_SIZE || Bitmap.bmHeight != ICON_SIZE) {
Dbg("size not fit\n");
return 0;
}

memset(&bi, 0, sizeof(bi));
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;

// 計(jì)算位圖大小
dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32) * 4 * Bitmap.bmHeight;
if (out_len < (int)dwBmBitsSize)
return 0;

// 處理調(diào)色板
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
 if (hPal) {
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}

// 獲取該調(diào)色板下新的像素值
GetDIBits(hDC,
hBitmap,
0,
(UINT)Bitmap.bmHeight,
(LPSTR)out,
(BITMAPINFO *)&bi,
DIB_PAL_COLORS
);

// 恢復(fù)調(diào)色板
 if (hOldPal) {
SelectPalette(hDC,(HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}

return dwBmBitsSize;
}


static int ExtToIcoFile(char *ext, U8 *out, int out_len)
  {
SHFILEINFOA sfi;
 char str[32] = { "*." };
U32 *buf;
ICONINFO ii;
U8 *orig = out;
int i;

#define XOR_SIZE ICON_SIZE*ICON_SIZE*4
#define AND_SIZE ICON_SIZE*ICON_SIZE/8

// Calc File Length
// 文件頭6字節(jié)
// 圖像信息塊16字節(jié)
// BMP信息頭40字節(jié)
// XOR位圖
// 單色AND位圖
if (out_len < 6 + 16 + 40 + XOR_SIZE + AND_SIZE)
return 0;

strncat(str, ext, sizeof(str) - 8);
SHGetFileInfoA(str,
FILE_ATTRIBUTE_NORMAL,
&sfi,
sizeof(SHFILEINFO),
SHGFI_USEFILEATTRIBUTES | SHGFI_ICON
);
GetIconInfo(sfi.hIcon, &ii);

 /**//*
(一、文件頭6字節(jié))
000(000)2 保留的字節(jié) 00 00
002(002)2 資源類型 01 00 (01為圖標(biāo),02為光標(biāo))
004(004)2 圖象個(gè)數(shù) 01 00
*/
*(U16 *)out = 0; out += 2;
*(U16 *)out = 1; out += 2;
*(U16 *)out = 1; out += 2;

 /**//*
(二、圖像信息塊16字節(jié))
006(006)1 圖標(biāo)寬度 20
007(007)1 圖標(biāo)高度 20
008(008)1 顏色計(jì)數(shù) 00(02=單色, 00≥256色)
009(009)1 未用 00
010(00A)4 保留的 00 00 00 00
014(00E)4 圖象數(shù)據(jù)塊的長(zhǎng)度 28 01 00 00(10進(jìn)制=296)
018(012)4 圖象數(shù)據(jù)塊相對(duì)于文件頭部的偏移量 16 00 00 00(10進(jìn)制=22)
*/
*out++ = ICON_SIZE;
*out++ = ICON_SIZE;
*out++ = 0;
*out++ = 0;
*(U32 *)out = 0; out += 4;
*(U32 *)out = 40 + XOR_SIZE + AND_SIZE; out += 4;
*(U32 *)out = 22; out += 4;

 /**//*
(三、BMP信息頭40字節(jié))
022(016)4 BMP 信息頭結(jié)構(gòu)長(zhǎng)度 28 00 00 00(10進(jìn)制=40)
026(01A)4 圖像寬度 10 00 00 00
030(01E)4 圖像高度(XOR圖高度+AND圖高度) 20 00 00 00
034(022)2 位面板數(shù) 01 00
036(024)2 每象素所占位數(shù) 04 00
038(026)4 象素?cái)?shù)據(jù)的壓縮類型 00 00 00 00(表示未壓縮)
042(02A)4 圖象數(shù)據(jù)的長(zhǎng)度 C0 00 00 00(10進(jìn)制=192)
046(02E)16 未用 16個(gè)00
*/
*(U32 *)out = 40; out += 4;
*(U32 *)out = 32; out += 4;
*(U32 *)out = 64; out += 4;
*(U16 *)out = 1; out += 2; // ??
*(U16 *)out = 32; out += 2;
*(U32 *)out = 0; out += 4;
*(U32 *)out = XOR_SIZE + AND_SIZE; out += 4;
memset(out, 0, 16); out += 16;

 /**//*
(五、XOR位圖的數(shù)據(jù))
*/
if (_HBitmapToBmp32Bits(ii.hbmColor, out, XOR_SIZE) != XOR_SIZE)
return 0;
out += 32*32*4;

 /**//*
(六、單色AND位圖的數(shù)據(jù))
*/
buf = (U32 *)malloc(XOR_SIZE);
if (!buf)
return 0;
if (_HBitmapToBmp32Bits(ii.hbmMask, (U8 *)buf, XOR_SIZE) != XOR_SIZE)
return 0;
memset(out, 0, AND_SIZE);
//out += 32*32/8;
 for (i = 0; i < AND_SIZE*8; i++) {
if (buf[i])
*out |= (1 << (7 - (i&7)));
if ((i&7) == 7)
out++;
}
free(buf);

#undef AND_SIZE
#undef XOR_SIZE

return out - orig;
}

#undef ICON_SIZE


int main()
  {
void *s, *a;
int len;
static char line[1024], method[16], url[128];
FILE *fp;
static U8 buf[1024*1024*1];
fp = fopen("b.ico", "wb+");
len = ExtToIcoFile("mp3", buf, sizeof(buf));
len = fwrite(buf, len, 1, fp);
fclose(fp);
return 0;

|