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