]>
git.saurik.com Git - wxWidgets.git/blob - 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>
7 // Copyright: (c) Guillermo Rodriguez Garcia
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #if wxUSE_STREAMS && wxUSE_GIF
21 #include "wx/palette.h"
26 #include "wx/gifdecod.h"
29 //---------------------------------------------------------------------------
30 // GIFImage constructor
31 //---------------------------------------------------------------------------
41 p
= (unsigned char *) NULL
;
42 pal
= (unsigned char *) NULL
;
43 next
= (GIFImage
*) NULL
;
44 prev
= (GIFImage
*) NULL
;
47 //---------------------------------------------------------------------------
48 // wxGIFDecoder constructor and destructor
49 //---------------------------------------------------------------------------
51 wxGIFDecoder::wxGIFDecoder(wxInputStream
*s
, bool anim
)
67 wxGIFDecoder::~wxGIFDecoder()
72 void wxGIFDecoder::Destroy()
74 GIFImage
*pimg
, *paux
;
95 //---------------------------------------------------------------------------
96 // Convert this image to a wxImage object
97 //---------------------------------------------------------------------------
99 // This function was designed by Vaclav Slavik
101 bool wxGIFDecoder::ConvertToImage(wxImage
*image
) const
103 unsigned char *src
, *dst
, *pal
;
107 /* just in case... */
110 /* create the image */
111 image
->Create(GetWidth(), GetHeight());
118 dst
= image
->GetData();
119 transparent
= GetTransparentColour();
121 /* set transparent colour mask */
122 if (transparent
!= -1)
124 for (i
= 0; i
< 256; i
++)
126 if ((pal
[3 * i
+ 0] == 255) &&
127 (pal
[3 * i
+ 1] == 0) &&
128 (pal
[3 * i
+ 2] == 255))
130 pal
[3 * i
+ 2] = 254;
134 pal
[3 * transparent
+ 0] = 255,
135 pal
[3 * transparent
+ 1] = 0,
136 pal
[3 * transparent
+ 2] = 255;
138 image
->SetMaskColour(255, 0, 255);
141 image
->SetMask(false);
144 unsigned char r
[256];
145 unsigned char g
[256];
146 unsigned char b
[256];
148 for (i
= 0; i
< 256; i
++)
155 image
->SetPalette(wxPalette(256, r
, g
, b
));
156 #endif // wxUSE_PALETTE
158 /* copy image data */
159 for (i
= 0; i
< (GetWidth() * GetHeight()); i
++, src
++)
161 *(dst
++) = pal
[3 * (*src
) + 0];
162 *(dst
++) = pal
[3 * (*src
) + 1];
163 *(dst
++) = pal
[3 * (*src
) + 2];
170 //---------------------------------------------------------------------------
172 //---------------------------------------------------------------------------
174 // Get data for current frame
176 int wxGIFDecoder::GetFrameIndex() const { return m_image
; }
177 unsigned char* wxGIFDecoder::GetData() const { return (m_pimage
->p
); }
178 unsigned char* wxGIFDecoder::GetPalette() const { return (m_pimage
->pal
); }
179 unsigned int wxGIFDecoder::GetWidth() const { return (m_pimage
->w
); }
180 unsigned int wxGIFDecoder::GetHeight() const { return (m_pimage
->h
); }
181 unsigned int wxGIFDecoder::GetTop() const { return (m_pimage
->top
); }
182 unsigned int wxGIFDecoder::GetLeft() const { return (m_pimage
->left
); }
183 int wxGIFDecoder::GetTransparentColour() const { return (m_pimage
->transparent
); }
184 int wxGIFDecoder::GetDisposalMethod() const { return (m_pimage
->disposal
); }
185 long wxGIFDecoder::GetDelay() const { return (m_pimage
->delay
); }
189 unsigned int wxGIFDecoder::GetLogicalScreenWidth() const { return m_screenw
; }
190 unsigned int wxGIFDecoder::GetLogicalScreenHeight() const { return m_screenh
; }
191 int wxGIFDecoder::GetBackgroundColour() const { return m_background
; }
192 int wxGIFDecoder::GetNumberOfFrames() const { return m_nimages
; }
193 bool wxGIFDecoder::IsAnimation() const { return (m_nimages
> 1); }
196 //---------------------------------------------------------------------------
197 // Functions to move through the animation
198 //---------------------------------------------------------------------------
200 bool wxGIFDecoder::GoFirstFrame()
210 bool wxGIFDecoder::GoLastFrame()
220 bool wxGIFDecoder::GoNextFrame(bool cyclic
)
225 if ((m_image
< m_nimages
) || (cyclic
))
227 m_pimage
= m_pimage
->next
;
242 bool wxGIFDecoder::GoPrevFrame(bool cyclic
)
247 if ((m_image
> 1) || (cyclic
))
249 m_pimage
= m_pimage
->prev
;
264 bool wxGIFDecoder::GoFrame(int which
)
269 if ((which
>= 1) && (which
<= m_nimages
))
274 while (m_image
< which
)
277 m_pimage
= m_pimage
->next
;
287 //---------------------------------------------------------------------------
288 // GIF reading and decoding
289 //---------------------------------------------------------------------------
292 // Reads the next code from the file stream, with size 'bits'
294 int wxGIFDecoder::getcode(int bits
, int ab_fin
)
296 unsigned int mask
; /* bit mask */
297 unsigned int code
; /* code (result) */
300 /* get remaining bits from last byte read */
301 mask
= (1 << bits
) - 1;
302 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
304 /* keep reading new bytes while needed */
305 while (bits
> m_restbits
)
307 /* if no bytes left in this block, read the next block */
310 m_restbyte
= (unsigned char)m_f
->GetC();
312 /* Some encoders are a bit broken: instead of issuing
313 * an end-of-image symbol (ab_fin) they come up with
314 * a zero-length subblock!! We catch this here so
315 * that the decoder sees an ab_fin code.
324 m_f
->Read((void *) m_buffer
, m_restbyte
);
325 if (m_f
->LastRead() != m_restbyte
)
333 /* read next byte and isolate the bits we need */
334 m_lastbyte
= (unsigned char) (*m_bufp
++);
335 mask
= (1 << (bits
- m_restbits
)) - 1;
336 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
339 /* adjust total number of bits extracted from the buffer */
340 m_restbits
= m_restbits
+ 8;
343 /* find number of bits remaining for next code */
344 m_restbits
= (m_restbits
- bits
);
351 // GIF decoding function. The initial code size (aka root size)
352 // is 'bits'. Supports interlaced images (interl == 1).
353 // Returns wxGIF_OK (== 0) on success, or an error code if something
354 // fails (see header file for details)
355 int wxGIFDecoder::dgif(GIFImage
*img
, int interl
, int bits
)
357 static const int allocSize
= 4096 + 1;
358 int *ab_prefix
= new int[allocSize
]; /* alphabet (prefixes) */
359 if (ab_prefix
== NULL
)
364 int *ab_tail
= new int[allocSize
]; /* alphabet (tails) */
371 int *stack
= new int[allocSize
]; /* decompression stack */
379 int ab_clr
; /* clear code */
380 int ab_fin
; /* end of info code */
381 int ab_bits
; /* actual symbol width, in bits */
382 int ab_free
; /* first free position in alphabet */
383 int ab_max
; /* last possible character in alphabet */
384 int pass
; /* pass number in interlaced images */
385 int pos
; /* index into decompresion stack */
386 unsigned int x
, y
; /* position in image buffer */
388 int code
, readcode
, lastcode
, abcabca
;
390 /* these won't change */
391 ab_clr
= (1 << bits
);
392 ab_fin
= (1 << bits
) + 1;
394 /* these will change through the decompression proccess */
396 ab_free
= (1 << bits
) + 2;
397 ab_max
= (1 << ab_bits
) - 1;
403 /* reset decoder vars */
411 readcode
= code
= getcode(ab_bits
, ab_fin
);
414 if (code
== ab_fin
) break;
416 /* reset alphabet? */
419 /* reset main variables */
421 ab_free
= (1 << bits
) + 2;
422 ab_max
= (1 << ab_bits
) - 1;
426 /* skip to next code */
430 /* unknown code: special case (like in ABCABCA) */
433 code
= lastcode
; /* take last string */
434 stack
[pos
++] = abcabca
; /* add first character */
437 /* build the string for this code in the stack */
438 while (code
> ab_clr
)
440 stack
[pos
++] = ab_tail
[code
];
441 code
= ab_prefix
[code
];
443 // Don't overflow. This shouldn't happen with normal
444 // GIF files, the allocSize of 4096+1 is enough. This
445 // will only happen with badly formed GIFs.
446 if (pos
>= allocSize
)
451 return wxGIF_INVFORMAT
;
455 if (pos
>= allocSize
)
460 return wxGIF_INVFORMAT
;
463 stack
[pos
] = code
; /* push last code into the stack */
464 abcabca
= code
; /* save for special case */
466 /* make new entry in alphabet (only if NOT just cleared) */
469 // Normally, after the alphabet is full and can't grow any
470 // further (ab_free == 4096), encoder should (must?) emit CLEAR
471 // to reset it. This checks whether we really got it, otherwise
472 // the GIF is damaged.
473 if (ab_free
> ab_max
)
478 return wxGIF_INVFORMAT
;
481 // This assert seems unnecessary since the condition above
482 // eliminates the only case in which it went false. But I really
483 // don't like being forced to ask "Who in .text could have
484 // written there?!" And I wouldn't have been forced to ask if
485 // this line had already been here.
486 wxASSERT(ab_free
< allocSize
);
488 ab_prefix
[ab_free
] = lastcode
;
489 ab_tail
[ab_free
] = code
;
492 if ((ab_free
> ab_max
) && (ab_bits
< 12))
495 ab_max
= (1 << ab_bits
) - 1;
499 /* dump stack data to the image buffer */
502 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
511 /* support for interlaced images */
514 case 1: y
+= 8; break;
515 case 2: y
+= 8; break;
516 case 3: y
+= 4; break;
517 case 4: y
+= 2; break;
520 /* loop until a valid y coordinate has been
521 found, Or if the maximum number of passes has
522 been reached, exit the loop, and stop image
523 decoding (At this point the image is successfully
525 If we don't loop, but merely set y to some other
526 value, that new value might still be invalid depending
527 on the height of the image. This would cause out of
530 while (y
>= (img
->h
))
534 case 2: y
= 4; break;
535 case 3: y
= 2; break;
536 case 4: y
= 1; break;
540 It's possible we arrive here. For example this
541 happens when the image is interlaced, and the
542 height is 1. Looking at the above cases, the
543 lowest possible y is 1. While the only valid
544 one would be 0 for an image of height 1. So
545 'eventually' the loop will arrive here.
546 This case makes sure this while loop is
547 exited, as well as the 2 other ones.
550 // Set y to a valid coordinate so the local
551 // while loop will be exited. (y = 0 always
552 // is >= img->h since if img->h == 0 the
553 // image is never decoded)
556 // This will exit the other outer while loop
559 // This will halt image decoding.
571 Normally image decoding is finished when an End of Information code is
572 encountered (code == ab_fin) however some broken encoders write wrong
573 "block byte counts" (The first byte value after the "code size" byte),
574 being one value too high. It might very well be possible other variants
575 of this problem occur as well. The only sensible solution seems to
576 be to check for clipping.
577 Example of wrong encoding:
578 (1 * 1 B/W image, raster data stream follows in hex bytes)
580 02 << B/W images have a code size of 2
581 02 << Block byte count
583 00 << Zero byte count (terminates data stream)
585 Because the block byte count is 2, the zero byte count is used in the
586 decoding process, and decoding is continued after this byte. (While it
587 should signal an end of image)
593 01 << When decoded this correctly includes the End of Information code
601 (The 44 doesn't include an End of Information code, but at least the
602 decoder correctly skips to 00 now after decoding, and signals this
603 as an End of Information itself)
617 while (code
!= ab_fin
);
619 delete [] ab_prefix
;
628 // Returns true if the file looks like a valid GIF, false otherwise.
630 bool wxGIFDecoder::CanRead()
632 unsigned char buf
[3];
634 if ( !m_f
->Read(buf
, WXSIZEOF(buf
)) )
637 m_f
->SeekI(-(wxFileOffset
)WXSIZEOF(buf
), wxFromCurrent
);
639 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
644 // Reads and decodes one or more GIF images, depending on whether
645 // animated GIF support is enabled. Can read GIFs with any bit
646 // size (color depth), but the output images are always expanded
647 // to 8 bits per pixel. Also, the image palettes always contain
648 // 256 colors, although some of them may be unused. Returns wxGIF_OK
649 // (== 0) on success, or an error code if something fails (see
650 // header file for details)
652 int wxGIFDecoder::ReadGIF()
654 unsigned int ncolors
;
655 int bits
, interl
, transparent
, disposal
, i
;
658 unsigned char type
= 0;
659 unsigned char pal
[768];
660 unsigned char buf
[16];
662 GIFImage
*pimg
, *pprev
;
664 /* check GIF signature */
666 return wxGIF_INVFORMAT
;
668 /* check for animated GIF support (ver. >= 89a) */
670 static const size_t headerSize
= (3 + 3);
671 m_f
->Read(buf
, headerSize
);
672 if (m_f
->LastRead() != headerSize
)
674 return wxGIF_INVFORMAT
;
677 if (memcmp(buf
+ 3, "89a", 3) < 0)
682 /* read logical screen descriptor block (LSDB) */
683 static const size_t lsdbSize
= (2 + 2 + 1 + 1 + 1);
684 m_f
->Read(buf
, lsdbSize
);
685 if (m_f
->LastRead() != lsdbSize
)
687 return wxGIF_INVFORMAT
;
690 m_screenw
= buf
[0] + 256 * buf
[1];
691 m_screenh
= buf
[2] + 256 * buf
[3];
693 if ((m_screenw
== 0) || (m_screenh
== 0))
695 return wxGIF_INVFORMAT
;
698 /* load global color map if available */
699 if ((buf
[4] & 0x80) == 0x80)
701 m_background
= buf
[5];
703 ncolors
= 2 << (buf
[4] & 0x07);
704 size_t numBytes
= 3 * ncolors
;
705 m_f
->Read(pal
, numBytes
);
706 if (m_f
->LastRead() != numBytes
)
708 return wxGIF_INVFORMAT
;
712 /* transparent colour, disposal method and delay default to unused */
726 type
= (unsigned char)m_f
->GetC();
729 If the end of file has been reached (or an error) and a ";"
730 (0x3B) hasn't been encountered yet, exit the loop. (Without this
731 check the while loop would loop endlessly.) Later on, in the next while
732 loop, the file will be treated as being truncated (But still
733 be decoded as far as possible). returning wxGIF_TRUNCATED is not
734 possible here since some init code is done after this loop.
736 if (m_f
->Eof())// || !m_f->IsOk())
739 type is set to some bogus value, so there's no
740 need to continue evaluating it.
742 break; // Alternative : "return wxGIF_INVFORMAT;"
751 /* extension block? */
754 if (((unsigned char)m_f
->GetC()) == 0xF9)
755 /* graphics control extension, parse it */
757 static const size_t gceSize
= 6;
758 m_f
->Read(buf
, gceSize
);
759 if (m_f
->LastRead() != gceSize
)
762 return wxGIF_INVFORMAT
;
765 /* read delay and convert from 1/100 of a second to ms */
766 delay
= 10 * (buf
[2] + 256 * buf
[3]);
768 /* read transparent colour index, if used */
770 transparent
= buf
[4];
772 /* read disposal method */
773 disposal
= ((buf
[1] & 0x1C) >> 2) - 1;
776 /* other extension, skip */
778 while ((i
= (unsigned char)m_f
->GetC()) != 0)
780 m_f
->SeekI(i
, wxFromCurrent
);
790 /* image descriptor block? */
793 /* allocate memory for IMAGEN struct */
794 pimg
= (*ppimg
) = new GIFImage();
802 /* fill in the data */
803 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
804 m_f
->Read(buf
, idbSize
);
805 if (m_f
->LastRead() != idbSize
)
808 return wxGIF_INVFORMAT
;
811 pimg
->left
= buf
[0] + 256 * buf
[1];
812 pimg
->top
= buf
[2] + 256 * buf
[3];
814 pimg->left = buf[4] + 256 * buf[5];
815 pimg->top = buf[4] + 256 * buf[5];
817 pimg
->w
= buf
[4] + 256 * buf
[5];
818 pimg
->h
= buf
[6] + 256 * buf
[7];
820 if ((pimg
->w
== 0) || (pimg
->w
> m_screenw
) || (pimg
->h
== 0) || (pimg
->h
> m_screenh
))
823 return wxGIF_INVFORMAT
;
826 interl
= ((buf
[8] & 0x40)? 1 : 0);
827 size
= pimg
->w
* pimg
->h
;
829 pimg
->transparent
= transparent
;
830 pimg
->disposal
= disposal
;
837 /* allocate memory for image and palette */
838 pimg
->p
= (unsigned char *) malloc((size_t)size
);
839 pimg
->pal
= (unsigned char *) malloc(768);
841 if ((!pimg
->p
) || (!pimg
->pal
))
847 /* load local color map if available, else use global map */
848 if ((buf
[8] & 0x80) == 0x80)
850 ncolors
= 2 << (buf
[8] & 0x07);
851 size_t numBytes
= 3 * ncolors
;
852 m_f
->Read(pimg
->pal
, numBytes
);
853 if (m_f
->LastRead() != numBytes
)
856 return wxGIF_INVFORMAT
;
861 memcpy(pimg
->pal
, pal
, 768);
864 /* get initial code size from first byte in raster data */
865 bits
= (unsigned char)m_f
->GetC();
869 return wxGIF_INVFORMAT
;
873 int result
= dgif(pimg
, interl
, bits
);
874 if (result
!= wxGIF_OK
)
881 /* if this is not an animated GIF, exit after first image */
890 return wxGIF_INVFORMAT
;
893 /* setup image pointers */
898 /* try to read to the end of the stream */
902 return wxGIF_TRUNCATED
;
904 type
= (unsigned char)m_f
->GetC();
912 while ((i
= (unsigned char)m_f
->GetC()) != 0)
914 m_f
->SeekI(i
, wxFromCurrent
);
917 else if (type
== 0x2C)
919 /* image descriptor block */
920 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
921 m_f
->Read(buf
, idbSize
);
922 if (m_f
->LastRead() != idbSize
)
925 return wxGIF_INVFORMAT
;
928 /* local color map */
929 if ((buf
[8] & 0x80) == 0x80)
931 ncolors
= 2 << (buf
[8] & 0x07);
932 wxFileOffset pos
= m_f
->TellI();
933 wxFileOffset numBytes
= 3 * ncolors
;
934 m_f
->SeekI(numBytes
, wxFromCurrent
);
935 if (m_f
->TellI() != (pos
+ numBytes
))
938 return wxGIF_INVFORMAT
;
942 /* initial code size */
946 while ((i
= (unsigned char)m_f
->GetC()) != 0)
948 m_f
->SeekI(i
, wxFromCurrent
);
951 else if ((type
!= 0x3B) && (type
!= 00)) /* testing */
953 /* images are OK, but couldn't read to the end of the stream */
954 return wxGIF_TRUNCATED
;
961 #endif // wxUSE_STREAMS && wxUSE_GIF