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