]>
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 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "gifdecod.h"
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
26 #if wxUSE_STREAMS && wxUSE_GIF
30 #include "wx/gifdecod.h"
33 //---------------------------------------------------------------------------
34 // GIFImage constructor
35 //---------------------------------------------------------------------------
45 p
= (unsigned char *) NULL
;
46 pal
= (unsigned char *) NULL
;
47 next
= (GIFImage
*) NULL
;
48 prev
= (GIFImage
*) NULL
;
51 //---------------------------------------------------------------------------
52 // wxGIFDecoder constructor and destructor
53 //---------------------------------------------------------------------------
55 wxGIFDecoder::wxGIFDecoder(wxInputStream
*s
, bool anim
)
71 wxGIFDecoder::~wxGIFDecoder()
76 void wxGIFDecoder::Destroy()
78 GIFImage
*pimg
, *paux
;
99 //---------------------------------------------------------------------------
100 // Convert this image to a wxImage object
101 //---------------------------------------------------------------------------
103 // This function was designed by Vaclav Slavik
105 bool wxGIFDecoder::ConvertToImage(wxImage
*image
) const
107 unsigned char *src
, *dst
, *pal
;
111 /* just in case... */
114 /* create the image */
115 image
->Create(GetWidth(), GetHeight());
122 dst
= image
->GetData();
123 transparent
= GetTransparentColour();
125 /* set transparent colour mask */
126 if (transparent
!= -1)
128 for (i
= 0; i
< 256; i
++)
130 if ((pal
[3 * i
+ 0] == 255) &&
131 (pal
[3 * i
+ 1] == 0) &&
132 (pal
[3 * i
+ 2] == 255))
134 pal
[3 * i
+ 2] = 254;
138 pal
[3 * transparent
+ 0] = 255,
139 pal
[3 * transparent
+ 1] = 0,
140 pal
[3 * transparent
+ 2] = 255;
142 image
->SetMaskColour(255, 0, 255);
145 image
->SetMask(FALSE
);
150 unsigned char r
[256];
151 unsigned char g
[256];
152 unsigned char b
[256];
154 for (i
= 0; i
< 256; i
++)
161 image
->SetPalette(wxPalette(256, r
, g
, b
));
163 #endif // wxUSE_PALETTE
165 /* copy image data */
166 for (i
= 0; i
< (GetWidth() * GetHeight()); i
++, src
++)
168 *(dst
++) = pal
[3 * (*src
) + 0];
169 *(dst
++) = pal
[3 * (*src
) + 1];
170 *(dst
++) = pal
[3 * (*src
) + 2];
177 //---------------------------------------------------------------------------
179 //---------------------------------------------------------------------------
181 // Get data for current frame
183 int wxGIFDecoder::GetFrameIndex() const { return m_image
; }
184 unsigned char* wxGIFDecoder::GetData() const { return (m_pimage
->p
); }
185 unsigned char* wxGIFDecoder::GetPalette() const { return (m_pimage
->pal
); }
186 unsigned int wxGIFDecoder::GetWidth() const { return (m_pimage
->w
); }
187 unsigned int wxGIFDecoder::GetHeight() const { return (m_pimage
->h
); }
188 unsigned int wxGIFDecoder::GetTop() const { return (m_pimage
->top
); }
189 unsigned int wxGIFDecoder::GetLeft() const { return (m_pimage
->left
); }
190 int wxGIFDecoder::GetTransparentColour() const { return (m_pimage
->transparent
); }
191 int wxGIFDecoder::GetDisposalMethod() const { return (m_pimage
->disposal
); }
192 long wxGIFDecoder::GetDelay() const { return (m_pimage
->delay
); }
196 unsigned int wxGIFDecoder::GetLogicalScreenWidth() const { return m_screenw
; }
197 unsigned int wxGIFDecoder::GetLogicalScreenHeight() const { return m_screenh
; }
198 int wxGIFDecoder::GetBackgroundColour() const { return m_background
; }
199 int wxGIFDecoder::GetNumberOfFrames() const { return m_nimages
; }
200 bool wxGIFDecoder::IsAnimation() const { return (m_nimages
> 1); }
203 //---------------------------------------------------------------------------
204 // Functions to move through the animation
205 //---------------------------------------------------------------------------
207 bool wxGIFDecoder::GoFirstFrame()
217 bool wxGIFDecoder::GoLastFrame()
227 bool wxGIFDecoder::GoNextFrame(bool cyclic
)
232 if ((m_image
< m_nimages
) || (cyclic
))
234 m_pimage
= m_pimage
->next
;
249 bool wxGIFDecoder::GoPrevFrame(bool cyclic
)
254 if ((m_image
> 1) || (cyclic
))
256 m_pimage
= m_pimage
->prev
;
271 bool wxGIFDecoder::GoFrame(int which
)
278 if ((which
>= 1) && (which
<= m_nimages
))
282 for (i
= 1; i
< which
; i
++)
283 m_pimage
= m_pimage
->next
;
292 //---------------------------------------------------------------------------
293 // GIF reading and decoding
294 //---------------------------------------------------------------------------
297 // Reads the next code from the file stream, with size 'bits'
299 int wxGIFDecoder::getcode(int bits
, int ab_fin
)
301 unsigned int mask
; /* bit mask */
302 unsigned int code
; /* code (result) */
305 /* get remaining bits from last byte read */
306 mask
= (1 << bits
) - 1;
307 code
= (m_lastbyte
>> (8 - m_restbits
)) & mask
;
309 /* keep reading new bytes while needed */
310 while (bits
> m_restbits
)
312 /* if no bytes left in this block, read the next block */
315 m_restbyte
= (unsigned char)m_f
->GetC();
317 /* Some encoders are a bit broken: instead of issuing
318 * an end-of-image symbol (ab_fin) they come up with
319 * a zero-length subblock!! We catch this here so
320 * that the decoder sees an ab_fin code.
329 m_f
->Read((void *) m_buffer
, m_restbyte
);
330 if (m_f
->LastRead() != m_restbyte
)
338 /* read next byte and isolate the bits we need */
339 m_lastbyte
= (unsigned char) (*m_bufp
++);
340 mask
= (1 << (bits
- m_restbits
)) - 1;
341 code
= code
+ ((m_lastbyte
& mask
) << m_restbits
);
344 /* adjust total number of bits extracted from the buffer */
345 m_restbits
= m_restbits
+ 8;
348 /* find number of bits remaining for next code */
349 m_restbits
= (m_restbits
- bits
);
356 // GIF decoding function. The initial code size (aka root size)
357 // is 'bits'. Supports interlaced images (interl == 1).
358 // Returns wxGIF_OK (== 0) on success, or an error code if something
359 // fails (see header file for details)
360 int wxGIFDecoder::dgif(GIFImage
*img
, int interl
, int bits
)
362 static const int allocSize
= 4096 + 1;
363 int *ab_prefix
= new int[allocSize
]; /* alphabet (prefixes) */
364 if (ab_prefix
== NULL
)
369 int *ab_tail
= new int[allocSize
]; /* alphabet (tails) */
376 int *stack
= new int[allocSize
]; /* decompression stack */
384 int ab_clr
; /* clear code */
385 int ab_fin
; /* end of info code */
386 int ab_bits
; /* actual symbol width, in bits */
387 int ab_free
; /* first free position in alphabet */
388 int ab_max
; /* last possible character in alphabet */
389 int pass
; /* pass number in interlaced images */
390 int pos
; /* index into decompresion stack */
391 unsigned int x
, y
; /* position in image buffer */
393 int code
, readcode
, lastcode
, abcabca
;
395 /* these won't change */
396 ab_clr
= (1 << bits
);
397 ab_fin
= (1 << bits
) + 1;
399 /* these will change through the decompression proccess */
401 ab_free
= (1 << bits
) + 2;
402 ab_max
= (1 << ab_bits
) - 1;
408 /* reset decoder vars */
416 readcode
= code
= getcode(ab_bits
, ab_fin
);
419 if (code
== ab_fin
) break;
421 /* reset alphabet? */
424 /* reset main variables */
426 ab_free
= (1 << bits
) + 2;
427 ab_max
= (1 << ab_bits
) - 1;
431 /* skip to next code */
435 /* unknown code: special case (like in ABCABCA) */
438 code
= lastcode
; /* take last string */
439 stack
[pos
++] = abcabca
; /* add first character */
442 /* build the string for this code in the stack */
443 while (code
> ab_clr
)
445 stack
[pos
++] = ab_tail
[code
];
446 code
= ab_prefix
[code
];
448 // Don't overflow. This shouldn't happen with normal
449 // GIF files, the allocSize of 4096+1 is enough. This
450 // will only happen with badly formed GIFs.
451 if (pos
>= allocSize
)
456 return wxGIF_INVFORMAT
;
460 if (pos
>= allocSize
)
465 return wxGIF_INVFORMAT
;
468 stack
[pos
] = code
; /* push last code into the stack */
469 abcabca
= code
; /* save for special case */
471 /* make new entry in alphabet (only if NOT just cleared) */
474 ab_prefix
[ab_free
] = lastcode
;
475 ab_tail
[ab_free
] = code
;
478 if ((ab_free
> ab_max
) && (ab_bits
< 12))
481 ab_max
= (1 << ab_bits
) - 1;
485 /* dump stack data to the image buffer */
488 (img
->p
)[x
+ (y
* (img
->w
))] = (char) stack
[pos
];
497 /* support for interlaced images */
500 case 1: y
+= 8; break;
501 case 2: y
+= 8; break;
502 case 3: y
+= 4; break;
503 case 4: y
+= 2; break;
506 /* loop until a valid y coordinate has been
507 found, Or if the maximum number of passes has
508 been reached, exit the loop, and stop image
509 decoding (At this point the image is succesfully
511 If we don't loop, but merely set y to some other
512 value, that new value might still be invalid depending
513 on the height of the image. This would cause out of
516 while (y
>= (img
->h
))
520 case 2: y
= 4; break;
521 case 3: y
= 2; break;
522 case 4: y
= 1; break;
526 It's possible we arrive here. For example this
527 happens when the image is interlaced, and the
528 height is 1. Looking at the above cases, the
529 lowest possible y is 1. While the only valid
530 one would be 0 for an image of height 1. So
531 'eventually' the loop will arrive here.
532 This case makes sure this while loop is
533 exited, as well as the 2 other ones.
536 // Set y to a valid coordinate so the local
537 // while loop will be exited. (y = 0 always
538 // is >= img->h since if img->h == 0 the
539 // image is never decoded)
542 // This will exit the other outer while loop
545 // This will halt image decoding.
557 Normally image decoding is finished when an End of Information code is
558 encountered (code == ab_fin) however some broken encoders write wrong
559 "block byte counts" (The first byte value after the "code size" byte),
560 being one value too high. It might very well be possible other variants
561 of this problem occur as well. The only sensible solution seems to
562 be to check for clipping.
563 Example of wrong encoding:
564 (1 * 1 B/W image, raster data stream follows in hex bytes)
566 02 << B/W images have a code size of 2
567 02 << Block byte count
569 00 << Zero byte count (terminates data stream)
571 Because the block byte count is 2, the zero byte count is used in the
572 decoding process, and decoding is continued after this byte. (While it
573 should signal an end of image)
579 01 << When decoded this correctly includes the End of Information code
587 (The 44 doesn't include an End of Information code, but at least the
588 decoder correctly skips to 00 now after decoding, and signals this
589 as an End of Information itself)
603 while (code
!= ab_fin
);
605 delete [] ab_prefix
;
614 // Returns TRUE if the file looks like a valid GIF, FALSE otherwise.
616 bool wxGIFDecoder::CanRead()
618 unsigned char buf
[3];
620 if ( !m_f
->Read(buf
, WXSIZEOF(buf
)) )
623 m_f
->SeekI(-(off_t
)WXSIZEOF(buf
), wxFromCurrent
);
625 return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0;
630 // Reads and decodes one or more GIF images, depending on whether
631 // animated GIF support is enabled. Can read GIFs with any bit
632 // size (color depth), but the output images are always expanded
633 // to 8 bits per pixel. Also, the image palettes always contain
634 // 256 colors, although some of them may be unused. Returns wxGIF_OK
635 // (== 0) on success, or an error code if something fails (see
636 // header file for details)
638 int wxGIFDecoder::ReadGIF()
640 unsigned int ncolors
;
641 int bits
, interl
, transparent
, disposal
, i
;
644 unsigned char type
= 0;
645 unsigned char pal
[768];
646 unsigned char buf
[16];
648 GIFImage
*pimg
, *pprev
;
650 /* check GIF signature */
652 return wxGIF_INVFORMAT
;
654 /* check for animated GIF support (ver. >= 89a) */
656 static const size_t headerSize
= (3 + 3);
657 m_f
->Read(buf
, headerSize
);
658 if (m_f
->LastRead() != headerSize
)
660 return wxGIF_INVFORMAT
;
663 if (memcmp(buf
+ 3, "89a", 3) < 0)
668 /* read logical screen descriptor block (LSDB) */
669 static const size_t lsdbSize
= (2 + 2 + 1 + 1 + 1);
670 m_f
->Read(buf
, lsdbSize
);
671 if (m_f
->LastRead() != lsdbSize
)
673 return wxGIF_INVFORMAT
;
676 m_screenw
= buf
[0] + 256 * buf
[1];
677 m_screenh
= buf
[2] + 256 * buf
[3];
679 /* load global color map if available */
680 if ((buf
[4] & 0x80) == 0x80)
682 m_background
= buf
[5];
684 ncolors
= 2 << (buf
[4] & 0x07);
685 size_t numBytes
= 3 * ncolors
;
686 m_f
->Read(pal
, numBytes
);
687 if (m_f
->LastRead() != numBytes
)
689 return wxGIF_INVFORMAT
;
693 /* transparent colour, disposal method and delay default to unused */
707 type
= (unsigned char)m_f
->GetC();
710 If the end of file has been reached (or an error) and a ";"
711 (0x3B) hasn't been encountered yet, exit the loop. (Without this
712 check the while loop would loop endlessly.) Later on, in the next while
713 loop, the file will be treated as being truncated (But still
714 be decoded as far as possible). returning wxGIF_TRUNCATED is not
715 possible here since some init code is done after this loop.
717 if (m_f
->Eof())// || !m_f->IsOk())
720 type is set to some bogus value, so there's no
721 need to continue evaluating it.
723 break; // Alternative : "return wxGIF_INVFORMAT;"
732 /* extension block? */
735 if (((unsigned char)m_f
->GetC()) == 0xF9)
736 /* graphics control extension, parse it */
738 static const size_t gceSize
= 6;
739 m_f
->Read(buf
, gceSize
);
740 if (m_f
->LastRead() != gceSize
)
743 return wxGIF_INVFORMAT
;
746 /* read delay and convert from 1/100 of a second to ms */
747 delay
= 10 * (buf
[2] + 256 * buf
[3]);
749 /* read transparent colour index, if used */
751 transparent
= buf
[4];
753 /* read disposal method */
754 disposal
= (buf
[1] & 0x1C) - 1;
757 /* other extension, skip */
759 while ((i
= (unsigned char)m_f
->GetC()) != 0)
761 m_f
->SeekI(i
, wxFromCurrent
);
771 /* image descriptor block? */
774 /* allocate memory for IMAGEN struct */
775 pimg
= (*ppimg
) = new GIFImage();
783 /* fill in the data */
784 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
785 m_f
->Read(buf
, idbSize
);
786 if (m_f
->LastRead() != idbSize
)
789 return wxGIF_INVFORMAT
;
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];
801 if (pimg
->w
== 0 || pimg
->h
== 0)
804 return wxGIF_INVFORMAT
;
807 interl
= ((buf
[8] & 0x40)? 1 : 0);
808 size
= pimg
->w
* pimg
->h
;
810 pimg
->transparent
= transparent
;
811 pimg
->disposal
= disposal
;
818 /* allocate memory for image and palette */
819 pimg
->p
= (unsigned char *) malloc((size_t)size
);
820 pimg
->pal
= (unsigned char *) malloc(768);
822 if ((!pimg
->p
) || (!pimg
->pal
))
828 /* load local color map if available, else use global map */
829 if ((buf
[8] & 0x80) == 0x80)
831 ncolors
= 2 << (buf
[8] & 0x07);
832 size_t numBytes
= 3 * ncolors
;
833 m_f
->Read(pimg
->pal
, numBytes
);
834 if (m_f
->LastRead() != numBytes
)
837 return wxGIF_INVFORMAT
;
842 memcpy(pimg
->pal
, pal
, 768);
845 /* get initial code size from first byte in raster data */
846 bits
= (unsigned char)m_f
->GetC();
849 int result
= dgif(pimg
, interl
, bits
);
850 if (result
!= wxGIF_OK
)
857 /* if this is not an animated GIF, exit after first image */
866 return wxGIF_INVFORMAT
;
869 /* setup image pointers */
874 /* try to read to the end of the stream */
878 return wxGIF_TRUNCATED
;
880 type
= (unsigned char)m_f
->GetC();
888 while ((i
= (unsigned char)m_f
->GetC()) != 0)
890 m_f
->SeekI(i
, wxFromCurrent
);
893 else if (type
== 0x2C)
895 /* image descriptor block */
896 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
897 m_f
->Read(buf
, idbSize
);
898 if (m_f
->LastRead() != idbSize
)
901 return wxGIF_INVFORMAT
;
904 /* local color map */
905 if ((buf
[8] & 0x80) == 0x80)
907 ncolors
= 2 << (buf
[8] & 0x07);
908 off_t pos
= m_f
->TellI();
909 off_t numBytes
= 3 * ncolors
;
910 m_f
->SeekI(numBytes
, wxFromCurrent
);
911 if (m_f
->TellI() != (pos
+ numBytes
))
914 return wxGIF_INVFORMAT
;
918 /* initial code size */
922 while ((i
= (unsigned char)m_f
->GetC()) != 0)
924 m_f
->SeekI(i
, wxFromCurrent
);
927 else if ((type
!= 0x3B) && (type
!= 00)) /* testing */
929 /* images are OK, but couldn't read to the end of the stream */
930 return wxGIF_TRUNCATED
;
937 #endif // wxUSE_STREAMS && wxUSE_GIF