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.

1769 lines
59 KiB

  1. //+-----------------------------------------------------------------------------------
  2. //
  3. // Microsoft
  4. // Copyright (c) Microsoft Corporation, 1999
  5. //
  6. // File: src\time\src\loadgif.cpp
  7. //
  8. // Contents: gif decoder, copied from direct animation source: danim\src\appel\util\loadgif.cpp
  9. //
  10. //------------------------------------------------------------------------------------
  11. //#include <wininetp.h>
  12. //bw #include "headers.h"
  13. // #define WIN32_LEAN_AND_MEAN
  14. #include <windows.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <stdarg.h>
  19. #include <ole2.h>
  20. #include <math.h>
  21. #include <windowsx.h>
  22. /*lint ++flb*/
  23. //bw DeclareTag(tagImageDecode, "Image Decode", "Image Decode Filters");
  24. const long COLORKEY_NOT_SET = -1;
  25. /*--
  26. Structs from IE img.hxx
  27. --*/
  28. void * __cdecl
  29. _calloc(size_t num, size_t size)
  30. {
  31. void * pv = malloc(num * size);
  32. if (NULL == pv)
  33. {
  34. return NULL;
  35. }
  36. ZeroMemory(pv, num * size);
  37. return pv;
  38. }
  39. enum
  40. {
  41. gifNoneSpecified = 0, // no disposal method specified
  42. gifNoDispose = 1, // do not dispose, leave the bits there
  43. gifRestoreBkgnd = 2, // replace the image with the background color
  44. gifRestorePrev = 3 // replace the image with the previous pixels
  45. };
  46. typedef struct _GCEDATA // data from GIF Graphic control extension
  47. {
  48. unsigned int uiDelayTime; // frame duration, initialy 1/100ths seconds
  49. // converted to milliseconds
  50. unsigned int uiDisposalMethod; // 0 - none specified.
  51. // 1 - do not dispose - leave bits in place.
  52. // 2 - replace with background color.
  53. // 3 - restore previous bits
  54. // >3 - not yet defined
  55. BOOL fTransparent; // TRUE is ucTransIndex describes transparent color
  56. unsigned char ucTransIndex; // transparent index
  57. } GCEDATA;
  58. typedef struct _GIFFRAME
  59. {
  60. struct _GIFFRAME *pgfNext;
  61. GCEDATA gced; // animation parameters for frame.
  62. int top; // bounds relative to the GIF logical screen
  63. int left;
  64. int width;
  65. int height;
  66. unsigned char *ppixels; // pointer to image pixel data
  67. int cColors; // number of entries in pcolors
  68. PALETTEENTRY *pcolors;
  69. PBITMAPINFO pbmi;
  70. HRGN hrgnVis; // region describing currently visible portion of the frame
  71. int iRgnKind; // region type for hrgnVis
  72. } GIFFRAME, *PGIFFRAME;
  73. typedef struct {
  74. BOOL fAnimating; // TRUE if animation is (still) running
  75. DWORD dwLoopIter; // current iteration of looped animation, not actually used for Netscape compliance reasons
  76. _GIFFRAME * pgfDraw; // last frame we need to draw
  77. DWORD dwNextTimeMS; // Time to display pgfDraw->pgfNext, or next iteration
  78. } GIFANIMATIONSTATE, *PGIFANIMATIONSTATE;
  79. #define dwGIFVerUnknown ((DWORD)0) // unknown version of GIF file
  80. #define dwGIFVer87a ((DWORD)87) // GIF87a file format
  81. #define dwGIFVer89a ((DWORD)89) // GIF89a file format.
  82. typedef struct _GIFANIMDATA
  83. {
  84. BOOL fAnimated; // TRUE if cFrames and pgf define a GIF animation
  85. BOOL fLooped; // TRUE if we've seen a Netscape loop block
  86. BOOL fHasTransparency; // TRUE if a frame is transparent, or if a frame does
  87. // not cover the entire logical screen.
  88. BOOL fNoBWMapping; // TRUE if we saw more than two colors in anywhere in the file.
  89. DWORD dwGIFVer; // GIF Version <see defines above> we need to special case 87a backgrounds
  90. unsigned short cLoops; // A la Netscape, we will treat this as
  91. // "loop forever" if it is zero.
  92. PGIFFRAME pgf; // animation frame entries
  93. PALETTEENTRY *pcolorsGlobal; // GIF global colors - NULL after GIF prepared for screen
  94. PGIFFRAME pgfLastProg; // remember the last frame to be drawn during decoding
  95. DWORD dwLastProgTimeMS; // time at which pgfLastProg was displayed.
  96. } GIFANIMDATA, *PGIFANIMDATA;
  97. /** End Structs **/
  98. #define MAXCOLORMAPSIZE 256
  99. #define TRUE 1
  100. #define FALSE 0
  101. #define CM_RED 0
  102. #define CM_GREEN 1
  103. #define CM_BLUE 2
  104. #define MAX_LWZ_BITS 12
  105. #define INTERLACE 0x40
  106. #define LOCALCOLORMAP 0x80
  107. #define BitSet(byte, bit) (((byte) & (bit)) == (bit))
  108. #define LM_to_uint(a,b) ((((unsigned int) b)<<8)|((unsigned int)a))
  109. #define dwIndefiniteGIFThreshold 300 // 300 seconds == 5 minutes
  110. // If the GIF runs longer than
  111. // this, we will assume the author
  112. // intended an indefinite run.
  113. #define dwMaxGIFBits 13107200 // keep corrupted GIFs from causing
  114. // us to allocate _too_ big a buffer.
  115. // This one is 1280 X 1024 X 10.
  116. typedef struct _GIFSCREEN
  117. {
  118. unsigned long Width;
  119. unsigned long Height;
  120. unsigned char ColorMap[3][MAXCOLORMAPSIZE];
  121. unsigned long BitPixel;
  122. unsigned long ColorResolution;
  123. unsigned long Background;
  124. unsigned long AspectRatio;
  125. }
  126. GIFSCREEN;
  127. typedef struct _GIF89
  128. {
  129. long transparent;
  130. long delayTime;
  131. long inputFlag;
  132. long disposal;
  133. }
  134. GIF89;
  135. #define MAX_STACK_SIZE ((1 << (MAX_LWZ_BITS)) * 2)
  136. #define MAX_TABLE_SIZE (1 << MAX_LWZ_BITS)
  137. typedef struct _GIFINFO
  138. {
  139. IStream *stream;
  140. GIF89 Gif89;
  141. long lGifLoc;
  142. long ZeroDataBlock;
  143. /*
  144. ** Pulled out of nextCode
  145. */
  146. long curbit, lastbit, get_done;
  147. long last_byte;
  148. long return_clear;
  149. /*
  150. ** Out of nextLWZ
  151. */
  152. unsigned short *pstack, *sp;
  153. long stacksize;
  154. long code_size, set_code_size;
  155. long max_code, max_code_size;
  156. long clear_code, end_code;
  157. /*
  158. * Were statics in procedures
  159. */
  160. unsigned char buf[280];
  161. unsigned short *table[2];
  162. long tablesize;
  163. long firstcode, oldcode;
  164. } GIFINFO,*PGIFINFO;
  165. /*
  166. DirectAnimation wrapper class for GIF info
  167. */
  168. class CImgGif
  169. {
  170. // Class methods
  171. public:
  172. CImgGif();
  173. ~CImgGif();
  174. unsigned char * ReadGIFMaster();
  175. BOOL Read(unsigned char *buffer, long len);
  176. long ReadColorMap(long number, unsigned char buffer[3][MAXCOLORMAPSIZE]);
  177. long DoExtension(long label);
  178. long GetDataBlock(unsigned char *buf);
  179. unsigned char * ReadImage(long len, long height, BOOL fInterlace, BOOL fGIFFrame);
  180. long readLWZ();
  181. long nextLWZ();
  182. long nextCode(long code_size);
  183. BOOL initLWZ(long input_code_size);
  184. unsigned short * growStack();
  185. BOOL growTables();
  186. BITMAPINFO * FinishDithering();
  187. // Data members
  188. public:
  189. LPCSTR _szFileName;
  190. BOOL _fInterleaved;
  191. BOOL _fInvalidateAll;
  192. int _yLogRow;
  193. GIFINFO _gifinfo;
  194. GIFANIMATIONSTATE _gas;
  195. GIFANIMDATA _gad;
  196. PALETTEENTRY _ape[256];
  197. int _xWidth;
  198. int _yHeight;
  199. LONG _lTrans;
  200. BYTE * _pbBits;
  201. } GIFIMAGE;
  202. CImgGif::CImgGif() {
  203. _gifinfo.pstack = NULL;
  204. _gifinfo.table[0] = NULL;
  205. _gifinfo.table[1] = NULL;
  206. }
  207. CImgGif::~CImgGif() {
  208. free(_gifinfo.pstack);
  209. free(_gifinfo.table[0]);
  210. free(_gifinfo.table[1]);
  211. PGIFFRAME nextPgf, curPgf;
  212. curPgf = _gad.pgf;
  213. while(curPgf != NULL) {
  214. nextPgf = curPgf->pgfNext;
  215. free(curPgf->ppixels);
  216. free(curPgf->pcolors);
  217. free(curPgf->pbmi);
  218. free(curPgf);
  219. curPgf = nextPgf;
  220. }
  221. }
  222. static int GetColorMode() { return 0; };
  223. #ifndef DEBUG
  224. #pragma optimize("t",on)
  225. #endif
  226. BOOL CImgGif::Read(unsigned char *buffer, long len)
  227. {
  228. DWORD lenout = 0;
  229. /* read len characters into buffer */
  230. _gifinfo.stream->Read(buffer,len,&lenout);
  231. return ((long)lenout == len);
  232. }
  233. long CImgGif::ReadColorMap(long number, unsigned char buffer[3][MAXCOLORMAPSIZE])
  234. {
  235. long i;
  236. unsigned char rgb[3];
  237. for (i = 0; i < number; ++i)
  238. {
  239. if (!Read(rgb, sizeof(rgb)))
  240. {
  241. //bw //bw TraceTag((tagImageDecode, "bad gif colormap."));
  242. return (TRUE);
  243. }
  244. buffer[CM_RED][i] = rgb[0];
  245. buffer[CM_GREEN][i] = rgb[1];
  246. buffer[CM_BLUE][i] = rgb[2];
  247. }
  248. return FALSE;
  249. }
  250. long
  251. CImgGif::GetDataBlock(unsigned char *buf)
  252. {
  253. unsigned char count;
  254. count = 0;
  255. if (!Read(&count, 1))
  256. {
  257. return -1;
  258. }
  259. _gifinfo.ZeroDataBlock = count == 0;
  260. if ((count != 0) && (!Read(buf, count)))
  261. {
  262. return -1;
  263. }
  264. return ((long) count);
  265. }
  266. #define MIN_CODE_BITS 5
  267. #define MIN_STACK_SIZE 64
  268. #define MINIMUM_CODE_SIZE 2
  269. BOOL CImgGif::initLWZ(long input_code_size)
  270. {
  271. if(input_code_size < MINIMUM_CODE_SIZE)
  272. return FALSE;
  273. _gifinfo.set_code_size = input_code_size;
  274. _gifinfo.code_size = _gifinfo.set_code_size + 1;
  275. _gifinfo.clear_code = 1 << _gifinfo.set_code_size;
  276. _gifinfo.end_code = _gifinfo.clear_code + 1;
  277. _gifinfo.max_code_size = 2 * _gifinfo.clear_code;
  278. _gifinfo.max_code = _gifinfo.clear_code + 2;
  279. _gifinfo.curbit = _gifinfo.lastbit = 0;
  280. _gifinfo.last_byte = 2;
  281. _gifinfo.get_done = FALSE;
  282. _gifinfo.return_clear = TRUE;
  283. if(input_code_size >= MIN_CODE_BITS)
  284. _gifinfo.stacksize = ((1 << (input_code_size)) * 2);
  285. else
  286. _gifinfo.stacksize = MIN_STACK_SIZE;
  287. if ( _gifinfo.pstack != NULL )
  288. free( _gifinfo.pstack );
  289. if ( _gifinfo.table[0] != NULL )
  290. free( _gifinfo.table[0] );
  291. if ( _gifinfo.table[1] != NULL )
  292. free( _gifinfo.table[1] );
  293. _gifinfo.table[0] = 0;
  294. _gifinfo.table[1] = 0;
  295. _gifinfo.pstack = 0;
  296. _gifinfo.pstack = (unsigned short *) malloc((_gifinfo.stacksize)*sizeof(unsigned short));
  297. if(_gifinfo.pstack == 0){
  298. goto ErrorExit;
  299. }
  300. _gifinfo.sp = _gifinfo.pstack;
  301. // Initialize the two tables.
  302. _gifinfo.tablesize = (_gifinfo.max_code_size);
  303. _gifinfo.table[0] = (unsigned short *) malloc((_gifinfo.tablesize)*sizeof(unsigned short));
  304. _gifinfo.table[1] = (unsigned short *) malloc((_gifinfo.tablesize)*sizeof(unsigned short));
  305. if((_gifinfo.table[0] == 0) || (_gifinfo.table[1] == 0)){
  306. goto ErrorExit;
  307. }
  308. return TRUE;
  309. ErrorExit:
  310. if(_gifinfo.pstack){
  311. free(_gifinfo.pstack);
  312. _gifinfo.pstack = 0;
  313. }
  314. if(_gifinfo.table[0]){
  315. free(_gifinfo.table[0]);
  316. _gifinfo.table[0] = 0;
  317. }
  318. if(_gifinfo.table[1]){
  319. free(_gifinfo.table[1]);
  320. _gifinfo.table[1] = 0;
  321. }
  322. return FALSE;
  323. }
  324. long CImgGif::nextCode(long code_size)
  325. {
  326. static const long maskTbl[16] =
  327. {
  328. 0x0000, 0x0001, 0x0003, 0x0007,
  329. 0x000f, 0x001f, 0x003f, 0x007f,
  330. 0x00ff, 0x01ff, 0x03ff, 0x07ff,
  331. 0x0fff, 0x1fff, 0x3fff, 0x7fff,
  332. };
  333. long i, j, ret, end;
  334. unsigned char *buf = &_gifinfo.buf[0];
  335. if (_gifinfo.return_clear)
  336. {
  337. _gifinfo.return_clear = FALSE;
  338. return _gifinfo.clear_code;
  339. }
  340. end = _gifinfo.curbit + code_size;
  341. if (end >= _gifinfo.lastbit)
  342. {
  343. long count;
  344. if (_gifinfo.get_done)
  345. {
  346. return -1;
  347. }
  348. buf[0] = buf[_gifinfo.last_byte - 2];
  349. buf[1] = buf[_gifinfo.last_byte - 1];
  350. if ((count = GetDataBlock(&buf[2])) == 0)
  351. _gifinfo.get_done = TRUE;
  352. if (count < 0)
  353. {
  354. return -1;
  355. }
  356. _gifinfo.last_byte = 2 + count;
  357. _gifinfo.curbit = (_gifinfo.curbit - _gifinfo.lastbit) + 16;
  358. _gifinfo.lastbit = (2 + count) * 8;
  359. end = _gifinfo.curbit + code_size;
  360. // Okay, bug 30784 time. It's possible that we only got 1
  361. // measly byte in the last data block. Rare, but it does happen.
  362. // In that case, the additional byte may still not supply us with
  363. // enough bits for the next code, so, as Mars Needs Women, IE
  364. // Needs Data.
  365. if ( end >= _gifinfo.lastbit && !_gifinfo.get_done )
  366. {
  367. // protect ourselve from the ( theoretically impossible )
  368. // case where between the last data block, the 2 bytes from
  369. // the block preceding that, and the potential 0xFF bytes in
  370. // the next block, we overflow the buffer.
  371. // Since count should always be 1,
  372. //bw Assert ( count == 1 );
  373. // there should be enough room in the buffer, so long as someone
  374. // doesn't shrink it.
  375. if ( count + 0x101 >= sizeof( _gifinfo.buf ) )
  376. {
  377. //bw Assert ( FALSE ); //
  378. return -1;
  379. }
  380. if ((count = GetDataBlock(&buf[2 + count])) == 0)
  381. _gifinfo.get_done = TRUE;
  382. if (count < 0)
  383. {
  384. return -1;
  385. }
  386. _gifinfo.last_byte += count;
  387. _gifinfo.lastbit = _gifinfo.last_byte * 8;
  388. end = _gifinfo.curbit + code_size;
  389. }
  390. }
  391. j = end / 8;
  392. i = _gifinfo.curbit / 8;
  393. if (i == j)
  394. ret = buf[i];
  395. else if (i + 1 == j)
  396. ret = buf[i] | (((long) buf[i + 1]) << 8);
  397. else
  398. ret = buf[i] | (((long) buf[i + 1]) << 8) | (((long) buf[i + 2]) << 16);
  399. ret = (ret >> (_gifinfo.curbit % 8)) & maskTbl[code_size];
  400. _gifinfo.curbit += code_size;
  401. return ret;
  402. }
  403. // Grows the stack and returns the top of the stack.
  404. unsigned short *
  405. CImgGif::growStack()
  406. {
  407. long index;
  408. unsigned short *lp;
  409. if (_gifinfo.stacksize >= MAX_STACK_SIZE) return 0;
  410. index = long(_gifinfo.sp - _gifinfo.pstack);
  411. lp = (unsigned short *)realloc(_gifinfo.pstack, (_gifinfo.stacksize)*2*sizeof(unsigned short));
  412. if(lp == 0)
  413. return 0;
  414. _gifinfo.pstack = lp;
  415. _gifinfo.sp = &(_gifinfo.pstack[index]);
  416. _gifinfo.stacksize = (_gifinfo.stacksize)*2;
  417. lp = &(_gifinfo.pstack[_gifinfo.stacksize]);
  418. return lp;
  419. }
  420. BOOL
  421. CImgGif::growTables()
  422. {
  423. unsigned short *lp;
  424. lp = (unsigned short *) realloc(_gifinfo.table[0], (_gifinfo.max_code_size)*sizeof(unsigned short));
  425. if(lp == 0){
  426. return FALSE;
  427. }
  428. _gifinfo.table[0] = lp;
  429. lp = (unsigned short *) realloc(_gifinfo.table[1], (_gifinfo.max_code_size)*sizeof(unsigned short));
  430. if(lp == 0){
  431. return FALSE;
  432. }
  433. _gifinfo.table[1] = lp;
  434. return TRUE;
  435. }
  436. inline
  437. long CImgGif::readLWZ()
  438. {
  439. return((_gifinfo.sp > _gifinfo.pstack) ? *--(_gifinfo.sp) : nextLWZ());
  440. }
  441. #define CODE_MASK 0xffff
  442. long CImgGif::nextLWZ()
  443. {
  444. long code, incode;
  445. unsigned short usi;
  446. unsigned short *table0 = _gifinfo.table[0];
  447. unsigned short *table1 = _gifinfo.table[1];
  448. unsigned short *pstacktop = &(_gifinfo.pstack[_gifinfo.stacksize]);
  449. while ((code = nextCode(_gifinfo.code_size)) >= 0)
  450. {
  451. if (code == _gifinfo.clear_code)
  452. {
  453. /* corrupt GIFs can make this happen */
  454. if (_gifinfo.clear_code >= (1 << MAX_LWZ_BITS))
  455. {
  456. return -2;
  457. }
  458. _gifinfo.code_size = _gifinfo.set_code_size + 1;
  459. _gifinfo.max_code_size = 2 * _gifinfo.clear_code;
  460. _gifinfo.max_code = _gifinfo.clear_code + 2;
  461. if(!growTables())
  462. return -2;
  463. table0 = _gifinfo.table[0];
  464. table1 = _gifinfo.table[1];
  465. _gifinfo.tablesize = _gifinfo.max_code_size;
  466. for (usi = 0; usi < _gifinfo.clear_code; ++usi)
  467. {
  468. table1[usi] = usi;
  469. }
  470. memset(table0,0,sizeof(unsigned short )*(_gifinfo.tablesize));
  471. memset(&table1[_gifinfo.clear_code],0,sizeof(unsigned short)*((_gifinfo.tablesize)-_gifinfo.clear_code));
  472. _gifinfo.sp = _gifinfo.pstack;
  473. do
  474. {
  475. _gifinfo.firstcode = _gifinfo.oldcode = nextCode(_gifinfo.code_size);
  476. }
  477. while (_gifinfo.firstcode == _gifinfo.clear_code);
  478. return _gifinfo.firstcode;
  479. }
  480. if (code == _gifinfo.end_code)
  481. {
  482. long count;
  483. unsigned char buf[260];
  484. if (_gifinfo.ZeroDataBlock)
  485. {
  486. return -2;
  487. }
  488. while ((count = GetDataBlock(buf)) > 0)
  489. ;
  490. if (count != 0)
  491. return -2;
  492. }
  493. incode = code;
  494. if (code >= _gifinfo.max_code)
  495. {
  496. if (_gifinfo.sp >= pstacktop){
  497. pstacktop = growStack();
  498. if(pstacktop == 0)
  499. return -2;
  500. }
  501. *(_gifinfo.sp)++ = (unsigned short)((CODE_MASK ) & (_gifinfo.firstcode));
  502. code = _gifinfo.oldcode;
  503. }
  504. #if FEATURE_FAST
  505. // (andyp) easy speedup here for ie3.1 (too late for ie3.0):
  506. //
  507. // 1. move growStack code out of loop (use max 12-bit/4k slop).
  508. // 2. do "sp = _gifinfo.sp" so it will get enreg'ed.
  509. // 3. un-inline growStack (and growTables).
  510. // 4. change short's to int's (benefits win32) (esp. table1 & table2)
  511. // (n.b. int not long, so we'll keep win3.1 perf)
  512. // 5. change long's to int's (benefits win16) (esp. code).
  513. //
  514. // together these will make the loop very tight w/ everything kept
  515. // enregistered and no 66 overrides.
  516. //
  517. // one caveat is that on average this loop iterates 4x so it's
  518. // not clear how much the speedup will really gain us until we
  519. // look at the outer loop as well.
  520. #endif
  521. while (code >= _gifinfo.clear_code)
  522. {
  523. if (_gifinfo.sp >= pstacktop){
  524. pstacktop = growStack();
  525. if(pstacktop == 0)
  526. return -2;
  527. }
  528. *(_gifinfo.sp)++ = table1[code];
  529. if (code == (long)(table0[code]))
  530. {
  531. return (code);
  532. }
  533. code = (long)(table0[code]);
  534. }
  535. if (_gifinfo.sp >= pstacktop){
  536. pstacktop = growStack();
  537. if(pstacktop == 0)
  538. return -2;
  539. }
  540. _gifinfo.firstcode = (long)table1[code];
  541. *(_gifinfo.sp)++ = table1[code];
  542. if ((code = _gifinfo.max_code) < (1 << MAX_LWZ_BITS))
  543. {
  544. table0[code] = (USHORT)(_gifinfo.oldcode) & CODE_MASK;
  545. table1[code] = (USHORT)(_gifinfo.firstcode) & CODE_MASK;
  546. ++_gifinfo.max_code;
  547. if ((_gifinfo.max_code >= _gifinfo.max_code_size) && (_gifinfo.max_code_size < ((1 << MAX_LWZ_BITS))))
  548. {
  549. _gifinfo.max_code_size *= 2;
  550. ++_gifinfo.code_size;
  551. if(!growTables())
  552. return -2;
  553. table0 = _gifinfo.table[0];
  554. table1 = _gifinfo.table[1];
  555. // Tables have been reallocated to the correct size but initialization
  556. // still remains to be done. This initialization is different from
  557. // the first time initialization of these tables.
  558. memset(&(table0[_gifinfo.tablesize]),0,
  559. sizeof(unsigned short )*(_gifinfo.max_code_size - _gifinfo.tablesize));
  560. memset(&(table1[_gifinfo.tablesize]),0,
  561. sizeof(unsigned short )*(_gifinfo.max_code_size - _gifinfo.tablesize));
  562. _gifinfo.tablesize = (_gifinfo.max_code_size);
  563. }
  564. }
  565. _gifinfo.oldcode = incode;
  566. if (_gifinfo.sp > _gifinfo.pstack)
  567. return ((long)(*--(_gifinfo.sp)));
  568. }
  569. return code;
  570. }
  571. #ifndef DEBUG
  572. // Return to default optimization flags
  573. #pragma optimize("",on)
  574. #endif
  575. unsigned char *
  576. CImgGif::ReadImage(long len, long height, BOOL fInterlace, BOOL fGIFFrame)
  577. {
  578. unsigned char *dp, c;
  579. long v;
  580. long xpos = 0, ypos = 0, pass = 0;
  581. unsigned char *image;
  582. long padlen = ((len + 3) / 4) * 4;
  583. DWORD cbImage = 0;
  584. char buf[256]; // need a buffer to read trailing blocks ( up to terminator ) into
  585. //ULONG ulCoversImg = IMGBITS_PARTIAL;
  586. /*
  587. ** Initialize the Compression routines
  588. */
  589. if (!Read(&c, 1))
  590. {
  591. return (NULL);
  592. }
  593. /*
  594. ** If this is an "uninteresting picture" ignore it.
  595. */
  596. cbImage = padlen * height * sizeof(char);
  597. if ( cbImage > dwMaxGIFBits
  598. || (image = (unsigned char *) _calloc(1, cbImage)) == NULL)
  599. {
  600. //bw TraceTag((tagImageDecode, "Cannot allocate space for gif image data\n"));
  601. return (NULL);
  602. }
  603. if (c == 1)
  604. {
  605. // Netscape seems to field these bogus GIFs by filling treating them
  606. // as transparent. While not the optimal way to simulate this effect,
  607. // we'll fake it by pushing the initial code size up to a safe value,
  608. // consuming the input, and returning a buffer full of the transparent
  609. // color or zero, if no transparency is indicated.
  610. if (initLWZ(MINIMUM_CODE_SIZE))
  611. while (readLWZ() >= 0);
  612. else {
  613. //bw TraceTag((tagImageDecode, "GIF: failed LZW decode.\n"));
  614. free(image);
  615. return (NULL);
  616. }
  617. if (_gifinfo.Gif89.transparent != -1)
  618. FillMemory(image, cbImage, (BYTE)_gifinfo.Gif89.transparent);
  619. else // fall back on the background color
  620. FillMemory(image, cbImage, 0);
  621. return image;
  622. }
  623. else if (initLWZ(c) == FALSE)
  624. {
  625. free(image);
  626. //bw TraceTag((tagImageDecode, "GIF: failed LZW decode.\n"));
  627. return NULL;
  628. }
  629. if (!fGIFFrame)
  630. _pbBits = image;
  631. if (fInterlace)
  632. {
  633. long i;
  634. long pass = 0, step = 8;
  635. if (!fGIFFrame && (height > 4))
  636. _fInterleaved = TRUE;
  637. for (i = 0; i < height; i++)
  638. {
  639. // message("readimage, logical=%d, offset=%d\n", i, padlen * ((height-1) - ypos));
  640. dp = &image[padlen * ((height-1) - ypos)];
  641. for (xpos = 0; xpos < len; xpos++)
  642. {
  643. if ((v = readLWZ()) < 0)
  644. goto abort;
  645. *dp++ = (unsigned char) v;
  646. }
  647. ypos += step;
  648. while (ypos >= height)
  649. {
  650. if (pass++ > 0)
  651. step /= 2;
  652. ypos = step / 2;
  653. /*if (!fGIFFrame && pass == 1)
  654. {
  655. ulCoversImg = IMGBITS_TOTAL;
  656. }*/
  657. }
  658. if (!fGIFFrame)
  659. {
  660. _yLogRow = i;
  661. /*if ((i & PROG_INTERVAL) == 0)
  662. {
  663. // Post ProgDraw (IE code has delay-logic)
  664. OnProg(FALSE, ulCoversImg);
  665. }*/
  666. }
  667. }
  668. /*if (!fGIFFrame)
  669. {
  670. OnProg(TRUE, ulCoversImg);
  671. }*/
  672. if (!fGIFFrame && height <= 4)
  673. {
  674. _yLogRow = height-1;
  675. }
  676. }
  677. else
  678. {
  679. if (!fGIFFrame)
  680. _yLogRow = -1;
  681. for (ypos = height-1; ypos >= 0; ypos--)
  682. {
  683. dp = &image[padlen * ypos];
  684. for (xpos = 0; xpos < len; xpos++)
  685. {
  686. if ((v = readLWZ()) < 0)
  687. goto abort;
  688. *dp++ = (unsigned char) v;
  689. }
  690. if (!fGIFFrame)
  691. {
  692. _yLogRow++;
  693. // message("readimage, logical=%d, offset=%d\n", _yLogRow, padlen * ypos);
  694. /*if ((_yLogRow & PROG_INTERVAL) == 0)
  695. {
  696. // Post ProgDraw (IE code has delay-logic)
  697. OnProg(FALSE, ulCoversImg);
  698. }*/
  699. }
  700. }
  701. /*if (!fGIFFrame)
  702. {
  703. OnProg(TRUE, ulCoversImg);
  704. }*/
  705. }
  706. // consume blocks up to image block terminator so we can proceed to the next image
  707. while (GetDataBlock((unsigned char *) buf) > 0)
  708. ;
  709. return (image);
  710. abort:
  711. /*if (!fGIFFrame)
  712. OnProg(TRUE, ulCoversImg);*/
  713. return NULL;
  714. }
  715. long CImgGif::DoExtension(long label)
  716. {
  717. unsigned char buf[256];
  718. int count;
  719. switch (label)
  720. {
  721. case 0x01: /* Plain Text Extension */
  722. break;
  723. case 0xff: /* Application Extension */
  724. // Is it the Netscape looping extension
  725. count = GetDataBlock((unsigned char *) buf);
  726. if (count >= 11)
  727. {
  728. char *szNSExt = "NETSCAPE2.0";
  729. if ( memcmp( buf, szNSExt, strlen( szNSExt ) ) == 0 )
  730. { // if it has their signature, get the data subblock with the iter count
  731. count = GetDataBlock((unsigned char *) buf);
  732. if ( count >= 3 )
  733. {
  734. _gad.fLooped = TRUE;
  735. _gad.cLoops = (buf[2] << 8) | buf[1];
  736. }
  737. }
  738. }
  739. while (GetDataBlock((unsigned char *) buf) > 0)
  740. ;
  741. return FALSE;
  742. break;
  743. case 0xfe: /* Comment Extension */
  744. while (GetDataBlock((unsigned char *) buf) > 0)
  745. {
  746. //bw TraceTag((tagImageDecode, "GIF comment: %s\n", buf));
  747. }
  748. return FALSE;
  749. case 0xf9: /* Graphic Control Extension */
  750. count = GetDataBlock((unsigned char *) buf);
  751. if (count >= 3)
  752. {
  753. _gifinfo.Gif89.disposal = (buf[0] >> 2) & 0x7;
  754. _gifinfo.Gif89.inputFlag = (buf[0] >> 1) & 0x1;
  755. _gifinfo.Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
  756. if ((buf[0] & 0x1) != 0)
  757. _gifinfo.Gif89.transparent = buf[3];
  758. else
  759. _gifinfo.Gif89.transparent = -1;
  760. }
  761. while (GetDataBlock((unsigned char *) buf) > 0)
  762. ;
  763. return FALSE;
  764. default:
  765. break;
  766. }
  767. while (GetDataBlock((unsigned char *) buf) > 0)
  768. ;
  769. return FALSE;
  770. }
  771. BOOL IsGifHdr(BYTE * pb)
  772. {
  773. return(pb[0] == 'G' && pb[1] == 'I' && pb[2] == 'F'
  774. && pb[3] == '8' && (pb[4] == '7' || pb[4] == '9') && pb[5] == 'a');
  775. }
  776. PBITMAPINFO x_8BPIBitmap(int xsize, int ysize)
  777. {
  778. PBITMAPINFO pbmi;
  779. if (GetColorMode() == 8)
  780. {
  781. pbmi = (PBITMAPINFO) _calloc(1, sizeof(BITMAPINFOHEADER) + 256 * sizeof(WORD));
  782. if (!pbmi)
  783. {
  784. return NULL;
  785. }
  786. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  787. pbmi->bmiHeader.biWidth = xsize;
  788. pbmi->bmiHeader.biHeight = ysize;
  789. pbmi->bmiHeader.biPlanes = 1;
  790. pbmi->bmiHeader.biBitCount = 8;
  791. pbmi->bmiHeader.biCompression = BI_RGB; /* no compression */
  792. pbmi->bmiHeader.biSizeImage = 0; /* not needed when not compressed */
  793. pbmi->bmiHeader.biXPelsPerMeter = 0;
  794. pbmi->bmiHeader.biYPelsPerMeter = 0;
  795. pbmi->bmiHeader.biClrUsed = 256;
  796. pbmi->bmiHeader.biClrImportant = 0;
  797. }
  798. else
  799. {
  800. pbmi = (PBITMAPINFO) _calloc(1, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
  801. if (!pbmi)
  802. {
  803. return NULL;
  804. }
  805. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  806. pbmi->bmiHeader.biWidth = xsize;
  807. pbmi->bmiHeader.biHeight = ysize;
  808. pbmi->bmiHeader.biPlanes = 1;
  809. pbmi->bmiHeader.biBitCount = 8;
  810. pbmi->bmiHeader.biCompression = BI_RGB; /* no compression */
  811. pbmi->bmiHeader.biSizeImage = 0; /* not needed when not compressed */
  812. pbmi->bmiHeader.biXPelsPerMeter = 0;
  813. pbmi->bmiHeader.biYPelsPerMeter = 0;
  814. pbmi->bmiHeader.biClrUsed = 256;
  815. pbmi->bmiHeader.biClrImportant = 0;
  816. }
  817. return pbmi;
  818. }
  819. /*
  820. For color images.
  821. This routine should only be used when drawing to an 8 bit palette screen.
  822. It always creates a DIB in DIB_PAL_COLORS format.
  823. */
  824. PBITMAPINFO BIT_Make_DIB_PAL_Header(int xsize, int ysize)
  825. {
  826. int i;
  827. PBITMAPINFO pbmi;
  828. WORD *pw;
  829. pbmi = x_8BPIBitmap(xsize, ysize);
  830. if (!pbmi)
  831. {
  832. return NULL;
  833. }
  834. pw = (WORD *) pbmi->bmiColors;
  835. for (i = 0; i < 256; i++)
  836. {
  837. pw[i] = (WORD)i;
  838. }
  839. return pbmi;
  840. }
  841. /*
  842. For color images.
  843. This routine is used when drawing to the nonpalette screens. It always creates
  844. DIBs in DIB_RGB_COLORS format.
  845. If there is a transparent color, it is modified in the palette to be the
  846. background color for the window.
  847. */
  848. PBITMAPINFO BIT_Make_DIB_RGB_Header_Screen(int xsize, int ysize,
  849. int cEntries, PALETTEENTRY * rgpe, int transparent)
  850. {
  851. int i;
  852. PBITMAPINFO pbmi;
  853. pbmi = x_8BPIBitmap(xsize, ysize);
  854. if (!pbmi)
  855. {
  856. return NULL;
  857. }
  858. for (i = 0; i < cEntries; i++)
  859. {
  860. pbmi->bmiColors[i].rgbRed = rgpe[i].peRed;
  861. pbmi->bmiColors[i].rgbGreen = rgpe[i].peGreen;
  862. pbmi->bmiColors[i].rgbBlue = rgpe[i].peBlue;
  863. pbmi->bmiColors[i].rgbReserved = 0;
  864. }
  865. /*
  866. if (transparent != -1)
  867. {
  868. COLORREF color;
  869. color = PREF_GetBackgroundColor();
  870. pbmi->bmiColors[transparent].rgbRed = GetRValue(color);
  871. pbmi->bmiColors[transparent].rgbGreen = GetGValue(color);
  872. pbmi->bmiColors[transparent].rgbBlue = GetBValue(color);
  873. }
  874. */
  875. return pbmi;
  876. }
  877. unsigned char *
  878. CImgGif::ReadGIFMaster()
  879. {
  880. HRESULT hr = S_OK;
  881. unsigned char buf[16];
  882. unsigned char c;
  883. unsigned char localColorMap[3][MAXCOLORMAPSIZE];
  884. long useGlobalColormap;
  885. long imageCount = 0;
  886. long imageNumber = 1;
  887. unsigned char *image = NULL;
  888. unsigned long i;
  889. long bitPixel;
  890. PGIFFRAME pgfLast = NULL;
  891. PGIFFRAME pgfNew;
  892. GIFSCREEN* GifScreen = new GIFSCREEN;
  893. if (GifScreen == NULL)
  894. {
  895. hr = E_FAIL;
  896. goto done;
  897. }
  898. _gifinfo.ZeroDataBlock = 0;
  899. /*
  900. * Initialize GIF89 extensions
  901. */
  902. _gifinfo.Gif89.transparent = -1;
  903. _gifinfo.Gif89.delayTime = 5;
  904. _gifinfo.Gif89.inputFlag = -1;
  905. _gifinfo.Gif89.disposal = 0;
  906. _gifinfo.lGifLoc = 0;
  907. // initialize our animation fields
  908. _gad.fAnimated = FALSE; // set to TRUE if we see more than one image
  909. _gad.fLooped = FALSE; // TRUE if we've seen a Netscape loop block
  910. _gad.fHasTransparency = FALSE; // until proven otherwise
  911. _gad.fNoBWMapping = FALSE;
  912. _gad.dwGIFVer = dwGIFVerUnknown;
  913. _gad.cLoops = 0;
  914. _gad.pgf = NULL;
  915. _gad.pcolorsGlobal = NULL;
  916. if (!Read(buf, 6))
  917. {
  918. //bw TraceTag((tagImageDecode, "GIF: error reading magic number\n"));
  919. hr = E_FAIL;
  920. goto done;
  921. }
  922. if (!IsGifHdr(buf)) {
  923. //bw TraceTag((tagImageDecode, "GIF: Malformed header\n"));
  924. hr = E_FAIL;
  925. goto done;
  926. }
  927. _gad.dwGIFVer = (buf[4] == '7') ? dwGIFVer87a : dwGIFVer89a;
  928. if (!Read(buf, 7))
  929. {
  930. //bw TraceTag((tagImageDecode, "GIF: failed to read screen descriptor\n"));
  931. hr = E_FAIL;
  932. goto done;
  933. }
  934. GifScreen->Width = LM_to_uint(buf[0], buf[1]);
  935. GifScreen->Height = LM_to_uint(buf[2], buf[3]);
  936. GifScreen->BitPixel = 2 << (buf[4] & 0x07);
  937. GifScreen->ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
  938. GifScreen->Background = buf[5];
  939. GifScreen->AspectRatio = buf[6];
  940. if (BitSet(buf[4], LOCALCOLORMAP))
  941. { /* Global Colormap */
  942. int scale = 65536 / MAXCOLORMAPSIZE;
  943. if (ReadColorMap(GifScreen->BitPixel, GifScreen->ColorMap))
  944. {
  945. //bw TraceTag((tagImageDecode, "error reading global colormap\n"));
  946. hr = E_FAIL;
  947. goto done;
  948. }
  949. for (i = 0; i < GifScreen->BitPixel; i++)
  950. {
  951. int tmp;
  952. tmp = (BYTE) (GifScreen->ColorMap[0][i]);
  953. _ape[i].peRed = (BYTE) (GifScreen->ColorMap[0][i]);
  954. _ape[i].peGreen = (BYTE) (GifScreen->ColorMap[1][i]);
  955. _ape[i].peBlue = (BYTE) (GifScreen->ColorMap[2][i]);
  956. _ape[i].peFlags = (BYTE) 0;
  957. }
  958. for (i = GifScreen->BitPixel; i < MAXCOLORMAPSIZE; i++)
  959. {
  960. _ape[i].peRed = (BYTE) 0;
  961. _ape[i].peGreen = (BYTE) 0;
  962. _ape[i].peBlue = (BYTE) 0;
  963. _ape[i].peFlags = (BYTE) 0;
  964. }
  965. }
  966. if (GifScreen->AspectRatio != 0 && GifScreen->AspectRatio != 49)
  967. {
  968. float r;
  969. r = ((float) (GifScreen->AspectRatio) + (float) 15.0) / (float) 64.0;
  970. //bw TraceTag((tagImageDecode, "Warning: non-square pixels!\n"));
  971. }
  972. for (;; ) // our appetite now knows no bounds save termination or error
  973. {
  974. if (!Read(&c, 1))
  975. {
  976. //bw TraceTag((tagImageDecode, "EOF / read error on image data\n"));
  977. hr = E_FAIL;
  978. goto done;
  979. }
  980. if (c == ';')
  981. { /* GIF terminator */
  982. if (imageCount < imageNumber)
  983. {
  984. //bw TraceTag((tagImageDecode, "No images found in file\n"));
  985. hr = E_FAIL;
  986. goto done;
  987. }
  988. break;
  989. }
  990. if (c == '!')
  991. { /* Extension */
  992. if (!Read(&c, 1))
  993. {
  994. //bw TraceTag((tagImageDecode, "EOF / read error on extension function code\n"));
  995. hr = E_FAIL;
  996. goto done;
  997. }
  998. DoExtension(c);
  999. continue;
  1000. }
  1001. if (c != ',')
  1002. { /* Not a valid start character */
  1003. break;
  1004. }
  1005. ++imageCount;
  1006. if (!Read(buf, 9))
  1007. {
  1008. //bw TraceTag((tagImageDecode, "couldn't read left/top/width/height\n"));
  1009. hr = E_FAIL;
  1010. goto done;
  1011. }
  1012. useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);
  1013. bitPixel = 1 << ((buf[8] & 0x07) + 1);
  1014. /*
  1015. * We only want to set width and height for the imageNumber
  1016. * we are requesting.
  1017. */
  1018. if (imageCount == imageNumber)
  1019. {
  1020. // Replicate some of Netscape's special cases:
  1021. // Don't use the logical screen if it's a GIF87a and the topLeft of the first image is at the origin.
  1022. // Don't use the logical screen if the first image spills out of the logical screen.
  1023. // These are artifacts of primitive authoring tools falling into the hands of hapless users.
  1024. RECT rectImage; // rect defining bounds of GIF
  1025. RECT rectLS; // rect defining bounds of GIF logical screen.
  1026. RECT rectSect; // intersection of image an logical screen
  1027. BOOL fNoSpill; // True if the image doesn't spill out of the logical screen
  1028. BOOL fGoofy87a; // TRUE if its one of the 87a pathologies that Netscape special cases
  1029. rectImage.left = LM_to_uint(buf[0], buf[1]);
  1030. rectImage.top = LM_to_uint(buf[2], buf[3]);
  1031. rectImage.right = rectImage.left + LM_to_uint(buf[4], buf[5]);
  1032. rectImage.bottom = rectImage.top + LM_to_uint(buf[6], buf[7]);
  1033. rectLS.left = rectLS.top = 0;
  1034. rectLS.right = GifScreen->Width;
  1035. rectLS.bottom = GifScreen->Height;
  1036. IntersectRect( &rectSect, &rectImage, &rectLS );
  1037. fNoSpill = EqualRect( &rectImage, &rectSect );
  1038. fGoofy87a = FALSE;
  1039. if (_gad.dwGIFVer == dwGIFVer87a)
  1040. {
  1041. // netscape ignores the logical screen if the image is flush against
  1042. // either the upper left or lower right corner
  1043. fGoofy87a = (rectImage.top == 0 && rectImage.left == 0) ||
  1044. (rectImage.bottom == rectLS.bottom &&
  1045. rectImage.right == rectLS.right);
  1046. }
  1047. if (!fGoofy87a && fNoSpill)
  1048. {
  1049. _xWidth = GifScreen->Width;
  1050. _yHeight = GifScreen->Height;
  1051. }
  1052. else
  1053. {
  1054. // Something is amiss. Fall back to the image's dimensions.
  1055. // If the sizes match, but the image is offset, or we're ignoring
  1056. // the logical screen cuz it's a goofy 87a, then pull it back to
  1057. // to the origin
  1058. if ((LM_to_uint(buf[4], buf[5]) == GifScreen->Width &&
  1059. LM_to_uint(buf[6], buf[7]) == GifScreen->Height) ||
  1060. fGoofy87a)
  1061. {
  1062. buf[0] = buf[1] = 0; // left corner to zero
  1063. buf[2] = buf[3] = 0; // top to zero.
  1064. }
  1065. _xWidth = LM_to_uint(buf[4], buf[5]);
  1066. _yHeight = LM_to_uint(buf[6], buf[7]);
  1067. }
  1068. _lTrans = _gifinfo.Gif89.transparent;
  1069. // Post WHKNOWN
  1070. //OnSize(_xWidth, _yHeight, _lTrans);
  1071. }
  1072. if (!useGlobalColormap)
  1073. {
  1074. if (ReadColorMap(bitPixel, localColorMap))
  1075. {
  1076. //bw TraceTag((tagImageDecode, "error reading local colormap\n"));
  1077. hr = E_FAIL;
  1078. goto done;
  1079. }
  1080. }
  1081. // We allocate a frame record for each imag in the GIF stream, including
  1082. // the first/primary image.
  1083. pgfNew = (PGIFFRAME) _calloc(1, sizeof(GIFFRAME));
  1084. if ( pgfNew == NULL )
  1085. {
  1086. //bw TraceTag((tagImageDecode, "not enough memory for GIF frame\n"));
  1087. hr = E_FAIL;
  1088. goto done;
  1089. }
  1090. if ( _gifinfo.Gif89.delayTime != -1 )
  1091. {
  1092. // we have a fresh control extension for this block
  1093. // convert to milliseconds
  1094. pgfNew->gced.uiDelayTime = _gifinfo.Gif89.delayTime * 10;
  1095. //REVIEW(seanf): crude hack to cope with 'degenerate animations' whose timing is set to some
  1096. // small value becaue of the delays imposed by Netscape's animation process
  1097. if ( pgfNew->gced.uiDelayTime <= 50 ) // assume these small values imply Netscape encoding delay
  1098. pgfNew->gced.uiDelayTime = 100; // pick a larger value s.t. the frame will be visible
  1099. pgfNew->gced.uiDisposalMethod = _gifinfo.Gif89.disposal;
  1100. pgfNew->gced.fTransparent = _gifinfo.Gif89.transparent != -1;
  1101. pgfNew->gced.ucTransIndex = (unsigned char)_gifinfo.Gif89.transparent;
  1102. }
  1103. else
  1104. { // fake one up s.t. GIFs that rely solely on Netscape's delay to time their animations will play
  1105. // The spec says that the scope of one of these blocks is the image after the block.
  1106. // Netscape says 'until further notice'. So we play it their way up to a point. We
  1107. // propagate the disposal method and transparency. Since Netscape doesn't honor the timing
  1108. // we use our default timing for these images.
  1109. pgfNew->gced.uiDelayTime = 100;
  1110. pgfNew->gced.uiDisposalMethod = _gifinfo.Gif89.disposal;
  1111. pgfNew->gced.fTransparent = _gifinfo.Gif89.transparent != -1;
  1112. pgfNew->gced.ucTransIndex = (unsigned char)_gifinfo.Gif89.transparent;
  1113. }
  1114. pgfNew->top = LM_to_uint(buf[2], buf[3]); // bounds relative to the GIF logical screen
  1115. pgfNew->left = LM_to_uint(buf[0], buf[1]);
  1116. pgfNew->width = LM_to_uint(buf[4], buf[5]);
  1117. pgfNew->height = LM_to_uint(buf[6], buf[7]);
  1118. // Images that are offset, or do not cover the full logical screen are 'transparent' in the
  1119. // sense that they require us to matte the frame onto the background.
  1120. if (!_gad.fHasTransparency && (pgfNew->gced.fTransparent ||
  1121. pgfNew->top != 0 ||
  1122. pgfNew->left != 0 ||
  1123. (UINT)pgfNew->width != (UINT)GifScreen->Width ||
  1124. (UINT)pgfNew->height != (UINT)GifScreen->Height))
  1125. {
  1126. _gad.fHasTransparency = TRUE;
  1127. //if (_lTrans == -1)
  1128. // OnTrans(0);
  1129. }
  1130. // We don't need to allocate a handle for the simple region case.
  1131. // FrancisH says Windows is too much of a cheapskate to allow us the simplicity
  1132. // of allocating the region once and modifying as needed. Well, okay, he didn't
  1133. // put it that way...
  1134. pgfNew->hrgnVis = NULL;
  1135. pgfNew->iRgnKind = NULLREGION;
  1136. if (!useGlobalColormap)
  1137. {
  1138. // remember that we saw a local color table and only map two-color images
  1139. // if we have a homogenous color environment
  1140. _gad.fNoBWMapping = _gad.fNoBWMapping || bitPixel > 2;
  1141. // CALLOC will set unused colors to <0,0,0,0>
  1142. pgfNew->pcolors = (PALETTEENTRY *) _calloc(MAXCOLORMAPSIZE, sizeof(PALETTEENTRY));
  1143. if ( pgfNew->pcolors == NULL )
  1144. {
  1145. DeleteRgn( pgfNew->hrgnVis );
  1146. free( pgfNew );
  1147. //bw TraceTag((tagImageDecode, "not enough memory for GIF frame colors\n"));
  1148. hr = E_FAIL;
  1149. goto done;
  1150. }
  1151. else
  1152. {
  1153. for (i = 0; i < (ULONG)bitPixel; ++i)
  1154. {
  1155. pgfNew->pcolors[i].peRed = localColorMap[CM_RED][i];
  1156. pgfNew->pcolors[i].peGreen = localColorMap[CM_GREEN][i];
  1157. pgfNew->pcolors[i].peBlue = localColorMap[CM_BLUE][i];
  1158. }
  1159. pgfNew->cColors = bitPixel;
  1160. }
  1161. }
  1162. else
  1163. {
  1164. if ( _gad.pcolorsGlobal == NULL )
  1165. { // Whoa! Somebody's interested in the global color table
  1166. // CALLOC will set unused colors to <0,0,0,0>
  1167. _gad.pcolorsGlobal = (PALETTEENTRY *) _calloc(MAXCOLORMAPSIZE, sizeof(PALETTEENTRY));
  1168. _gad.fNoBWMapping = _gad.fNoBWMapping || GifScreen->BitPixel > 2;
  1169. if ( _gad.pcolorsGlobal != NULL )
  1170. {
  1171. CopyMemory(_gad.pcolorsGlobal, _ape,
  1172. GifScreen->BitPixel * sizeof(PALETTEENTRY) );
  1173. }
  1174. else
  1175. {
  1176. DeleteRgn( pgfNew->hrgnVis );
  1177. free( pgfNew );
  1178. //bw TraceTag((tagImageDecode, "not enough memory for GIF frame colors\n"));
  1179. hr = E_FAIL;
  1180. goto done;
  1181. }
  1182. }
  1183. pgfNew->cColors = GifScreen->BitPixel;
  1184. pgfNew->pcolors = _gad.pcolorsGlobal;
  1185. }
  1186. // Get this in here so that GifStrectchDIBits can use it during progressive
  1187. // rendering.
  1188. if ( _gad.pgf == NULL )
  1189. _gad.pgf = pgfNew;
  1190. pgfNew->ppixels = ReadImage(LM_to_uint(buf[4], buf[5]), // width
  1191. LM_to_uint(buf[6], buf[7]), // height
  1192. BitSet(buf[8], INTERLACE),
  1193. imageCount != imageNumber);
  1194. if ( pgfNew->ppixels != NULL )
  1195. {
  1196. // Oh JOY of JOYS! We got the pixels!
  1197. if (pgfLast != NULL)
  1198. {
  1199. int transparent = (pgfNew->gced.fTransparent) ? (int) pgfNew->gced.ucTransIndex : -1;
  1200. _gad.fAnimated = TRUE; // say multi-image == animated
  1201. if (GetColorMode() == 8) // palettized, use DIB_PAL_COLORS
  1202. { // This will also dither the bits to the screen palette
  1203. pgfNew->pbmi = BIT_Make_DIB_PAL_Header(pgfNew->width, pgfNew->height);
  1204. //if (x_Dither(pgfNew->ppixels, pgfNew->pcolors, pgfNew->width, pgfNew->height, transparent))
  1205. // goto exitPoint;
  1206. }
  1207. else // give it an RGB header
  1208. {
  1209. pgfNew->pbmi = BIT_Make_DIB_RGB_Header_Screen(
  1210. pgfNew->width,
  1211. pgfNew->height,
  1212. pgfNew->cColors, pgfNew->pcolors,
  1213. transparent);
  1214. }
  1215. // Okay, so we've done any mapping on the GIFFRAME, so there's
  1216. // no need to keep the pcolors around. Let's go can clear out
  1217. // the pcolors.
  1218. // REVIEW(seanf): This assumes a common palette is used by all
  1219. // clients of the image
  1220. if ( pgfNew->pcolors != NULL && pgfNew->pcolors != _gad.pcolorsGlobal )
  1221. free( pgfNew->pcolors );
  1222. pgfNew->pcolors = NULL;
  1223. pgfLast->pgfNext = pgfNew;
  1224. // Do something to here to get the new frame on the screen.
  1225. _fInvalidateAll = TRUE;
  1226. //super::OnProg(FALSE, IMGBITS_TOTAL);
  1227. }
  1228. else
  1229. { // first frame
  1230. _gad.pgf = pgfNew;
  1231. _gad.pgfLastProg = pgfNew;
  1232. _gad.dwLastProgTimeMS = 0;
  1233. // set up a temporary animation state for use in progressive draw
  1234. _gas.fAnimating = TRUE;
  1235. _gas.dwLoopIter = 0;
  1236. _gas.pgfDraw = pgfNew;
  1237. if ( imageCount == imageNumber )
  1238. image = pgfNew->ppixels;
  1239. }
  1240. pgfLast = pgfNew;
  1241. }
  1242. // make the _gifinfo.Gif89.delayTime stale, so we know if we got a new
  1243. // GCE for the next image
  1244. _gifinfo.Gif89.delayTime = -1;
  1245. }
  1246. if ( imageCount > imageNumber )
  1247. _gad.fAnimated = TRUE; // say multi-image == animated
  1248. #ifdef FEATURE_GIF_ANIMATION_LONG_LOOP_GOES_INFINITE
  1249. // RAID #23709 - If an animation is sufficiently long, we treat it as indefinite...
  1250. // Indefinite stays indefinite.
  1251. // 5/29/96 - JCordell sez we shouldn't introduce this gratuitous NS incompatibility.
  1252. // We'll keep it around inside this ifdef in case we decide we want it.
  1253. if ( _gad.fLooped &&
  1254. (_gad.dwLoopDurMS * _gad.cLoops) / 1000 > dwIndefiniteGIFThreshold ) // if longer than five minutes
  1255. _gad.cLoops = 0; // set to indefinite looping.
  1256. #endif // FEATURE_GIF_ANIMATION_LONG_LOOP_GOES_INFINITE
  1257. done:
  1258. if (GifScreen)
  1259. {
  1260. delete GifScreen;
  1261. }
  1262. return image;
  1263. }
  1264. BITMAPINFO *
  1265. CImgGif::FinishDithering()
  1266. {
  1267. BITMAPINFO * pbmi;
  1268. if (GetColorMode() == 8)
  1269. {
  1270. pbmi = BIT_Make_DIB_PAL_Header(_gad.pgf->width, _gad.pgf->height);
  1271. }
  1272. else
  1273. {
  1274. pbmi = BIT_Make_DIB_RGB_Header_Screen(_gad.pgf->width, _gad.pgf->height,
  1275. _gad.pgf->cColors, _gad.pgf->pcolors, _lTrans);
  1276. }
  1277. return pbmi;
  1278. }
  1279. //#include <vector>
  1280. //#define vector std::vector
  1281. //+-----------------------------------------------------------------------
  1282. //
  1283. // Member: LoadGifImage
  1284. //
  1285. // Overview: Given an IStream, decode an image into an array of bitmaps
  1286. //
  1287. // Arguments: pStream data source
  1288. // colorKeys pointer to where to store colorKey data
  1289. // numBitmaps where to store number of bitmaps
  1290. // delays where to store delay array
  1291. // loop where to store number of times to loop
  1292. // ppBitMaps where to store bitmaps
  1293. //
  1294. // Returns: S_OK on success otherwise error code
  1295. //
  1296. //------------------------------------------------------------------------
  1297. HRESULT
  1298. LoadGifImage(IStream *stream,
  1299. COLORREF **colorKeys,
  1300. int *numBitmaps,
  1301. int **delays,
  1302. double *loop,
  1303. HBITMAP *phBitmap)
  1304. {
  1305. HRESULT hr = S_OK;
  1306. /*
  1307. The odd approach here lets us keep the original IE GIF code unchanged while removing
  1308. DA specific inserts (except error reporting). The progressive rendering and palette
  1309. dithering found in the IE code is also not supported yet.
  1310. */
  1311. CImgGif* gifimage = new CImgGif;
  1312. if (gifimage == NULL)
  1313. {
  1314. hr = E_FAIL;
  1315. goto done;
  1316. }
  1317. gifimage->_szFileName = NULL;
  1318. gifimage->_gifinfo.stream = stream;
  1319. BYTE *pbBits = gifimage->ReadGIFMaster();
  1320. if (pbBits) {
  1321. gifimage->_pbBits = pbBits;
  1322. gifimage->_gad.pgf->pbmi = gifimage->FinishDithering();
  1323. }
  1324. /*
  1325. Extract information from GIF decoder, and format it into an array of bitmaps.
  1326. */
  1327. *delays = NULL;
  1328. /*vector<>*/HBITMAP vhbmp;
  1329. /*vector<>*/COLORREF vcolorKey;
  1330. /*vector<>*/int vdelay;
  1331. LPVOID image = NULL;
  1332. LPVOID lastBits = pbBits;
  1333. LPVOID bitsBeforeLastBits = NULL;
  1334. PBITMAPINFO pbmi = NULL;
  1335. HBITMAP hbm;
  1336. PGIFFRAME pgf = gifimage->_gad.pgf;
  1337. PGIFFRAME pgfOld = NULL;
  1338. bool fUseOffset = false;
  1339. bool fFirstFrame = true;
  1340. long pgfWidth,pgfHeight, // animation frame dims
  1341. fullWidth,fullHeight, // main frame dims
  1342. fullPad, pgfPad, // row padding vals
  1343. fullSize, pgfSize;
  1344. unsigned int disp = 0;
  1345. int i = 0;
  1346. // TODO: Dither global palette to display palette
  1347. fullWidth = gifimage->_xWidth;
  1348. fullHeight = gifimage->_yHeight;
  1349. fullPad = (((fullWidth + 3) / 4) * 4) - fullWidth;
  1350. fullSize = (fullPad+fullWidth)*fullHeight;
  1351. if (NULL == pgf)
  1352. {
  1353. hr = E_FAIL;
  1354. goto done;
  1355. }
  1356. while(1)
  1357. {
  1358. // Assert(pgf);
  1359. pbmi = pgf->pbmi;
  1360. if (pbmi == NULL)
  1361. {
  1362. hr = E_FAIL;
  1363. goto done;
  1364. }
  1365. // TODO: It would be nice to pass local palettes up so they could
  1366. // be mapped to system palettes.
  1367. // Check to see if frame is offset from logical frame
  1368. if(pgf->top != 0 ||
  1369. pgf->left != 0 ||
  1370. pgf->width != fullWidth ||
  1371. pgf->height != fullHeight)
  1372. {
  1373. fUseOffset = true;
  1374. pgfWidth = pbmi->bmiHeader.biWidth;
  1375. pgfHeight = pbmi->bmiHeader.biHeight;
  1376. pbmi->bmiHeader.biWidth = fullWidth;
  1377. pbmi->bmiHeader.biHeight = fullHeight;
  1378. pgfPad = (((pgfWidth + 3) / 4) * 4) - pgfWidth;
  1379. pgfSize = (pgfPad+pgfWidth)*pgfHeight;
  1380. }
  1381. hbm = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (LPVOID *) &image, NULL, 0);
  1382. if(!hbm)
  1383. {
  1384. hr = E_OUTOFMEMORY;
  1385. goto done;
  1386. }
  1387. // Correctly composite bitmaps based on disposal method specified
  1388. disp = pgf->gced.uiDisposalMethod;
  1389. // If the frame is offset, fill it with
  1390. if( (disp == gifRestorePrev) && (bitsBeforeLastBits != NULL) )
  1391. memcpy(image, bitsBeforeLastBits, fullSize);
  1392. else if( (disp == gifRestoreBkgnd) || (disp == gifRestorePrev) || fFirstFrame ) // fill with bgColor
  1393. memset(image, pgf->gced.ucTransIndex, fullSize);
  1394. else // fill with last frames data
  1395. memcpy(image, lastBits, fullSize);
  1396. // For offset gifs allocate an image the size of the first frame
  1397. // and then fill in the bits at the offset location.
  1398. if(fUseOffset) {
  1399. for(i=0; i<pgfHeight; i++) {
  1400. BYTE *dst, *src;
  1401. // the destination is the address of the image data plus the frame and row offset.
  1402. int topOffset = fullHeight - pgfHeight - pgf->top;
  1403. dst = (BYTE*)image +
  1404. ( ((topOffset + i) *(fullPad+fullWidth)) + pgf->left );
  1405. // copy from the frame's nth row
  1406. src = pgf->ppixels + i*(pgfPad+pgfWidth);
  1407. for(int j=0; j<pgfWidth; j++) {
  1408. // copy the frame row data, excluding transparent bytes
  1409. if(src[j] != pgf->gced.ucTransIndex)
  1410. dst[j] = src[j];
  1411. }
  1412. }
  1413. }
  1414. else {
  1415. // Overwritten accumulated bits with current bits. If the
  1416. // new image contains transparency we need to take it into
  1417. // account. Since this is slower, special case it.
  1418. if(pgf->gced.fTransparent) {
  1419. for(i=0; i<((fullPad+fullWidth)*fullHeight); i++) {
  1420. if(pgf->ppixels[i] != pgf->gced.ucTransIndex)
  1421. ((BYTE*)image)[i] = ((BYTE*)pgf->ppixels)[i];
  1422. }
  1423. }
  1424. else // Otherwise, just copy over the offset window's bytes
  1425. memcpy(image, pgf->ppixels, (fullPad+fullWidth)*fullHeight);
  1426. }
  1427. /*
  1428. If we got a transparent color extension, convert it to a COLORREF
  1429. */
  1430. COLORREF colorKey = COLORKEY_NOT_SET;
  1431. if (pgf->gced.fTransparent) {
  1432. int transparent = pgf->gced.ucTransIndex;
  1433. colorKey = RGB(pgf->pbmi->bmiColors[transparent].rgbRed,
  1434. pgf->pbmi->bmiColors[transparent].rgbGreen,
  1435. pgf->pbmi->bmiColors[transparent].rgbBlue);
  1436. }
  1437. // vcolorKey.push_back(colorKey);
  1438. vcolorKey = colorKey;
  1439. // biao change : vhbmp.push_back(hbm);
  1440. vhbmp = hbm;
  1441. /*
  1442. The delay times are frame specific and can be different, these
  1443. should be propagated as an array to the sampling code.
  1444. */
  1445. // vdelay.push_back(pgf->gced.uiDelayTime);
  1446. vdelay = pgf->gced.uiDelayTime;
  1447. bitsBeforeLastBits = lastBits;
  1448. lastBits = image;
  1449. fUseOffset = false;
  1450. if(pgf->pgfNext == NULL)
  1451. break;
  1452. pgfOld = pgf;
  1453. pgf = pgf->pgfNext;
  1454. fFirstFrame = FALSE;
  1455. }
  1456. // The number of times to loop are also propagated. Note we add one because
  1457. // all other GIF decoders appear to treat the loop as the number of times to
  1458. // loop AFTER the first run through the frames.
  1459. if (gifimage->_gad.cLoops == 0 && gifimage->_gad.fLooped != 0)
  1460. {
  1461. *loop = 0; // HUGE_VAL;
  1462. }
  1463. else
  1464. {
  1465. *loop = gifimage->_gad.cLoops;
  1466. }
  1467. *numBitmaps = 1;
  1468. // Since the vector will go out of scope, move contents over to heap
  1469. *delays = (int*)malloc(1 * sizeof(int));
  1470. if (NULL == *delays)
  1471. {
  1472. hr = E_OUTOFMEMORY;
  1473. goto done;
  1474. }
  1475. *colorKeys = (COLORREF*)malloc( sizeof(COLORREF) * 1 );
  1476. if (NULL == *colorKeys)
  1477. {
  1478. hr = E_OUTOFMEMORY;
  1479. goto done;
  1480. }
  1481. *phBitmap = vhbmp; // biao fix [i];
  1482. (*colorKeys)[0] = vcolorKey; // [i];
  1483. (*delays)[0] = vdelay; //[i];
  1484. hr = S_OK;
  1485. done:
  1486. if (FAILED(hr))
  1487. {
  1488. free(*delays);
  1489. free(*colorKeys);
  1490. if (gifimage)
  1491. {
  1492. delete gifimage;
  1493. }
  1494. }
  1495. return hr;
  1496. }
  1497. /*lint --flb*/
  1498. BOOL Gif2Bmp(LPSTREAM pStream, HBITMAP* phBmp)
  1499. {
  1500. HRESULT hr;
  1501. int numGifs = 0;
  1502. double loop = 0;
  1503. int * pDelays = NULL;
  1504. COLORREF * pColorKeys = NULL;
  1505. hr = LoadGifImage(pStream,
  1506. &pColorKeys,
  1507. &numGifs,
  1508. &pDelays,
  1509. &loop,
  1510. phBmp);
  1511. if (FAILED(hr))
  1512. {
  1513. return FALSE;
  1514. }
  1515. return TRUE;
  1516. }