PageRenderTime 62ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/ExtLibs/wxWidgets/src/common/gifdecod.cpp

https://bitbucket.org/lennonchan/cafu
C++ | 968 lines | 622 code | 146 blank | 200 comment | 136 complexity | 8d40d17ae51288cac9a3d58bc6c67a75 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/common/gifdecod.cpp
  3. // Purpose: wxGIFDecoder, GIF reader for wxImage and wxAnimation
  4. // Author: Guillermo Rodriguez Garcia <guille@iies.es>
  5. // Version: 3.04
  6. // RCS-ID: $Id$
  7. // Copyright: (c) Guillermo Rodriguez Garcia
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. // For compilers that support precompilation, includes "wx.h".
  11. #include "wx/wxprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #if wxUSE_STREAMS && wxUSE_GIF
  16. #ifndef WX_PRECOMP
  17. #include "wx/palette.h"
  18. #include "wx/intl.h"
  19. #include "wx/log.h"
  20. #endif
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "wx/gifdecod.h"
  24. #include "wx/scopedptr.h"
  25. #include "wx/scopeguard.h"
  26. enum
  27. {
  28. GIF_MARKER_EXT = '!', // 0x21
  29. GIF_MARKER_SEP = ',', // 0x2C
  30. GIF_MARKER_ENDOFDATA = ';', // 0x3B
  31. GIF_MARKER_EXT_GRAPHICS_CONTROL = 0xF9,
  32. GIF_MARKER_EXT_COMMENT = 0xFE,
  33. GIF_MARKER_EXT_APP = 0xFF
  34. };
  35. #define GetFrame(n) ((GIFImage*)m_frames[n])
  36. //---------------------------------------------------------------------------
  37. // GIFImage
  38. //---------------------------------------------------------------------------
  39. // internal class for storing GIF image data
  40. class GIFImage
  41. {
  42. public:
  43. // def ctor
  44. GIFImage();
  45. unsigned int w; // width
  46. unsigned int h; // height
  47. unsigned int left; // x coord (in logical screen)
  48. unsigned int top; // y coord (in logical screen)
  49. int transparent; // transparent color index (-1 = none)
  50. wxAnimationDisposal disposal; // disposal method
  51. long delay; // delay in ms (-1 = unused)
  52. unsigned char *p; // bitmap
  53. unsigned char *pal; // palette
  54. unsigned int ncolours; // number of colours
  55. wxString comment;
  56. wxDECLARE_NO_COPY_CLASS(GIFImage);
  57. };
  58. wxDECLARE_SCOPED_PTR(GIFImage, GIFImagePtr)
  59. wxDEFINE_SCOPED_PTR(GIFImage, GIFImagePtr)
  60. //---------------------------------------------------------------------------
  61. // GIFImage constructor
  62. //---------------------------------------------------------------------------
  63. GIFImage::GIFImage()
  64. {
  65. w = 0;
  66. h = 0;
  67. left = 0;
  68. top = 0;
  69. transparent = 0;
  70. disposal = wxANIM_DONOTREMOVE;
  71. delay = -1;
  72. p = (unsigned char *) NULL;
  73. pal = (unsigned char *) NULL;
  74. ncolours = 0;
  75. }
  76. //---------------------------------------------------------------------------
  77. // wxGIFDecoder constructor and destructor
  78. //---------------------------------------------------------------------------
  79. wxGIFDecoder::wxGIFDecoder()
  80. {
  81. }
  82. wxGIFDecoder::~wxGIFDecoder()
  83. {
  84. Destroy();
  85. }
  86. void wxGIFDecoder::Destroy()
  87. {
  88. wxASSERT(m_nFrames==m_frames.GetCount());
  89. for (unsigned int i=0; i<m_nFrames; i++)
  90. {
  91. GIFImage *f = (GIFImage*)m_frames[i];
  92. free(f->p);
  93. free(f->pal);
  94. delete f;
  95. }
  96. m_frames.Clear();
  97. m_nFrames = 0;
  98. }
  99. //---------------------------------------------------------------------------
  100. // Convert this image to a wxImage object
  101. //---------------------------------------------------------------------------
  102. // This function was designed by Vaclav Slavik
  103. bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
  104. {
  105. unsigned char *src, *dst, *pal;
  106. unsigned long i;
  107. int transparent;
  108. // just in case...
  109. image->Destroy();
  110. // create the image
  111. wxSize sz = GetFrameSize(frame);
  112. image->Create(sz.GetWidth(), sz.GetHeight());
  113. image->SetType(wxBITMAP_TYPE_GIF);
  114. if (!image->IsOk())
  115. return false;
  116. pal = GetPalette(frame);
  117. src = GetData(frame);
  118. dst = image->GetData();
  119. transparent = GetTransparentColourIndex(frame);
  120. // set transparent colour mask
  121. if (transparent != -1)
  122. {
  123. for (i = 0; i < GetNcolours(frame); i++)
  124. {
  125. if ((pal[3 * i + 0] == 255) &&
  126. (pal[3 * i + 1] == 0) &&
  127. (pal[3 * i + 2] == 255))
  128. {
  129. pal[3 * i + 2] = 254;
  130. }
  131. }
  132. pal[3 * transparent + 0] = 255,
  133. pal[3 * transparent + 1] = 0,
  134. pal[3 * transparent + 2] = 255;
  135. image->SetMaskColour(255, 0, 255);
  136. }
  137. else
  138. image->SetMask(false);
  139. #if wxUSE_PALETTE
  140. unsigned char r[256];
  141. unsigned char g[256];
  142. unsigned char b[256];
  143. for (i = 0; i < 256; i++)
  144. {
  145. r[i] = pal[3*i + 0];
  146. g[i] = pal[3*i + 1];
  147. b[i] = pal[3*i + 2];
  148. }
  149. image->SetPalette(wxPalette(GetNcolours(frame), r, g, b));
  150. #endif // wxUSE_PALETTE
  151. // copy image data
  152. unsigned long npixel = sz.GetWidth() * sz.GetHeight();
  153. for (i = 0; i < npixel; i++, src++)
  154. {
  155. *(dst++) = pal[3 * (*src) + 0];
  156. *(dst++) = pal[3 * (*src) + 1];
  157. *(dst++) = pal[3 * (*src) + 2];
  158. }
  159. wxString comment = GetFrame(frame)->comment;
  160. if ( !comment.empty() )
  161. {
  162. image->SetOption(wxIMAGE_OPTION_GIF_COMMENT, comment);
  163. }
  164. return true;
  165. }
  166. //---------------------------------------------------------------------------
  167. // Data accessors
  168. //---------------------------------------------------------------------------
  169. // Get data for current frame
  170. wxSize wxGIFDecoder::GetFrameSize(unsigned int frame) const
  171. {
  172. return wxSize(GetFrame(frame)->w, GetFrame(frame)->h);
  173. }
  174. wxPoint wxGIFDecoder::GetFramePosition(unsigned int frame) const
  175. {
  176. return wxPoint(GetFrame(frame)->left, GetFrame(frame)->top);
  177. }
  178. wxAnimationDisposal wxGIFDecoder::GetDisposalMethod(unsigned int frame) const
  179. {
  180. return GetFrame(frame)->disposal;
  181. }
  182. long wxGIFDecoder::GetDelay(unsigned int frame) const
  183. {
  184. return GetFrame(frame)->delay;
  185. }
  186. wxColour wxGIFDecoder::GetTransparentColour(unsigned int frame) const
  187. {
  188. unsigned char *pal = GetFrame(frame)->pal;
  189. int n = GetFrame(frame)->transparent;
  190. if (n == -1)
  191. return wxNullColour;
  192. return wxColour(pal[n*3 + 0],
  193. pal[n*3 + 1],
  194. pal[n*3 + 2]);
  195. }
  196. unsigned char* wxGIFDecoder::GetData(unsigned int frame) const { return (GetFrame(frame)->p); }
  197. unsigned char* wxGIFDecoder::GetPalette(unsigned int frame) const { return (GetFrame(frame)->pal); }
  198. unsigned int wxGIFDecoder::GetNcolours(unsigned int frame) const { return (GetFrame(frame)->ncolours); }
  199. int wxGIFDecoder::GetTransparentColourIndex(unsigned int frame) const { return (GetFrame(frame)->transparent); }
  200. //---------------------------------------------------------------------------
  201. // GIF reading and decoding
  202. //---------------------------------------------------------------------------
  203. // getcode:
  204. // Reads the next code from the file stream, with size 'bits'
  205. //
  206. int wxGIFDecoder::getcode(wxInputStream& stream, int bits, int ab_fin)
  207. {
  208. unsigned int mask; // bit mask
  209. unsigned int code; // code (result)
  210. // get remaining bits from last byte read
  211. mask = (1 << bits) - 1;
  212. code = (m_lastbyte >> (8 - m_restbits)) & mask;
  213. // keep reading new bytes while needed
  214. while (bits > m_restbits)
  215. {
  216. // if no bytes left in this block, read the next block
  217. if (m_restbyte == 0)
  218. {
  219. m_restbyte = stream.GetC();
  220. /* Some encoders are a bit broken: instead of issuing
  221. * an end-of-image symbol (ab_fin) they come up with
  222. * a zero-length subblock!! We catch this here so
  223. * that the decoder sees an ab_fin code.
  224. */
  225. if (m_restbyte == 0)
  226. {
  227. code = ab_fin;
  228. break;
  229. }
  230. // prefetch data
  231. stream.Read((void *) m_buffer, m_restbyte);
  232. if (stream.LastRead() != m_restbyte)
  233. {
  234. code = ab_fin;
  235. return code;
  236. }
  237. m_bufp = m_buffer;
  238. }
  239. // read next byte and isolate the bits we need
  240. m_lastbyte = (unsigned char) (*m_bufp++);
  241. mask = (1 << (bits - m_restbits)) - 1;
  242. code = code + ((m_lastbyte & mask) << m_restbits);
  243. m_restbyte--;
  244. // adjust total number of bits extracted from the buffer
  245. m_restbits = m_restbits + 8;
  246. }
  247. // find number of bits remaining for next code
  248. m_restbits = (m_restbits - bits);
  249. return code;
  250. }
  251. // dgif:
  252. // GIF decoding function. The initial code size (aka root size)
  253. // is 'bits'. Supports interlaced images (interl == 1).
  254. // Returns wxGIF_OK (== 0) on success, or an error code if something
  255. // fails (see header file for details)
  256. wxGIFErrorCode
  257. wxGIFDecoder::dgif(wxInputStream& stream, GIFImage *img, int interl, int bits)
  258. {
  259. static const int allocSize = 4096 + 1;
  260. int *ab_prefix = new int[allocSize]; // alphabet (prefixes)
  261. if (ab_prefix == NULL)
  262. {
  263. return wxGIF_MEMERR;
  264. }
  265. int *ab_tail = new int[allocSize]; // alphabet (tails)
  266. if (ab_tail == NULL)
  267. {
  268. delete[] ab_prefix;
  269. return wxGIF_MEMERR;
  270. }
  271. int *stack = new int[allocSize]; // decompression stack
  272. if (stack == NULL)
  273. {
  274. delete[] ab_prefix;
  275. delete[] ab_tail;
  276. return wxGIF_MEMERR;
  277. }
  278. int ab_clr; // clear code
  279. int ab_fin; // end of info code
  280. int ab_bits; // actual symbol width, in bits
  281. int ab_free; // first free position in alphabet
  282. int ab_max; // last possible character in alphabet
  283. int pass; // pass number in interlaced images
  284. int pos; // index into decompresion stack
  285. unsigned int x, y; // position in image buffer
  286. int code, readcode, lastcode, abcabca;
  287. // these won't change
  288. ab_clr = (1 << bits);
  289. ab_fin = (1 << bits) + 1;
  290. // these will change through the decompression proccess
  291. ab_bits = bits + 1;
  292. ab_free = (1 << bits) + 2;
  293. ab_max = (1 << ab_bits) - 1;
  294. lastcode = -1;
  295. abcabca = -1;
  296. pass = 1;
  297. pos = x = y = 0;
  298. // reset decoder vars
  299. m_restbits = 0;
  300. m_restbyte = 0;
  301. m_lastbyte = 0;
  302. do
  303. {
  304. // get next code
  305. readcode = code = getcode(stream, ab_bits, ab_fin);
  306. // end of image?
  307. if (code == ab_fin) break;
  308. // reset alphabet?
  309. if (code == ab_clr)
  310. {
  311. // reset main variables
  312. ab_bits = bits + 1;
  313. ab_free = (1 << bits) + 2;
  314. ab_max = (1 << ab_bits) - 1;
  315. lastcode = -1;
  316. abcabca = -1;
  317. // skip to next code
  318. continue;
  319. }
  320. // unknown code: special case (like in ABCABCA)
  321. if (code >= ab_free)
  322. {
  323. code = lastcode; // take last string
  324. stack[pos++] = abcabca; // add first character
  325. }
  326. // build the string for this code in the stack
  327. while (code > ab_clr)
  328. {
  329. stack[pos++] = ab_tail[code];
  330. code = ab_prefix[code];
  331. // Don't overflow. This shouldn't happen with normal
  332. // GIF files, the allocSize of 4096+1 is enough. This
  333. // will only happen with badly formed GIFs.
  334. if (pos >= allocSize)
  335. {
  336. delete[] ab_prefix;
  337. delete[] ab_tail;
  338. delete[] stack;
  339. return wxGIF_INVFORMAT;
  340. }
  341. }
  342. if (pos >= allocSize)
  343. {
  344. delete[] ab_prefix;
  345. delete[] ab_tail;
  346. delete[] stack;
  347. return wxGIF_INVFORMAT;
  348. }
  349. stack[pos] = code; // push last code into the stack
  350. abcabca = code; // save for special case
  351. // make new entry in alphabet (only if NOT just cleared)
  352. if (lastcode != -1)
  353. {
  354. // Normally, after the alphabet is full and can't grow any
  355. // further (ab_free == 4096), encoder should (must?) emit CLEAR
  356. // to reset it. This checks whether we really got it, otherwise
  357. // the GIF is damaged.
  358. if (ab_free > ab_max)
  359. {
  360. delete[] ab_prefix;
  361. delete[] ab_tail;
  362. delete[] stack;
  363. return wxGIF_INVFORMAT;
  364. }
  365. // This assert seems unnecessary since the condition above
  366. // eliminates the only case in which it went false. But I really
  367. // don't like being forced to ask "Who in .text could have
  368. // written there?!" And I wouldn't have been forced to ask if
  369. // this line had already been here.
  370. wxASSERT(ab_free < allocSize);
  371. ab_prefix[ab_free] = lastcode;
  372. ab_tail[ab_free] = code;
  373. ab_free++;
  374. if ((ab_free > ab_max) && (ab_bits < 12))
  375. {
  376. ab_bits++;
  377. ab_max = (1 << ab_bits) - 1;
  378. }
  379. }
  380. // dump stack data to the image buffer
  381. while (pos >= 0)
  382. {
  383. (img->p)[x + (y * (img->w))] = (char) stack[pos];
  384. pos--;
  385. if (++x >= (img->w))
  386. {
  387. x = 0;
  388. if (interl)
  389. {
  390. // support for interlaced images
  391. switch (pass)
  392. {
  393. case 1: y += 8; break;
  394. case 2: y += 8; break;
  395. case 3: y += 4; break;
  396. case 4: y += 2; break;
  397. }
  398. /* loop until a valid y coordinate has been
  399. found, Or if the maximum number of passes has
  400. been reached, exit the loop, and stop image
  401. decoding (At this point the image is successfully
  402. decoded).
  403. If we don't loop, but merely set y to some other
  404. value, that new value might still be invalid depending
  405. on the height of the image. This would cause out of
  406. bounds writing.
  407. */
  408. while (y >= (img->h))
  409. {
  410. switch (++pass)
  411. {
  412. case 2: y = 4; break;
  413. case 3: y = 2; break;
  414. case 4: y = 1; break;
  415. default:
  416. /*
  417. It's possible we arrive here. For example this
  418. happens when the image is interlaced, and the
  419. height is 1. Looking at the above cases, the
  420. lowest possible y is 1. While the only valid
  421. one would be 0 for an image of height 1. So
  422. 'eventually' the loop will arrive here.
  423. This case makes sure this while loop is
  424. exited, as well as the 2 other ones.
  425. */
  426. // Set y to a valid coordinate so the local
  427. // while loop will be exited. (y = 0 always
  428. // is >= img->h since if img->h == 0 the
  429. // image is never decoded)
  430. y = 0;
  431. // This will exit the other outer while loop
  432. pos = -1;
  433. // This will halt image decoding.
  434. code = ab_fin;
  435. break;
  436. }
  437. }
  438. }
  439. else
  440. {
  441. // non-interlaced
  442. y++;
  443. /*
  444. Normally image decoding is finished when an End of Information code is
  445. encountered (code == ab_fin) however some broken encoders write wrong
  446. "block byte counts" (The first byte value after the "code size" byte),
  447. being one value too high. It might very well be possible other variants
  448. of this problem occur as well. The only sensible solution seems to
  449. be to check for clipping.
  450. Example of wrong encoding:
  451. (1 * 1 B/W image, raster data stream follows in hex bytes)
  452. 02 << B/W images have a code size of 2
  453. 02 << Block byte count
  454. 44 << LZW packed
  455. 00 << Zero byte count (terminates data stream)
  456. Because the block byte count is 2, the zero byte count is used in the
  457. decoding process, and decoding is continued after this byte. (While it
  458. should signal an end of image)
  459. It should be:
  460. 02
  461. 02
  462. 44
  463. 01 << When decoded this correctly includes the End of Information code
  464. 00
  465. Or (Worse solution):
  466. 02
  467. 01
  468. 44
  469. 00
  470. (The 44 doesn't include an End of Information code, but at least the
  471. decoder correctly skips to 00 now after decoding, and signals this
  472. as an End of Information itself)
  473. */
  474. if (y >= img->h)
  475. {
  476. code = ab_fin;
  477. break;
  478. }
  479. }
  480. }
  481. }
  482. pos = 0;
  483. lastcode = readcode;
  484. }
  485. while (code != ab_fin);
  486. delete [] ab_prefix ;
  487. delete [] ab_tail ;
  488. delete [] stack ;
  489. return wxGIF_OK;
  490. }
  491. // CanRead:
  492. // Returns true if the file looks like a valid GIF, false otherwise.
  493. //
  494. bool wxGIFDecoder::DoCanRead(wxInputStream &stream) const
  495. {
  496. unsigned char buf[3];
  497. if ( !stream.Read(buf, WXSIZEOF(buf)) )
  498. return false;
  499. return memcmp(buf, "GIF", WXSIZEOF(buf)) == 0;
  500. }
  501. // LoadGIF:
  502. // Reads and decodes one or more GIF images, depending on whether
  503. // animated GIF support is enabled. Can read GIFs with any bit
  504. // size (color depth), but the output images are always expanded
  505. // to 8 bits per pixel. Also, the image palettes always contain
  506. // 256 colors, although some of them may be unused. Returns wxGIF_OK
  507. // (== 0) on success, or an error code if something fails (see
  508. // header file for details)
  509. //
  510. wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
  511. {
  512. unsigned int global_ncolors = 0;
  513. int bits, interl, i;
  514. wxAnimationDisposal disposal;
  515. long size;
  516. long delay;
  517. unsigned char type = 0;
  518. unsigned char pal[768];
  519. unsigned char buf[16];
  520. bool anim = true;
  521. // check GIF signature
  522. if (!CanRead(stream))
  523. return wxGIF_INVFORMAT;
  524. // check for animated GIF support (ver. >= 89a)
  525. static const unsigned int headerSize = (3 + 3);
  526. stream.Read(buf, headerSize);
  527. if (stream.LastRead() != headerSize)
  528. {
  529. return wxGIF_INVFORMAT;
  530. }
  531. if (memcmp(buf + 3, "89a", 3) < 0)
  532. {
  533. anim = false;
  534. }
  535. // read logical screen descriptor block (LSDB)
  536. static const unsigned int lsdbSize = (2 + 2 + 1 + 1 + 1);
  537. stream.Read(buf, lsdbSize);
  538. if (stream.LastRead() != lsdbSize)
  539. {
  540. return wxGIF_INVFORMAT;
  541. }
  542. m_szAnimation.SetWidth( buf[0] + 256 * buf[1] );
  543. m_szAnimation.SetHeight( buf[2] + 256 * buf[3] );
  544. if (anim && ((m_szAnimation.GetWidth() == 0) || (m_szAnimation.GetHeight() == 0)))
  545. {
  546. return wxGIF_INVFORMAT;
  547. }
  548. // load global color map if available
  549. if ((buf[4] & 0x80) == 0x80)
  550. {
  551. int backgroundColIndex = buf[5];
  552. global_ncolors = 2 << (buf[4] & 0x07);
  553. unsigned int numBytes = 3 * global_ncolors;
  554. stream.Read(pal, numBytes);
  555. if (stream.LastRead() != numBytes)
  556. {
  557. return wxGIF_INVFORMAT;
  558. }
  559. m_background.Set(pal[backgroundColIndex*3 + 0],
  560. pal[backgroundColIndex*3 + 1],
  561. pal[backgroundColIndex*3 + 2]);
  562. }
  563. // transparent colour, disposal method and delay default to unused
  564. int transparent = -1;
  565. disposal = wxANIM_UNSPECIFIED;
  566. delay = -1;
  567. wxString comment;
  568. bool done = false;
  569. while (!done)
  570. {
  571. type = stream.GetC();
  572. /*
  573. If the end of file has been reached (or an error) and a ";"
  574. (GIF_MARKER_ENDOFDATA) hasn't been encountered yet, exit the loop. (Without this
  575. check the while loop would loop endlessly.) Later on, in the next while
  576. loop, the file will be treated as being truncated (But still
  577. be decoded as far as possible). returning wxGIF_TRUNCATED is not
  578. possible here since some init code is done after this loop.
  579. */
  580. if (stream.Eof())// || !stream.IsOk())
  581. {
  582. /*
  583. type is set to some bogus value, so there's no
  584. need to continue evaluating it.
  585. */
  586. break; // Alternative : "return wxGIF_INVFORMAT;"
  587. }
  588. switch (type)
  589. {
  590. case GIF_MARKER_ENDOFDATA:
  591. done = true;
  592. break;
  593. case GIF_MARKER_EXT:
  594. switch (stream.GetC())
  595. {
  596. case GIF_MARKER_EXT_GRAPHICS_CONTROL:
  597. {
  598. // graphics control extension, parse it
  599. static const unsigned int gceSize = 6;
  600. stream.Read(buf, gceSize);
  601. if (stream.LastRead() != gceSize)
  602. {
  603. Destroy();
  604. return wxGIF_INVFORMAT;
  605. }
  606. // read delay and convert from 1/100 of a second to ms
  607. delay = 10 * (buf[2] + 256 * buf[3]);
  608. // read transparent colour index, if used
  609. transparent = buf[1] & 0x01 ? buf[4] : -1;
  610. // read disposal method
  611. disposal = (wxAnimationDisposal)(((buf[1] & 0x1C) >> 2) - 1);
  612. break;
  613. }
  614. case GIF_MARKER_EXT_COMMENT:
  615. {
  616. int len = stream.GetC();
  617. while (len)
  618. {
  619. if ( stream.Eof() )
  620. {
  621. done = true;
  622. break;
  623. }
  624. wxCharBuffer charbuf(len);
  625. stream.Read(charbuf.data(), len);
  626. if ( (int) stream.LastRead() != len )
  627. {
  628. done = true;
  629. break;
  630. }
  631. comment += wxConvertMB2WX(charbuf.data());
  632. len = stream.GetC();
  633. }
  634. break;
  635. }
  636. default:
  637. // other extension, skip
  638. while ((i = stream.GetC()) != 0)
  639. {
  640. if (stream.Eof() || (stream.LastRead() == 0) ||
  641. stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
  642. {
  643. done = true;
  644. break;
  645. }
  646. }
  647. break;
  648. }
  649. break;
  650. case GIF_MARKER_SEP:
  651. {
  652. // allocate memory for IMAGEN struct
  653. GIFImagePtr pimg(new GIFImage());
  654. wxScopeGuard guardDestroy = wxMakeObjGuard(*this, &wxGIFDecoder::Destroy);
  655. if ( !pimg.get() )
  656. return wxGIF_MEMERR;
  657. // fill in the data
  658. static const unsigned int idbSize = (2 + 2 + 2 + 2 + 1);
  659. stream.Read(buf, idbSize);
  660. if (stream.LastRead() != idbSize)
  661. return wxGIF_INVFORMAT;
  662. pimg->comment = comment;
  663. comment.clear();
  664. pimg->left = buf[0] + 256 * buf[1];
  665. pimg->top = buf[2] + 256 * buf[3];
  666. /*
  667. pimg->left = buf[4] + 256 * buf[5];
  668. pimg->top = buf[4] + 256 * buf[5];
  669. */
  670. pimg->w = buf[4] + 256 * buf[5];
  671. pimg->h = buf[6] + 256 * buf[7];
  672. if ( anim )
  673. {
  674. // some GIF images specify incorrect animation size but we can
  675. // still open them if we fix up the animation size, see #9465
  676. if ( m_nFrames == 0 )
  677. {
  678. if ( pimg->w > (unsigned)m_szAnimation.x )
  679. m_szAnimation.x = pimg->w;
  680. if ( pimg->h > (unsigned)m_szAnimation.y )
  681. m_szAnimation.y = pimg->h;
  682. }
  683. else // subsequent frames
  684. {
  685. // check that we have valid size
  686. if ( (!pimg->w || pimg->w > (unsigned)m_szAnimation.x) ||
  687. (!pimg->h || pimg->h > (unsigned)m_szAnimation.y) )
  688. {
  689. wxLogError(_("Incorrect GIF frame size (%u, %d) for "
  690. "the frame #%u"),
  691. pimg->w, pimg->h, m_nFrames);
  692. return wxGIF_INVFORMAT;
  693. }
  694. }
  695. }
  696. interl = ((buf[8] & 0x40)? 1 : 0);
  697. size = pimg->w * pimg->h;
  698. pimg->transparent = transparent;
  699. pimg->disposal = disposal;
  700. pimg->delay = delay;
  701. // allocate memory for image and palette
  702. pimg->p = (unsigned char *) malloc((unsigned int)size);
  703. pimg->pal = (unsigned char *) malloc(768);
  704. if ((!pimg->p) || (!pimg->pal))
  705. return wxGIF_MEMERR;
  706. // load local color map if available, else use global map
  707. if ((buf[8] & 0x80) == 0x80)
  708. {
  709. unsigned int local_ncolors = 2 << (buf[8] & 0x07);
  710. unsigned int numBytes = 3 * local_ncolors;
  711. stream.Read(pimg->pal, numBytes);
  712. pimg->ncolours = local_ncolors;
  713. if (stream.LastRead() != numBytes)
  714. return wxGIF_INVFORMAT;
  715. }
  716. else
  717. {
  718. memcpy(pimg->pal, pal, 768);
  719. pimg->ncolours = global_ncolors;
  720. }
  721. // get initial code size from first byte in raster data
  722. bits = stream.GetC();
  723. if (bits == 0)
  724. return wxGIF_INVFORMAT;
  725. // decode image
  726. wxGIFErrorCode result = dgif(stream, pimg.get(), interl, bits);
  727. if (result != wxGIF_OK)
  728. return result;
  729. guardDestroy.Dismiss();
  730. // add the image to our frame array
  731. m_frames.Add(pimg.release());
  732. m_nFrames++;
  733. // if this is not an animated GIF, exit after first image
  734. if (!anim)
  735. done = true;
  736. break;
  737. }
  738. }
  739. }
  740. if (m_nFrames <= 0)
  741. {
  742. Destroy();
  743. return wxGIF_INVFORMAT;
  744. }
  745. // try to read to the end of the stream
  746. while (type != GIF_MARKER_ENDOFDATA)
  747. {
  748. if (!stream.IsOk())
  749. return wxGIF_TRUNCATED;
  750. type = stream.GetC();
  751. switch (type)
  752. {
  753. case GIF_MARKER_EXT:
  754. // extension type
  755. (void) stream.GetC();
  756. // skip all data
  757. while ((i = stream.GetC()) != 0)
  758. {
  759. if (stream.Eof() || (stream.LastRead() == 0) ||
  760. stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
  761. {
  762. Destroy();
  763. return wxGIF_INVFORMAT;
  764. }
  765. }
  766. break;
  767. case GIF_MARKER_SEP:
  768. {
  769. // image descriptor block
  770. static const unsigned int idbSize = (2 + 2 + 2 + 2 + 1);
  771. stream.Read(buf, idbSize);
  772. if (stream.LastRead() != idbSize)
  773. {
  774. Destroy();
  775. return wxGIF_INVFORMAT;
  776. }
  777. // local color map
  778. if ((buf[8] & 0x80) == 0x80)
  779. {
  780. unsigned int local_ncolors = 2 << (buf[8] & 0x07);
  781. wxFileOffset numBytes = 3 * local_ncolors;
  782. if (stream.SeekI(numBytes, wxFromCurrent) == wxInvalidOffset)
  783. {
  784. Destroy();
  785. return wxGIF_INVFORMAT;
  786. }
  787. }
  788. // initial code size
  789. (void) stream.GetC();
  790. if (stream.Eof() || (stream.LastRead() == 0))
  791. {
  792. Destroy();
  793. return wxGIF_INVFORMAT;
  794. }
  795. // skip all data
  796. while ((i = stream.GetC()) != 0)
  797. {
  798. if (stream.Eof() || (stream.LastRead() == 0) ||
  799. stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
  800. {
  801. Destroy();
  802. return wxGIF_INVFORMAT;
  803. }
  804. }
  805. break;
  806. }
  807. default:
  808. if ((type != GIF_MARKER_ENDOFDATA) && (type != 00)) // testing
  809. {
  810. // images are OK, but couldn't read to the end of the stream
  811. return wxGIF_TRUNCATED;
  812. }
  813. break;
  814. }
  815. }
  816. return wxGIF_OK;
  817. }
  818. #endif // wxUSE_STREAMS && wxUSE_GIF