GIFAPI.CPP
上传用户:gdjinyi
上传日期:2013-02-01
资源大小:1701k
文件大小:36k
源码类别:

源码/资料

开发平台:

Visual C++

  1. // ************************************************************************
  2. //  文件名:GIFAPI.cpp
  3. //
  4. //  GIF(Graphics Interchange Format) API函数库:
  5. //
  6. //  DIBToGIF()          - 将指定的DIB对象(< 256色)保存为GIF文件
  7. //  EncodeGIF_LZW() - 对指定图像进行GIF_LZW编码
  8. //  GIF_LZW_WriteCode() - 输出一个编码
  9. //  ReadGIF()           - 读取GIF文件
  10. //  DecodeGIF_LZW()     - 对GIF_LZW编码结果进行解码
  11. //  ReadSrcData()       - 读取GIF_LZW编码
  12. //
  13. // ************************************************************************
  14. #include "stdafx.h"
  15. #include "DIBAPI.h"
  16. #include "GIFAPI.h"
  17. #include <io.h>
  18. #include <errno.h>
  19. #include <math.h>
  20. #include <direct.h>
  21. /*************************************************************************
  22.  *
  23.  * 函数名称:
  24.  *   DIBToGIF()
  25.  *
  26.  * 参数:
  27.  *   LPSTR lpDIB        - 指向DIB对象的指针
  28.  *   CFile& file        - 要保存的文件
  29.  *   BOOL bInterlace - 是否按照交错方式保存
  30.  *
  31.  * 返回值:
  32.  *   BOOL               - 成功返回True,否则返回False。
  33.  *
  34.  * 说明:
  35.  *   该函数将指定的DIB对象(< 256色)保存为GIF文件。
  36.  *
  37.  *************************************************************************/
  38. BOOL WINAPI DIBToGIF(LPSTR lpDIB, CFile& file, BOOL bInterlace)
  39. {
  40. // 循环变量
  41. WORD i;
  42. WORD j;
  43. // DIB高度
  44. WORD wHeight;
  45. // DIB宽度
  46. WORD wWidth;
  47. // 指向DIB象素指针
  48. LPSTR   lpDIBBits;
  49. // GIF文件头
  50. GIFHEADER          GIFH;
  51. // GIF逻辑屏幕描述块
  52. GIFSCRDESC         GIFS;
  53. // GIF图像描述块
  54. GIFIMAGE           GIFI;
  55. // GIF编码参数
  56. GIFC_VAR           GIFCVar;
  57. // 颜色数目
  58. WORD               wColors;
  59. // 每行字节数
  60. WORD               wWidthBytes;
  61. // 调色板
  62. BYTE               byGIF_Pal[768];
  63. // 字节变量
  64. BYTE               byChar;
  65. // 指向BITMAPINFO结构的指针(Win3.0)
  66. LPBITMAPINFO    lpbmi;
  67. // 指向BITMAPCOREINFO结构的指针
  68. LPBITMAPCOREINFO   lpbmc;
  69. // 表明是否是Win3.0 DIB的标记
  70. BOOL    bWinStyleDIB;
  71. // 获取DIB高度
  72. wHeight = (WORD) DIBHeight(lpDIB);
  73. // 获取DIB宽度
  74. wWidth  = (WORD) DIBWidth(lpDIB);
  75. // 找到DIB图像象素起始位置
  76. lpDIBBits = FindDIBBits(lpDIB);
  77. // 给GIFCVar结构赋值
  78. GIFCVar.wWidth     = wWidth;
  79. GIFCVar.wDepth     = wHeight;
  80. GIFCVar.wBits      = DIBBitCount(lpDIB);
  81. GIFCVar.wLineBytes = (WORD)BYTE_WBYTES((DWORD)GIFCVar.wWidth *
  82.    (DWORD)GIFCVar.wBits);
  83. // 计算每行字节数
  84. wWidthBytes = (WORD)DWORD_WBYTES(wWidth * (DWORD)GIFCVar.wBits);
  85. // 计算颜色数目
  86. wColors     = 1 << GIFCVar.wBits;
  87. // 获取指向BITMAPINFO结构的指针(Win3.0)
  88. lpbmi = (LPBITMAPINFO)lpDIB;
  89. // 获取指向BITMAPCOREINFO结构的指针
  90. lpbmc = (LPBITMAPCOREINFO)lpDIB;
  91. // 判断是否是WIN3.0的DIB
  92. bWinStyleDIB = IS_WIN30_DIB(lpDIB);
  93. // 给调色板赋值
  94. if (bWinStyleDIB)
  95. {
  96. j = 0;
  97. for (i = 0; i < wColors; i++)
  98. {
  99. // 读取红色分量
  100. byGIF_Pal[j++] = lpbmi->bmiColors[i].rgbRed;
  101. // 读取绿色分量
  102. byGIF_Pal[j++] = lpbmi->bmiColors[i].rgbGreen;
  103. // 读取蓝色分量
  104. byGIF_Pal[j++] = lpbmi->bmiColors[i].rgbBlue;
  105. }
  106. }
  107. else
  108. {
  109. j = 0;
  110. for (i = 0; i < wColors; i++)
  111. {
  112. // 读取红色分量
  113. byGIF_Pal[j++] = lpbmc->bmciColors[i].rgbtRed;
  114. // 读取绿色分量
  115. byGIF_Pal[j++] = lpbmc->bmciColors[i].rgbtGreen;
  116. // 读取红色分量
  117. byGIF_Pal[j++] = lpbmc->bmciColors[i].rgbtBlue;
  118. }
  119. }
  120. ////////////////////////////////////////////////////////////////////////////////////////
  121. // 开始写GIF文件
  122. // 写GIF文件头
  123. GIFH.bySignature[0] = 'G';
  124. GIFH.bySignature[1] = 'I';
  125. GIFH.bySignature[2] = 'F';
  126. GIFH.byVersion[0]='8';
  127. GIFH.byVersion[1]='9';
  128. GIFH.byVersion[2]='a';
  129. file.Write((LPSTR)&GIFH, 6);
  130. // 写GIF逻辑屏幕描述块
  131. GIFS.wWidth               = GIFCVar.wWidth;
  132. GIFS.wDepth               = GIFCVar.wDepth;
  133. GIFS.GlobalFlag.PalBits   = (BYTE)(GIFCVar.wBits - 1);
  134. GIFS.GlobalFlag.SortFlag  = 0x00;
  135. GIFS.GlobalFlag.ColorRes  = (BYTE)(GIFCVar.wBits - 1);
  136. GIFS.GlobalFlag.GlobalPal = 0x01;
  137. GIFS.byBackground         = 0x00;
  138. GIFS.byAspect             = 0x00;
  139. file.Write((LPSTR)&GIFS, 7);
  140. // 写GIF全局调色板
  141. file.Write((LPSTR)byGIF_Pal,(wColors*3));
  142. // 写GIF图像描述间隔符
  143. byChar      = 0x2C;
  144. file.Write((LPSTR)&byChar,1);
  145. // 写GIF图像描述块
  146. GIFI.wLeft                = 0;
  147. GIFI.wTop                 = 0;
  148. GIFI.wWidth               = GIFCVar.wWidth;
  149. GIFI.wDepth               = GIFCVar.wDepth;
  150. GIFI.LocalFlag.PalBits    = 0x00;
  151. GIFI.LocalFlag.Reserved   = 0x00;
  152. GIFI.LocalFlag.SortFlag   = 0x00;
  153. GIFI.LocalFlag.Interlace  = (BYTE)(bInterlace ? 0x01 : 0x00);
  154. GIFI.LocalFlag.LocalPal   = 0x00;
  155. file.Write((LPSTR)&GIFI, 9);
  156. // 写GIF图像压缩数据
  157. HANDLE hSrcBuff = GlobalAlloc(GHND,(DWORD)MAX_BUFF_SIZE);
  158. GIFCVar.lpDataBuff = (LPSTR)GlobalLock(hSrcBuff);
  159. GIFCVar.lpEndBuff  = GIFCVar.lpDataBuff;
  160. GIFCVar.dwTempCode = 0UL;
  161. GIFCVar.wByteCnt   = 0;
  162. GIFCVar.wBlockNdx  = 1;
  163. GIFCVar.byLeftBits = 0x00;
  164. // 进行GIF_LZW编码
  165. EncodeGIF_LZW(lpDIBBits, file, &GIFCVar,wWidthBytes, bInterlace);
  166. // 判断是否编码成功
  167. if (GIFCVar.wByteCnt)
  168. {
  169. // 写入文件
  170. file.Write(GIFCVar.lpDataBuff, GIFCVar.wByteCnt);
  171. }
  172. // 释放内存
  173. GlobalUnlock(hSrcBuff);
  174. GlobalFree(hSrcBuff);
  175. // 写GIF Block Terminator
  176. byChar   = 0x00;
  177. file.Write((LPSTR)&byChar,1);
  178. // 写GIF文件结尾块
  179. byChar   = 0x3B;
  180. file.Write((LPSTR)&byChar,1);
  181. // 返回
  182. return TRUE;
  183. }
  184. /*************************************************************************
  185.  *
  186.  * 函数名称:
  187.  *   EncodeGIF_LZW()
  188.  *
  189.  * 参数:
  190.  *   LPSTR lpDIBBits - 指向源DIB图像指针
  191.  *   CFile& file - 要保存的文件
  192.  *   LPGIFC_VAR lpGIFCVar - 指向GIFC_VAR结构的指针
  193.  *  WORD wWidthBytes - 每行图像字节数
  194.  *  BOOL bInterlace - 是否按照交错方式保存
  195.  *
  196.  * 返回值:
  197.  *   无
  198.  *
  199.  * 说明:
  200.  *   该函数对指定图像进行GIF_LZW编码。
  201.  *
  202.  *************************************************************************/
  203. void WINAPI EncodeGIF_LZW(LPSTR lpDIBBits, CFile& file, 
  204.   LPGIFC_VAR lpGIFCVar,WORD wWidthBytes, BOOL bInterlace)
  205. {
  206. // 内存分配句柄
  207. HANDLE hTableNdx;
  208. HANDLE hPrefix;
  209. HANDLE hSuffix;
  210. // 指向字串表指针
  211. LPWORD lpwTableNdx;
  212. // 用于字串表搜索的索引
  213. LPWORD lpwPrefix;
  214. LPBYTE lpbySuffix;
  215. // 指向当前编码像素的指针
  216. LPSTR  lpImage;
  217. // 计算当前数据图像的偏移量
  218. DWORD  dwDataNdx;
  219. // LZW_CLEAR
  220. WORD   wLZW_CLEAR;
  221. // LZW_EOI
  222. WORD   wLZW_EOI;
  223. // LZW_MinCodeLen
  224. BYTE   byLZW_MinCodeLen;
  225. // 字串表索引
  226. WORD   wPreTableNdx;
  227. WORD   wNowTableNdx;
  228. WORD   wTopTableNdx;
  229. // 哈希表索引
  230. WORD   wHashNdx;
  231. WORD   wHashGap;
  232. WORD   wPrefix;
  233. WORD   wShiftBits;
  234. // 当前图像的行数
  235. WORD   wRowNum;
  236. WORD   wWidthCnt;
  237. // 循环变量
  238. WORD   wi;
  239. WORD   wj;
  240. // 交错方式存储时每次增加的行数
  241. WORD   wIncTable[5]  = { 8,8,4,2,0 }; 
  242. // 交错方式存储时起始行数
  243. WORD   wBgnTable[5]  = { 0,4,2,1,0 }; 
  244. BOOL   bStart;
  245. BYTE   bySuffix;
  246. BYTE   bySubBlock[256];
  247. BYTE   byCurrentBits;
  248. BYTE   byMask;
  249. BYTE   byChar;
  250. BYTE   byPass;
  251. // 临时字节变量
  252. BYTE   byTemp;
  253. // 给字串表分配内存
  254. hTableNdx        = GlobalAlloc(GHND,(DWORD)(MAX_HASH_SIZE<<1));
  255. hPrefix          = GlobalAlloc(GHND,(DWORD)(MAX_HASH_SIZE<<1));
  256. hSuffix          = GlobalAlloc(GHND,(DWORD)MAX_HASH_SIZE);
  257. // 锁定内存
  258. lpwTableNdx      = (LPWORD)GlobalLock(hTableNdx);
  259. lpwPrefix        = (LPWORD)GlobalLock(hPrefix);
  260. lpbySuffix       = (LPBYTE)GlobalLock(hSuffix);
  261. // 计算LZW_MinCodeLen
  262. byLZW_MinCodeLen = (BYTE)((lpGIFCVar->wBits>1) ? lpGIFCVar->wBits : 0x02);
  263. // 写GIF LZW最小代码大小
  264. file.Write((LPSTR)&byLZW_MinCodeLen,1);
  265. wRowNum          = 0;
  266. bStart           = TRUE;
  267. byPass           = 0x00;
  268. // 计算LZW_CLEAR
  269. wLZW_CLEAR       = 1 << byLZW_MinCodeLen;
  270. // 计算LZW_EOI
  271. wLZW_EOI         = wLZW_CLEAR + 1;
  272. // 初始化字串表
  273. byCurrentBits    = byLZW_MinCodeLen + (BYTE)0x01;
  274. wNowTableNdx     = wLZW_CLEAR + 2;
  275. wTopTableNdx     = 1 << byCurrentBits;
  276. for(wi=0; wi<MAX_HASH_SIZE; wi++)
  277. {
  278. // 初始化为0xFFFF
  279. *(lpwTableNdx+wi) = 0xFFFF;
  280. }
  281. // 输出LZW_CLEAR
  282. GIF_LZW_WriteCode(file, wLZW_CLEAR, (LPSTR)bySubBlock,
  283.   &byCurrentBits, lpGIFCVar);
  284. // 逐行编码
  285. for(wi=0; wi<lpGIFCVar->wDepth; wi++)
  286. {
  287. // 计算当前偏移量
  288. dwDataNdx  = (DWORD)(lpGIFCVar->wDepth - 1 - wRowNum) * (DWORD)wWidthBytes;
  289. // 指向当前行图像的指针
  290. lpImage    = (LPSTR) (((BYTE*)lpDIBBits) + dwDataNdx);
  291. wWidthCnt  = 0;
  292. wShiftBits = 8 - lpGIFCVar->wBits;
  293. byMask     = (BYTE)((lpGIFCVar->wBits==1) ? 0x80 : 0xF0);
  294. if (bStart)
  295. {
  296. // 判断是否是256色位图(一个像素一字节)
  297. if (lpGIFCVar->wBits==8)
  298. {
  299. // 256色,直接赋值即可
  300. byTemp      = *lpImage++;
  301. }
  302. else
  303. {
  304. // 非256色,需要移位获取像素值
  305. wShiftBits  = 8 - lpGIFCVar->wBits;
  306. byMask      = (BYTE)((lpGIFCVar->wBits==1) ? 0x80 : 0xF0);
  307. byTemp      = (BYTE)((*lpImage & byMask) >> wShiftBits);
  308. byMask    >>= lpGIFCVar->wBits;
  309. wShiftBits -= lpGIFCVar->wBits;
  310. }
  311. wPrefix    = (WORD)byTemp;
  312. bStart     = FALSE;
  313. wWidthCnt ++;
  314. }
  315. // 每行编码
  316. while(wWidthCnt < lpGIFCVar->wWidth)
  317. {
  318. // 判断是否是256色位图(一个像素一字节)
  319. if (lpGIFCVar->wBits==8)
  320. {
  321. // 256色,直接赋值即可
  322. byTemp = *lpImage++;
  323. }
  324. else
  325. {
  326. // 非256色,需要移位获取像素值
  327. byChar = *lpImage;
  328. byTemp = (BYTE)((byChar & byMask) >> wShiftBits);
  329. if (wShiftBits)
  330. {
  331. byMask    >>= lpGIFCVar->wBits;
  332. wShiftBits -= lpGIFCVar->wBits;
  333. }
  334. else
  335. {
  336. wShiftBits  = 8 - lpGIFCVar->wBits;
  337. byMask      = (BYTE)((lpGIFCVar->wBits==1) ? 0x80 : 0xF0);
  338. lpImage    ++;
  339. }
  340. }
  341. bySuffix   = byTemp;
  342. wWidthCnt ++;
  343. // 查找当前字符串是否存在于字串表中
  344. wHashNdx = wPrefix ^ ((WORD)bySuffix << 4);
  345. wHashGap = (wHashNdx ? (MAX_HASH_SIZE - wHashNdx) : 1);
  346. // 判断当前字符串是否在字串表中
  347. while(TRUE)
  348. {
  349. // 当前字符串不在字串表中
  350. if (*(lpwTableNdx + wHashNdx) == 0xFFFF)
  351. {
  352.    // 新字符串,退出循环
  353.    break;
  354. }
  355. // 判断是否找到该字符串
  356. if ((*(lpwPrefix+wHashNdx)  == wPrefix) &&
  357. (*(lpbySuffix+wHashNdx) == bySuffix))
  358. {
  359. // 找到,退出循环
  360. break;
  361. }
  362. // 第二哈希表
  363. if (wHashNdx < wHashGap)
  364. {
  365. wHashNdx += MAX_HASH_SIZE;
  366. }
  367. wHashNdx -= wHashGap;
  368. }
  369. // 判断是否是新字符串
  370. if (*(lpwTableNdx+wHashNdx) != 0xFFFF)
  371. {
  372. // 不是新字符串
  373. wPrefix = *(lpwTableNdx + wHashNdx);
  374.  }
  375.  else
  376.  {
  377. // 新字符串
  378. // 输出该编码
  379. GIF_LZW_WriteCode(file,wPrefix,(LPSTR)bySubBlock,
  380.    &byCurrentBits,lpGIFCVar);
  381. // 将该新字符串添加到字串表中
  382. wPreTableNdx = wNowTableNdx;
  383. // 判断是否达到最大字串表大小
  384. if (wNowTableNdx < MAX_TABLE_SIZE)
  385. {
  386. *(lpwTableNdx+wHashNdx) = wNowTableNdx++;
  387. *(lpwPrefix+wHashNdx)   = wPrefix;
  388. *(lpbySuffix+wHashNdx)  = bySuffix;
  389. }
  390. if (wPreTableNdx == wTopTableNdx)
  391. {
  392. if (byCurrentBits<12)
  393. {
  394. byCurrentBits ++;
  395. wTopTableNdx <<= 1;
  396. }
  397. else
  398. {
  399. // 字串表到达最大长度
  400. // 输出LZW_CLEAR
  401. GIF_LZW_WriteCode(file, wLZW_CLEAR, (LPSTR)bySubBlock,
  402.  &byCurrentBits,lpGIFCVar);
  403. // 重新初始化字串表
  404. byCurrentBits    = byLZW_MinCodeLen + (BYTE)0x01;
  405. wLZW_CLEAR       = 1 << byLZW_MinCodeLen;
  406. wLZW_EOI         = wLZW_CLEAR + 1;
  407. wNowTableNdx     = wLZW_CLEAR + 2;
  408. wTopTableNdx     = 1 << byCurrentBits;
  409. for(wj=0;wj<MAX_HASH_SIZE;wj++)
  410. {
  411. // 初始化为0xFFFF
  412. *(lpwTableNdx+wj) = 0xFFFF;
  413. }
  414. }
  415. }
  416. wPrefix = (WORD)bySuffix;
  417. }
  418. }
  419. // 判断是否是交错方式
  420. if (bInterlace)
  421. {
  422. // 交错方式,计算下一行位置
  423. wRowNum += wIncTable[byPass];
  424. if (wRowNum>=lpGIFCVar->wDepth)
  425. {
  426. byPass ++;
  427. wRowNum = wBgnTable[byPass];
  428. }
  429. }
  430. else
  431. {
  432. // 非交错方式,直接将行数加一即可
  433. wRowNum ++;
  434. }
  435. }
  436. // 输出当前编码
  437. GIF_LZW_WriteCode(file, wPrefix, (LPSTR)bySubBlock,
  438.   &byCurrentBits,lpGIFCVar);
  439. // 输出LZW_EOI
  440. GIF_LZW_WriteCode(file,wLZW_EOI,(LPSTR)bySubBlock,
  441.   &byCurrentBits,lpGIFCVar);
  442. if (lpGIFCVar->byLeftBits)
  443. {
  444. // 加入该字符
  445. bySubBlock[lpGIFCVar->wBlockNdx++] = (BYTE)lpGIFCVar->dwTempCode;
  446. // 判断是否超出MAX_SUBBLOCK_SIZE
  447. if (lpGIFCVar->wBlockNdx > MAX_SUBBLOCK_SIZE)
  448. {
  449. // 判断wByteCnt + 256是否超过MAX_BUFF_SIZE
  450. if ((lpGIFCVar->wByteCnt + 256) >= MAX_BUFF_SIZE)
  451. {
  452. // 输出
  453. file.Write(lpGIFCVar->lpDataBuff,
  454.   lpGIFCVar->wByteCnt);
  455. lpGIFCVar->lpEndBuff = lpGIFCVar->lpDataBuff;
  456. lpGIFCVar->wByteCnt  = 0;
  457. }
  458. bySubBlock[0]           = (BYTE)(lpGIFCVar->wBlockNdx - 1);
  459. memcpy(lpGIFCVar->lpEndBuff,(LPSTR)bySubBlock,lpGIFCVar->wBlockNdx);
  460. lpGIFCVar->lpEndBuff   += lpGIFCVar->wBlockNdx;
  461. lpGIFCVar->wByteCnt    += lpGIFCVar->wBlockNdx;
  462. lpGIFCVar->wBlockNdx    = 1;
  463. }
  464. lpGIFCVar->dwTempCode = 0UL;
  465. lpGIFCVar->byLeftBits = 0x00;
  466. }
  467. if (lpGIFCVar->wBlockNdx > 1)
  468. {
  469. // 判断wByteCnt + 256是否超过MAX_BUFF_SIZE
  470. if ((lpGIFCVar->wByteCnt + 256) >= MAX_BUFF_SIZE)
  471. {
  472. // 输出
  473. file.Write(lpGIFCVar->lpDataBuff,
  474.    lpGIFCVar->wByteCnt);
  475. lpGIFCVar->lpEndBuff = lpGIFCVar->lpDataBuff;
  476. lpGIFCVar->wByteCnt  = 0;
  477. }
  478. bySubBlock[0]           = (BYTE)(lpGIFCVar->wBlockNdx - 1);
  479. memcpy(lpGIFCVar->lpEndBuff,(LPSTR)bySubBlock,lpGIFCVar->wBlockNdx);
  480. lpGIFCVar->lpEndBuff   += lpGIFCVar->wBlockNdx;
  481. lpGIFCVar->wByteCnt    += lpGIFCVar->wBlockNdx;
  482. lpGIFCVar->wBlockNdx    = 1;
  483. }
  484. // 解除锁定
  485. GlobalUnlock(hTableNdx);
  486. GlobalUnlock(hPrefix);
  487. GlobalUnlock(hSuffix);
  488. // 释放内存
  489. GlobalFree(hTableNdx);
  490. GlobalFree(hPrefix);
  491. GlobalFree(hSuffix);
  492. // 退出
  493. return;
  494. }
  495. /*************************************************************************
  496.  *
  497.  * 函数名称:
  498.  *   GIF_LZW_WriteCode()
  499.  *
  500.  * 参数:
  501.  *   CFile& file - 要保存的文件
  502.  *  WORD wCode - 要添加的编码
  503.  *   LPSTR lpSubBlock - 子块
  504.  *  LPBYTE lpbyCurrentBits - 当前位数
  505.  *  LPGIFC_VAR lpGIFCVar - 指向GIFC_VAR结构的指针
  506.  *
  507.  * 返回值:
  508.  *   无
  509.  *
  510.  * 说明:
  511.  *   该函数用来输出一个编码。
  512.  *
  513.  *************************************************************************/
  514. void WINAPI GIF_LZW_WriteCode(CFile& file, WORD wCode, LPSTR lpSubBlock,
  515.                               LPBYTE lpbyCurrentBits,LPGIFC_VAR lpGIFCVar)
  516. {
  517. // 输出该编码
  518. lpGIFCVar->dwTempCode |= ((DWORD)wCode << lpGIFCVar->byLeftBits);
  519. lpGIFCVar->byLeftBits += (*lpbyCurrentBits);
  520. while(lpGIFCVar->byLeftBits >= 0x08)
  521. {
  522. lpSubBlock[lpGIFCVar->wBlockNdx++] = (BYTE)lpGIFCVar->dwTempCode;
  523.       
  524. // 判断是否超出MAX_SUBBLOCK_SIZE
  525. if (lpGIFCVar->wBlockNdx > MAX_SUBBLOCK_SIZE)
  526. {
  527. // 判断wByteCnt + 256是否超过MAX_BUFF_SIZE
  528. if ((lpGIFCVar->wByteCnt + 256) >= MAX_BUFF_SIZE)
  529. {
  530. // 输出
  531. file.Write(lpGIFCVar->lpDataBuff,
  532. lpGIFCVar->wByteCnt);
  533.             lpGIFCVar->lpEndBuff = lpGIFCVar->lpDataBuff;
  534.         lpGIFCVar->wByteCnt  = 0;
  535. }
  536. lpSubBlock[0]           = (BYTE)(lpGIFCVar->wBlockNdx - 1);
  537. memcpy(lpGIFCVar->lpEndBuff,lpSubBlock,lpGIFCVar->wBlockNdx);
  538. lpGIFCVar->lpEndBuff   += lpGIFCVar->wBlockNdx;
  539. lpGIFCVar->wByteCnt    += lpGIFCVar->wBlockNdx;
  540. lpGIFCVar->wBlockNdx    = 1;
  541. }
  542. lpGIFCVar->dwTempCode >>= 8;
  543. lpGIFCVar->byLeftBits  -= 0x08;
  544. }
  545. // 返回
  546. return;
  547. }
  548. /*************************************************************************
  549.  *
  550.  * 函数名称:
  551.  *   ReadGIF()
  552.  *
  553.  * 参数:
  554.  *   CFile& file        - 要读取的文件
  555.  *
  556.  * 返回值:
  557.  *   HDIB               - 成功返回DIB的句柄,否则返回NULL。
  558.  *
  559.  * 说明:
  560.  *   该函数将读取指定的GIF文件。将读取的结果保存在一个未压缩
  561.  * 编码的DIB对象中。
  562.  *
  563.  *************************************************************************/
  564. HDIB WINAPI ReadGIF(CFile& file)
  565. {
  566. // DIB句柄
  567. HDIB    hDIB;
  568. // DIB指针
  569. LPSTR    pDIB;
  570. // 指向DIB像素的指针
  571. LPSTR    lpDIBBits;
  572. // 指向BITMAPINFOHEADER的指针
  573. LPBITMAPINFOHEADER lpBIH;
  574. // 指向BITMAPINFO的指针
  575. LPBITMAPINFO       lpBI;
  576. // GIF文件头
  577. GIFHEADER          GIFH;
  578. // GIF逻辑屏幕描述块
  579. GIFSCRDESC         GIFS;
  580. // GIF图像描述块
  581. GIFIMAGE           GIFI;
  582. // GIF图像控制扩充块
  583. GIFCONTROL         GIFC;
  584. // GIF图像说明扩充块
  585. GIFPLAINTEXT       GIFP;
  586. // GIF应用程序扩充块
  587. GIFAPPLICATION     GIFA;
  588. // GIF编码参数
  589. GIFD_VAR           GIFDVar;
  590. // 颜色数目
  591. WORD               wColors;
  592. // 每行字节数
  593. WORD               wWidthBytes;
  594. // 调色板
  595. BYTE               byGIF_Pal[768];
  596. // 16色系统调色板
  597. BYTE               bySysPal16[48] = { 0,   0,   0,   0,   0, 128,
  598. 0, 128,   0,   0, 128, 128,
  599.   128,   0,   0, 128,   0, 128,
  600.   128, 128,   0, 128, 128, 128,
  601.   192, 192, 192,   0,   0, 255,
  602. 0, 255,   0,   0, 255, 255,
  603.   255,   0,   0, 255,   0, 255,
  604.   255, 255,   0, 255, 255, 255
  605.    };
  606. // DIB大小(字节数)
  607. DWORD              dwDIB_Size;
  608. // 调色板大小(字节数)
  609. WORD               wPalSize;
  610. // 字节变量
  611. BYTE               byTemp;
  612. // 内存句柄
  613. HANDLE    hSrcBuff;
  614. HANDLE             hTemp;
  615. // 内存指针
  616. LPSTR              lpTemp;
  617. // 字变量
  618. WORD               wTemp;
  619. // 循环变量
  620. WORD               wi;
  621. // 标签
  622. BYTE               byLabel;
  623. // 块大小
  624. BYTE               byBlockSize;
  625. // 读取GIF文件头
  626. file.Read((LPSTR)&GIFH, sizeof(GIFH));
  627. // 判断是否是GIF文件
  628. if (memicmp((LPSTR)GIFH.bySignature,"GIF",3) != 0)
  629. {
  630. // 非GIF文件,返回NULL
  631. return NULL;
  632. }
  633. // 判断版本号是否正确
  634. if ((memicmp((LPSTR)GIFH.byVersion,"87a",3) != 0) &&
  635. (memicmp((LPSTR)GIFH.byVersion,"89a",3) != 0))
  636. {
  637. // 不支持该版本,返回NULL
  638. return NULL;
  639. }
  640. // 读取GIF逻辑屏幕描述块
  641. file.Read((LPSTR)&GIFS, 7);
  642. // 获取调色板的位数
  643. GIFDVar.wBits = (WORD)GIFS.GlobalFlag.PalBits + 1;
  644. // 判断是否有全局调色板
  645. if (GIFS.GlobalFlag.GlobalPal)
  646. {
  647. // 赋初值
  648. memset((LPSTR)byGIF_Pal,0,768);
  649. // 全局调色板大小
  650. wPalSize = 3 * (1 << GIFDVar.wBits);
  651. // 读取全局调色板
  652. file.Read((LPSTR)byGIF_Pal,wPalSize);
  653. }
  654. // 读取下一个字节
  655. file.Read((LPSTR)&byTemp,1);
  656. // 对每一个描述块循环
  657. while(TRUE)
  658. {
  659. // 判断是否是图像描述块
  660. if (byTemp == 0x2C)
  661. {
  662. // 是图像描述块,退出循环
  663. break;
  664. }
  665. // 判断是否是GIF扩展块
  666. if (byTemp==0x21)
  667. {
  668. // 是GIF扩展块
  669. // 分配内存
  670. hTemp  = GlobalAlloc(GHND,(DWORD)MAX_BUFF_SIZE);
  671. // 锁定内存
  672. lpTemp = (LPSTR) GlobalLock(hTemp);
  673. // 读取下一个字节
  674. file.Read((LPSTR)&byLabel, 1);
  675. // 针对各种扩充块,进行分别处理
  676. switch(byLabel)
  677. {
  678. case 0xF9:
  679. {
  680. // 图像控制扩充块
  681. file.Read((LPSTR)&GIFC, 6);
  682. // 跳出
  683. break;
  684. }
  685. case 0x01:
  686. {
  687. // 图像说明扩充块
  688. file.Read((LPSTR)&GIFP,sizeof(GIFP));
  689. // 读取扩充块大小
  690. file.Read((LPSTR)&byBlockSize,1);
  691. // 当byBlockSize > 0时循环读取
  692. while(byBlockSize)
  693. {
  694. // 读取图像说明扩充块(这里没有进行任何处理)
  695. file.Read(lpTemp,byBlockSize);
  696. // 读取扩充块大小
  697. file.Read((LPSTR)&byBlockSize,1);
  698. }
  699. // 跳出
  700. break;
  701. }
  702. case 0xFE:
  703. {
  704. // 注释说明扩充块
  705. // 读取扩充块大小
  706. file.Read((LPSTR)&byBlockSize,1);
  707. // 当byBlockSize > 0时循环读取
  708. while(byBlockSize)
  709. {
  710. // 读取注释说明扩充块(这里没有进行任何处理)
  711. file.Read(lpTemp,byBlockSize);
  712. // 读取扩充块大小
  713. file.Read((LPSTR)&byBlockSize,1);
  714. }
  715. // 跳出
  716. break;
  717. }
  718. case 0xFF:
  719. {
  720. // 应用程序扩充块
  721. file.Read((LPSTR)&GIFA, sizeof(GIFA));
  722. // 读取扩充块大小
  723. file.Read((LPSTR)&byBlockSize,1);
  724. // 当byBlockSize > 0时循环读取
  725. while(byBlockSize)
  726. {
  727. // 读取应用程序扩充块(这里没有进行任何处理)
  728. file.Read(lpTemp,byBlockSize);
  729. // 读取扩充块大小
  730. file.Read((LPSTR)&byBlockSize,1);
  731. }
  732. // 跳出
  733. break;
  734. }
  735. default:
  736. {
  737. // 忽略未知的扩充块
  738. // 读取扩充块大小
  739. file.Read((LPSTR)&byBlockSize,1);
  740. // 当byBlockSize > 0时循环读取
  741. while(byBlockSize)
  742. {
  743. // 读取未知的扩充块(这里没有进行任何处理)
  744. file.Read(lpTemp,byBlockSize);
  745. // 读取扩充块大小
  746. file.Read((LPSTR)&byBlockSize,1);
  747. }
  748. // 跳出
  749. break;
  750. }
  751. // 释放内存
  752. GlobalUnlock(hTemp);
  753. GlobalFree(hTemp);
  754. }
  755. }
  756. // 读取下一个字节
  757. file.Read((LPSTR)&byTemp,1);
  758. }
  759. // 读取GIF图像描述块
  760. file.Read((LPSTR)&GIFI, 9);
  761. // 获取图像宽度
  762. GIFDVar.wWidth         = GIFI.wWidth;
  763. // 获取图像高度
  764. GIFDVar.wDepth         = GIFI.wDepth;
  765. // 判断是否有区域调色板
  766. if (GIFI.LocalFlag.LocalPal)
  767. {
  768. // 赋初值
  769. memset((LPSTR)byGIF_Pal, 0, 768);
  770. // 读取区域调色板位数
  771. GIFDVar.wBits = (WORD)GIFI.LocalFlag.PalBits + 1;
  772. // 区域调色板大小
  773. wPalSize      = 3 * (1 << GIFDVar.wBits);
  774. // 读取区域调色板
  775. file.Read((LPSTR)byGIF_Pal,wPalSize);
  776. }
  777. // 给GIFDVar成员赋值
  778. GIFDVar.wBits          = ((GIFDVar.wBits==1) ? 1 :
  779.   (GIFDVar.wBits<=4) ? 4 : 8);
  780. GIFDVar.wLineBytes     = (WORD)BYTE_WBYTES((DWORD)GIFDVar.wWidth *
  781.    (DWORD)GIFDVar.wBits);
  782. GIFDVar.bEOF           = FALSE;
  783. // 交错方式
  784. GIFDVar.bInterlace     = (GIFI.LocalFlag.Interlace ? TRUE : FALSE);
  785. // 每行字节数
  786. wWidthBytes    = (WORD)DWORD_WBYTES((DWORD)GIFDVar.wWidth *
  787.    (DWORD)GIFDVar.wBits);
  788. // 颜色数目
  789. wColors    = 1 << GIFDVar.wBits;
  790. // 调色板大小
  791. wPalSize    = wColors * sizeof(RGBQUAD);
  792. // 计算DIB长度(字节)
  793. dwDIB_Size    = sizeof(BITMAPINFOHEADER) + wPalSize
  794.  + GIFDVar.wDepth * wWidthBytes;
  795. // 为DIB分配内存
  796. hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIB_Size);
  797. if (hDIB == 0)
  798. {
  799. // 内存分配失败,返回NULL。
  800. return NULL;
  801. }
  802. // 锁定
  803. pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  804. ///////////////////////////////////////////////////////////////////////////
  805. // 设置BITMAPINFOHEADER
  806. // 赋值
  807. lpBIH = (LPBITMAPINFOHEADER) pDIB;
  808. lpBI  = (LPBITMAPINFO) pDIB;
  809. // 给lpBIH成员赋值
  810. lpBIH->biSize = (DWORD)sizeof(BITMAPINFOHEADER);
  811. lpBIH->biWidth = (DWORD)GIFDVar.wWidth;
  812. lpBIH->biHeight = (DWORD)GIFDVar.wDepth;
  813. lpBIH->biPlanes = 1;
  814. lpBIH->biBitCount = GIFDVar.wBits;
  815. lpBIH->biCompression = BI_RGB;
  816. lpBIH->biSizeImage = (DWORD)wWidthBytes * GIFDVar.wDepth;
  817. lpBIH->biXPelsPerMeter = 0;
  818. lpBIH->biYPelsPerMeter = 0;
  819. lpBIH->biClrUsed = wColors;
  820. lpBIH->biClrImportant = 0;
  821. ///////////////////////////////////////////////////////////////////////////
  822. // 设置调色板
  823. // 判断是否指定全局或区域调色板
  824. if (GIFS.GlobalFlag.GlobalPal || GIFI.LocalFlag.LocalPal)
  825. {
  826. wTemp = 0;
  827. for(wi=0; wi<wColors; wi++)
  828. {
  829. lpBI->bmiColors[wi].rgbRed      = byGIF_Pal[wTemp++];
  830. lpBI->bmiColors[wi].rgbGreen    = byGIF_Pal[wTemp++];
  831. lpBI->bmiColors[wi].rgbBlue     = byGIF_Pal[wTemp++];
  832. lpBI->bmiColors[wi].rgbReserved = 0x00;
  833. }
  834. }
  835. else
  836. {
  837. // 没有指定全局和区域调色板,采用系统调色板
  838. // 按照颜色数目来分别给调色板赋值
  839. switch(wColors)
  840. {
  841. case   2:
  842. {
  843. // 单色位图
  844. lpBI->bmiColors[0].rgbRed          = 0x00;
  845. lpBI->bmiColors[0].rgbGreen        = 0x00;
  846. lpBI->bmiColors[0].rgbBlue         = 0x00;
  847. lpBI->bmiColors[0].rgbReserved     = 0x00;
  848. lpBI->bmiColors[1].rgbRed          = 0xFF;
  849. lpBI->bmiColors[1].rgbGreen        = 0xFF;
  850. lpBI->bmiColors[1].rgbBlue         = 0xFF;
  851. lpBI->bmiColors[1].rgbReserved     = 0x00;
  852. // 跳出
  853. break;
  854. }
  855. case  16:
  856. {
  857. // 16色位图
  858. wTemp = 0;
  859. for(wi=0;wi<wColors;wi++)
  860. {
  861. lpBI->bmiColors[wi].rgbRed      = bySysPal16[wTemp++];
  862. lpBI->bmiColors[wi].rgbGreen    = bySysPal16[wTemp++];
  863. lpBI->bmiColors[wi].rgbBlue     = bySysPal16[wTemp++];
  864. lpBI->bmiColors[wi].rgbReserved = 0x00;
  865. }
  866. // 跳出
  867. break;
  868. }
  869. case 256:
  870. {
  871. // 256色位图
  872. for(wi=0; wi<wColors; wi++)
  873. {
  874. lpBI->bmiColors[wi].rgbRed      = (BYTE)wi;
  875. lpBI->bmiColors[wi].rgbGreen    = (BYTE)wi;
  876. lpBI->bmiColors[wi].rgbBlue     = (BYTE)wi;
  877. lpBI->bmiColors[wi].rgbReserved = 0x00;
  878. }
  879. // 跳出
  880. break;
  881. }
  882. }
  883. }
  884. ///////////////////////////////////////////////////////////////////////////
  885. // 解码
  886. // 获取编码数据长度
  887. GIFDVar.dwDataLen  = (DWORD) (file.GetLength() - file.GetPosition());
  888. // 计算内存大小(最大不超过MAX_BUFF_SIZE)
  889. GIFDVar.wMemLen    = ((GIFDVar.dwDataLen > (DWORD)MAX_BUFF_SIZE) ?
  890.   (WORD)MAX_BUFF_SIZE : (WORD)GIFDVar.dwDataLen);
  891. // 分配内存
  892. hSrcBuff = GlobalAlloc(GHND, (DWORD)GIFDVar.wMemLen);
  893. // 锁定内存
  894. GIFDVar.lpDataBuff = (LPSTR)GlobalLock(hSrcBuff);
  895. // 读取编码数据
  896. ReadSrcData(file,&GIFDVar.wMemLen,&GIFDVar.dwDataLen,
  897. GIFDVar.lpDataBuff,&GIFDVar.bEOF);
  898. // 缓冲区起始位置
  899. GIFDVar.lpBgnBuff  = GIFDVar.lpDataBuff;
  900. // 缓冲区中止位置
  901. GIFDVar.lpEndBuff  = GIFDVar.lpBgnBuff + GIFDVar.wMemLen;
  902. // 计算DIB中像素位置
  903. lpDIBBits = (LPSTR) FindDIBBits(pDIB);
  904. // 解码
  905. DecodeGIF_LZW(file, lpDIBBits, &GIFDVar, wWidthBytes);
  906. // 释放内存
  907. GlobalUnlock(hSrcBuff);
  908. GlobalFree(hSrcBuff);
  909. // 返回DIB句柄
  910. return hDIB;
  911. }
  912. /*************************************************************************
  913.  *
  914.  * 函数名称:
  915.  *   ReadSrcData()
  916.  *
  917.  * 参数:
  918.  *   CFile& file - 源GIF文件
  919.  *   LPWORD lpwMemLen - 缓冲区长度(指针)
  920.  *   LPDWORD lpdwDataLen - 剩余数据长度(指针)
  921.  *   LPSTR lpSrcBuff - 缓冲区指针
  922.  *  LPBOOL lpbEOF - 结束标志
  923.  *
  924.  * 返回值:
  925.  *   无
  926.  *
  927.  * 说明:
  928.  *   该函数用来读取指定GIF文件中的图像编码,每次最多读取MAX_BUFF_SIZE
  929.  * 字节,是否读完由标志lpbEOF指定。
  930.  *
  931.  *************************************************************************/
  932. void WINAPI ReadSrcData(CFile& file, LPWORD lpwMemLen, LPDWORD lpdwDataLen,
  933.                         LPSTR lpSrcBuff, LPBOOL lpbEOF)
  934. {
  935. // 判断数据长度是否仍然大于内存大小
  936. if ((*lpdwDataLen) > (DWORD)(*lpwMemLen))
  937. {
  938. // 数据长度大于内存大小,表示没有解码完
  939. // 数据长度减内存大小
  940. (*lpdwDataLen) -= (DWORD)(*lpwMemLen);
  941. }
  942. else
  943. {
  944. // 数据长度不大于内存大小,表示解码将要完成
  945. // 内存大小就是剩余数据长度
  946. (*lpwMemLen)    = (WORD)(*lpdwDataLen);
  947. // EOF标志设置为TRUE
  948. (*lpbEOF)       = TRUE;
  949. }
  950. // 读取编码数据
  951. file.Read(lpSrcBuff, (*lpwMemLen));
  952. // 返回
  953. return;
  954. }
  955. /*************************************************************************
  956.  *
  957.  * 函数名称:
  958.  *   DecodeGIF_LZW()
  959.  *
  960.  * 参数:
  961.  *   CFile& file - 源GIF文件
  962.  *   LPSTR lpDIBBits - 指向要保存的DIB图像指针
  963.  *   LPGIFD_VAR lpGIFDVar - 指向GIFC_VAR结构的指针
  964.  *  WORD wWidthBytes - 每行图像字节数
  965.  *
  966.  * 返回值:
  967.  *   无
  968.  *
  969.  * 说明:
  970.  *   该函数对指定GIF_LZW编码数据进行解码。
  971.  *
  972.  *************************************************************************/
  973. void WINAPI DecodeGIF_LZW(CFile& file, LPSTR lpDIBBits,
  974.   LPGIFD_VAR lpGIFDVar,WORD wWidthBytes)
  975. {
  976. // 指向编码后图像数据的指针
  977. BYTE * lpDst;
  978. // 内存分配句柄
  979. HANDLE hPrefix;
  980. HANDLE hSuffix;
  981. HANDLE hStack;
  982. HANDLE hImage;
  983. // 用于字串表搜索的索引
  984. LPWORD lpwPrefix;
  985. LPBYTE lpbySuffix;
  986. LPBYTE lpbyStack;
  987. LPBYTE lpbyStackBgn;
  988. // 指向图像当前行解码结果的指针
  989. LPSTR  lpImageBgn;
  990. // 指向当前编码像素的指针
  991. LPSTR  lpImage;
  992. // 计算当前数据图像的偏移量
  993. DWORD  dwDataNdx;
  994. // LZW_CLEAR
  995. WORD   wLZW_CLEAR;
  996. // LZW_EOI
  997. WORD   wLZW_EOI;
  998. // LZW_MinCodeLen
  999. BYTE   byLZW_MinCodeLen;
  1000. // 字串表索引
  1001. WORD   wNowTableNdx;
  1002. WORD   wTopTableNdx;
  1003. // 当前图像的行数
  1004. WORD   wRowNum;
  1005. // 计数
  1006. WORD   wWidthCnt;
  1007. WORD   wBitCnt;
  1008. WORD   wRowCnt;
  1009. // 循环变量
  1010. WORD   wi;
  1011. // 交错方式存储时每次增加的行数
  1012. WORD   wIncTable[5]  = { 8,8,4,2,0 }; 
  1013. // 交错方式存储时起始行数
  1014. WORD   wBgnTable[5]  = { 0,4,2,1,0 }; 
  1015. // 块大小
  1016. BYTE   byBlockSize;
  1017. // 块索引
  1018. BYTE   byBlockNdx;
  1019. DWORD  dwData;
  1020. // 当前编码
  1021. WORD   wCode;
  1022. // 上一个编码
  1023. WORD   wOldCode;
  1024. // 临时索引
  1025. WORD   wTempNdx;
  1026. WORD   wCodeMask[13] = {0x0000,
  1027. 0x0001,0x0003,0x0007,0x000F,
  1028. 0x001F,0x003F,0x007F,0x00FF,
  1029. 0x01FF,0x03FF,0x07FF,0x0FFF
  1030. };
  1031. BYTE   byLeftBits;
  1032. BYTE   byFirstChar;
  1033. BYTE   byCode;
  1034. BYTE   byCurrentBits;
  1035. BYTE   byPass;
  1036. // 临时字节变量
  1037. BYTE   byTempChar;
  1038. // 给字串表分配内存
  1039. hPrefix          = GlobalAlloc(GHND,(DWORD)(MAX_TABLE_SIZE<<1));
  1040. hSuffix          = GlobalAlloc(GHND,(DWORD)MAX_TABLE_SIZE);
  1041. hStack           = GlobalAlloc(GHND,(DWORD)MAX_TABLE_SIZE);
  1042. hImage           = GlobalAlloc(GHND,(DWORD)wWidthBytes);
  1043. // 锁定内存
  1044. lpwPrefix        = (LPWORD)GlobalLock(hPrefix);
  1045. lpbySuffix       = (LPBYTE)GlobalLock(hSuffix);
  1046. lpbyStack        = (LPBYTE)GlobalLock(hStack);
  1047. lpbyStackBgn     = lpbyStack;
  1048. lpImage          = (LPSTR)GlobalLock(hImage);
  1049. lpImageBgn       = lpImage;
  1050. // 读取GIF LZW最小编码大小
  1051. byLZW_MinCodeLen = *lpGIFDVar->lpBgnBuff++;
  1052. byCurrentBits    = byLZW_MinCodeLen + (BYTE)0x01;
  1053. // 计算LZW_CLEAR
  1054. wLZW_CLEAR       = 1 << byLZW_MinCodeLen;
  1055. // 计算LZW_EOI
  1056. wLZW_EOI         = wLZW_CLEAR + 1;
  1057. // 计算字串表索引
  1058. wNowTableNdx     = wLZW_CLEAR + 2;
  1059. wTopTableNdx     = 1 << byCurrentBits;
  1060. // 赋初值
  1061. dwData           = 0UL;
  1062. wBitCnt          = lpGIFDVar->wBits;
  1063. wRowNum          = 0;
  1064. wRowCnt          = 1;
  1065. wWidthCnt        = 0;
  1066. wCode            = 0;
  1067. wOldCode         = 0xFFFF;
  1068. byBlockSize      = 0x01;
  1069. byBlockNdx       = 0x00;
  1070. byLeftBits       = 0x00;
  1071. byTempChar       = 0x00;
  1072. byPass           = 0x00;
  1073. // 读取下一个编码
  1074. while(byLeftBits < byCurrentBits)
  1075. {
  1076. // 读取下一个字符
  1077. // 判断是否读完一个数据块
  1078. if (++byBlockNdx == byBlockSize)
  1079. {
  1080. // 读取下一个数据块
  1081. byBlockSize = *lpGIFDVar->lpBgnBuff++;
  1082. byBlockNdx  = 0x00;
  1083. // 判断是否读完
  1084. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1085.     !lpGIFDVar->bEOF)
  1086. {
  1087. // 读取下一个数据块
  1088. ReadSrcData(file,&lpGIFDVar->wMemLen,
  1089. &lpGIFDVar->dwDataLen,
  1090. lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);
  1091. // 指针重新赋值
  1092. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1093. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;
  1094. }
  1095. }
  1096. // 下一个字符
  1097. byCode      = *lpGIFDVar->lpBgnBuff++;
  1098. // 移位
  1099. dwData     |= ((DWORD)byCode << byLeftBits);
  1100. byLeftBits += 0x08;
  1101. // 判断是否读完
  1102. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1103.     !lpGIFDVar->bEOF)
  1104. {
  1105. // 读取下一个数据块
  1106. ReadSrcData(file,&lpGIFDVar->wMemLen,
  1107. &lpGIFDVar->dwDataLen,
  1108. lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);
  1109. // 指针重新赋值
  1110. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1111. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;
  1112. }
  1113. }
  1114. wCode       = (WORD)dwData & wCodeMask[byCurrentBits];
  1115. dwData    >>= byCurrentBits;
  1116. byLeftBits -= byCurrentBits;
  1117. // 解码
  1118. while(wCode != wLZW_EOI)
  1119. {
  1120. // 当前编码不是LZW_EOI码
  1121. // 判断是否是LZW_CLEAR码
  1122. if (wCode == wLZW_CLEAR)
  1123. {
  1124. // 是LZW_CLEAR,清除字串表
  1125. // 重新初始化字串表
  1126. for(wi = 0; wi < wLZW_CLEAR; wi++)
  1127. {
  1128. *(lpwPrefix  + wi)  = 0xFFFF;
  1129. *(lpbySuffix + wi) = (BYTE)wi;
  1130. }
  1131. for(wi = wNowTableNdx; wi < MAX_TABLE_SIZE; wi++)
  1132. {
  1133. *(lpwPrefix+wi)  = 0xFFFF;
  1134. *(lpbySuffix+wi) = 0x00;
  1135. }
  1136. byCurrentBits = byLZW_MinCodeLen + (BYTE)0x01;
  1137. wNowTableNdx  = wLZW_CLEAR + 2;
  1138. wTopTableNdx  = 1 << byCurrentBits;
  1139. wOldCode      = 0xFFFF;
  1140. // 获取下一个编码
  1141. while(byLeftBits < byCurrentBits)
  1142. {
  1143. // 读取下一个字符
  1144. // 判断是否读完一个数据块
  1145. if (++byBlockNdx == byBlockSize)
  1146. {
  1147. // 读取下一个数据块
  1148. byBlockSize = *lpGIFDVar->lpBgnBuff++;
  1149. byBlockNdx  = 0x00;
  1150. // 判断是否读完
  1151. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1152. !lpGIFDVar->bEOF)
  1153. {
  1154. // 读取下一个数据块
  1155. ReadSrcData(file, &lpGIFDVar->wMemLen,
  1156. &lpGIFDVar->dwDataLen,
  1157. lpGIFDVar->lpDataBuff,
  1158. &lpGIFDVar->bEOF);
  1159. // 指针重新赋值
  1160. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1161. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff +
  1162.    lpGIFDVar->wMemLen;
  1163. }
  1164. }
  1165. byCode      = *lpGIFDVar->lpBgnBuff++;
  1166. dwData     |= ((DWORD)byCode << byLeftBits);
  1167. byLeftBits += 0x08;
  1168. // 判断是否读完
  1169. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1170.  !lpGIFDVar->bEOF)
  1171. {
  1172. // 读取下一个数据块
  1173. ReadSrcData(file,&lpGIFDVar->wMemLen,
  1174. &lpGIFDVar->dwDataLen,
  1175. lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);
  1176. // 指针重新赋值
  1177. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1178. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;
  1179. }
  1180. }
  1181. wCode       = (WORD)dwData & wCodeMask[byCurrentBits];
  1182. dwData    >>= byCurrentBits;
  1183. byLeftBits -= byCurrentBits;
  1184. // 判断编码是否为LZW_EOI
  1185. if (wCode!=wLZW_EOI)
  1186. {
  1187. // 这里没有用到lpbyStack[0]
  1188. lpbyStack  ++;
  1189. // 将数据压入堆栈
  1190. while((*(lpwPrefix+wCode)) != 0xFFFF)
  1191. {
  1192. *lpbyStack++ = *(lpbySuffix+wCode);
  1193. wCode        = *(lpwPrefix+wCode);
  1194. }
  1195. *lpbyStack  = *(lpbySuffix+wCode);
  1196. byFirstChar = *lpbyStack;
  1197. // 输出数据
  1198. while(lpbyStack>lpbyStackBgn)
  1199. {
  1200. byTempChar |= (*lpbyStack-- << (8-wBitCnt));
  1201. if (wBitCnt==8)
  1202. {
  1203. *lpImage++ = byTempChar;
  1204. byTempChar = 0x00;
  1205. wBitCnt    = lpGIFDVar->wBits;
  1206. }
  1207. else
  1208. {
  1209. wBitCnt   += lpGIFDVar->wBits;
  1210. }
  1211. wWidthCnt  ++;
  1212. if (wWidthCnt==lpGIFDVar->wWidth)
  1213. {
  1214. if (wBitCnt!=lpGIFDVar->wBits)
  1215. {
  1216. *lpImage   = byTempChar;
  1217. byTempChar = 0x00;
  1218. wBitCnt    = lpGIFDVar->wBits;
  1219. }
  1220. // 图像当前行偏移量
  1221. dwDataNdx = (DWORD)(lpGIFDVar->wDepth - 1 - wRowNum) * (DWORD)wWidthBytes;
  1222. // 图像当前行起始位置
  1223. lpDst = (BYTE *)lpDIBBits + dwDataNdx;
  1224. // 赋值
  1225. memcpy(lpDst, lpImageBgn, wWidthBytes);
  1226. lpImage   = lpImageBgn;
  1227. // 判断是否按照交错方式保存
  1228. if (lpGIFDVar->bInterlace)
  1229. {
  1230. // 交错方式
  1231. // 计算下一行的行号
  1232. wRowNum += wIncTable[byPass];
  1233. if (wRowNum >= lpGIFDVar->wDepth)
  1234. {
  1235. byPass ++;
  1236. wRowNum = wBgnTable[byPass];
  1237. }
  1238. }
  1239. else
  1240. {
  1241. // 非交错方式,行号直接加1
  1242. wRowNum ++;
  1243. }
  1244. wWidthCnt = 0;
  1245. }
  1246. }
  1247. }
  1248. }
  1249. else
  1250. {
  1251. // 这里没有用到lpbyStack[0]
  1252. lpbyStack  ++;
  1253. // 判断字符串是否在字串表中
  1254. if (wCode < wNowTableNdx)
  1255. {
  1256. // 不在字串表中
  1257. wTempNdx   = wCode;
  1258. }
  1259. else
  1260. {
  1261. // 在字串表中
  1262. wTempNdx     = wOldCode;
  1263. *lpbyStack++ = byFirstChar;
  1264. }
  1265. // 将数据压入堆栈
  1266. while((*(lpwPrefix+wTempNdx)) != 0xFFFF)
  1267. {
  1268. *lpbyStack++ = *(lpbySuffix+wTempNdx);
  1269. wTempNdx     = *(lpwPrefix+wTempNdx);
  1270. }
  1271. *lpbyStack  = *(lpbySuffix+wTempNdx);
  1272. byFirstChar = *lpbyStack;
  1273. // 将字符串添加到字串表中
  1274. *(lpwPrefix+wNowTableNdx)  = wOldCode;
  1275. *(lpbySuffix+wNowTableNdx) = byFirstChar;
  1276. if (++wNowTableNdx==wTopTableNdx && byCurrentBits<12)
  1277. {
  1278. byCurrentBits ++;
  1279. wTopTableNdx   = 1 << byCurrentBits;
  1280. }
  1281. // 输出数据
  1282. while(lpbyStack>lpbyStackBgn)
  1283. {
  1284. byTempChar |= (*lpbyStack-- << (8-wBitCnt));
  1285. if (wBitCnt==8)
  1286. {
  1287. *lpImage++ = byTempChar;
  1288. byTempChar = 0x00;
  1289. wBitCnt    = lpGIFDVar->wBits;
  1290. }
  1291. else
  1292. {
  1293. wBitCnt   += lpGIFDVar->wBits;
  1294. }
  1295. wWidthCnt  ++;
  1296. if (wWidthCnt==lpGIFDVar->wWidth)
  1297. {
  1298. if (wBitCnt!=lpGIFDVar->wBits)
  1299. {
  1300. *lpImage   = byTempChar;
  1301. byTempChar = 0x00;
  1302. wBitCnt    = lpGIFDVar->wBits;
  1303. }
  1304. // 图像当前行偏移量
  1305. dwDataNdx = (DWORD)(lpGIFDVar->wDepth - 1 - wRowNum) * (DWORD)wWidthBytes;
  1306. // 图像当前行起始位置
  1307. lpDst = (BYTE *)lpDIBBits + dwDataNdx;
  1308. // 赋值
  1309. memcpy(lpDst, lpImageBgn, wWidthBytes);
  1310. lpImage   = lpImageBgn;
  1311. // 判断是否按照交错方式保存
  1312. if (lpGIFDVar->bInterlace)
  1313. {
  1314. // 交错方式
  1315. // 计算下一行的行号
  1316. wRowNum += wIncTable[byPass];
  1317. if (wRowNum >= lpGIFDVar->wDepth)
  1318. {
  1319. byPass ++;
  1320. wRowNum = wBgnTable[byPass];
  1321. }
  1322. }
  1323. else
  1324. {
  1325. // 非交错方式,行号直接加1
  1326. wRowNum ++;
  1327. }
  1328. wWidthCnt = 0;
  1329. }
  1330. }
  1331. }
  1332. wOldCode = wCode;
  1333. // 读取下一个编码
  1334. while(byLeftBits < byCurrentBits)
  1335. {
  1336. // 读取下一个字符
  1337. // 判断是否读完一个数据块
  1338. if (++byBlockNdx == byBlockSize)
  1339. {
  1340. // 读取下一个数据块
  1341. byBlockSize = *lpGIFDVar->lpBgnBuff++;
  1342. byBlockNdx  = 0x00;
  1343. // 判断是否读完
  1344. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1345.  !lpGIFDVar->bEOF)
  1346. {
  1347. // 读取下一个数据块
  1348. ReadSrcData(file,&lpGIFDVar->wMemLen,
  1349. &lpGIFDVar->dwDataLen,
  1350. lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);
  1351. // 指针重新赋值
  1352. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1353. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;
  1354. }
  1355. }
  1356. byCode      = *lpGIFDVar->lpBgnBuff++;
  1357. dwData     |= ((DWORD)byCode << byLeftBits);
  1358. byLeftBits += 0x08;
  1359. // 判断是否读完
  1360. if ((lpGIFDVar->lpBgnBuff == lpGIFDVar->lpEndBuff) &&
  1361.   !lpGIFDVar->bEOF)
  1362. {
  1363. // 读取下一个数据块
  1364. ReadSrcData(file,&lpGIFDVar->wMemLen,
  1365. &lpGIFDVar->dwDataLen,
  1366. lpGIFDVar->lpDataBuff,&lpGIFDVar->bEOF);
  1367. // 指针重新赋值
  1368. lpGIFDVar->lpBgnBuff = lpGIFDVar->lpDataBuff;
  1369. lpGIFDVar->lpEndBuff = lpGIFDVar->lpBgnBuff + lpGIFDVar->wMemLen;
  1370. }
  1371. }
  1372. wCode       = (WORD)dwData & wCodeMask[byCurrentBits];
  1373. dwData    >>= byCurrentBits;
  1374. byLeftBits -= byCurrentBits;
  1375. }
  1376. // 释放内存
  1377. GlobalUnlock(hPrefix);
  1378. GlobalUnlock(hSuffix);
  1379. GlobalUnlock(hStack);
  1380. GlobalFree(hPrefix);
  1381. GlobalFree(hSuffix);
  1382. GlobalFree(hStack);
  1383. // 返回
  1384. return;
  1385. }