1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/gifdecod.cpp
3 // Purpose: wxGIFDecoder, GIF reader for wxImage and wxAnimation
4 // Author: Guillermo Rodriguez Garcia <guille@iies.es>
6 // Copyright: (c) Guillermo Rodriguez Garcia
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #if wxUSE_STREAMS && wxUSE_GIF
20 #include "wx/palette.h"
27 #include "wx/gifdecod.h"
28 #include "wx/scopedptr.h"
29 #include "wx/scopeguard.h"
33 GIF_MARKER_EXT
= '!', // 0x21
34 GIF_MARKER_SEP
= ',', // 0x2C
35 GIF_MARKER_ENDOFDATA
= ';', // 0x3B
37 GIF_MARKER_EXT_GRAPHICS_CONTROL
= 0xF9,
38 GIF_MARKER_EXT_COMMENT
= 0xFE,
39 GIF_MARKER_EXT_APP
= 0xFF
42 #define GetFrame(n) ((GIFImage*)m_frames[n])
44 //---------------------------------------------------------------------------
46 //---------------------------------------------------------------------------
48 // internal class for storing GIF image data
55 unsigned int w
; // width
56 unsigned int h
; // height
57 unsigned int left
; // x coord (in logical screen)
58 unsigned int top
; // y coord (in logical screen)
59 int transparent
; // transparent color index (-1 = none)
60 wxAnimationDisposal disposal
; // disposal method
61 long delay
; // delay in ms (-1 = unused)
62 unsigned char *p
; // bitmap
63 unsigned char *pal
; // palette
64 unsigned int ncolours
; // number of colours
67 wxDECLARE_NO_COPY_CLASS(GIFImage
);
70 wxDECLARE_SCOPED_PTR(GIFImage
, GIFImagePtr
)
71 wxDEFINE_SCOPED_PTR(GIFImage
, GIFImagePtr
)
74 //---------------------------------------------------------------------------
75 // GIFImage constructor
76 //---------------------------------------------------------------------------
84 disposal
= wxANIM_DONOTREMOVE
;
86 p
= (unsigned char *) NULL
;
87 pal
= (unsigned char *) NULL
;
91 //---------------------------------------------------------------------------
92 // wxGIFDecoder constructor and destructor
93 //---------------------------------------------------------------------------
95 wxGIFDecoder::wxGIFDecoder()
99 wxGIFDecoder::~wxGIFDecoder()
104 void wxGIFDecoder::Destroy()
106 wxASSERT(m_nFrames
==m_frames
.GetCount());
107 for (unsigned int i
=0; i
<m_nFrames
; i
++)
109 GIFImage
*f
= (GIFImage
*)m_frames
[i
];
120 //---------------------------------------------------------------------------
121 // Convert this image to a wxImage object
122 //---------------------------------------------------------------------------
124 // This function was designed by Vaclav Slavik
126 bool wxGIFDecoder::ConvertToImage(unsigned int frame
, wxImage
*image
) const
128 unsigned char *src
, *dst
, *pal
;
136 wxSize sz
= GetFrameSize(frame
);
137 image
->Create(sz
.GetWidth(), sz
.GetHeight());
138 image
->SetType(wxBITMAP_TYPE_GIF
);
143 pal
= GetPalette(frame
);
144 src
= GetData(frame
);
145 dst
= image
->GetData();
146 transparent
= GetTransparentColourIndex(frame
);
148 // set transparent colour mask
149 if (transparent
!= -1)
151 for (i
= 0; i
< GetNcolours(frame
); i
++)
153 if ((pal
[3 * i
+ 0] == 255) &&
154 (pal
[3 * i
+ 1] == 0) &&
155 (pal
[3 * i
+ 2] == 255))
157 pal
[3 * i
+ 2] = 254;
161 pal
[3 * transparent
+ 0] = 255,
162 pal
[3 * transparent
+ 1] = 0,
163 pal
[3 * transparent
+ 2] = 255;
165 image
->SetMaskColour(255, 0, 255);
168 image
->SetMask(false);
171 unsigned char r
[256];
172 unsigned char g
[256];
173 unsigned char b
[256];
175 for (i
= 0; i
< 256; i
++)
182 image
->SetPalette(wxPalette(GetNcolours(frame
), r
, g
, b
));
183 #endif // wxUSE_PALETTE
186 unsigned long npixel
= sz
.GetWidth() * sz
.GetHeight();
187 for (i
= 0; i
< npixel
; i
++, src
++)
189 *(dst
++) = pal
[3 * (*src
) + 0];
190 *(dst
++) = pal
[3 * (*src
) + 1];
191 *(dst
++) = pal
[3 * (*src
) + 2];
194 wxString comment
= GetFrame(frame
)->comment
;
195 if ( !comment
.empty() )
197 image
->SetOption(wxIMAGE_OPTION_GIF_COMMENT
, comment
);
204 //---------------------------------------------------------------------------
206 //---------------------------------------------------------------------------
208 // Get data for current frame
210 wxSize
wxGIFDecoder::GetFrameSize(unsigned int frame
) const
212 return wxSize(GetFrame(frame
)->w
, GetFrame(frame
)->h
);
215 wxPoint
wxGIFDecoder::GetFramePosition(unsigned int frame
) const
217 return wxPoint(GetFrame(frame
)->left
, GetFrame(frame
)->top
);
220 wxAnimationDisposal
wxGIFDecoder::GetDisposalMethod(unsigned int frame
) const
222 return GetFrame(frame
)->disposal
;
225 long wxGIFDecoder::GetDelay(unsigned int frame
) const
227 return GetFrame(frame
)->delay
;
230 wxColour
wxGIFDecoder::GetTransparentColour(unsigned int frame
) const
232 unsigned char *pal
= GetFrame(frame
)->pal
;
233 int n
= GetFrame(frame
)->transparent
;
237 return wxColour(pal
[n
*3 + 0],
242 unsigned char* wxGIFDecoder::GetData(unsigned int frame
) const { return (GetFrame(frame
)->p
); }
243 unsigned char* wxGIFDecoder::GetPalette(unsigned int frame
) const { return (GetFrame(frame
)->pal
); }
244 unsigned int wxGIFDecoder::GetNcolours(unsigned int frame
) const { return (GetFrame(frame
)->ncolours
); }
245 int wxGIFDecoder::GetTransparentColourIndex(unsigned int frame
) const { return (GetFrame(frame
)->transparent
); }
249 //---------------------------------------------------------------------------
250 // GIF reading and decoding
251 //---------------------------------------------------------------------------
254 // Reads the next code from the file stream, with size 'bits'
256 int wxGIFDecoder::getcode(wxInputStream
& stream
, int bits
, int ab_fin
)
258 unsigned int mask
; // bit mask
259 unsigned int code
; // code (result)
261 // get remaining bits from last byte read
262 mask
= (1 << bits
) - 1;
263 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
265 // keep reading new bytes while needed
266 while (bits
> m_restbits
)
268 // if no bytes left in this block, read the next block
271 m_restbyte
= stream
.GetC();
273 /* Some encoders are a bit broken: instead of issuing
274 * an end-of-image symbol (ab_fin) they come up with
275 * a zero-length subblock!! We catch this here so
276 * that the decoder sees an ab_fin code.
285 stream
.Read((void *) m_buffer
, m_restbyte
);
286 if (stream
.LastRead() != m_restbyte
)
294 // read next byte and isolate the bits we need
295 m_lastbyte
= (unsigned char) (*m_bufp
++);
296 mask
= (1 << (bits
- m_restbits
)) - 1;
297 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
300 // adjust total number of bits extracted from the buffer
301 m_restbits
= m_restbits
+ 8;
304 // find number of bits remaining for next code
305 m_restbits
= (m_restbits
- bits
);
312 // GIF decoding function. The initial code size (aka root size)
313 // is 'bits'. Supports interlaced images (interl == 1).
314 // Returns wxGIF_OK (== 0) on success, or an error code if something
315 // fails (see header file for details)
317 wxGIFDecoder::dgif(wxInputStream
& stream
, GIFImage
*img
, int interl
, int bits
)
319 static const int allocSize
= 4096 + 1;
320 int *ab_prefix
= new int[allocSize
]; // alphabet (prefixes)
321 if (ab_prefix
== NULL
)
326 int *ab_tail
= new int[allocSize
]; // alphabet (tails)
333 int *stack
= new int[allocSize
]; // decompression stack
341 int ab_clr
; // clear code
342 int ab_fin
; // end of info code
343 int ab_bits
; // actual symbol width, in bits
344 int ab_free
; // first free position in alphabet
345 int ab_max
; // last possible character in alphabet
346 int pass
; // pass number in interlaced images
347 int pos
; // index into decompresion stack
348 unsigned int x
, y
; // position in image buffer
350 int code
, readcode
, lastcode
, abcabca
;
352 // these won't change
353 ab_clr
= (1 << bits
);
354 ab_fin
= (1 << bits
) + 1;
356 // these will change through the decompression process
358 ab_free
= (1 << bits
) + 2;
359 ab_max
= (1 << ab_bits
) - 1;
365 // reset decoder vars
373 readcode
= code
= getcode(stream
, ab_bits
, ab_fin
);
376 if (code
== ab_fin
) break;
381 // reset main variables
383 ab_free
= (1 << bits
) + 2;
384 ab_max
= (1 << ab_bits
) - 1;
392 // unknown code: special case (like in ABCABCA)
395 code
= lastcode
; // take last string
396 stack
[pos
++] = abcabca
; // add first character
399 // build the string for this code in the stack
400 while (code
> ab_clr
)
402 stack
[pos
++] = ab_tail
[code
];
403 code
= ab_prefix
[code
];
405 // Don't overflow. This shouldn't happen with normal
406 // GIF files, the allocSize of 4096+1 is enough. This
407 // will only happen with badly formed GIFs.
408 if (pos
>= allocSize
)
413 return wxGIF_INVFORMAT
;
417 if (pos
>= allocSize
)
422 return wxGIF_INVFORMAT
;
425 stack
[pos
] = code
; // push last code into the stack
426 abcabca
= code
; // save for special case
428 // make new entry in alphabet (only if NOT just cleared)
431 // Normally, after the alphabet is full and can't grow any
432 // further (ab_free == 4096), encoder should (must?) emit CLEAR
433 // to reset it. This checks whether we really got it, otherwise
434 // the GIF is damaged.
435 if (ab_free
> ab_max
)
440 return wxGIF_INVFORMAT
;
443 // This assert seems unnecessary since the condition above
444 // eliminates the only case in which it went false. But I really
445 // don't like being forced to ask "Who in .text could have
446 // written there?!" And I wouldn't have been forced to ask if
447 // this line had already been here.
448 wxASSERT(ab_free
< allocSize
);
450 ab_prefix
[ab_free
] = lastcode
;
451 ab_tail
[ab_free
] = code
;
454 if ((ab_free
> ab_max
) && (ab_bits
< 12))
457 ab_max
= (1 << ab_bits
) - 1;
461 // dump stack data to the image buffer
464 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
473 // support for interlaced images
476 case 1: y
+= 8; break;
477 case 2: y
+= 8; break;
478 case 3: y
+= 4; break;
479 case 4: y
+= 2; break;
482 /* loop until a valid y coordinate has been
483 found, Or if the maximum number of passes has
484 been reached, exit the loop, and stop image
485 decoding (At this point the image is successfully
487 If we don't loop, but merely set y to some other
488 value, that new value might still be invalid depending
489 on the height of the image. This would cause out of
492 while (y
>= (img
->h
))
496 case 2: y
= 4; break;
497 case 3: y
= 2; break;
498 case 4: y
= 1; break;
502 It's possible we arrive here. For example this
503 happens when the image is interlaced, and the
504 height is 1. Looking at the above cases, the
505 lowest possible y is 1. While the only valid
506 one would be 0 for an image of height 1. So
507 'eventually' the loop will arrive here.
508 This case makes sure this while loop is
509 exited, as well as the 2 other ones.
512 // Set y to a valid coordinate so the local
513 // while loop will be exited. (y = 0 always
514 // is >= img->h since if img->h == 0 the
515 // image is never decoded)
518 // This will exit the other outer while loop
521 // This will halt image decoding.
533 Normally image decoding is finished when an End of Information code is
534 encountered (code == ab_fin) however some broken encoders write wrong
535 "block byte counts" (The first byte value after the "code size" byte),
536 being one value too high. It might very well be possible other variants
537 of this problem occur as well. The only sensible solution seems to
538 be to check for clipping.
539 Example of wrong encoding:
540 (1 * 1 B/W image, raster data stream follows in hex bytes)
542 02 << B/W images have a code size of 2
543 02 << Block byte count
545 00 << Zero byte count (terminates data stream)
547 Because the block byte count is 2, the zero byte count is used in the
548 decoding process, and decoding is continued after this byte. (While it
549 should signal an end of image)
555 01 << When decoded this correctly includes the End of Information code
563 (The 44 doesn't include an End of Information code, but at least the
564 decoder correctly skips to 00 now after decoding, and signals this
565 as an End of Information itself)
579 while (code
!= ab_fin
);
581 delete [] ab_prefix
;
590 // Returns true if the file looks like a valid GIF, false otherwise.
592 bool wxGIFDecoder::DoCanRead(wxInputStream
&stream
) const
594 unsigned char buf
[3];
596 if ( !stream
.Read(buf
, WXSIZEOF(buf
)) )
599 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
604 // Reads and decodes one or more GIF images, depending on whether
605 // animated GIF support is enabled. Can read GIFs with any bit
606 // size (color depth), but the output images are always expanded
607 // to 8 bits per pixel. Also, the image palettes always contain
608 // 256 colors, although some of them may be unused. Returns wxGIF_OK
609 // (== 0) on success, or an error code if something fails (see
610 // header file for details)
612 wxGIFErrorCode
wxGIFDecoder::LoadGIF(wxInputStream
& stream
)
614 unsigned int global_ncolors
= 0;
616 wxAnimationDisposal disposal
;
619 unsigned char type
= 0;
620 unsigned char pal
[768];
621 unsigned char buf
[16];
624 // check GIF signature
625 if (!CanRead(stream
))
626 return wxGIF_INVFORMAT
;
628 // check for animated GIF support (ver. >= 89a)
630 static const unsigned int headerSize
= (3 + 3);
631 stream
.Read(buf
, headerSize
);
632 if (stream
.LastRead() != headerSize
)
634 return wxGIF_INVFORMAT
;
637 if (memcmp(buf
+ 3, "89a", 3) < 0)
642 // read logical screen descriptor block (LSDB)
643 static const unsigned int lsdbSize
= (2 + 2 + 1 + 1 + 1);
644 stream
.Read(buf
, lsdbSize
);
645 if (stream
.LastRead() != lsdbSize
)
647 return wxGIF_INVFORMAT
;
650 m_szAnimation
.SetWidth( buf
[0] + 256 * buf
[1] );
651 m_szAnimation
.SetHeight( buf
[2] + 256 * buf
[3] );
653 if (anim
&& ((m_szAnimation
.GetWidth() == 0) || (m_szAnimation
.GetHeight() == 0)))
655 return wxGIF_INVFORMAT
;
658 // load global color map if available
659 if ((buf
[4] & 0x80) == 0x80)
661 int backgroundColIndex
= buf
[5];
663 global_ncolors
= 2 << (buf
[4] & 0x07);
664 unsigned int numBytes
= 3 * global_ncolors
;
665 stream
.Read(pal
, numBytes
);
666 if (stream
.LastRead() != numBytes
)
668 return wxGIF_INVFORMAT
;
671 m_background
.Set(pal
[backgroundColIndex
*3 + 0],
672 pal
[backgroundColIndex
*3 + 1],
673 pal
[backgroundColIndex
*3 + 2]);
676 // transparent colour, disposal method and delay default to unused
677 int transparent
= -1;
678 disposal
= wxANIM_UNSPECIFIED
;
685 type
= stream
.GetC();
688 If the end of file has been reached (or an error) and a ";"
689 (GIF_MARKER_ENDOFDATA) hasn't been encountered yet, exit the loop. (Without this
690 check the while loop would loop endlessly.) Later on, in the next while
691 loop, the file will be treated as being truncated (But still
692 be decoded as far as possible). returning wxGIF_TRUNCATED is not
693 possible here since some init code is done after this loop.
695 if (stream
.Eof())// || !stream.IsOk())
698 type is set to some bogus value, so there's no
699 need to continue evaluating it.
701 break; // Alternative : "return wxGIF_INVFORMAT;"
706 case GIF_MARKER_ENDOFDATA
:
710 switch (stream
.GetC())
712 case GIF_MARKER_EXT_GRAPHICS_CONTROL
:
714 // graphics control extension, parse it
716 static const unsigned int gceSize
= 6;
717 stream
.Read(buf
, gceSize
);
718 if (stream
.LastRead() != gceSize
)
721 return wxGIF_INVFORMAT
;
724 // read delay and convert from 1/100 of a second to ms
725 delay
= 10 * (buf
[2] + 256 * buf
[3]);
727 // read transparent colour index, if used
728 transparent
= buf
[1] & 0x01 ? buf
[4] : -1;
730 // read disposal method
731 disposal
= (wxAnimationDisposal
)(((buf
[1] & 0x1C) >> 2) - 1);
734 case GIF_MARKER_EXT_COMMENT
:
736 int len
= stream
.GetC();
745 wxCharBuffer
charbuf(len
);
746 stream
.Read(charbuf
.data(), len
);
747 if ( (int) stream
.LastRead() != len
)
753 comment
+= wxConvertMB2WX(charbuf
.data());
761 // other extension, skip
762 while ((i
= stream
.GetC()) != 0)
764 if (stream
.Eof() || (stream
.LastRead() == 0) ||
765 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
776 // allocate memory for IMAGEN struct
777 GIFImagePtr
pimg(new GIFImage());
779 wxScopeGuard guardDestroy
= wxMakeObjGuard(*this, &wxGIFDecoder::Destroy
);
785 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
786 stream
.Read(buf
, idbSize
);
787 if (stream
.LastRead() != idbSize
)
788 return wxGIF_INVFORMAT
;
790 pimg
->comment
= comment
;
792 pimg
->left
= buf
[0] + 256 * buf
[1];
793 pimg
->top
= buf
[2] + 256 * buf
[3];
795 pimg->left = buf[4] + 256 * buf[5];
796 pimg->top = buf[4] + 256 * buf[5];
798 pimg
->w
= buf
[4] + 256 * buf
[5];
799 pimg
->h
= buf
[6] + 256 * buf
[7];
803 // some GIF images specify incorrect animation size but we can
804 // still open them if we fix up the animation size, see #9465
805 if ( m_nFrames
== 0 )
807 if ( pimg
->w
> (unsigned)m_szAnimation
.x
)
808 m_szAnimation
.x
= pimg
->w
;
809 if ( pimg
->h
> (unsigned)m_szAnimation
.y
)
810 m_szAnimation
.y
= pimg
->h
;
812 else // subsequent frames
814 // check that we have valid size
815 if ( (!pimg
->w
|| pimg
->w
> (unsigned)m_szAnimation
.x
) ||
816 (!pimg
->h
|| pimg
->h
> (unsigned)m_szAnimation
.y
) )
818 wxLogError(_("Incorrect GIF frame size (%u, %d) for "
820 pimg
->w
, pimg
->h
, m_nFrames
);
821 return wxGIF_INVFORMAT
;
826 interl
= ((buf
[8] & 0x40)? 1 : 0);
827 size
= pimg
->w
* pimg
->h
;
829 pimg
->transparent
= transparent
;
830 pimg
->disposal
= disposal
;
833 // allocate memory for image and palette
834 pimg
->p
= (unsigned char *) malloc((unsigned int)size
);
835 pimg
->pal
= (unsigned char *) malloc(768);
837 if ((!pimg
->p
) || (!pimg
->pal
))
840 // load local color map if available, else use global map
841 if ((buf
[8] & 0x80) == 0x80)
843 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
844 unsigned int numBytes
= 3 * local_ncolors
;
845 stream
.Read(pimg
->pal
, numBytes
);
846 pimg
->ncolours
= local_ncolors
;
847 if (stream
.LastRead() != numBytes
)
848 return wxGIF_INVFORMAT
;
852 memcpy(pimg
->pal
, pal
, 768);
853 pimg
->ncolours
= global_ncolors
;
856 // get initial code size from first byte in raster data
857 bits
= stream
.GetC();
859 return wxGIF_INVFORMAT
;
862 wxGIFErrorCode result
= dgif(stream
, pimg
.get(), interl
, bits
);
863 if (result
!= wxGIF_OK
)
866 guardDestroy
.Dismiss();
868 // add the image to our frame array
869 m_frames
.Add(pimg
.release());
872 // if this is not an animated GIF, exit after first image
883 return wxGIF_INVFORMAT
;
886 // try to read to the end of the stream
887 while (type
!= GIF_MARKER_ENDOFDATA
)
890 return wxGIF_TRUNCATED
;
892 type
= stream
.GetC();
898 (void) stream
.GetC();
901 while ((i
= stream
.GetC()) != 0)
903 if (stream
.Eof() || (stream
.LastRead() == 0) ||
904 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
907 return wxGIF_INVFORMAT
;
913 // image descriptor block
914 static const unsigned int idbSize
= (2 + 2 + 2 + 2 + 1);
915 stream
.Read(buf
, idbSize
);
916 if (stream
.LastRead() != idbSize
)
919 return wxGIF_INVFORMAT
;
923 if ((buf
[8] & 0x80) == 0x80)
925 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
926 wxFileOffset numBytes
= 3 * local_ncolors
;
927 if (stream
.SeekI(numBytes
, wxFromCurrent
) == wxInvalidOffset
)
930 return wxGIF_INVFORMAT
;
935 (void) stream
.GetC();
936 if (stream
.Eof() || (stream
.LastRead() == 0))
939 return wxGIF_INVFORMAT
;
943 while ((i
= stream
.GetC()) != 0)
945 if (stream
.Eof() || (stream
.LastRead() == 0) ||
946 stream
.SeekI(i
, wxFromCurrent
) == wxInvalidOffset
)
949 return wxGIF_INVFORMAT
;
955 if ((type
!= GIF_MARKER_ENDOFDATA
) && (type
!= 00)) // testing
957 // images are OK, but couldn't read to the end of the stream
958 return wxGIF_TRUNCATED
;
967 #endif // wxUSE_STREAMS && wxUSE_GIF