Gif.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:20k
源码类别:

图形图象

开发平台:

Visual C++

  1. /********************************************************************
  2. GifModule.cpp - ISee图像浏览器—GIF图像读写模块实现文件
  3.           
  4.     版权所有(C) 2000 VCHelp-coPathway-ISee workgroup member - Sam, YZ
  5.     这一程序是自由软件,你可以遵照自由软件基金会出版的GNU 通用公共许
  6. 可证条款来修改和重新发布这一程序。或者用许可证的第二版,或者(根
  7. 据你的选择)用任何更新的版本。
  8.     发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特定
  9. 目地的隐含的担保。更详细的情况请参阅GNU通用公共许可证。
  10.     你应该已经和程序一起收到一份GNU通用公共许可证的副本。如果还没有,
  11. 写信给:
  12.     The Free Software Foundation, Inc.,  675  Mass Ave,  Cambridge,
  13.     MA02139,  USA
  14. 如果你在使用本软件时有什么问题或建议,用以下地址可以与我们取得联
  15. 系:
  16. http://isee.126.com
  17. http://www.vchelp.net
  18. 或:
  19. iseesoft@china.com
  20. 原创人    :Sam (http://go.163.com/~program2000/)
  21. 第二编写人:YZ (http://isee.126.com/  or  yzfree@sina.com)
  22. 文件版本:
  23. Build 00818
  24. Date  2000-8-18
  25. ********************************************************************/
  26. #include "stdafx.h"
  27. #include "GifModule.h"
  28. #ifdef _DEBUG
  29. #undef THIS_FILE
  30. static char THIS_FILE[]=__FILE__;
  31. #define new DEBUG_NEW
  32. #endif
  33. //////////////////////////////////////////////////////////////////////
  34. // Construction/Destruction
  35. //////////////////////////////////////////////////////////////////////
  36. BMPIMAGE::BMPIMAGE()
  37. {
  38. pImageData = NULL;
  39. }
  40. BMPIMAGE::~BMPIMAGE()
  41. {
  42. if (pImageData) GlobalFree(pImageData);
  43. }
  44. /*
  45. CGIF()
  46. {
  47. }
  48. ~CGIF()
  49. {
  50. BMPIMAGE * pBmpImage;
  51. while (!m_ImageList.IsEmpty ())
  52. {
  53. pBmpImage = (BMPIMAGE *) m_ImageList.GetTail ();
  54. m_ImageList.RemoveTail ();
  55. delete pBmpImage;
  56. }
  57. }
  58. */
  59. BOOL LoadGIF(LPCTSTR GifFileName)
  60. {
  61. //将文件内容考到内存中,pFileContent;
  62. CFile file;
  63. if (!file.Open (GifFileName,CFile::modeRead | CFile::typeBinary )) return 0;
  64. PBYTE pFileContent = (PBYTE)GlobalAlloc(GPTR,file.GetLength() + 1);
  65. file.Read (pFileContent,file.GetLength ());
  66. file.Close ();
  67. //Clear 
  68. BMPIMAGE * pBmpImage;
  69. while (!m_ImageList.IsEmpty ())
  70. {
  71. pBmpImage = (BMPIMAGE *) m_ImageList.GetTail ();
  72. m_ImageList.RemoveTail ();
  73. delete pBmpImage;
  74. }
  75. //
  76. //得到有用信息
  77. UINT HeaderSize = AnalizeFileHeader(pFileContent);
  78. /*
  79. if (m_GifInfo.ColorMode == 1)
  80. {
  81. GlobalFree(pFileContent);
  82. return 0;
  83. }
  84. */
  85. m_pDataArea = pFileContent + HeaderSize;
  86. //
  87. m_CurTColorIndex = -1;
  88. m_CurDelayTime = 0;
  89. PBYTE p = m_pDataArea;
  90. UINT  Offset;
  91. while (1)
  92. {
  93. if (p[0] == 0x21 && p[1] == 0xf9 && p[2] == 0x04)
  94. {//图形补充区
  95. Offset = GetGrphContent(p);
  96. p += Offset;
  97. }
  98. else if (p[0] == 0x21 && p[1] == 0x01 && p[2] == 0x0c)
  99. {//文字补充区
  100. Offset = ShowText(p);
  101. p += Offset;
  102. }
  103. else if (p[0] == 0x21 && p[1] == 0xff && p[2] == 0x0b)
  104. {//应用块
  105. Offset = GetAppContent(p);
  106. p += Offset;
  107. }
  108. else if (p[0] == 0x21 && p[1] == 0xfe)
  109. {//注解区
  110.    Offset = GetNoteContent(p);
  111.    p += Offset;
  112. }
  113. else if (p[0] == 0x2c)
  114. {//数据块
  115.    Offset = GetImage(p);
  116.    p += Offset;
  117. }
  118. else break;
  119. }
  120. GlobalFree(pFileContent);
  121. return 1;
  122. }
  123. /***************************************************************************
  124. * AnalizeFileHeader - 获得GIF文件信息
  125. *
  126. * Parameter: PBYTE - 完整的GIF文件数据首指针
  127. *
  128. * Result   : UINT  - GIF文件头结构尺寸
  129. *
  130. ***************************************************************************/
  131. UINT  AnalizeFileHeader(PBYTE pFileContent)
  132. {
  133. GIFHEADER gifHeader; //文件头
  134. memcpy(&gifHeader,pFileContent,sizeof(GIFHEADER));
  135. m_GifInfo.Width  = gifHeader.ScreenWidth ;
  136. m_GifInfo.Height = gifHeader.ScreenHeight ;
  137. //Analize Header
  138. //char radio = (gifHeader.AspectRadio +15)/64;//保留
  139. //得到调色板大小---颜色模式 1,2,3,4,5,6,7,8
  140. m_GifInfo.ColorMode  = (gifHeader.GlobalFlagByte&0x7)+1;
  141. //单个压缩数据初始位数
  142. m_GifInfo.InitPixelBits = m_GifInfo.ColorMode+1;
  143. m_GifInfo.ColorType = 1;
  144. switch (m_GifInfo.ColorMode)
  145. {
  146. case 1:
  147. m_GifInfo.ColorType = m_GifInfo.ColorType << 1;
  148. break;
  149. case 2:
  150. m_GifInfo.ColorType = m_GifInfo.ColorType << 2;
  151. break;
  152. case 3:
  153. m_GifInfo.ColorType = m_GifInfo.ColorType << 3;
  154. break;
  155. case 4:
  156. m_GifInfo.ColorType = m_GifInfo.ColorType << 4;
  157. break;
  158. case 5:
  159. m_GifInfo.ColorType = m_GifInfo.ColorType << 5;
  160. break;
  161. case 6:
  162. m_GifInfo.ColorType = m_GifInfo.ColorType << 6;
  163. break;
  164. case 7:
  165. m_GifInfo.ColorType = m_GifInfo.ColorType << 7;
  166. break;
  167. case 8:
  168. m_GifInfo.ColorType = m_GifInfo.ColorType << 8;
  169. break;
  170. }
  171. if (gifHeader.GlobalFlagByte & 0x80)
  172. //AfxMessageBox("有通用调色板数据!");
  173. //read pal data and save it to BitMap pal
  174. PBYTE p = pFileContent + sizeof(GIFHEADER);
  175. LPGIFRGB pRGB = (LPGIFRGB)p;
  176. for (UINT j = 0; j < m_GifInfo.ColorType ; j ++)
  177. {
  178. m_CurRgbQuad[j].rgbRed       = pRGB->bRed;
  179. m_CurRgbQuad[j].rgbGreen     = pRGB->bGreen;
  180. m_CurRgbQuad[j].rgbBlue      = pRGB->bBlue;
  181. m_CurRgbQuad[j].rgbReserved  = 0;
  182. pRGB++;
  183. }
  184. p += 3 * m_GifInfo.ColorType; //越过调色板
  185. return  sizeof(GIFHEADER)+ 3 * m_GifInfo.ColorType;
  186. }
  187. return sizeof(GIFHEADER);
  188. }
  189. //处理图形控制补充区
  190. UINT GetGrphContent(PBYTE pGrCtrl)
  191. {
  192. GRAPHCTRL GraphCtrl;
  193. memcpy(&GraphCtrl,pGrCtrl,sizeof(GRAPHCTRL));
  194. WORD Flag = GraphCtrl.PackedField;
  195. //保留 Flag = (Flag & 0x1c)>>2;//get 2,3,4 bits
  196. m_CurTColorIndex = -1;
  197. m_CurDelayTime = 0;
  198. if (Flag & 1)
  199. {
  200. m_CurTColorIndex = GraphCtrl.TranColorIndex ;
  201. }
  202. if (Flag & 2)
  203. {
  204. m_CurDelayTime = GraphCtrl.DelayTime ;
  205. }
  206. return sizeof(GRAPHCTRL);
  207. }
  208. //处理文字补充区
  209. UINT ShowText(PBYTE pText)
  210. {
  211. TEXTCTRL TextCtrl;
  212. memcpy(&TextCtrl,pText,sizeof(TEXTCTRL));
  213. return sizeof(TEXTCTRL)+TextCtrl.Data [0] - 256 + 1;
  214. }
  215. //处理应用补充区
  216. UINT GetAppContent(PBYTE pApp)
  217. {
  218. APPCTRL AppCtrl;
  219. memcpy(&AppCtrl,pApp,sizeof(APPCTRL));
  220. return sizeof(APPCTRL)+AppCtrl.Data [0] - 256 + 1;
  221. }
  222. //处理附注补充区
  223. UINT GetNoteContent(PBYTE pNote)
  224. {
  225. NOTEHCTRL NoteCtrl;
  226. memcpy(&NoteCtrl,pNote,sizeof(NOTEHCTRL));
  227. return sizeof(NOTEHCTRL)+NoteCtrl.Data[0] - 256 + 1;
  228. }
  229. UINT GetImage(PBYTE pData)
  230. {
  231. IMAGEDATAINFO ImageData;
  232. memcpy(&ImageData,pData,sizeof(IMAGEDATAINFO));
  233. PBYTE p = pData + sizeof(IMAGEDATAINFO);
  234. UINT PalSize = 0;
  235. m_CurSaveMode = 0;
  236. m_CurX = ImageData.ImageLeft;
  237. m_CurY = ImageData.ImageTop ;
  238. m_CurWidth = ImageData.ImageWidth ;
  239. m_CurHeight = ImageData.ImageHeight;
  240. if (ImageData.LocalFlagByte  & 0x80) //AfxMessageBox("有局部调色板数据!");
  241. LPGIFRGB pRGB = (LPGIFRGB)p;
  242. for (UINT j = 0; j < m_GifInfo.ColorType ; j ++)
  243. {
  244. m_CurRgbQuad[j].rgbRed       = pRGB->bRed;
  245. m_CurRgbQuad[j].rgbGreen     = pRGB->bGreen;
  246. m_CurRgbQuad[j].rgbBlue      = pRGB->bBlue;
  247. m_CurRgbQuad[j].rgbReserved  = 0;
  248. pRGB++;
  249. }
  250. p += 3 * m_GifInfo.ColorType;//pass pal
  251. PalSize = 3 * m_GifInfo.ColorType;
  252. }
  253. else if (ImageData.LocalFlagByte  & 0x40)
  254. {
  255. m_CurSaveMode = 1;
  256. }
  257. UINT InitBits = *p++;//跳过第一字节,进入真正的段落 ;
  258. UINT offset;
  259. UINT dataCount = GetCodeCountOnChar(p,offset);//得到当前区数据总数
  260. PBYTE pCodeData = GetCodeDataOnChar(p);//得到当前区数据内容
  261. //提取真实数据,所有数据存为字符大小
  262. PBYTE pTrueCodeData = GetCodeDataOnBits (pCodeData,m_GifInfo.InitPixelBits,dataCount);
  263. ConvertToBmpImage(pTrueCodeData);
  264. GlobalFree(pCodeData);
  265. GlobalFree(pTrueCodeData);
  266. return sizeof(IMAGEDATAINFO) + offset + PalSize;
  267. }
  268. WORD GetOneCode(PBYTE CodeStr ,UINT CodeStrLen, UINT OffsetChar , UINT OffsetBits, UINT Length)
  269. {
  270. ASSERT (Length <= 12);
  271. BYTE *pValue,*lp = (BYTE*)CodeStr;
  272. UINT value = 0;
  273. pValue = (BYTE *)&value;
  274. pValue[0] = lp[OffsetChar+0];
  275. if (OffsetChar + 1 < CodeStrLen)
  276. pValue[1] = lp[OffsetChar+1];
  277. if (OffsetChar + 2 < CodeStrLen)
  278. pValue[2] = lp[OffsetChar+2];
  279. if (OffsetChar + 3 < CodeStrLen)
  280. pValue[3] = lp[OffsetChar+3];
  281. value = value >> OffsetBits;
  282. value = value << (32 - Length);
  283. value = value >> (32 - Length);
  284. return (WORD)value;
  285. }
  286. UINT GetCodeCountOnChar (PBYTE CodeDataStr,UINT &AllDataLen)
  287. {
  288. UINT dataCount = 0;
  289. BYTE dataLen;
  290. PBYTE p1 = CodeDataStr;
  291. AllDataLen = 0;
  292. while (1)
  293. {
  294. dataLen = *p1 ++;
  295. p1 += dataLen;
  296. dataCount += dataLen;
  297. AllDataLen += (dataLen + 1);
  298. if (dataLen == 0x00) break;
  299. }
  300. AllDataLen ++;
  301. return dataCount;
  302. }
  303. PBYTE GetCodeDataOnChar (PBYTE CodeDataStr)
  304. {
  305. UINT offset;
  306. UINT dataCount = GetCodeCountOnChar(CodeDataStr,offset);
  307. PBYTE pData,p2;
  308. pData = (PBYTE)GlobalAlloc (GPTR,dataCount+1);
  309. p2 = pData;
  310. BYTE dataLen;
  311. PBYTE p1 = CodeDataStr;
  312. while (1)
  313. {
  314. dataLen = *p1 ++;
  315. if (dataLen == 0x00) 
  316. break;
  317. memcpy(p2,p1,dataLen);
  318. p1 += dataLen;
  319. p2 += dataLen;
  320. dataCount += dataLen;
  321. }
  322. return pData;
  323. }
  324. PBYTE  GetCodeDataOnBits (PBYTE CodeDataStr ,UINT InitLen ,UINT &CodeDataLen)
  325. {
  326. PBYTE p = CodeDataStr;
  327. PBYTE pData = (PBYTE ) GlobalAlloc (GPTR ,m_CurWidth*m_CurHeight*2);
  328. PBYTE pTrueData = pData;
  329. int i = 0;
  330. UINT BitsCount = 0;
  331. WORD TCode,s = m_GifInfo.ColorType + 2;//起始的代码值
  332. UINT TableLen,iLen = InitLen;
  333. UINT Pos,index,j = 0;
  334. UINT SrcCodeLEN = CodeDataLen;
  335. while (1)
  336. {
  337. TCode = GetOneCode(p ,CodeDataLen,BitsCount / 8, BitsCount % 8, iLen);
  338. BitsCount += iLen;
  339. if (TCode < m_GifInfo.ColorType)
  340. {
  341. LZWTable[j].Header = TCode;
  342. LZWTable[j].Code   = s ++;
  343. if (j != 0)
  344. {
  345. LZWTable[j - 1].Tail = TCode;
  346. }
  347. j++;
  348. }
  349. else if (TCode > m_GifInfo.ColorType + 1)//为代码
  350. {
  351. if (j == 0) continue;
  352. LZWTable[j].Header = TCode;
  353. LZWTable[j].Code   = s ++;
  354. ASSERT( LZWTable[j].Header < LZWTable[j].Code);
  355. index = j - 1;
  356. Pos = j;
  357. // TRACE("BitsCount = %dn",BitsCount);
  358. // afxDump<<"BitsCount = %d"<<BitsCount;
  359. while (1)
  360. {
  361. Pos = LZWTable[Pos].Header - (m_GifInfo.ColorType + 2) ;
  362. if (LZWTable[Pos].Header < m_GifInfo.ColorType) 
  363. break;
  364. }
  365. LZWTable[index].Tail  = LZWTable[Pos].Header;
  366. j++;
  367. }
  368. else if (TCode == m_GifInfo.ColorType)//清除码
  369. {
  370. iLen = InitLen;
  371. TableLen = j;
  372. j = 0;
  373. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  374. //pData+=TableLen;
  375. s = m_GifInfo.ColorType + 2 ;
  376. }
  377. else if (TCode == m_GifInfo.ColorType + 1) //结束码
  378. {
  379. //end build table
  380. iLen = InitLen;
  381. TableLen = j;
  382. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  383. //pData+=TableLen;
  384. s = m_GifInfo.ColorType + 2;
  385. break;
  386. }
  387. if (s == 3)
  388. iLen = 2;
  389. else if (s == 5)
  390. iLen = 3;
  391. else if (s == 9)
  392. iLen = 4;
  393. else if (s == 17)
  394. iLen = 5;
  395. else if (s == 33)
  396. iLen = 6;
  397. else if (s == 65)
  398. iLen = 7;
  399. else if (s == 129)
  400. iLen  = 8;
  401. else if (s == 257)
  402. iLen  = 9;
  403. else if ( s == 513 ) 
  404. iLen = 10;
  405. else if (s == 1025 ) 
  406. iLen = 11;
  407. else if (s == 2049 ) 
  408. iLen = 12;
  409. if (BitsCount / 8 > SrcCodeLEN)
  410. {
  411. iLen = InitLen;
  412. TableLen = j;
  413. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  414. //pData+=TableLen;
  415. s = m_GifInfo.ColorType + 2;
  416. break;
  417. }
  418. }
  419. CodeDataLen = BitsCount / 8;
  420. return pTrueData;
  421. }
  422. void  GetPartImageDataFromTable(PBYTE &pImage,LZWTABLE * Table,UINT TableLen)
  423. {
  424. UINT i;
  425. PBYTE p = pImage;
  426. WORD *TailStack = new WORD[5200];
  427. int j;
  428. int sp;
  429. for (i = 0 ; i < TableLen; i++)
  430. {
  431. if (Table[i].Header < m_GifInfo.ColorType)
  432. {
  433. *p++ = (BYTE)Table[i].Header ;
  434. }
  435. else
  436. {
  437. sp = 0;
  438. j = Table[i].Header - (m_GifInfo.ColorType + 2);
  439. while (Table[j].Header > m_GifInfo.ColorType + 1)
  440. {
  441. TailStack[sp++] = Table[j].Tail ;
  442. j = Table[j].Header;
  443. j -= (m_GifInfo.ColorType + 2);
  444. ASSERT(sp < 5200);
  445. }
  446. *p++ = (BYTE)Table[j].Header;
  447. *p++ = (BYTE)Table[j].Tail;
  448. sp --;
  449. while (sp >= 0)
  450. {
  451. *p++ = (BYTE)TailStack[sp--];
  452. }
  453. }
  454. }
  455. int len = p - pImage;
  456. pImage = p;
  457. delete []TailStack;
  458. }
  459. BOOL SaveBmp(LPCTSTR BmpFileName,PBYTE pData)
  460. {
  461. BITMAPINFOHEADER BmpInfoHeader;
  462. BITMAPFILEHEADER BmpFileHeader;
  463. BmpFileHeader.bfType = 0x4d42;
  464. BmpFileHeader.bfSize = m_GifInfo.Width*m_GifInfo.Height ;
  465. BmpFileHeader.bfReserved1 = 0;
  466. BmpFileHeader.bfReserved2 = 0;
  467. BmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 4 * m_GifInfo.ColorType;
  468. BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  469. BmpInfoHeader.biWidth = m_CurWidth;
  470. BmpInfoHeader.biHeight = m_CurHeight ;
  471. BmpInfoHeader.biPlanes = 1;
  472. BmpInfoHeader.biBitCount = 8;
  473. BmpInfoHeader.biCompression = BI_RGB;
  474. BmpInfoHeader.biSizeImage = 0;
  475. BmpInfoHeader.biXPelsPerMeter = 0;
  476. BmpInfoHeader.biYPelsPerMeter = 0;
  477. BmpInfoHeader.biClrUsed = 0;
  478. BmpInfoHeader.biClrImportant = 0;
  479. CFile newFile("1.bmp",CFile::typeBinary|CFile::modeWrite|CFile::modeCreate);
  480. newFile.Write(&BmpFileHeader,sizeof(BITMAPFILEHEADER));
  481. newFile.Write(&BmpInfoHeader,sizeof(BITMAPINFOHEADER));
  482. newFile.Write(&m_CurRgbQuad,sizeof(RGBQUAD)*256);
  483. WORD TrueWidth = WIDTHBYTES(m_CurWidth * 8);
  484. newFile.Write(pData,TrueWidth*m_CurHeight);
  485. newFile.Close ();
  486. return 1;
  487. }
  488. BOOL ConvertToBmpImage(PBYTE SrcData)
  489. {
  490. PBYTE p0,p1,p2,pTmp;
  491. PBYTE pSrcData = SrcData;
  492. UINT i,j,k,Step;
  493. if (m_CurSaveMode )//交叉存储
  494. {
  495. pTmp = p2 = (PBYTE)GlobalAlloc(GPTR,m_CurWidth*m_CurHeight);
  496. k = 0; Step = 8;
  497. for (j = 0; j < m_CurHeight  ; j ++)
  498. {
  499. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  500. k += Step;
  501. if (k >= m_CurHeight) break;
  502. }
  503. j++;//每行中存了一个越界值
  504. k = 4; Step = 8;
  505. for (; j < m_CurHeight  ; j ++)
  506. {
  507. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  508. k += Step;
  509. if (k >= m_CurHeight) break;
  510. }
  511. j++;
  512. k = 2; Step = 4;
  513. for (; j < m_CurHeight  ; j ++)
  514. {
  515. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  516. k += Step;
  517. if (k >= m_CurHeight) break;
  518. }
  519. j++;
  520. k = 1; Step = 2;
  521. for (; j < m_CurHeight  ; j ++)
  522. {
  523. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_GifInfo.Width);
  524. k += Step;
  525. if (k >= m_CurHeight) break;
  526. }
  527. pSrcData = p2;
  528. }
  529. BMPIMAGE * pBmpImage = new BMPIMAGE;
  530. pBmpImage->tColor = m_CurTColorIndex;
  531. pBmpImage->DelayTime = m_CurDelayTime;
  532. pBmpImage->Left = m_CurX;
  533. pBmpImage->Top = m_CurY;
  534. pBmpImage->Width = m_CurWidth ;
  535. pBmpImage->Height = m_CurHeight ;
  536. pBmpImage->SaveMode = m_CurSaveMode;
  537. memcpy(&pBmpImage->Palette ,&m_CurRgbQuad,sizeof(RGBQUAD)*256);
  538. WORD TrueWidth = WIDTHBYTES(m_CurWidth * 8);//全转成256显示图片
  539. pBmpImage->pImageData = (PBYTE)GlobalAlloc(GPTR,TrueWidth*m_CurHeight );
  540. p0 = pSrcData;
  541.     p1 = pBmpImage->pImageData;
  542. for (j = 0; j < m_CurHeight  ; j ++)//图形翻转
  543. {
  544. k = (m_CurHeight - j - 1);
  545. for (i = 0 ; i < m_CurWidth ;i ++)
  546. {
  547. p1[ k * TrueWidth + i] = p0[j*m_CurWidth+i];
  548. }
  549. }
  550.  
  551. if (m_CurSaveMode) //交叉存储
  552. {
  553. GlobalFree(pSrcData);
  554. }
  555. m_ImageList.AddTail (pBmpImage);
  556. return 1;
  557. }
  558. /*
  559. BOOL ShowImage(HDC hDC, POINT StartPos, UINT ImageNo)
  560. {
  561. //CDC *pDC = CDC::FromHandle (hDC);
  562. BITMAPINFOHEADER  BmpInfoHeader;
  563. BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  564. BmpInfoHeader.biPlanes = 1;
  565. BmpInfoHeader.biBitCount = 8;
  566. BmpInfoHeader.biCompression = BI_RGB;
  567. BmpInfoHeader.biSizeImage = 0;
  568. BmpInfoHeader.biXPelsPerMeter = 0;
  569. BmpInfoHeader.biYPelsPerMeter = 0;
  570. BmpInfoHeader.biClrUsed = 0;
  571. BmpInfoHeader.biClrImportant = 0;
  572. POSITION Pos;
  573. Pos = m_ImageList.FindIndex(ImageNo);
  574. if (Pos)
  575. {
  576. BMPIMAGE * pBmpImage = (BMPIMAGE *)m_ImageList.GetAt(Pos );
  577. BmpInfoHeader.biWidth = pBmpImage->Width;
  578. BmpInfoHeader.biHeight = pBmpImage->Height;
  579. BITMAPINFO  *pBmInfo = (BITMAPINFO  *)GlobalAlloc(GPTR,sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
  580. memcpy(&pBmInfo->bmiHeader ,&BmpInfoHeader,sizeof(BITMAPINFOHEADER));
  581. memcpy(pBmInfo->bmiColors ,pBmpImage->Palette ,sizeof(RGBQUAD)*256);
  582. if (pBmpImage->tColor >= 0)
  583. {
  584. HDC hMemDC = ::CreateCompatibleDC(hDC);
  585. HBITMAP hBmp = (HBITMAP)::CreateCompatibleBitmap(hDC,pBmpImage->Width,pBmpImage->Height);
  586. HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC,hBmp);
  587. ::StretchDIBits(hMemDC,0 ,0,pBmpImage->Width,pBmpImage->Height,
  588. 0,0,pBmpImage->Width,pBmpImage->Height ,pBmpImage->pImageData,pBmInfo,
  589. DIB_RGB_COLORS,SRCCOPY);
  590. COLORREF cRgb = RGB(pBmpImage->Palette [pBmpImage->tColor].rgbRed,
  591. pBmpImage->Palette [pBmpImage->tColor].rgbGreen,
  592. pBmpImage->Palette [pBmpImage->tColor].rgbBlue );
  593. BitBltEx(hDC,pBmpImage->Left+StartPos.x ,pBmpImage->Top+StartPos.y ,pBmpImage->Width,pBmpImage->Height,hMemDC,0,0 ,cRgb);
  594. ::SelectObject(hMemDC,hOldBmp);
  595. ::DeleteObject(hBmp);
  596. ::DeleteDC(hMemDC);
  597. }
  598. else ::StretchDIBits(hDC,pBmpImage->Left+StartPos.x ,pBmpImage->Top+StartPos.y ,pBmpImage->Width,pBmpImage->Height,
  599. 0,0,pBmpImage->Width,pBmpImage->Height ,pBmpImage->pImageData,pBmInfo,
  600. DIB_RGB_COLORS,SRCCOPY);
  601.  
  602. GlobalFree(pBmInfo);
  603. //SaveBmp("1.bmp",pBmpImage->pImageData);
  604. }
  605. else return 0;
  606. return 1;
  607. }
  608. BOOL BitBltEx(
  609.   HDC hdcDest, // handle to destination device context
  610.   int nXDest,  // x-coordinate of destination rectangle's upper-left 
  611.                // corner
  612.   int nYDest,  // y-coordinate of destination rectangle's upper-left 
  613.                // corner
  614.   int nWidth,  // width of destination rectangle
  615.   int nHeight, // height of destination rectangle
  616.   HDC hdcSrc,  // handle to source device context
  617.   int nXSrc,   // x-coordinate of source rectangle's upper-left 
  618.                // corner
  619.   int nYSrc,   // y-coordinate of source rectangle's upper-left 
  620.   COLORREF cTransparentColor      // corner
  621.    // raster operation code
  622. )
  623. {
  624. HDC hDC1,hDC2;
  625. hDC1 = CreateCompatibleDC( hdcSrc );
  626. hDC2 = CreateCompatibleDC( hdcSrc );
  627. HBITMAP bmp1Old, bmp1 = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  628. bmp1Old = (HBITMAP)SelectObject(hDC1, bmp1);
  629. COLORREF cColor = SetBkColor(hdcSrc, cTransparentColor); 
  630. ::BitBlt(hDC1,0,0,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,SRCCOPY);
  631. HBITMAP bmp2Old, bmp2 = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  632. bmp2Old = (HBITMAP)SelectObject(hDC2, bmp2);
  633. ::BitBlt(hDC2,0,0,nWidth,nHeight,hDC1,0,0,NOTSRCCOPY);
  634. HDC hDC3;
  635. hDC3 = CreateCompatibleDC( hdcSrc );
  636. HBITMAP bmp3Old, bmp3 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  637. bmp3Old = (HBITMAP)SelectObject(hDC3, bmp3);
  638. ::BitBlt(hDC3,0,0,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,SRCCOPY);
  639. ::BitBlt(hDC3,0,0,nWidth,nHeight,hDC2,0,0,SRCAND);
  640. SelectObject(hDC2, bmp2Old);
  641. DeleteObject(bmp2);
  642. DeleteDC(hDC2);
  643. HDC hDC4;
  644. hDC4 = CreateCompatibleDC( hdcSrc );
  645. HBITMAP bmp4Old, bmp4 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  646. bmp4Old = (HBITMAP)SelectObject(hDC4, bmp4);
  647. ::BitBlt(hDC4,0,0,nWidth,nHeight,hdcDest,nXDest,nYDest,SRCCOPY);
  648. ::BitBlt(hDC4,0,0,nWidth,nHeight,hDC1,0,0,SRCAND);
  649. SelectObject(hDC1, bmp1Old);
  650. DeleteObject(bmp1);
  651. DeleteDC(hDC1);
  652. HDC hDC5;
  653. hDC5 = CreateCompatibleDC( hdcSrc );
  654. HBITMAP bmp5Old, bmp5 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  655. bmp5Old = (HBITMAP)SelectObject(hDC5, bmp5);
  656. ::BitBlt(hDC5,0,0,nWidth,nHeight,hDC3,0,0,SRCCOPY);
  657. ::BitBlt(hDC5,0,0,nWidth,nHeight,hDC4,0,0,SRCPAINT);
  658. SelectObject(hDC3, bmp3Old);
  659. DeleteObject(bmp3);
  660. DeleteDC(hDC3);
  661. SelectObject(hDC4, bmp4Old);
  662. DeleteObject(bmp4);
  663. DeleteDC(hDC4);
  664. ::BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hDC5,0,0,SRCCOPY);
  665. SelectObject(hDC5, bmp5Old);
  666. DeleteObject(bmp5);
  667. DeleteDC(hDC5);
  668. return 1;
  669. }
  670. BOOL GetImageInfo(RECT &Rect,COLORREF &tColor ,UINT ImageNo)
  671. {
  672. POSITION Pos;
  673. Pos = m_ImageList.FindIndex(ImageNo);
  674. if (Pos)
  675. {
  676. BMPIMAGE * pBmpImage = (BMPIMAGE *)m_ImageList.GetAt(Pos );
  677. Rect.left = pBmpImage->Left ;
  678. Rect.top =  pBmpImage->Top ;
  679. Rect.right = pBmpImage->Left + pBmpImage->Width ;
  680. Rect.bottom = pBmpImage->Top + pBmpImage->Height ;
  681. tColor = pBmpImage->tColor ;
  682. return 1;
  683. }
  684. else return 0;
  685. }
  686. */