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"
30 //---------------------------------------------------------------------------
32 //---------------------------------------------------------------------------
34 // internal class for storing GIF image data
41 unsigned int w
; // width
42 unsigned int h
; // height
43 unsigned int left
; // x coord (in logical screen)
44 unsigned int top
; // y coord (in logical screen)
45 int transparent
; // transparent color index (-1 = none)
46 wxAnimationDisposal disposal
; // disposal method
47 long delay
; // delay in ms (-1 = unused)
48 unsigned char *p
; // bitmap
49 unsigned char *pal
; // palette
50 unsigned int ncolours
; // number of colours
52 DECLARE_NO_COPY_CLASS(GIFImage
)
57 //---------------------------------------------------------------------------
58 // GIFImage constructor
59 //---------------------------------------------------------------------------
67 disposal
= wxANIM_DONOTREMOVE
;
69 p
= (unsigned char *) NULL
;
70 pal
= (unsigned char *) NULL
;
74 //---------------------------------------------------------------------------
75 // wxGIFDecoder constructor and destructor
76 //---------------------------------------------------------------------------
78 wxGIFDecoder::wxGIFDecoder()
82 wxGIFDecoder::~wxGIFDecoder()
87 void wxGIFDecoder::Destroy()
89 wxASSERT(m_nFrames
==m_frames
.GetCount());
90 for (unsigned int i
=0; i
<m_nFrames
; i
++)
92 GIFImage
*f
= (GIFImage
*)m_frames
[i
];
103 //---------------------------------------------------------------------------
104 // Convert this image to a wxImage object
105 //---------------------------------------------------------------------------
107 // This function was designed by Vaclav Slavik
109 bool wxGIFDecoder::ConvertToImage(unsigned int frame
, wxImage
*image
) const
111 unsigned char *src
, *dst
, *pal
;
119 wxSize sz
= GetFrameSize(frame
);
120 image
->Create(sz
.GetWidth(), sz
.GetHeight());
125 pal
= GetPalette(frame
);
126 src
= GetData(frame
);
127 dst
= image
->GetData();
128 transparent
= GetTransparentColourIndex(frame
);
130 // set transparent colour mask
131 if (transparent
!= -1)
133 for (i
= 0; i
< GetNcolours(frame
); i
++)
135 if ((pal
[3 * i
+ 0] == 255) &&
136 (pal
[3 * i
+ 1] == 0) &&
137 (pal
[3 * i
+ 2] == 255))
139 pal
[3 * i
+ 2] = 254;
143 pal
[3 * transparent
+ 0] = 255,
144 pal
[3 * transparent
+ 1] = 0,
145 pal
[3 * transparent
+ 2] = 255;
147 image
->SetMaskColour(255, 0, 255);
150 image
->SetMask(false);
153 unsigned char r
[256];
154 unsigned char g
[256];
155 unsigned char b
[256];
157 for (i
= 0; i
< 256; i
++)
164 image
->SetPalette(wxPalette(GetNcolours(frame
), r
, g
, b
));
165 #endif // wxUSE_PALETTE
168 unsigned long npixel
= sz
.GetWidth() * sz
.GetHeight();
169 for (i
= 0; i
< npixel
; i
++, src
++)
171 *(dst
++) = pal
[3 * (*src
) + 0];
172 *(dst
++) = pal
[3 * (*src
) + 1];
173 *(dst
++) = pal
[3 * (*src
) + 2];
180 //---------------------------------------------------------------------------
182 //---------------------------------------------------------------------------
184 #define GetFrame(n) ((GIFImage*)m_frames[n])
187 // Get data for current frame
189 wxSize
wxGIFDecoder::GetFrameSize(unsigned int frame
) const
191 return wxSize(GetFrame(frame
)->w
, GetFrame(frame
)->h
);
194 wxPoint
wxGIFDecoder::GetFramePosition(unsigned int frame
) const
196 return wxPoint(GetFrame(frame
)->left
, GetFrame(frame
)->top
);
199 wxAnimationDisposal
wxGIFDecoder::GetDisposalMethod(unsigned int frame
) const
201 return GetFrame(frame
)->disposal
;
204 long wxGIFDecoder::GetDelay(unsigned int frame
) const
206 return GetFrame(frame
)->delay
;
209 wxColour
wxGIFDecoder::GetTransparentColour(unsigned int frame
) const
211 unsigned char *pal
= GetFrame(frame
)->pal
;
212 int n
= GetFrame(frame
)->transparent
;
216 return wxColour(pal
[n
*3 + 0],
221 unsigned char* wxGIFDecoder::GetData(unsigned int frame
) const { return (GetFrame(frame
)->p
); }
222 unsigned char* wxGIFDecoder::GetPalette(unsigned int frame
) const { return (GetFrame(frame
)->pal
); }
223 unsigned int wxGIFDecoder::GetNcolours(unsigned int frame
) const { return (GetFrame(frame
)->ncolours
); }
224 int wxGIFDecoder::GetTransparentColourIndex(unsigned int frame
) const { return (GetFrame(frame
)->transparent
); }
228 //---------------------------------------------------------------------------
229 // GIF reading and decoding
230 //---------------------------------------------------------------------------
233 // Reads the next code from the file stream, with size 'bits'
235 int wxGIFDecoder::getcode(wxInputStream
& stream
, int bits
, int ab_fin
)
237 unsigned int mask
; // bit mask
238 unsigned int code
; // code (result)
240 // get remaining bits from last byte read
241 mask
= (1 << bits
) - 1;
242 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
244 // keep reading new bytes while needed
245 while (bits
> m_restbits
)
247 // if no bytes left in this block, read the next block
250 m_restbyte
= (unsigned char)stream
.GetC();
252 /* Some encoders are a bit broken: instead of issuing
253 * an end-of-image symbol (ab_fin) they come up with
254 * a zero-length subblock!! We catch this here so
255 * that the decoder sees an ab_fin code.
264 stream
.Read((void *) m_buffer
, m_restbyte
);
265 if (stream
.LastRead() != m_restbyte
)
273 // read next byte and isolate the bits we need
274 m_lastbyte
= (unsigned char) (*m_bufp
++);
275 mask
= (1 << (bits
- m_restbits
)) - 1;
276 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
279 // adjust total number of bits extracted from the buffer
280 m_restbits
= m_restbits
+ 8;
283 // find number of bits remaining for next code
284 m_restbits
= (m_restbits
- bits
);
291 // GIF decoding function. The initial code size (aka root size)
292 // is 'bits'. Supports interlaced images (interl == 1).
293 // Returns wxGIF_OK (== 0) on success, or an error code if something
294 // fails (see header file for details)
296 wxGIFDecoder::dgif(wxInputStream
& stream
, GIFImage
*img
, int interl
, int bits
)
298 static const int allocSize
= 4096 + 1;
299 int *ab_prefix
= new int[allocSize
]; // alphabet (prefixes)
300 if (ab_prefix
== NULL
)
305 int *ab_tail
= new int[allocSize
]; // alphabet (tails)
312 int *stack
= new int[allocSize
]; // decompression stack
320 int ab_clr
; // clear code
321 int ab_fin
; // end of info code
322 int ab_bits
; // actual symbol width, in bits
323 int ab_free
; // first free position in alphabet
324 int ab_max
; // last possible character in alphabet
325 int pass
; // pass number in interlaced images
326 int pos
; // index into decompresion stack
327 unsigned int x
, y
; // position in image buffer
329 int code
, readcode
, lastcode
, abcabca
;
331 // these won't change
332 ab_clr
= (1 << bits
);
333 ab_fin
= (1 << bits
) + 1;
335 // these will change through the decompression proccess
337 ab_free
= (1 << bits
) + 2;
338 ab_max
= (1 << ab_bits
) - 1;
344 // reset decoder vars
352 readcode
= code
= getcode(stream
, ab_bits
, ab_fin
);
355 if (code
== ab_fin
) break;
360 // reset main variables
362 ab_free
= (1 << bits
) + 2;
363 ab_max
= (1 << ab_bits
) - 1;
371 // unknown code: special case (like in ABCABCA)
374 code
= lastcode
; // take last string
375 stack
[pos
++] = abcabca
; // add first character
378 // build the string for this code in the stack
379 while (code
> ab_clr
)
381 stack
[pos
++] = ab_tail
[code
];
382 code
= ab_prefix
[code
];
384 // Don't overflow. This shouldn't happen with normal
385 // GIF files, the allocSize of 4096+1 is enough. This
386 // will only happen with badly formed GIFs.
387 if (pos
>= allocSize
)
392 return wxGIF_INVFORMAT
;
396 if (pos
>= allocSize
)
401 return wxGIF_INVFORMAT
;
404 stack
[pos
] = code
; // push last code into the stack
405 abcabca
= code
; // save for special case
407 // make new entry in alphabet (only if NOT just cleared)
410 // Normally, after the alphabet is full and can't grow any
411 // further (ab_free == 4096), encoder should (must?) emit CLEAR
412 // to reset it. This checks whether we really got it, otherwise
413 // the GIF is damaged.
414 if (ab_free
> ab_max
)
419 return wxGIF_INVFORMAT
;
422 // This assert seems unnecessary since the condition above
423 // eliminates the only case in which it went false. But I really
424 // don't like being forced to ask "Who in .text could have
425 // written there?!" And I wouldn't have been forced to ask if
426 // this line had already been here.
427 wxASSERT(ab_free
< allocSize
);
429 ab_prefix
[ab_free
] = lastcode
;
430 ab_tail
[ab_free
] = code
;
433 if ((ab_free
> ab_max
) && (ab_bits
< 12))
436 ab_max
= (1 << ab_bits
) - 1;
440 // dump stack data to the image buffer
443 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
452 // support for interlaced images
455 case 1: y
+= 8; break;
456 case 2: y
+= 8; break;
457 case 3: y
+= 4; break;
458 case 4: y
+= 2; break;
461 /* loop until a valid y coordinate has been
462 found, Or if the maximum number of passes has
463 been reached, exit the loop, and stop image
464 decoding (At this point the image is successfully
466 If we don't loop, but merely set y to some other
467 value, that new value might still be invalid depending
468 on the height of the image. This would cause out of
471 while (y
>= (img
->h
))
475 case 2: y
= 4; break;
476 case 3: y
= 2; break;
477 case 4: y
= 1; break;
481 It's possible we arrive here. For example this
482 happens when the image is interlaced, and the
483 height is 1. Looking at the above cases, the
484 lowest possible y is 1. While the only valid
485 one would be 0 for an image of height 1. So
486 'eventually' the loop will arrive here.
487 This case makes sure this while loop is
488 exited, as well as the 2 other ones.
491 // Set y to a valid coordinate so the local
492 // while loop will be exited. (y = 0 always
493 // is >= img->h since if img->h == 0 the
494 // image is never decoded)
497 // This will exit the other outer while loop
500 // This will halt image decoding.
512 Normally image decoding is finished when an End of Information code is
513 encountered (code == ab_fin) however some broken encoders write wrong
514 "block byte counts" (The first byte value after the "code size" byte),
515 being one value too high. It might very well be possible other variants
516 of this problem occur as well. The only sensible solution seems to
517 be to check for clipping.
518 Example of wrong encoding:
519 (1 * 1 B/W image, raster data stream follows in hex bytes)
521 02 << B/W images have a code size of 2
522 02 << Block byte count
524 00 << Zero byte count (terminates data stream)
526 Because the block byte count is 2, the zero byte count is used in the
527 decoding process, and decoding is continued after this byte. (While it
528 should signal an end of image)
534 01 << When decoded this correctly includes the End of Information code
542 (The 44 doesn't include an End of Information code, but at least the
543 decoder correctly skips to 00 now after decoding, and signals this
544 as an End of Information itself)
558 while (code
!= ab_fin
);
560 delete [] ab_prefix
;
569 // Returns true if the file looks like a valid GIF, false otherwise.
571 bool wxGIFDecoder::CanRead(wxInputStream
&stream
) const
573 unsigned char buf
[3];
575 if ( !stream
.Read(buf
, WXSIZEOF(buf
)) )
578 stream
.SeekI(-(wxFileOffset
)WXSIZEOF(buf
), wxFromCurrent
);
580 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
585 // Reads and decodes one or more GIF images, depending on whether
586 // animated GIF support is enabled. Can read GIFs with any bit
587 // size (color depth), but the output images are always expanded
588 // to 8 bits per pixel. Also, the image palettes always contain
589 // 256 colors, although some of them may be unused. Returns wxGIF_OK
590 // (== 0) on success, or an error code if something fails (see
591 // header file for details)
593 wxGIFErrorCode
wxGIFDecoder::LoadGIF(wxInputStream
& stream
)
595 unsigned int global_ncolors
= 0;
596 int bits
, interl
, transparent
, i
;
597 wxAnimationDisposal disposal
;
600 unsigned char type
= 0;
601 unsigned char pal
[768];
602 unsigned char buf
[16];
605 // check GIF signature
606 if (!CanRead(stream
))
607 return wxGIF_INVFORMAT
;
609 // check for animated GIF support (ver. >= 89a)
611 static const unsigned int headerSize
= (3 + 3);
612 stream
.Read(buf
, headerSize
);
613 if (stream
.LastRead() != headerSize
)
615 return wxGIF_INVFORMAT
;
618 if (memcmp(buf
+ 3, "89a", 3) < 0)
623 // read logical screen descriptor block (LSDB)
624 static const unsigned int lsdbSize
= (2 + 2 + 1 + 1 + 1);
625 stream
.Read(buf
, lsdbSize
);
626 if (stream
.LastRead() != lsdbSize
)
628 return wxGIF_INVFORMAT
;
631 m_szAnimation
.SetWidth( buf
[0] + 256 * buf
[1] );
632 m_szAnimation
.SetHeight( buf
[2] + 256 * buf
[3] );
634 if (anim
&& ((m_szAnimation
.GetWidth() == 0) || (m_szAnimation
.GetHeight() == 0)))
636 return wxGIF_INVFORMAT
;
639 // load global color map if available
640 if ((buf
[4] & 0x80) == 0x80)
642 int backgroundColIndex
= buf
[5];
644 global_ncolors
= 2 << (buf
[4] & 0x07);
645 unsigned int numBytes
= 3 * global_ncolors
;
646 stream
.Read(pal
, numBytes
);
647 if (stream
.LastRead() != numBytes
)
649 return wxGIF_INVFORMAT
;
652 m_background
.Set(pal
[backgroundColIndex
*3 + 0],
653 pal
[backgroundColIndex
*3 + 1],
654 pal
[backgroundColIndex
*3 + 2]);
657 // transparent colour, disposal method and delay default to unused
659 disposal
= wxANIM_UNSPECIFIED
;
665 type
= (unsigned char)stream
.GetC();
668 If the end of file has been reached (or an error) and a ";"
669 (0x3B) hasn't been encountered yet, exit the loop. (Without this
670 check the while loop would loop endlessly.) Later on, in the next while
671 loop, the file will be treated as being truncated (But still
672 be decoded as far as possible). returning wxGIF_TRUNCATED is not
673 possible here since some init code is done after this loop.
675 if (stream
.Eof())// || !stream.IsOk())
678 type is set to some bogus value, so there's no
679 need to continue evaluating it.
681 break; // Alternative : "return wxGIF_INVFORMAT;"
693 if (((unsigned char)stream
.GetC()) == 0xF9)
694 // graphics control extension, parse it
696 static const unsigned int gceSize
= 6;
697 stream
.Read(buf
, gceSize
);
698 if (stream
.LastRead() != gceSize
)
701 return wxGIF_INVFORMAT
;
704 // read delay and convert from 1/100 of a second to ms
705 delay
= 10 * (buf
[2] + 256 * buf
[3]);
707 // read transparent colour index, if used
709 transparent
= buf
[4];
711 // read disposal method
712 disposal
= (wxAnimationDisposal
)(((buf
[1] & 0x1C) >> 2) - 1);
715 // other extension, skip
717 while ((i
= (unsigned char)stream
.GetC()) != 0)
719 if (stream
.Eof() || (stream
.LastRead() == 0))
724 stream
.SeekI(i
, wxFromCurrent
);
729 // image descriptor block?
732 // allocate memory for IMAGEN struct
733 GIFImage
*pimg
= new GIFImage();
742 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
743 stream
.Read(buf
, idbSize
);
744 if (stream
.LastRead() != idbSize
)
747 return wxGIF_INVFORMAT
;
750 pimg
->left
= buf
[0] + 256 * buf
[1];
751 pimg
->top
= buf
[2] + 256 * buf
[3];
753 pimg->left = buf[4] + 256 * buf[5];
754 pimg->top = buf[4] + 256 * buf[5];
756 pimg
->w
= buf
[4] + 256 * buf
[5];
757 pimg
->h
= buf
[6] + 256 * buf
[7];
759 if (anim
&& ((pimg
->w
== 0) || (pimg
->w
> (unsigned int)m_szAnimation
.GetWidth()) ||
760 (pimg
->h
== 0) || (pimg
->h
> (unsigned int)m_szAnimation
.GetHeight())))
763 return wxGIF_INVFORMAT
;
766 interl
= ((buf
[8] & 0x40)? 1 : 0);
767 size
= pimg
->w
* pimg
->h
;
769 pimg
->transparent
= transparent
;
770 pimg
->disposal
= disposal
;
773 // allocate memory for image and palette
774 pimg
->p
= (unsigned char *) malloc((unsigned int)size
);
775 pimg
->pal
= (unsigned char *) malloc(768);
777 if ((!pimg
->p
) || (!pimg
->pal
))
783 // load local color map if available, else use global map
784 if ((buf
[8] & 0x80) == 0x80)
786 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
787 unsigned int numBytes
= 3 * local_ncolors
;
788 stream
.Read(pimg
->pal
, numBytes
);
789 pimg
->ncolours
= local_ncolors
;
790 if (stream
.LastRead() != numBytes
)
793 return wxGIF_INVFORMAT
;
798 memcpy(pimg
->pal
, pal
, 768);
799 pimg
->ncolours
= global_ncolors
;
802 // get initial code size from first byte in raster data
803 bits
= (unsigned char)stream
.GetC();
807 return wxGIF_INVFORMAT
;
811 wxGIFErrorCode result
= dgif(stream
, pimg
, interl
, bits
);
812 if (result
!= wxGIF_OK
)
818 // add the image to our frame array
819 m_frames
.Add((void*)pimg
);
822 // if this is not an animated GIF, exit after first image
831 return wxGIF_INVFORMAT
;
834 // try to read to the end of the stream
838 return wxGIF_TRUNCATED
;
840 type
= (unsigned char)stream
.GetC();
845 (void) stream
.GetC();
848 while ((i
= (unsigned char)stream
.GetC()) != 0)
850 if (stream
.Eof() || (stream
.LastRead() == 0))
853 return wxGIF_INVFORMAT
;
855 stream
.SeekI(i
, wxFromCurrent
);
858 else if (type
== 0x2C)
860 // image descriptor block
861 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
862 stream
.Read(buf
, idbSize
);
863 if (stream
.LastRead() != idbSize
)
866 return wxGIF_INVFORMAT
;
870 if ((buf
[8] & 0x80) == 0x80)
872 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
873 wxFileOffset numBytes
= 3 * local_ncolors
;
874 stream
.SeekI(numBytes
, wxFromCurrent
);
878 (void) stream
.GetC();
879 if (stream
.Eof() || (stream
.LastRead() == 0))
882 return wxGIF_INVFORMAT
;
886 while ((i
= (unsigned char)stream
.GetC()) != 0)
888 if (stream
.Eof() || (stream
.LastRead() == 0))
891 return wxGIF_INVFORMAT
;
893 stream
.SeekI(i
, wxFromCurrent
);
896 else if ((type
!= 0x3B) && (type
!= 00)) // testing
898 // images are OK, but couldn't read to the end of the stream
899 return wxGIF_TRUNCATED
;
906 #endif // wxUSE_STREAMS && wxUSE_GIF