]>
git.saurik.com Git - wxWidgets.git/blob - src/common/gifdecod.cpp
1 /////////////////////////////////////////////////////////////////////////////
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"
20 # include "wx/palette.h"
23 #if wxUSE_STREAMS && wxUSE_GIF
27 #include "wx/gifdecod.h"
30 //---------------------------------------------------------------------------
31 // GIFImage constructor
32 //---------------------------------------------------------------------------
42 p
= (unsigned char *) NULL
;
43 pal
= (unsigned char *) NULL
;
44 next
= (GIFImage
*) NULL
;
45 prev
= (GIFImage
*) NULL
;
48 //---------------------------------------------------------------------------
49 // wxGIFDecoder constructor and destructor
50 //---------------------------------------------------------------------------
52 wxGIFDecoder::wxGIFDecoder(wxInputStream
*s
, bool anim
)
68 wxGIFDecoder::~wxGIFDecoder()
73 void wxGIFDecoder::Destroy()
75 GIFImage
*pimg
, *paux
;
96 //---------------------------------------------------------------------------
97 // Convert this image to a wxImage object
98 //---------------------------------------------------------------------------
100 // This function was designed by Vaclav Slavik
102 bool wxGIFDecoder::ConvertToImage(wxImage
*image
) const
104 unsigned char *src
, *dst
, *pal
;
108 /* just in case... */
111 /* create the image */
112 image
->Create(GetWidth(), GetHeight());
119 dst
= image
->GetData();
120 transparent
= GetTransparentColour();
122 /* set transparent colour mask */
123 if (transparent
!= -1)
125 for (i
= 0; i
< 256; i
++)
127 if ((pal
[3 * i
+ 0] == 255) &&
128 (pal
[3 * i
+ 1] == 0) &&
129 (pal
[3 * i
+ 2] == 255))
131 pal
[3 * i
+ 2] = 254;
135 pal
[3 * transparent
+ 0] = 255,
136 pal
[3 * transparent
+ 1] = 0,
137 pal
[3 * transparent
+ 2] = 255;
139 image
->SetMaskColour(255, 0, 255);
142 image
->SetMask(false);
145 unsigned char r
[256];
146 unsigned char g
[256];
147 unsigned char b
[256];
149 for (i
= 0; i
< 256; i
++)
156 image
->SetPalette(wxPalette(256, r
, g
, b
));
157 #endif // wxUSE_PALETTE
159 /* copy image data */
160 for (i
= 0; i
< (GetWidth() * GetHeight()); i
++, src
++)
162 *(dst
++) = pal
[3 * (*src
) + 0];
163 *(dst
++) = pal
[3 * (*src
) + 1];
164 *(dst
++) = pal
[3 * (*src
) + 2];
171 //---------------------------------------------------------------------------
173 //---------------------------------------------------------------------------
175 // Get data for current frame
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::GetWidth() const { return (m_pimage
->w
); }
181 unsigned int wxGIFDecoder::GetHeight() const { return (m_pimage
->h
); }
182 unsigned int wxGIFDecoder::GetTop() const { return (m_pimage
->top
); }
183 unsigned int wxGIFDecoder::GetLeft() const { return (m_pimage
->left
); }
184 int wxGIFDecoder::GetTransparentColour() const { return (m_pimage
->transparent
); }
185 int wxGIFDecoder::GetDisposalMethod() const { return (m_pimage
->disposal
); }
186 long wxGIFDecoder::GetDelay() const { return (m_pimage
->delay
); }
190 unsigned int wxGIFDecoder::GetLogicalScreenWidth() const { return m_screenw
; }
191 unsigned int wxGIFDecoder::GetLogicalScreenHeight() const { return m_screenh
; }
192 int wxGIFDecoder::GetBackgroundColour() const { return m_background
; }
193 int wxGIFDecoder::GetNumberOfFrames() const { return m_nimages
; }
194 bool wxGIFDecoder::IsAnimation() const { return (m_nimages
> 1); }
197 //---------------------------------------------------------------------------
198 // Functions to move through the animation
199 //---------------------------------------------------------------------------
201 bool wxGIFDecoder::GoFirstFrame()
211 bool wxGIFDecoder::GoLastFrame()
221 bool wxGIFDecoder::GoNextFrame(bool cyclic
)
226 if ((m_image
< m_nimages
) || (cyclic
))
228 m_pimage
= m_pimage
->next
;
243 bool wxGIFDecoder::GoPrevFrame(bool cyclic
)
248 if ((m_image
> 1) || (cyclic
))
250 m_pimage
= m_pimage
->prev
;
265 bool wxGIFDecoder::GoFrame(int which
)
270 if ((which
>= 1) && (which
<= m_nimages
))
275 while (m_image
< which
)
278 m_pimage
= m_pimage
->next
;
288 //---------------------------------------------------------------------------
289 // GIF reading and decoding
290 //---------------------------------------------------------------------------
293 // Reads the next code from the file stream, with size 'bits'
295 int wxGIFDecoder::getcode(int bits
, int ab_fin
)
297 unsigned int mask
; /* bit mask */
298 unsigned int code
; /* code (result) */
301 /* get remaining bits from last byte read */
302 mask
= (1 << bits
) - 1;
303 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
305 /* keep reading new bytes while needed */
306 while (bits
> m_restbits
)
308 /* if no bytes left in this block, read the next block */
311 m_restbyte
= (unsigned char)m_f
->GetC();
313 /* Some encoders are a bit broken: instead of issuing
314 * an end-of-image symbol (ab_fin) they come up with
315 * a zero-length subblock!! We catch this here so
316 * that the decoder sees an ab_fin code.
325 m_f
->Read((void *) m_buffer
, m_restbyte
);
326 if (m_f
->LastRead() != m_restbyte
)
334 /* read next byte and isolate the bits we need */
335 m_lastbyte
= (unsigned char) (*m_bufp
++);
336 mask
= (1 << (bits
- m_restbits
)) - 1;
337 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
340 /* adjust total number of bits extracted from the buffer */
341 m_restbits
= m_restbits
+ 8;
344 /* find number of bits remaining for next code */
345 m_restbits
= (m_restbits
- bits
);
352 // GIF decoding function. The initial code size (aka root size)
353 // is 'bits'. Supports interlaced images (interl == 1).
354 // Returns wxGIF_OK (== 0) on success, or an error code if something
355 // fails (see header file for details)
356 int wxGIFDecoder::dgif(GIFImage
*img
, int interl
, int bits
)
358 static const int allocSize
= 4096 + 1;
359 int *ab_prefix
= new int[allocSize
]; /* alphabet (prefixes) */
360 if (ab_prefix
== NULL
)
365 int *ab_tail
= new int[allocSize
]; /* alphabet (tails) */
372 int *stack
= new int[allocSize
]; /* decompression stack */
380 int ab_clr
; /* clear code */
381 int ab_fin
; /* end of info code */
382 int ab_bits
; /* actual symbol width, in bits */
383 int ab_free
; /* first free position in alphabet */
384 int ab_max
; /* last possible character in alphabet */
385 int pass
; /* pass number in interlaced images */
386 int pos
; /* index into decompresion stack */
387 unsigned int x
, y
; /* position in image buffer */
389 int code
, readcode
, lastcode
, abcabca
;
391 /* these won't change */
392 ab_clr
= (1 << bits
);
393 ab_fin
= (1 << bits
) + 1;
395 /* these will change through the decompression proccess */
397 ab_free
= (1 << bits
) + 2;
398 ab_max
= (1 << ab_bits
) - 1;
404 /* reset decoder vars */
412 readcode
= code
= getcode(ab_bits
, ab_fin
);
415 if (code
== ab_fin
) break;
417 /* reset alphabet? */
420 /* reset main variables */
422 ab_free
= (1 << bits
) + 2;
423 ab_max
= (1 << ab_bits
) - 1;
427 /* skip to next code */
431 /* unknown code: special case (like in ABCABCA) */
434 code
= lastcode
; /* take last string */
435 stack
[pos
++] = abcabca
; /* add first character */
438 /* build the string for this code in the stack */
439 while (code
> ab_clr
)
441 stack
[pos
++] = ab_tail
[code
];
442 code
= ab_prefix
[code
];
444 // Don't overflow. This shouldn't happen with normal
445 // GIF files, the allocSize of 4096+1 is enough. This
446 // will only happen with badly formed GIFs.
447 if (pos
>= allocSize
)
452 return wxGIF_INVFORMAT
;
456 if (pos
>= allocSize
)
461 return wxGIF_INVFORMAT
;
464 stack
[pos
] = code
; /* push last code into the stack */
465 abcabca
= code
; /* save for special case */
467 /* make new entry in alphabet (only if NOT just cleared) */
470 // Normally, after the alphabet is full and can't grow any
471 // further (ab_free == 4096), encoder should (must?) emit CLEAR
472 // to reset it. This checks whether we really got it, otherwise
473 // the GIF is damaged.
474 if (ab_free
> ab_max
)
479 return wxGIF_INVFORMAT
;
482 // This assert seems unnecessary since the condition above
483 // eliminates the only case in which it went false. But I really
484 // don't like being forced to ask "Who in .text could have
485 // written there?!" And I wouldn't have been forced to ask if
486 // this line had already been here.
487 wxASSERT(ab_free
< allocSize
);
489 ab_prefix
[ab_free
] = lastcode
;
490 ab_tail
[ab_free
] = code
;
493 if ((ab_free
> ab_max
) && (ab_bits
< 12))
496 ab_max
= (1 << ab_bits
) - 1;
500 /* dump stack data to the image buffer */
503 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
512 /* support for interlaced images */
515 case 1: y
+= 8; break;
516 case 2: y
+= 8; break;
517 case 3: y
+= 4; break;
518 case 4: y
+= 2; break;
521 /* loop until a valid y coordinate has been
522 found, Or if the maximum number of passes has
523 been reached, exit the loop, and stop image
524 decoding (At this point the image is successfully
526 If we don't loop, but merely set y to some other
527 value, that new value might still be invalid depending
528 on the height of the image. This would cause out of
531 while (y
>= (img
->h
))
535 case 2: y
= 4; break;
536 case 3: y
= 2; break;
537 case 4: y
= 1; break;
541 It's possible we arrive here. For example this
542 happens when the image is interlaced, and the
543 height is 1. Looking at the above cases, the
544 lowest possible y is 1. While the only valid
545 one would be 0 for an image of height 1. So
546 'eventually' the loop will arrive here.
547 This case makes sure this while loop is
548 exited, as well as the 2 other ones.
551 // Set y to a valid coordinate so the local
552 // while loop will be exited. (y = 0 always
553 // is >= img->h since if img->h == 0 the
554 // image is never decoded)
557 // This will exit the other outer while loop
560 // This will halt image decoding.
572 Normally image decoding is finished when an End of Information code is
573 encountered (code == ab_fin) however some broken encoders write wrong
574 "block byte counts" (The first byte value after the "code size" byte),
575 being one value too high. It might very well be possible other variants
576 of this problem occur as well. The only sensible solution seems to
577 be to check for clipping.
578 Example of wrong encoding:
579 (1 * 1 B/W image, raster data stream follows in hex bytes)
581 02 << B/W images have a code size of 2
582 02 << Block byte count
584 00 << Zero byte count (terminates data stream)
586 Because the block byte count is 2, the zero byte count is used in the
587 decoding process, and decoding is continued after this byte. (While it
588 should signal an end of image)
594 01 << When decoded this correctly includes the End of Information code
602 (The 44 doesn't include an End of Information code, but at least the
603 decoder correctly skips to 00 now after decoding, and signals this
604 as an End of Information itself)
618 while (code
!= ab_fin
);
620 delete [] ab_prefix
;
629 // Returns true if the file looks like a valid GIF, false otherwise.
631 bool wxGIFDecoder::CanRead()
633 unsigned char buf
[3];
635 if ( !m_f
->Read(buf
, WXSIZEOF(buf
)) )
638 m_f
->SeekI(-(wxFileOffset
)WXSIZEOF(buf
), wxFromCurrent
);
640 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
645 // Reads and decodes one or more GIF images, depending on whether
646 // animated GIF support is enabled. Can read GIFs with any bit
647 // size (color depth), but the output images are always expanded
648 // to 8 bits per pixel. Also, the image palettes always contain
649 // 256 colors, although some of them may be unused. Returns wxGIF_OK
650 // (== 0) on success, or an error code if something fails (see
651 // header file for details)
653 int wxGIFDecoder::ReadGIF()
655 unsigned int ncolors
;
656 int bits
, interl
, transparent
, disposal
, i
;
659 unsigned char type
= 0;
660 unsigned char pal
[768];
661 unsigned char buf
[16];
663 GIFImage
*pimg
, *pprev
;
665 /* check GIF signature */
667 return wxGIF_INVFORMAT
;
669 /* check for animated GIF support (ver. >= 89a) */
671 static const size_t headerSize
= (3 + 3);
672 m_f
->Read(buf
, headerSize
);
673 if (m_f
->LastRead() != headerSize
)
675 return wxGIF_INVFORMAT
;
678 if (memcmp(buf
+ 3, "89a", 3) < 0)
683 /* read logical screen descriptor block (LSDB) */
684 static const size_t lsdbSize
= (2 + 2 + 1 + 1 + 1);
685 m_f
->Read(buf
, lsdbSize
);
686 if (m_f
->LastRead() != lsdbSize
)
688 return wxGIF_INVFORMAT
;
691 m_screenw
= buf
[0] + 256 * buf
[1];
692 m_screenh
= buf
[2] + 256 * buf
[3];
694 if ((m_screenw
== 0) || (m_screenh
== 0))
696 return wxGIF_INVFORMAT
;
699 /* load global color map if available */
700 if ((buf
[4] & 0x80) == 0x80)
702 m_background
= buf
[5];
704 ncolors
= 2 << (buf
[4] & 0x07);
705 size_t numBytes
= 3 * ncolors
;
706 m_f
->Read(pal
, numBytes
);
707 if (m_f
->LastRead() != numBytes
)
709 return wxGIF_INVFORMAT
;
713 /* transparent colour, disposal method and delay default to unused */
727 type
= (unsigned char)m_f
->GetC();
730 If the end of file has been reached (or an error) and a ";"
731 (0x3B) hasn't been encountered yet, exit the loop. (Without this
732 check the while loop would loop endlessly.) Later on, in the next while
733 loop, the file will be treated as being truncated (But still
734 be decoded as far as possible). returning wxGIF_TRUNCATED is not
735 possible here since some init code is done after this loop.
737 if (m_f
->Eof())// || !m_f->IsOk())
740 type is set to some bogus value, so there's no
741 need to continue evaluating it.
743 break; // Alternative : "return wxGIF_INVFORMAT;"
752 /* extension block? */
755 if (((unsigned char)m_f
->GetC()) == 0xF9)
756 /* graphics control extension, parse it */
758 static const size_t gceSize
= 6;
759 m_f
->Read(buf
, gceSize
);
760 if (m_f
->LastRead() != gceSize
)
763 return wxGIF_INVFORMAT
;
766 /* read delay and convert from 1/100 of a second to ms */
767 delay
= 10 * (buf
[2] + 256 * buf
[3]);
769 /* read transparent colour index, if used */
771 transparent
= buf
[4];
773 /* read disposal method */
774 disposal
= ((buf
[1] & 0x1C) >> 2) - 1;
777 /* other extension, skip */
779 while ((i
= (unsigned char)m_f
->GetC()) != 0)
781 m_f
->SeekI(i
, wxFromCurrent
);
791 /* image descriptor block? */
794 /* allocate memory for IMAGEN struct */
795 pimg
= (*ppimg
) = new GIFImage();
803 /* fill in the data */
804 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
805 m_f
->Read(buf
, idbSize
);
806 if (m_f
->LastRead() != idbSize
)
809 return wxGIF_INVFORMAT
;
812 pimg
->left
= buf
[0] + 256 * buf
[1];
813 pimg
->top
= buf
[2] + 256 * buf
[3];
815 pimg->left = buf[4] + 256 * buf[5];
816 pimg->top = buf[4] + 256 * buf[5];
818 pimg
->w
= buf
[4] + 256 * buf
[5];
819 pimg
->h
= buf
[6] + 256 * buf
[7];
821 if ((pimg
->w
== 0) || (pimg
->w
> m_screenw
) || (pimg
->h
== 0) || (pimg
->h
> m_screenh
))
824 return wxGIF_INVFORMAT
;
827 interl
= ((buf
[8] & 0x40)? 1 : 0);
828 size
= pimg
->w
* pimg
->h
;
830 pimg
->transparent
= transparent
;
831 pimg
->disposal
= disposal
;
838 /* allocate memory for image and palette */
839 pimg
->p
= (unsigned char *) malloc((size_t)size
);
840 pimg
->pal
= (unsigned char *) malloc(768);
842 if ((!pimg
->p
) || (!pimg
->pal
))
848 /* load local color map if available, else use global map */
849 if ((buf
[8] & 0x80) == 0x80)
851 ncolors
= 2 << (buf
[8] & 0x07);
852 size_t numBytes
= 3 * ncolors
;
853 m_f
->Read(pimg
->pal
, numBytes
);
854 if (m_f
->LastRead() != numBytes
)
857 return wxGIF_INVFORMAT
;
862 memcpy(pimg
->pal
, pal
, 768);
865 /* get initial code size from first byte in raster data */
866 bits
= (unsigned char)m_f
->GetC();
870 return wxGIF_INVFORMAT
;
874 int result
= dgif(pimg
, interl
, bits
);
875 if (result
!= wxGIF_OK
)
882 /* if this is not an animated GIF, exit after first image */
891 return wxGIF_INVFORMAT
;
894 /* setup image pointers */
899 /* try to read to the end of the stream */
903 return wxGIF_TRUNCATED
;
905 type
= (unsigned char)m_f
->GetC();
913 while ((i
= (unsigned char)m_f
->GetC()) != 0)
915 m_f
->SeekI(i
, wxFromCurrent
);
918 else if (type
== 0x2C)
920 /* image descriptor block */
921 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
922 m_f
->Read(buf
, idbSize
);
923 if (m_f
->LastRead() != idbSize
)
926 return wxGIF_INVFORMAT
;
929 /* local color map */
930 if ((buf
[8] & 0x80) == 0x80)
932 ncolors
= 2 << (buf
[8] & 0x07);
933 wxFileOffset pos
= m_f
->TellI();
934 wxFileOffset numBytes
= 3 * ncolors
;
935 m_f
->SeekI(numBytes
, wxFromCurrent
);
936 if (m_f
->TellI() != (pos
+ numBytes
))
939 return wxGIF_INVFORMAT
;
943 /* initial code size */
947 while ((i
= (unsigned char)m_f
->GetC()) != 0)
949 m_f
->SeekI(i
, wxFromCurrent
);
952 else if ((type
!= 0x3B) && (type
!= 00)) /* testing */
954 /* images are OK, but couldn't read to the end of the stream */
955 return wxGIF_TRUNCATED
;
962 #endif // wxUSE_STREAMS && wxUSE_GIF