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"
28 #include "wx/gifdecod.h"
29 #include "wx/scopedptr.h"
30 #include "wx/scopeguard.h"
34 GIF_MARKER_EXT
= '!', // 0x21
35 GIF_MARKER_SEP
= ',', // 0x2C
36 GIF_MARKER_ENDOFDATA
= ';', // 0x3B
38 GIF_MARKER_EXT_GRAPHICS_CONTROL
= 0xF9,
39 GIF_MARKER_EXT_COMMENT
= 0xFE,
40 GIF_MARKER_EXT_APP
= 0xFF
43 #define GetFrame(n) ((GIFImage*)m_frames[n])
45 //---------------------------------------------------------------------------
47 //---------------------------------------------------------------------------
49 // internal class for storing GIF image data
56 unsigned int w
; // width
57 unsigned int h
; // height
58 unsigned int left
; // x coord (in logical screen)
59 unsigned int top
; // y coord (in logical screen)
60 int transparent
; // transparent color index (-1 = none)
61 wxAnimationDisposal disposal
; // disposal method
62 long delay
; // delay in ms (-1 = unused)
63 unsigned char *p
; // bitmap
64 unsigned char *pal
; // palette
65 unsigned int ncolours
; // number of colours
68 wxDECLARE_NO_COPY_CLASS(GIFImage
);
71 wxDECLARE_SCOPED_PTR(GIFImage
, GIFImagePtr
)
72 wxDEFINE_SCOPED_PTR(GIFImage
, GIFImagePtr
)
75 //---------------------------------------------------------------------------
76 // GIFImage constructor
77 //---------------------------------------------------------------------------
85 disposal
= wxANIM_DONOTREMOVE
;
87 p
= (unsigned char *) NULL
;
88 pal
= (unsigned char *) NULL
;
92 //---------------------------------------------------------------------------
93 // wxGIFDecoder constructor and destructor
94 //---------------------------------------------------------------------------
96 wxGIFDecoder::wxGIFDecoder()
100 wxGIFDecoder::~wxGIFDecoder()
105 void wxGIFDecoder::Destroy()
107 wxASSERT(m_nFrames
==m_frames
.GetCount());
108 for (unsigned int i
=0; i
<m_nFrames
; i
++)
110 GIFImage
*f
= (GIFImage
*)m_frames
[i
];
121 //---------------------------------------------------------------------------
122 // Convert this image to a wxImage object
123 //---------------------------------------------------------------------------
125 // This function was designed by Vaclav Slavik
127 bool wxGIFDecoder::ConvertToImage(unsigned int frame
, wxImage
*image
) const
129 unsigned char *src
, *dst
, *pal
;
137 wxSize sz
= GetFrameSize(frame
);
138 image
->Create(sz
.GetWidth(), sz
.GetHeight());
139 image
->SetType(wxBITMAP_TYPE_GIF
);
144 pal
= GetPalette(frame
);
145 src
= GetData(frame
);
146 dst
= image
->GetData();
147 transparent
= GetTransparentColourIndex(frame
);
149 // set transparent colour mask
150 if (transparent
!= -1)
152 for (i
= 0; i
< GetNcolours(frame
); i
++)
154 if ((pal
[3 * i
+ 0] == 255) &&
155 (pal
[3 * i
+ 1] == 0) &&
156 (pal
[3 * i
+ 2] == 255))
158 pal
[3 * i
+ 2] = 254;
162 pal
[3 * transparent
+ 0] = 255,
163 pal
[3 * transparent
+ 1] = 0,
164 pal
[3 * transparent
+ 2] = 255;
166 image
->SetMaskColour(255, 0, 255);
169 image
->SetMask(false);
172 unsigned char r
[256];
173 unsigned char g
[256];
174 unsigned char b
[256];
176 for (i
= 0; i
< 256; i
++)
183 image
->SetPalette(wxPalette(GetNcolours(frame
), r
, g
, b
));
184 #endif // wxUSE_PALETTE
187 unsigned long npixel
= sz
.GetWidth() * sz
.GetHeight();
188 for (i
= 0; i
< npixel
; i
++, src
++)
190 *(dst
++) = pal
[3 * (*src
) + 0];
191 *(dst
++) = pal
[3 * (*src
) + 1];
192 *(dst
++) = pal
[3 * (*src
) + 2];
195 wxString comment
= GetFrame(frame
)->comment
;
196 if ( !comment
.empty() )
198 image
->SetOption(wxIMAGE_OPTION_GIF_COMMENT
, comment
);
205 //---------------------------------------------------------------------------
207 //---------------------------------------------------------------------------
209 // Get data for current frame
211 wxSize
wxGIFDecoder::GetFrameSize(unsigned int frame
) const
213 return wxSize(GetFrame(frame
)->w
, GetFrame(frame
)->h
);
216 wxPoint
wxGIFDecoder::GetFramePosition(unsigned int frame
) const
218 return wxPoint(GetFrame(frame
)->left
, GetFrame(frame
)->top
);
221 wxAnimationDisposal
wxGIFDecoder::GetDisposalMethod(unsigned int frame
) const
223 return GetFrame(frame
)->disposal
;
226 long wxGIFDecoder::GetDelay(unsigned int frame
) const
228 return GetFrame(frame
)->delay
;
231 wxColour
wxGIFDecoder::GetTransparentColour(unsigned int frame
) const
233 unsigned char *pal
= GetFrame(frame
)->pal
;
234 int n
= GetFrame(frame
)->transparent
;
238 return wxColour(pal
[n
*3 + 0],
243 unsigned char* wxGIFDecoder::GetData(unsigned int frame
) const { return (GetFrame(frame
)->p
); }
244 unsigned char* wxGIFDecoder::GetPalette(unsigned int frame
) const { return (GetFrame(frame
)->pal
); }
245 unsigned int wxGIFDecoder::GetNcolours(unsigned int frame
) const { return (GetFrame(frame
)->ncolours
); }
246 int wxGIFDecoder::GetTransparentColourIndex(unsigned int frame
) const { return (GetFrame(frame
)->transparent
); }
250 //---------------------------------------------------------------------------
251 // GIF reading and decoding
252 //---------------------------------------------------------------------------
255 // Reads the next code from the file stream, with size 'bits'
257 int wxGIFDecoder::getcode(wxInputStream
& stream
, int bits
, int ab_fin
)
259 unsigned int mask
; // bit mask
260 unsigned int code
; // code (result)
262 // get remaining bits from last byte read
263 mask
= (1 << bits
) - 1;
264 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
266 // keep reading new bytes while needed
267 while (bits
> m_restbits
)
269 // if no bytes left in this block, read the next block
272 m_restbyte
= stream
.GetC();
274 /* Some encoders are a bit broken: instead of issuing
275 * an end-of-image symbol (ab_fin) they come up with
276 * a zero-length subblock!! We catch this here so
277 * that the decoder sees an ab_fin code.
286 stream
.Read((void *) m_buffer
, m_restbyte
);
287 if (stream
.LastRead() != m_restbyte
)
295 // read next byte and isolate the bits we need
296 m_lastbyte
= (unsigned char) (*m_bufp
++);
297 mask
= (1 << (bits
- m_restbits
)) - 1;
298 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
301 // adjust total number of bits extracted from the buffer
302 m_restbits
= m_restbits
+ 8;
305 // find number of bits remaining for next code
306 m_restbits
= (m_restbits
- bits
);
313 // GIF decoding function. The initial code size (aka root size)
314 // is 'bits'. Supports interlaced images (interl == 1).
315 // Returns wxGIF_OK (== 0) on success, or an error code if something
316 // fails (see header file for details)
318 wxGIFDecoder::dgif(wxInputStream
& stream
, GIFImage
*img
, int interl
, int bits
)
320 static const int allocSize
= 4096 + 1;
321 int *ab_prefix
= new int[allocSize
]; // alphabet (prefixes)
322 if (ab_prefix
== NULL
)
327 int *ab_tail
= new int[allocSize
]; // alphabet (tails)
334 int *stack
= new int[allocSize
]; // decompression stack
342 int ab_clr
; // clear code
343 int ab_fin
; // end of info code
344 int ab_bits
; // actual symbol width, in bits
345 int ab_free
; // first free position in alphabet
346 int ab_max
; // last possible character in alphabet
347 int pass
; // pass number in interlaced images
348 int pos
; // index into decompresion stack
349 unsigned int x
, y
; // position in image buffer
351 int code
, readcode
, lastcode
, abcabca
;
353 // these won't change
354 ab_clr
= (1 << bits
);
355 ab_fin
= (1 << bits
) + 1;
357 // these will change through the decompression process
359 ab_free
= (1 << bits
) + 2;
360 ab_max
= (1 << ab_bits
) - 1;
366 // reset decoder vars
374 readcode
= code
= getcode(stream
, ab_bits
, ab_fin
);
377 if (code
== ab_fin
) break;
382 // reset main variables
384 ab_free
= (1 << bits
) + 2;
385 ab_max
= (1 << ab_bits
) - 1;
393 // unknown code: special case (like in ABCABCA)
396 code
= lastcode
; // take last string
397 stack
[pos
++] = abcabca
; // add first character
400 // build the string for this code in the stack
401 while (code
> ab_clr
)
403 stack
[pos
++] = ab_tail
[code
];
404 code
= ab_prefix
[code
];
406 // Don't overflow. This shouldn't happen with normal
407 // GIF files, the allocSize of 4096+1 is enough. This
408 // will only happen with badly formed GIFs.
409 if (pos
>= allocSize
)
414 return wxGIF_INVFORMAT
;
418 if (pos
>= allocSize
)
423 return wxGIF_INVFORMAT
;
426 stack
[pos
] = code
; // push last code into the stack
427 abcabca
= code
; // save for special case
429 // make new entry in alphabet (only if NOT just cleared)
432 // Normally, after the alphabet is full and can't grow any
433 // further (ab_free == 4096), encoder should (must?) emit CLEAR
434 // to reset it. This checks whether we really got it, otherwise
435 // the GIF is damaged.
436 if (ab_free
> ab_max
)
441 return wxGIF_INVFORMAT
;
444 // This assert seems unnecessary since the condition above
445 // eliminates the only case in which it went false. But I really
446 // don't like being forced to ask "Who in .text could have
447 // written there?!" And I wouldn't have been forced to ask if
448 // this line had already been here.
449 wxASSERT(ab_free
< allocSize
);
451 ab_prefix
[ab_free
] = lastcode
;
452 ab_tail
[ab_free
] = code
;
455 if ((ab_free
> ab_max
) && (ab_bits
< 12))
458 ab_max
= (1 << ab_bits
) - 1;
462 // dump stack data to the image buffer
465 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
474 // support for interlaced images
477 case 1: y
+= 8; break;
478 case 2: y
+= 8; break;
479 case 3: y
+= 4; break;
480 case 4: y
+= 2; break;
483 /* loop until a valid y coordinate has been
484 found, Or if the maximum number of passes has
485 been reached, exit the loop, and stop image
486 decoding (At this point the image is successfully
488 If we don't loop, but merely set y to some other
489 value, that new value might still be invalid depending
490 on the height of the image. This would cause out of
493 while (y
>= (img
->h
))
497 case 2: y
= 4; break;
498 case 3: y
= 2; break;
499 case 4: y
= 1; break;
503 It's possible we arrive here. For example this
504 happens when the image is interlaced, and the
505 height is 1. Looking at the above cases, the
506 lowest possible y is 1. While the only valid
507 one would be 0 for an image of height 1. So
508 'eventually' the loop will arrive here.
509 This case makes sure this while loop is
510 exited, as well as the 2 other ones.
513 // Set y to a valid coordinate so the local
514 // while loop will be exited. (y = 0 always
515 // is >= img->h since if img->h == 0 the
516 // image is never decoded)
519 // This will exit the other outer while loop
522 // This will halt image decoding.
534 Normally image decoding is finished when an End of Information code is
535 encountered (code == ab_fin) however some broken encoders write wrong
536 "block byte counts" (The first byte value after the "code size" byte),
537 being one value too high. It might very well be possible other variants
538 of this problem occur as well. The only sensible solution seems to
539 be to check for clipping.
540 Example of wrong encoding:
541 (1 * 1 B/W image, raster data stream follows in hex bytes)
543 02 << B/W images have a code size of 2
544 02 << Block byte count
546 00 << Zero byte count (terminates data stream)
548 Because the block byte count is 2, the zero byte count is used in the
549 decoding process, and decoding is continued after this byte. (While it
550 should signal an end of image)
556 01 << When decoded this correctly includes the End of Information code
564 (The 44 doesn't include an End of Information code, but at least the
565 decoder correctly skips to 00 now after decoding, and signals this
566 as an End of Information itself)
580 while (code
!= ab_fin
);
582 delete [] ab_prefix
;
591 // Returns true if the file looks like a valid GIF, false otherwise.
593 bool wxGIFDecoder::DoCanRead(wxInputStream
&stream
) const
595 unsigned char buf
[3];
597 if ( !stream
.Read(buf
, WXSIZEOF(buf
)) )
600 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
605 // Reads and decodes one or more GIF images, depending on whether
606 // animated GIF support is enabled. Can read GIFs with any bit
607 // size (color depth), but the output images are always expanded
608 // to 8 bits per pixel. Also, the image palettes always contain
609 // 256 colors, although some of them may be unused. Returns wxGIF_OK
610 // (== 0) on success, or an error code if something fails (see
611 // header file for details)
613 wxGIFErrorCode
wxGIFDecoder::LoadGIF(wxInputStream
& stream
)
615 unsigned int global_ncolors
= 0;
617 wxAnimationDisposal disposal
;
620 unsigned char type
= 0;
621 unsigned char pal
[768];
622 unsigned char buf
[16];
625 // check GIF signature
626 if (!CanRead(stream
))
627 return wxGIF_INVFORMAT
;
629 // check for animated GIF support (ver. >= 89a)
631 static const unsigned int headerSize
= (3 + 3);
632 stream
.Read(buf
, headerSize
);
633 if (stream
.LastRead() != headerSize
)
635 return wxGIF_INVFORMAT
;
638 if (memcmp(buf
+ 3, "89a", 3) < 0)
643 // read logical screen descriptor block (LSDB)
644 static const unsigned int lsdbSize
= (2 + 2 + 1 + 1 + 1);
645 stream
.Read(buf
, lsdbSize
);
646 if (stream
.LastRead() != lsdbSize
)
648 return wxGIF_INVFORMAT
;
651 m_szAnimation
.SetWidth( buf
[0] + 256 * buf
[1] );
652 m_szAnimation
.SetHeight( buf
[2] + 256 * buf
[3] );
654 if (anim
&& ((m_szAnimation
.GetWidth() == 0) || (m_szAnimation
.GetHeight() == 0)))
656 return wxGIF_INVFORMAT
;
659 // load global color map if available
660 if ((buf
[4] & 0x80) == 0x80)
662 int backgroundColIndex
= buf
[5];
664 global_ncolors
= 2 << (buf
[4] & 0x07);
665 unsigned int numBytes
= 3 * global_ncolors
;
666 stream
.Read(pal
, numBytes
);
667 if (stream
.LastRead() != numBytes
)
669 return wxGIF_INVFORMAT
;
672 m_background
.Set(pal
[backgroundColIndex
*3 + 0],
673 pal
[backgroundColIndex
*3 + 1],
674 pal
[backgroundColIndex
*3 + 2]);
677 // transparent colour, disposal method and delay default to unused
678 int transparent
= -1;
679 disposal
= wxANIM_UNSPECIFIED
;
686 type
= stream
.GetC();
689 If the end of file has been reached (or an error) and a ";"
690 (GIF_MARKER_ENDOFDATA) hasn't been encountered yet, exit the loop. (Without this
691 check the while loop would loop endlessly.) Later on, in the next while
692 loop, the file will be treated as being truncated (But still
693 be decoded as far as possible). returning wxGIF_TRUNCATED is not
694 possible here since some init code is done after this loop.
696 if (stream
.Eof())// || !stream.IsOk())
699 type is set to some bogus value, so there's no
700 need to continue evaluating it.
702 break; // Alternative : "return wxGIF_INVFORMAT;"
707 case GIF_MARKER_ENDOFDATA
:
711 switch (stream
.GetC())
713 case GIF_MARKER_EXT_GRAPHICS_CONTROL
:
715 // graphics control extension, parse it
717 static const unsigned int gceSize
= 6;
718 stream
.Read(buf
, gceSize
);
719 if (stream
.LastRead() != gceSize
)
722 return wxGIF_INVFORMAT
;
725 // read delay and convert from 1/100 of a second to ms
726 delay
= 10 * (buf
[2] + 256 * buf
[3]);
728 // read transparent colour index, if used
729 transparent
= buf
[1] & 0x01 ? buf
[4] : -1;
731 // read disposal method
732 disposal
= (wxAnimationDisposal
)(((buf
[1] & 0x1C) >> 2) - 1);
735 case GIF_MARKER_EXT_COMMENT
:
737 int len
= stream
.GetC();
746 wxCharBuffer
charbuf(len
);
747 stream
.Read(charbuf
.data(), len
);
748 if ( (int) stream
.LastRead() != len
)
754 comment
+= wxConvertMB2WX(charbuf
.data());
762 // other extension, skip
763 while ((i
= stream
.GetC()) != 0)
765 if (stream
.Eof() || (stream
.LastRead() == 0) ||
766 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
777 // allocate memory for IMAGEN struct
778 GIFImagePtr
pimg(new GIFImage());
780 wxScopeGuard guardDestroy
= wxMakeObjGuard(*this, &wxGIFDecoder::Destroy
);
786 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
787 stream
.Read(buf
, idbSize
);
788 if (stream
.LastRead() != idbSize
)
789 return wxGIF_INVFORMAT
;
791 pimg
->comment
= comment
;
793 pimg
->left
= buf
[0] + 256 * buf
[1];
794 pimg
->top
= buf
[2] + 256 * buf
[3];
796 pimg->left = buf[4] + 256 * buf[5];
797 pimg->top = buf[4] + 256 * buf[5];
799 pimg
->w
= buf
[4] + 256 * buf
[5];
800 pimg
->h
= buf
[6] + 256 * buf
[7];
804 // some GIF images specify incorrect animation size but we can
805 // still open them if we fix up the animation size, see #9465
806 if ( m_nFrames
== 0 )
808 if ( pimg
->w
> (unsigned)m_szAnimation
.x
)
809 m_szAnimation
.x
= pimg
->w
;
810 if ( pimg
->h
> (unsigned)m_szAnimation
.y
)
811 m_szAnimation
.y
= pimg
->h
;
813 else // subsequent frames
815 // check that we have valid size
816 if ( (!pimg
->w
|| pimg
->w
> (unsigned)m_szAnimation
.x
) ||
817 (!pimg
->h
|| pimg
->h
> (unsigned)m_szAnimation
.y
) )
819 wxLogError(_("Incorrect GIF frame size (%u, %d) for "
821 pimg
->w
, pimg
->h
, m_nFrames
);
822 return wxGIF_INVFORMAT
;
827 interl
= ((buf
[8] & 0x40)? 1 : 0);
828 size
= pimg
->w
* pimg
->h
;
830 pimg
->transparent
= transparent
;
831 pimg
->disposal
= disposal
;
834 // allocate memory for image and palette
835 pimg
->p
= (unsigned char *) malloc((unsigned int)size
);
836 pimg
->pal
= (unsigned char *) malloc(768);
838 if ((!pimg
->p
) || (!pimg
->pal
))
841 // load local color map if available, else use global map
842 if ((buf
[8] & 0x80) == 0x80)
844 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
845 unsigned int numBytes
= 3 * local_ncolors
;
846 stream
.Read(pimg
->pal
, numBytes
);
847 pimg
->ncolours
= local_ncolors
;
848 if (stream
.LastRead() != numBytes
)
849 return wxGIF_INVFORMAT
;
853 memcpy(pimg
->pal
, pal
, 768);
854 pimg
->ncolours
= global_ncolors
;
857 // get initial code size from first byte in raster data
858 bits
= stream
.GetC();
860 return wxGIF_INVFORMAT
;
863 wxGIFErrorCode result
= dgif(stream
, pimg
.get(), interl
, bits
);
864 if (result
!= wxGIF_OK
)
867 guardDestroy
.Dismiss();
869 // add the image to our frame array
870 m_frames
.Add(pimg
.release());
873 // if this is not an animated GIF, exit after first image
884 return wxGIF_INVFORMAT
;
887 // try to read to the end of the stream
888 while (type
!= GIF_MARKER_ENDOFDATA
)
891 return wxGIF_TRUNCATED
;
893 type
= stream
.GetC();
899 (void) stream
.GetC();
902 while ((i
= stream
.GetC()) != 0)
904 if (stream
.Eof() || (stream
.LastRead() == 0) ||
905 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
908 return wxGIF_INVFORMAT
;
914 // image descriptor block
915 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
916 stream
.Read(buf
, idbSize
);
917 if (stream
.LastRead() != idbSize
)
920 return wxGIF_INVFORMAT
;
924 if ((buf
[8] & 0x80) == 0x80)
926 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
927 wxFileOffset numBytes
= 3 * local_ncolors
;
928 if (stream
.SeekI(numBytes
, wxFromCurrent
) == wxInvalidOffset
)
931 return wxGIF_INVFORMAT
;
936 (void) stream
.GetC();
937 if (stream
.Eof() || (stream
.LastRead() == 0))
940 return wxGIF_INVFORMAT
;
944 while ((i
= stream
.GetC()) != 0)
946 if (stream
.Eof() || (stream
.LastRead() == 0) ||
947 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
950 return wxGIF_INVFORMAT
;
956 if ((type
!= GIF_MARKER_ENDOFDATA
) && (type
!= 00)) // testing
958 // images are OK, but couldn't read to the end of the stream
959 return wxGIF_TRUNCATED
;
968 #endif // wxUSE_STREAMS && wxUSE_GIF