]>
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
;
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
< GetNcolours(); 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(GetNcolours(), 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::GetNcolours() const { return (m_pimage
->ncolours
); }
181 unsigned int wxGIFDecoder::GetWidth() const { return (m_pimage
->w
); }
182 unsigned int wxGIFDecoder::GetHeight() const { return (m_pimage
->h
); }
183 unsigned int wxGIFDecoder::GetTop() const { return (m_pimage
->top
); }
184 unsigned int wxGIFDecoder::GetLeft() const { return (m_pimage
->left
); }
185 int wxGIFDecoder::GetTransparentColour() const { return (m_pimage
->transparent
); }
186 int wxGIFDecoder::GetDisposalMethod() const { return (m_pimage
->disposal
); }
187 long wxGIFDecoder::GetDelay() const { return (m_pimage
->delay
); }
191 unsigned int wxGIFDecoder::GetLogicalScreenWidth() const { return m_screenw
; }
192 unsigned int wxGIFDecoder::GetLogicalScreenHeight() const { return m_screenh
; }
193 int wxGIFDecoder::GetBackgroundColour() const { return m_background
; }
194 int wxGIFDecoder::GetNumberOfFrames() const { return m_nimages
; }
195 bool wxGIFDecoder::IsAnimation() const { return (m_nimages
> 1); }
198 //---------------------------------------------------------------------------
199 // Functions to move through the animation
200 //---------------------------------------------------------------------------
202 bool wxGIFDecoder::GoFirstFrame()
212 bool wxGIFDecoder::GoLastFrame()
222 bool wxGIFDecoder::GoNextFrame(bool cyclic
)
227 if ((m_image
< m_nimages
) || (cyclic
))
229 m_pimage
= m_pimage
->next
;
244 bool wxGIFDecoder::GoPrevFrame(bool cyclic
)
249 if ((m_image
> 1) || (cyclic
))
251 m_pimage
= m_pimage
->prev
;
266 bool wxGIFDecoder::GoFrame(int which
)
271 if ((which
>= 1) && (which
<= m_nimages
))
276 while (m_image
< which
)
279 m_pimage
= m_pimage
->next
;
289 //---------------------------------------------------------------------------
290 // GIF reading and decoding
291 //---------------------------------------------------------------------------
294 // Reads the next code from the file stream, with size 'bits'
296 int wxGIFDecoder::getcode(int bits
, int ab_fin
)
298 unsigned int mask
; /* bit mask */
299 unsigned int code
; /* code (result) */
302 /* get remaining bits from last byte read */
303 mask
= (1 << bits
) - 1;
304 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
306 /* keep reading new bytes while needed */
307 while (bits
> m_restbits
)
309 /* if no bytes left in this block, read the next block */
312 m_restbyte
= (unsigned char)m_f
->GetC();
314 /* Some encoders are a bit broken: instead of issuing
315 * an end-of-image symbol (ab_fin) they come up with
316 * a zero-length subblock!! We catch this here so
317 * that the decoder sees an ab_fin code.
326 m_f
->Read((void *) m_buffer
, m_restbyte
);
327 if (m_f
->LastRead() != m_restbyte
)
335 /* read next byte and isolate the bits we need */
336 m_lastbyte
= (unsigned char) (*m_bufp
++);
337 mask
= (1 << (bits
- m_restbits
)) - 1;
338 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
341 /* adjust total number of bits extracted from the buffer */
342 m_restbits
= m_restbits
+ 8;
345 /* find number of bits remaining for next code */
346 m_restbits
= (m_restbits
- bits
);
353 // GIF decoding function. The initial code size (aka root size)
354 // is 'bits'. Supports interlaced images (interl == 1).
355 // Returns wxGIF_OK (== 0) on success, or an error code if something
356 // fails (see header file for details)
357 int wxGIFDecoder::dgif(GIFImage
*img
, int interl
, int bits
)
359 static const int allocSize
= 4096 + 1;
360 int *ab_prefix
= new int[allocSize
]; /* alphabet (prefixes) */
361 if (ab_prefix
== NULL
)
366 int *ab_tail
= new int[allocSize
]; /* alphabet (tails) */
373 int *stack
= new int[allocSize
]; /* decompression stack */
381 int ab_clr
; /* clear code */
382 int ab_fin
; /* end of info code */
383 int ab_bits
; /* actual symbol width, in bits */
384 int ab_free
; /* first free position in alphabet */
385 int ab_max
; /* last possible character in alphabet */
386 int pass
; /* pass number in interlaced images */
387 int pos
; /* index into decompresion stack */
388 unsigned int x
, y
; /* position in image buffer */
390 int code
, readcode
, lastcode
, abcabca
;
392 /* these won't change */
393 ab_clr
= (1 << bits
);
394 ab_fin
= (1 << bits
) + 1;
396 /* these will change through the decompression proccess */
398 ab_free
= (1 << bits
) + 2;
399 ab_max
= (1 << ab_bits
) - 1;
405 /* reset decoder vars */
413 readcode
= code
= getcode(ab_bits
, ab_fin
);
416 if (code
== ab_fin
) break;
418 /* reset alphabet? */
421 /* reset main variables */
423 ab_free
= (1 << bits
) + 2;
424 ab_max
= (1 << ab_bits
) - 1;
428 /* skip to next code */
432 /* unknown code: special case (like in ABCABCA) */
435 code
= lastcode
; /* take last string */
436 stack
[pos
++] = abcabca
; /* add first character */
439 /* build the string for this code in the stack */
440 while (code
> ab_clr
)
442 stack
[pos
++] = ab_tail
[code
];
443 code
= ab_prefix
[code
];
445 // Don't overflow. This shouldn't happen with normal
446 // GIF files, the allocSize of 4096+1 is enough. This
447 // will only happen with badly formed GIFs.
448 if (pos
>= allocSize
)
453 return wxGIF_INVFORMAT
;
457 if (pos
>= allocSize
)
462 return wxGIF_INVFORMAT
;
465 stack
[pos
] = code
; /* push last code into the stack */
466 abcabca
= code
; /* save for special case */
468 /* make new entry in alphabet (only if NOT just cleared) */
471 // Normally, after the alphabet is full and can't grow any
472 // further (ab_free == 4096), encoder should (must?) emit CLEAR
473 // to reset it. This checks whether we really got it, otherwise
474 // the GIF is damaged.
475 if (ab_free
> ab_max
)
480 return wxGIF_INVFORMAT
;
483 // This assert seems unnecessary since the condition above
484 // eliminates the only case in which it went false. But I really
485 // don't like being forced to ask "Who in .text could have
486 // written there?!" And I wouldn't have been forced to ask if
487 // this line had already been here.
488 wxASSERT(ab_free
< allocSize
);
490 ab_prefix
[ab_free
] = lastcode
;
491 ab_tail
[ab_free
] = code
;
494 if ((ab_free
> ab_max
) && (ab_bits
< 12))
497 ab_max
= (1 << ab_bits
) - 1;
501 /* dump stack data to the image buffer */
504 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
513 /* support for interlaced images */
516 case 1: y
+= 8; break;
517 case 2: y
+= 8; break;
518 case 3: y
+= 4; break;
519 case 4: y
+= 2; break;
522 /* loop until a valid y coordinate has been
523 found, Or if the maximum number of passes has
524 been reached, exit the loop, and stop image
525 decoding (At this point the image is successfully
527 If we don't loop, but merely set y to some other
528 value, that new value might still be invalid depending
529 on the height of the image. This would cause out of
532 while (y
>= (img
->h
))
536 case 2: y
= 4; break;
537 case 3: y
= 2; break;
538 case 4: y
= 1; break;
542 It's possible we arrive here. For example this
543 happens when the image is interlaced, and the
544 height is 1. Looking at the above cases, the
545 lowest possible y is 1. While the only valid
546 one would be 0 for an image of height 1. So
547 'eventually' the loop will arrive here.
548 This case makes sure this while loop is
549 exited, as well as the 2 other ones.
552 // Set y to a valid coordinate so the local
553 // while loop will be exited. (y = 0 always
554 // is >= img->h since if img->h == 0 the
555 // image is never decoded)
558 // This will exit the other outer while loop
561 // This will halt image decoding.
573 Normally image decoding is finished when an End of Information code is
574 encountered (code == ab_fin) however some broken encoders write wrong
575 "block byte counts" (The first byte value after the "code size" byte),
576 being one value too high. It might very well be possible other variants
577 of this problem occur as well. The only sensible solution seems to
578 be to check for clipping.
579 Example of wrong encoding:
580 (1 * 1 B/W image, raster data stream follows in hex bytes)
582 02 << B/W images have a code size of 2
583 02 << Block byte count
585 00 << Zero byte count (terminates data stream)
587 Because the block byte count is 2, the zero byte count is used in the
588 decoding process, and decoding is continued after this byte. (While it
589 should signal an end of image)
595 01 << When decoded this correctly includes the End of Information code
603 (The 44 doesn't include an End of Information code, but at least the
604 decoder correctly skips to 00 now after decoding, and signals this
605 as an End of Information itself)
619 while (code
!= ab_fin
);
621 delete [] ab_prefix
;
630 // Returns true if the file looks like a valid GIF, false otherwise.
632 bool wxGIFDecoder::CanRead()
634 unsigned char buf
[3];
636 if ( !m_f
->Read(buf
, WXSIZEOF(buf
)) )
639 m_f
->SeekI(-(wxFileOffset
)WXSIZEOF(buf
), wxFromCurrent
);
641 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
646 // Reads and decodes one or more GIF images, depending on whether
647 // animated GIF support is enabled. Can read GIFs with any bit
648 // size (color depth), but the output images are always expanded
649 // to 8 bits per pixel. Also, the image palettes always contain
650 // 256 colors, although some of them may be unused. Returns wxGIF_OK
651 // (== 0) on success, or an error code if something fails (see
652 // header file for details)
654 int wxGIFDecoder::ReadGIF()
656 unsigned int global_ncolors
= 0;
657 int bits
, interl
, transparent
, disposal
, i
;
660 unsigned char type
= 0;
661 unsigned char pal
[768];
662 unsigned char buf
[16];
664 GIFImage
*pimg
, *pprev
;
666 /* check GIF signature */
668 return wxGIF_INVFORMAT
;
670 /* check for animated GIF support (ver. >= 89a) */
672 static const size_t headerSize
= (3 + 3);
673 m_f
->Read(buf
, headerSize
);
674 if (m_f
->LastRead() != headerSize
)
676 return wxGIF_INVFORMAT
;
679 if (memcmp(buf
+ 3, "89a", 3) < 0)
684 /* read logical screen descriptor block (LSDB) */
685 static const size_t lsdbSize
= (2 + 2 + 1 + 1 + 1);
686 m_f
->Read(buf
, lsdbSize
);
687 if (m_f
->LastRead() != lsdbSize
)
689 return wxGIF_INVFORMAT
;
692 m_screenw
= buf
[0] + 256 * buf
[1];
693 m_screenh
= buf
[2] + 256 * buf
[3];
695 if ((m_screenw
== 0) || (m_screenh
== 0))
697 return wxGIF_INVFORMAT
;
700 /* load global color map if available */
701 if ((buf
[4] & 0x80) == 0x80)
703 m_background
= buf
[5];
705 global_ncolors
= 2 << (buf
[4] & 0x07);
706 size_t numBytes
= 3 * global_ncolors
;
707 m_f
->Read(pal
, numBytes
);
708 if (m_f
->LastRead() != numBytes
)
710 return wxGIF_INVFORMAT
;
714 /* transparent colour, disposal method and delay default to unused */
728 type
= (unsigned char)m_f
->GetC();
731 If the end of file has been reached (or an error) and a ";"
732 (0x3B) hasn't been encountered yet, exit the loop. (Without this
733 check the while loop would loop endlessly.) Later on, in the next while
734 loop, the file will be treated as being truncated (But still
735 be decoded as far as possible). returning wxGIF_TRUNCATED is not
736 possible here since some init code is done after this loop.
738 if (m_f
->Eof())// || !m_f->IsOk())
741 type is set to some bogus value, so there's no
742 need to continue evaluating it.
744 break; // Alternative : "return wxGIF_INVFORMAT;"
753 /* extension block? */
756 if (((unsigned char)m_f
->GetC()) == 0xF9)
757 /* graphics control extension, parse it */
759 static const size_t gceSize
= 6;
760 m_f
->Read(buf
, gceSize
);
761 if (m_f
->LastRead() != gceSize
)
764 return wxGIF_INVFORMAT
;
767 /* read delay and convert from 1/100 of a second to ms */
768 delay
= 10 * (buf
[2] + 256 * buf
[3]);
770 /* read transparent colour index, if used */
772 transparent
= buf
[4];
774 /* read disposal method */
775 disposal
= ((buf
[1] & 0x1C) >> 2) - 1;
778 /* other extension, skip */
780 while ((i
= (unsigned char)m_f
->GetC()) != 0)
782 m_f
->SeekI(i
, wxFromCurrent
);
792 /* image descriptor block? */
795 /* allocate memory for IMAGEN struct */
796 pimg
= (*ppimg
) = new GIFImage();
804 /* fill in the data */
805 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
806 m_f
->Read(buf
, idbSize
);
807 if (m_f
->LastRead() != idbSize
)
810 return wxGIF_INVFORMAT
;
813 pimg
->left
= buf
[0] + 256 * buf
[1];
814 pimg
->top
= buf
[2] + 256 * buf
[3];
816 pimg->left = buf[4] + 256 * buf[5];
817 pimg->top = buf[4] + 256 * buf[5];
819 pimg
->w
= buf
[4] + 256 * buf
[5];
820 pimg
->h
= buf
[6] + 256 * buf
[7];
822 if ((pimg
->w
== 0) || (pimg
->w
> m_screenw
) || (pimg
->h
== 0) || (pimg
->h
> m_screenh
))
825 return wxGIF_INVFORMAT
;
828 interl
= ((buf
[8] & 0x40)? 1 : 0);
829 size
= pimg
->w
* pimg
->h
;
831 pimg
->transparent
= transparent
;
832 pimg
->disposal
= disposal
;
839 /* allocate memory for image and palette */
840 pimg
->p
= (unsigned char *) malloc((size_t)size
);
841 pimg
->pal
= (unsigned char *) malloc(768);
843 if ((!pimg
->p
) || (!pimg
->pal
))
849 /* load local color map if available, else use global map */
850 if ((buf
[8] & 0x80) == 0x80)
852 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
853 size_t numBytes
= 3 * local_ncolors
;
854 m_f
->Read(pimg
->pal
, numBytes
);
855 pimg
->ncolours
= local_ncolors
;
856 if (m_f
->LastRead() != numBytes
)
859 return wxGIF_INVFORMAT
;
864 memcpy(pimg
->pal
, pal
, 768);
865 pimg
->ncolours
= global_ncolors
;
868 /* get initial code size from first byte in raster data */
869 bits
= (unsigned char)m_f
->GetC();
873 return wxGIF_INVFORMAT
;
877 int result
= dgif(pimg
, interl
, bits
);
878 if (result
!= wxGIF_OK
)
885 /* if this is not an animated GIF, exit after first image */
894 return wxGIF_INVFORMAT
;
897 /* setup image pointers */
902 /* try to read to the end of the stream */
906 return wxGIF_TRUNCATED
;
908 type
= (unsigned char)m_f
->GetC();
916 while ((i
= (unsigned char)m_f
->GetC()) != 0)
918 m_f
->SeekI(i
, wxFromCurrent
);
921 else if (type
== 0x2C)
923 /* image descriptor block */
924 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
925 m_f
->Read(buf
, idbSize
);
926 if (m_f
->LastRead() != idbSize
)
929 return wxGIF_INVFORMAT
;
932 /* local color map */
933 if ((buf
[8] & 0x80) == 0x80)
935 unsigned int local_ncolors
= 2 << (buf
[8] & 0x07);
936 wxFileOffset pos
= m_f
->TellI();
937 wxFileOffset numBytes
= 3 * local_ncolors
;
938 m_f
->SeekI(numBytes
, wxFromCurrent
);
939 if (m_f
->TellI() != (pos
+ numBytes
))
942 return wxGIF_INVFORMAT
;
946 /* initial code size */
950 while ((i
= (unsigned char)m_f
->GetC()) != 0)
952 m_f
->SeekI(i
, wxFromCurrent
);
955 else if ((type
!= 0x3B) && (type
!= 00)) /* testing */
957 /* images are OK, but couldn't read to the end of the stream */
958 return wxGIF_TRUNCATED
;
965 #endif // wxUSE_STREAMS && wxUSE_GIF