Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

754 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1992 Microsoft Corporation
  3. Module Name:
  4. htuigif.c
  5. Abstract:
  6. This module contains GIF file decompression to generate a memory DIB type
  7. bitmap for the GIF
  8. Author:
  9. 21-Apr-1992 Tue 11:38:11 created -by- Daniel Chou (danielc)
  10. [Environment:]
  11. GDI Device Driver - Halftone.
  12. [Notes:]
  13. Revision History:
  14. --*/
  15. #include <stddef.h>
  16. #include <windows.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ht.h>
  20. #include "htuidlg.h"
  21. #include "htuimain.h"
  22. #include "htuigif.h"
  23. extern HMODULE hHTUIModule;
  24. //
  25. // Following structures and #defines are only used in this C file
  26. //
  27. #pragma pack(1)
  28. typedef struct _GIFRGB { /* gifrgb */
  29. BYTE Red;
  30. BYTE Green;
  31. BYTE Blue;
  32. } GIFRGB, FAR *PGIFRGB;
  33. #pragma pack()
  34. typedef struct _GIFMAP {
  35. SHORT CurX;
  36. SHORT CurY;
  37. SHORT Width;
  38. SHORT Height;
  39. } GIFMAP;
  40. #pragma pack(1)
  41. typedef struct _GIFHEADER {
  42. BYTE Signature[3]; /* This is the 'GIF' signature */
  43. BYTE Version[3]; /* version number such as '89a' */
  44. WORD Width; /* Width of the picture in pels */
  45. WORD Height; /* Height of the picture in pels */
  46. BYTE Flags; /* GIFH_xxxx flags */
  47. BYTE BColorIndex; /* background color index */
  48. BYTE AspectRatio; /* w/h ratio = (x + 15) / 64 */
  49. } GIFHEADER, *PGIFHEADER;
  50. #pragma pack()
  51. #define GIFH_GLOBAL_COLOR_TABLE 0x80
  52. #define GIFH_PRIMARY_COLOR_BITS 0xe0
  53. #define GIFH_SORTED_COLORS 0x08
  54. #define GIFH_SIZE_COLOR_TABLE 0x07
  55. #define GIFMAP_INTERLACE 0x40
  56. typedef struct _GIF2DIBINFO {
  57. LPSHORT pLineIncVec;
  58. LPBYTE pDIBLine1;
  59. LPBYTE pDIBCurLine;
  60. LPBYTE pDIBNow;
  61. LPBYTE pGIFBuf;
  62. DWORD SizeGIFBuf;
  63. GIFMAP Map;
  64. WORD cx;
  65. WORD cy;
  66. WORD cxBytes;
  67. WORD LinesDone;
  68. WORD RemainXPels;
  69. WORD PelMask;
  70. } GIF2DIBINFO, *PGIF2DIBINFO;
  71. typedef VOID (*PFNOUTPUTPELS)(PGIF2DIBINFO pGIF2DIBInfo, UINT TotalPels);
  72. #define SET_NEXT_DIB_PBUF \
  73. { \
  74. SHORT LineInc; \
  75. \
  76. GIF2DIBInfo.pDIBCurLine -= \
  77. (LONG)(LineInc = *(GIF2DIBInfo.pLineIncVec)) * \
  78. (LONG)GIF2DIBInfo.cxBytes; \
  79. \
  80. if ((GIF2DIBInfo.Map.CurY += LineInc) >= GIF2DIBInfo.Map.Height) { \
  81. \
  82. GIF2DIBInfo.pLineIncVec++; \
  83. \
  84. if (*(GIF2DIBInfo.pLineIncVec) >= 0) { \
  85. \
  86. GIF2DIBInfo.Map.CurY = *(GIF2DIBInfo.pLineIncVec++); \
  87. GIF2DIBInfo.pDIBCurLine = GIF2DIBInfo.pDIBLine1 - \
  88. ((LONG)GIF2DIBInfo.Map.CurX * \
  89. (LONG)GIF2DIBInfo.Map.CurY); \
  90. } \
  91. } \
  92. \
  93. ++GIF2DIBInfo.LinesDone; \
  94. \
  95. GIF2DIBInfo.pDIBNow = GIF2DIBInfo.pDIBCurLine; \
  96. GIF2DIBInfo.RemainXPels = GIF2DIBInfo.cx; \
  97. GIF2DIBInfo.PelMask = 0; \
  98. } \
  99. //////////////////////////////////////////////////////////////////////////////
  100. // //
  101. // LZW DeCompression //
  102. // //
  103. //////////////////////////////////////////////////////////////////////////////
  104. #define MAXBITS 12
  105. #define SIZE_GIF_BUF (60 * 1024)
  106. #define SIZE_LZW_LASTCHAR (1 << MAXBITS)
  107. #define SIZE_LZW_RASTERBLOCK 256
  108. #define SIZE_LZW_PREFIX ((1 << MAXBITS) * 2)
  109. #define SIZE_LZW_BUFS (SIZE_LZW_LASTCHAR + SIZE_LZW_RASTERBLOCK + \
  110. SIZE_LZW_PREFIX)
  111. typedef struct _LZWINFO {
  112. LPBYTE pLastChar;
  113. LPBYTE pRasterBlock;
  114. LPSHORT pPrefix;
  115. SHORT EODCode;
  116. SHORT CSMask;
  117. SHORT CodeSize;
  118. SHORT BitsLeft;
  119. DWORD CodeBuf;
  120. SHORT GetCodeRet;
  121. BYTE RBIndex;
  122. BYTE RBLen;
  123. } LZWINFO;
  124. #define GET_GIF_CODE \
  125. { \
  126. BOOL EODCodeBreak = FALSE; \
  127. \
  128. while (LZWInfo.BitsLeft < LZWInfo.CodeSize) { \
  129. \
  130. if (LZWInfo.RBIndex >= LZWInfo.RBLen) { \
  131. \
  132. if ((!ReadFile(hFile, &LZWInfo.RBLen, 1, &cbRead, NULL)) || \
  133. (cbRead != 1) || \
  134. (LZWInfo.RBLen < 1) || \
  135. (!ReadFile(hFile, LZWInfo.pRasterBlock, LZWInfo.RBLen, \
  136. &cbRead, NULL)) || \
  137. (cbRead != (DWORD)LZWInfo.RBLen)) { \
  138. \
  139. EODCodeBreak = TRUE; \
  140. break; \
  141. } \
  142. \
  143. LZWInfo.RBIndex = 0; \
  144. } \
  145. \
  146. LZWInfo.CodeBuf |= (DWORD)*(LZWInfo.pRasterBlock + \
  147. LZWInfo.RBIndex++) << LZWInfo.BitsLeft; \
  148. LZWInfo.BitsLeft += 8; \
  149. } \
  150. \
  151. if (EODCodeBreak) { \
  152. \
  153. LZWInfo.GetCodeRet = LZWInfo.EODCode; \
  154. \
  155. } else { \
  156. \
  157. LZWInfo.GetCodeRet = (SHORT)(LZWInfo.CodeBuf & \
  158. (DWORD)LZWInfo.CSMask); \
  159. LZWInfo.CodeBuf >>= LZWInfo.CodeSize; \
  160. LZWInfo.BitsLeft -= LZWInfo.CodeSize; \
  161. } \
  162. } \
  163. BOOL
  164. DeCompressGIFFileToDIB(
  165. HANDLE hFile,
  166. PGIF2DIBINFO pGIF2DIBInfo,
  167. LPBYTE pLZWBuf,
  168. PFNOUTPUTPELS pfnOutputPels,
  169. WORD BitCount
  170. )
  171. {
  172. LPBYTE pGIFBufBeg;
  173. LPBYTE pGIFBufEnd;
  174. LPBYTE pOutBufTail;
  175. LPBYTE pOutBufHead;
  176. LZWINFO LZWInfo;
  177. UINT SizeGIFBuf;
  178. DWORD cbRead;
  179. WORD BytesMove;
  180. SHORT FinalChar;
  181. SHORT OldCode;
  182. SHORT CurCode;
  183. SHORT InitialCodeSize;
  184. SHORT ClearCode;
  185. SHORT MaxCode;
  186. SHORT MaxCol;
  187. SHORT NextCode;
  188. BYTE bCh;
  189. //
  190. // First initialize all the local buffer
  191. //
  192. LZWInfo.pLastChar = pLZWBuf;
  193. LZWInfo.pRasterBlock = pLZWBuf + SIZE_LZW_LASTCHAR;
  194. LZWInfo.pPrefix = (LPSHORT)(LZWInfo.pRasterBlock +
  195. SIZE_LZW_RASTERBLOCK);
  196. LZWInfo.BitsLeft = 0;
  197. LZWInfo.CodeBuf = 0;
  198. LZWInfo.GetCodeRet = 0;
  199. LZWInfo.RBIndex =
  200. LZWInfo.RBLen = 0;
  201. *(LZWInfo.pLastChar) = (BYTE)0;
  202. *(LZWInfo.pPrefix) =
  203. FinalChar =
  204. OldCode = 0;
  205. if ((!ReadFile(hFile, &bCh, 1, &cbRead, NULL)) ||
  206. (cbRead != 1)) {
  207. return(FALSE);
  208. }
  209. pGIFBufBeg = pGIF2DIBInfo->pGIFBuf;
  210. SizeGIFBuf = (UINT)pGIF2DIBInfo->SizeGIFBuf;
  211. pGIFBufEnd = pGIFBufBeg + SizeGIFBuf;
  212. InitialCodeSize = (SHORT)bCh;
  213. LZWInfo.CodeSize = ++InitialCodeSize;
  214. if (LZWInfo.CodeSize < 3 || LZWInfo.CodeSize > 9) {
  215. return(FALSE);
  216. }
  217. MaxCol = (SHORT)((1 << BitCount) - 1);
  218. ClearCode = (SHORT)(1 << (LZWInfo.CodeSize - 1));
  219. LZWInfo.EODCode = (SHORT)(ClearCode + 1);
  220. NextCode = (SHORT)(ClearCode + 2);
  221. MaxCode = (SHORT)(ClearCode << 1);
  222. LZWInfo.CSMask = (SHORT)(MaxCode - 1);
  223. pOutBufHead = pGIFBufBeg;
  224. while (TRUE) {
  225. //
  226. // GET_GIF_CODE will reeurn from this function if _ReadFile() failed,
  227. // otherwise it set the curretn read code into LZWInfo.GetCodeRet
  228. //
  229. GET_GIF_CODE;
  230. if (LZWInfo.GetCodeRet == LZWInfo.EODCode) {
  231. break; // Done
  232. }
  233. //
  234. // Write out the color data if the buffer is full
  235. //
  236. if (pOutBufHead >= pGIFBufEnd) {
  237. pfnOutputPels(pGIF2DIBInfo, (UINT)SizeGIFBuf);
  238. pOutBufHead = pGIFBufBeg;
  239. }
  240. if (LZWInfo.GetCodeRet == ClearCode) {
  241. LZWInfo.CodeSize = InitialCodeSize;
  242. NextCode = (SHORT)(ClearCode + (SHORT)2);
  243. MaxCode = (SHORT)(1 << LZWInfo.CodeSize);
  244. LZWInfo.CSMask = (SHORT)(MaxCode - 1);
  245. do {
  246. GET_GIF_CODE;
  247. } while (LZWInfo.GetCodeRet == ClearCode);
  248. if (LZWInfo.GetCodeRet == LZWInfo.EODCode) {
  249. break;
  250. } else if (LZWInfo.GetCodeRet >= NextCode) {
  251. LZWInfo.GetCodeRet = 0;
  252. }
  253. *pOutBufHead++ = (BYTE)(OldCode = FinalChar = LZWInfo.GetCodeRet);
  254. } else {
  255. CurCode = LZWInfo.GetCodeRet;
  256. //
  257. // At here, we guranteed that at least one byte in the buffer
  258. // is available
  259. //
  260. pOutBufTail = pGIFBufEnd;
  261. if (CurCode == NextCode) {
  262. *--pOutBufTail = (BYTE)FinalChar;
  263. CurCode = OldCode;
  264. } else if (CurCode > NextCode) {
  265. return(FALSE);
  266. }
  267. while (CurCode > MaxCol) {
  268. if (pOutBufTail <= pOutBufHead) {
  269. //
  270. // Output some when buffer full
  271. //
  272. pfnOutputPels(pGIF2DIBInfo, (UINT)(pOutBufHead-pGIFBufBeg));
  273. pOutBufHead = pGIFBufBeg;
  274. }
  275. *--pOutBufTail = *(LZWInfo.pLastChar + CurCode);
  276. CurCode = *(LZWInfo.pPrefix + CurCode);
  277. }
  278. if (pOutBufTail <= pOutBufHead) {
  279. pfnOutputPels(pGIF2DIBInfo, (UINT)(pOutBufHead - pGIFBufBeg));
  280. pOutBufHead = pGIFBufBeg;
  281. }
  282. *--pOutBufTail = (BYTE)(FinalChar = CurCode);
  283. //
  284. // Need to move little bit, we guranteed that we minimum
  285. // has one byte generated in this ELSE()
  286. //
  287. if (pOutBufTail > pOutBufHead) {
  288. memmove(pOutBufHead,
  289. pOutBufTail,
  290. BytesMove = (WORD)(pGIFBufEnd - pOutBufTail));
  291. pOutBufHead += BytesMove;
  292. } else {
  293. //
  294. // We are exactly fill up the buffer, so do not need to
  295. // move but just advance the pointer
  296. //
  297. pOutBufHead = pGIFBufEnd;
  298. }
  299. if (NextCode < MaxCode) {
  300. *(LZWInfo.pPrefix + NextCode) = OldCode;
  301. *(LZWInfo.pLastChar + NextCode) = (BYTE)(FinalChar = CurCode);
  302. OldCode = LZWInfo.GetCodeRet;
  303. }
  304. if ((++NextCode >= MaxCode) &&
  305. (LZWInfo.CodeSize < MAXBITS)) {
  306. ++LZWInfo.CodeSize;
  307. MaxCode <<= 1;
  308. LZWInfo.CSMask = (SHORT)(MaxCode - 1);
  309. }
  310. }
  311. }
  312. if (pOutBufHead > pGIFBufBeg) {
  313. pfnOutputPels(pGIF2DIBInfo, (UINT)(pOutBufHead - pGIFBufBeg));
  314. pOutBufHead = pGIFBufBeg;
  315. }
  316. return(TRUE);
  317. }
  318. VOID
  319. Output8BPP(
  320. PGIF2DIBINFO pGIF2DIBInfo,
  321. UINT TotalPels
  322. )
  323. {
  324. GIF2DIBINFO GIF2DIBInfo;
  325. LPBYTE pGIFBuf;
  326. UINT CopySize;
  327. GIF2DIBInfo = *pGIF2DIBInfo;
  328. pGIFBuf = GIF2DIBInfo.pGIFBuf;
  329. while (TotalPels) {
  330. CopySize = (TotalPels > (UINT)GIF2DIBInfo.RemainXPels) ?
  331. (UINT)GIF2DIBInfo.RemainXPels : TotalPels;
  332. CopyMemory(GIF2DIBInfo.pDIBNow, pGIFBuf, CopySize);
  333. GIF2DIBInfo.pDIBNow += CopySize;
  334. pGIFBuf += CopySize;
  335. TotalPels -= CopySize;
  336. if (!(GIF2DIBInfo.RemainXPels -= (WORD)CopySize)) {
  337. SET_NEXT_DIB_PBUF;
  338. }
  339. }
  340. *pGIF2DIBInfo = GIF2DIBInfo;
  341. }
  342. VOID
  343. Output4BPP(
  344. PGIF2DIBINFO pGIF2DIBInfo,
  345. UINT TotalPels
  346. )
  347. {
  348. GIF2DIBINFO GIF2DIBInfo;
  349. LPBYTE pGIFBuf;
  350. UINT CopySize;
  351. GIF2DIBInfo = *pGIF2DIBInfo;
  352. pGIFBuf = GIF2DIBInfo.pGIFBuf;
  353. while (TotalPels) {
  354. CopySize = (TotalPels > (UINT)GIF2DIBInfo.RemainXPels) ?
  355. (UINT)GIF2DIBInfo.RemainXPels : TotalPels;
  356. TotalPels -= (WORD)CopySize;
  357. GIF2DIBInfo.RemainXPels -= (WORD)CopySize;
  358. while (CopySize--) {
  359. if (GIF2DIBInfo.PelMask ^= 0x01) {
  360. *GIF2DIBInfo.pDIBNow++ |= (BYTE)(*pGIFBuf++ & 0x0f);
  361. } else {
  362. *GIF2DIBInfo.pDIBNow = (BYTE)(*pGIFBuf++ << 4);
  363. }
  364. }
  365. if (!GIF2DIBInfo.RemainXPels) {
  366. SET_NEXT_DIB_PBUF;
  367. }
  368. }
  369. *pGIF2DIBInfo = GIF2DIBInfo;
  370. }
  371. VOID
  372. Output1BPP(
  373. PGIF2DIBINFO pGIF2DIBInfo,
  374. UINT TotalPels
  375. )
  376. {
  377. GIF2DIBINFO GIF2DIBInfo;
  378. LPBYTE pGIFBuf;
  379. UINT CopySize;
  380. BYTE bPel;
  381. GIF2DIBInfo = *pGIF2DIBInfo;
  382. pGIFBuf = GIF2DIBInfo.pGIFBuf;
  383. while (TotalPels) {
  384. CopySize = (TotalPels > (UINT)GIF2DIBInfo.RemainXPels) ?
  385. (UINT)GIF2DIBInfo.RemainXPels : TotalPels;
  386. TotalPels -= CopySize;
  387. GIF2DIBInfo.RemainXPels -= (WORD)CopySize;
  388. bPel = (BYTE)((GIF2DIBInfo.PelMask) ? *GIF2DIBInfo.pDIBNow : 0);
  389. while (CopySize--) {
  390. bPel = (BYTE)((bPel << 1) | ((*pGIFBuf++) & 0x01));
  391. if (++GIF2DIBInfo.PelMask == 8) {
  392. *GIF2DIBInfo.pDIBNow++ = bPel;
  393. bPel = 0;
  394. GIF2DIBInfo.PelMask = 0;
  395. }
  396. }
  397. if (GIF2DIBInfo.PelMask) {
  398. *(GIF2DIBInfo.pDIBNow) = bPel;
  399. }
  400. if (!GIF2DIBInfo.RemainXPels) {
  401. SET_NEXT_DIB_PBUF;
  402. }
  403. }
  404. *pGIF2DIBInfo = GIF2DIBInfo;
  405. }
  406. HANDLE
  407. ReadGIFFile(
  408. HANDLE hFile
  409. )
  410. {
  411. static SHORT NotInterleaved[] = { 0, 1, -1, -1};
  412. static SHORT Interleaved[] = { 0, 8, 4, 8, 2, 4, 1, 2, -1, -1};
  413. PFNOUTPUTPELS pfnOutputPels;
  414. LPBYTE pLZWBuf;
  415. LPBYTE pDIB;
  416. HANDLE hDIB;
  417. PGIFRGB pGIFRGB;
  418. RGBQUAD FAR *pRGBQUAD;
  419. GIFHEADER GIFHeader;
  420. BITMAPINFOHEADER biGIF;
  421. GIF2DIBINFO GIF2DIBInfo;
  422. DWORD cbRead;
  423. DWORD GIFPalSize;
  424. WORD BitCount;
  425. WORD ColorCount;
  426. WORD Loop;
  427. BOOL Ok = TRUE;
  428. BYTE Seperator;
  429. BYTE iFlags;
  430. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  431. if ((!ReadFile(hFile, &GIFHeader, sizeof(GIFHEADER), &cbRead, NULL)) ||
  432. (cbRead != sizeof(GIFHEADER)) ||
  433. (strncmp(GIFHeader.Signature, "GIF", 3))) {
  434. return(NULL); // non-gif
  435. }
  436. biGIF.biSize = sizeof(BITMAPINFOHEADER);
  437. biGIF.biWidth = (DWORD)(GIF2DIBInfo.cx = (WORD)GIFHeader.Width);
  438. biGIF.biHeight = (DWORD)(GIF2DIBInfo.cy = (WORD)GIFHeader.Height);
  439. biGIF.biPlanes = 1;
  440. BitCount =
  441. biGIF.biBitCount = (WORD)((GIFHeader.Flags & 0x07) + 1);
  442. biGIF.biCompression = (DWORD)BI_RGB;
  443. biGIF.biXPelsPerMeter = 0;
  444. biGIF.biYPelsPerMeter = 0;
  445. if (BitCount == 1) {
  446. pfnOutputPels = Output1BPP;
  447. } else if (BitCount <= 4) {
  448. pfnOutputPels = Output4BPP;
  449. biGIF.biBitCount = 4;
  450. } else if (BitCount <= 8) {
  451. pfnOutputPels = Output8BPP;
  452. biGIF.biBitCount = 8;
  453. } else {
  454. return(NULL);
  455. }
  456. biGIF.biClrUsed =
  457. biGIF.biClrImportant = (DWORD)1 << biGIF.biBitCount;
  458. GIFPalSize = (DWORD)sizeof(RGBQUAD) * (DWORD)biGIF.biClrUsed;
  459. GIF2DIBInfo.cxBytes = (WORD)ALIGN_BPP_DW(GIF2DIBInfo.cx,
  460. biGIF.biBitCount);
  461. biGIF.biSizeImage = (DWORD)GIF2DIBInfo.cxBytes * (DWORD)GIF2DIBInfo.cy;
  462. if (!(hDIB = GlobalAlloc(GHND, (DWORD)sizeof(BITMAPINFOHEADER) +
  463. GIFPalSize + (DWORD)biGIF.biSizeImage))) {
  464. return(NULL);
  465. }
  466. GIF2DIBInfo.SizeGIFBuf = (DWORD)SIZE_GIF_BUF;
  467. if (!(GIF2DIBInfo.pGIFBuf = (LPBYTE)LocalAlloc(LPTR,
  468. GIF2DIBInfo.SizeGIFBuf))) {
  469. GlobalFree(hDIB);
  470. return(NULL); // no memory for decompress
  471. }
  472. if (!(pLZWBuf = (LPBYTE)LocalAlloc(LPTR, SIZE_LZW_BUFS))) {
  473. GlobalFree(hDIB);
  474. LocalFree((HANDLE)GIF2DIBInfo.pGIFBuf);
  475. return(NULL);
  476. }
  477. pDIB = GlobalLock(hDIB);
  478. *(LPBITMAPINFOHEADER)pDIB = biGIF;
  479. if (GIFHeader.Flags & GIFH_GLOBAL_COLOR_TABLE) {
  480. ColorCount = (WORD)(1 << BitCount);
  481. pGIFRGB = (PGIFRGB)(pDIB + sizeof(BITMAPINFOHEADER) +
  482. ((sizeof(RGBQUAD) - sizeof(GIFRGB)) * ColorCount));
  483. pRGBQUAD = (RGBQUAD FAR *)(pDIB + sizeof(BITMAPINFOHEADER));
  484. if ((!ReadFile(hFile,
  485. pGIFRGB,
  486. sizeof(GIFRGB) * ColorCount,
  487. &cbRead,
  488. NULL)) ||
  489. (cbRead != sizeof(GIFRGB) * ColorCount)) {
  490. Ok = FALSE;
  491. } else {
  492. for (Loop = 0; Loop < ColorCount; Loop++) {
  493. pRGBQUAD->rgbRed = pGIFRGB->Red;
  494. pRGBQUAD->rgbGreen = pGIFRGB->Green;
  495. pRGBQUAD->rgbBlue = pGIFRGB->Blue;
  496. pRGBQUAD->rgbReserved = 0;
  497. ++pRGBQUAD;
  498. ++pGIFRGB;
  499. }
  500. if (Loop = (WORD)(biGIF.biClrUsed - ColorCount)) {
  501. ZeroMemory((LPVOID)pRGBQUAD, Loop * sizeof(RGBQUAD));
  502. }
  503. }
  504. }
  505. if ((!Ok) ||
  506. (!ReadFile(hFile, &Seperator, sizeof(Seperator), &cbRead, NULL)) ||
  507. (cbRead != sizeof(Seperator)) ||
  508. (!ReadFile(hFile,
  509. &(GIF2DIBInfo.Map),
  510. sizeof(GIFMAP),
  511. &cbRead,
  512. NULL)) ||
  513. (cbRead != sizeof(GIFMAP)) ||
  514. (!ReadFile(hFile, &iFlags, sizeof(iFlags), &cbRead, NULL)) ||
  515. (cbRead != sizeof(iFlags))) {
  516. Ok = FALSE;
  517. } else {
  518. GIF2DIBInfo.pLineIncVec = (LPSHORT)((iFlags & GIFMAP_INTERLACE) ?
  519. Interleaved : NotInterleaved);
  520. GIF2DIBInfo.Map.CurY = *(GIF2DIBInfo.pLineIncVec++);
  521. GIF2DIBInfo.Map.CurX = 0;
  522. GIF2DIBInfo.PelMask =
  523. GIF2DIBInfo.LinesDone = 0;
  524. GIF2DIBInfo.RemainXPels = GIF2DIBInfo.cx;
  525. GIF2DIBInfo.pDIBLine1 =
  526. GIF2DIBInfo.pDIBCurLine =
  527. GIF2DIBInfo.pDIBNow = pDIB +
  528. (DWORD)sizeof(BITMAPINFOHEADER) +
  529. (DWORD)GIFPalSize +
  530. ((DWORD)(GIF2DIBInfo.cy - 1) *
  531. (DWORD)GIF2DIBInfo.cxBytes);
  532. Ok = DeCompressGIFFileToDIB(hFile,
  533. &GIF2DIBInfo,
  534. pLZWBuf,
  535. pfnOutputPels,
  536. BitCount);
  537. }
  538. LocalFree((HANDLE)GIF2DIBInfo.pGIFBuf);
  539. LocalFree((HANDLE)pLZWBuf);
  540. GlobalUnlock(hDIB);
  541. if (!Ok) {
  542. GlobalFree(hDIB);
  543. hDIB = NULL;
  544. }
  545. return(hDIB);
  546. }