]>
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
;
459 stack
[pos
] = code
; /* push last code into the stack */
460 abcabca
= code
; /* save for special case */
462 /* make new entry in alphabet (only if NOT just cleared) */
465 ab_prefix
[ab_free
] = lastcode
;
466 ab_tail
[ab_free
] = code
;
469 if ((ab_free
> ab_max
) && (ab_bits
< 12))
472 ab_max
= (1 << ab_bits
) - 1;
476 /* dump stack data to the buffer */
479 if (pos
>= allocSize
)
484 return wxGIF_INVFORMAT
;
487 (img
->p
)[x
+ (y
* (img
->w
))] = (char)stack
[pos
--];
495 /* support for interlaced images */
498 case 1: y
+= 8; break;
499 case 2: y
+= 8; break;
500 case 3: y
+= 4; break;
501 case 4: y
+= 2; break;
507 case 2: y
= 4; break;
508 case 3: y
= 2; break;
509 case 4: y
= 1; break;
518 Normally image decoding is finished when an End of Information code is
519 encountered (code == ab_fin) however some broken encoders write wrong
520 "block byte counts" (The first byte value after the "code size" byte),
521 being one value too high. It might very well be possible other variants
522 of this problem occur as well. The only sensible solution seems to
523 be to check for clipping.
524 Example of wrong encoding:
525 (1 * 1 B/W image, raster data stream follows in hex bytes)
527 02 << B/W images have a code size of 2
528 02 << Block byte count
530 00 << Zero byte count (terminates data stream)
532 Because the block byte count is 2, the zero byte count is used in the
533 decoding process, and decoding is continued after this byte. (While it
534 should signal an end of image)
540 01 << When decoded this correctly includes the End of Information code
548 (The 44 doesn't include an End of Information code, but at least the
549 decoder correctly skips to 00 now after decoding, and signals this
550 as an End of Information itself)
564 while (code
!= ab_fin
);
566 delete [] ab_prefix
;
575 // Returns TRUE if the file looks like a valid GIF, FALSE otherwise.
577 bool wxGIFDecoder::CanRead()
579 unsigned char buf
[3];
582 m_f
->SeekI(-3, wxFromCurrent
);
584 return (memcmp(buf
, "GIF", 3) == 0);
589 // Reads and decodes one or more GIF images, depending on whether
590 // animated GIF support is enabled. Can read GIFs with any bit
591 // size (color depth), but the output images are always expanded
592 // to 8 bits per pixel. Also, the image palettes always contain
593 // 256 colors, although some of them may be unused. Returns wxGIF_OK
594 // (== 0) on success, or an error code if something fails (see
595 // header file for details)
597 int wxGIFDecoder::ReadGIF()
599 unsigned int ncolors
;
600 int bits
, interl
, transparent
, disposal
, i
;
603 unsigned char type
= 0;
604 unsigned char pal
[768];
605 unsigned char buf
[16];
607 GIFImage
*pimg
, *pprev
;
609 /* check GIF signature */
611 return wxGIF_INVFORMAT
;
613 /* check for animated GIF support (ver. >= 89a) */
615 static const size_t headerSize
= (3 + 3);
616 m_f
->Read(buf
, headerSize
);
617 if (m_f
->LastRead() != headerSize
)
619 return wxGIF_INVFORMAT
;
622 if (memcmp(buf
+ 3, "89a", 3) < 0)
627 /* read logical screen descriptor block (LSDB) */
628 static const size_t lsdbSize
= (2 + 2 + 1 + 1 + 1);
629 m_f
->Read(buf
, lsdbSize
);
630 if (m_f
->LastRead() != lsdbSize
)
632 return wxGIF_INVFORMAT
;
635 m_screenw
= buf
[0] + 256 * buf
[1];
636 m_screenh
= buf
[2] + 256 * buf
[3];
638 /* load global color map if available */
639 if ((buf
[4] & 0x80) == 0x80)
641 m_background
= buf
[5];
643 ncolors
= 2 << (buf
[4] & 0x07);
644 size_t numBytes
= 3 * ncolors
;
645 m_f
->Read(pal
, numBytes
);
646 if (m_f
->LastRead() != numBytes
)
648 return wxGIF_INVFORMAT
;
652 /* transparent colour, disposal method and delay default to unused */
666 type
= (unsigned char)m_f
->GetC();
669 If the end of file has been reached (or an error) and a ";"
670 (0x3B) hasn't been encountered yet, exit the loop. (Without this
671 check the while loop would loop endlessly.) Later on, in the next while
672 loop, the file will be treated as being truncated (But still
673 be decoded as far as possible). returning wxGIF_TRUNCATED is not
674 possible here since some init code is done after this loop.
676 if (m_f
->Eof())// || !m_f->IsOk())
679 type is set to some bogus value, so there's no
680 need to continue evaluating it.
682 break; // Alternative : "return wxGIF_INVFORMAT;"
691 /* extension block? */
694 if (((unsigned char)m_f
->GetC()) == 0xF9)
695 /* graphics control extension, parse it */
697 static const size_t gceSize
= 6;
698 m_f
->Read(buf
, gceSize
);
699 if (m_f
->LastRead() != gceSize
)
702 return wxGIF_INVFORMAT
;
705 /* read delay and convert from 1/100 of a second to ms */
706 delay
= 10 * (buf
[2] + 256 * buf
[3]);
708 /* read transparent colour index, if used */
710 transparent
= buf
[4];
712 /* read disposal method */
713 disposal
= (buf
[1] & 0x1C) - 1;
716 /* other extension, skip */
718 while ((i
= (unsigned char)m_f
->GetC()) != 0)
720 m_f
->SeekI(i
, wxFromCurrent
);
730 /* image descriptor block? */
733 /* allocate memory for IMAGEN struct */
734 pimg
= (*ppimg
) = new GIFImage();
742 /* fill in the data */
743 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
744 m_f
->Read(buf
, idbSize
);
745 if (m_f
->LastRead() != idbSize
)
748 return wxGIF_INVFORMAT
;
751 pimg
->left
= buf
[0] + 256 * buf
[1];
752 pimg
->top
= buf
[2] + 256 * buf
[3];
754 pimg->left = buf[4] + 256 * buf[5];
755 pimg->top = buf[4] + 256 * buf[5];
757 pimg
->w
= buf
[4] + 256 * buf
[5];
758 pimg
->h
= buf
[6] + 256 * buf
[7];
760 if (pimg
->w
== 0 || pimg
->h
== 0)
763 return wxGIF_INVFORMAT
;
766 interl
= ((buf
[8] & 0x40)? 1 : 0);
767 size
= pimg
->w
* pimg
->h
;
769 pimg
->transparent
= transparent
;
770 pimg
->disposal
= disposal
;
777 /* allocate memory for image and palette */
778 pimg
->p
= (unsigned char *) malloc((size_t)size
);
779 pimg
->pal
= (unsigned char *) malloc(768);
781 if ((!pimg
->p
) || (!pimg
->pal
))
787 /* load local color map if available, else use global map */
788 if ((buf
[8] & 0x80) == 0x80)
790 ncolors
= 2 << (buf
[8] & 0x07);
791 size_t numBytes
= 3 * ncolors
;
792 m_f
->Read(pimg
->pal
, numBytes
);
793 if (m_f
->LastRead() != numBytes
)
796 return wxGIF_INVFORMAT
;
801 memcpy(pimg
->pal
, pal
, 768);
804 /* get initial code size from first byte in raster data */
805 bits
= (unsigned char)m_f
->GetC();
808 int result
= dgif(pimg
, interl
, bits
);
809 if (result
!= wxGIF_OK
)
816 /* if this is not an animated GIF, exit after first image */
825 return wxGIF_INVFORMAT
;
828 /* setup image pointers */
833 /* try to read to the end of the stream */
837 return wxGIF_TRUNCATED
;
839 type
= (unsigned char)m_f
->GetC();
847 while ((i
= (unsigned char)m_f
->GetC()) != 0)
849 m_f
->SeekI(i
, wxFromCurrent
);
852 else if (type
== 0x2C)
854 /* image descriptor block */
855 static const size_t idbSize
= (2 + 2 + 2 + 2 + 1);
856 m_f
->Read(buf
, idbSize
);
857 if (m_f
->LastRead() != idbSize
)
860 return wxGIF_INVFORMAT
;
863 /* local color map */
864 if ((buf
[8] & 0x80) == 0x80)
866 ncolors
= 2 << (buf
[8] & 0x07);
867 off_t pos
= m_f
->TellI();
868 off_t numBytes
= 3 * ncolors
;
869 m_f
->SeekI(numBytes
, wxFromCurrent
);
870 if (m_f
->TellI() != (pos
+ numBytes
))
873 return wxGIF_INVFORMAT
;
877 /* initial code size */
881 while ((i
= (unsigned char)m_f
->GetC()) != 0)
883 m_f
->SeekI(i
, wxFromCurrent
);
886 else if ((type
!= 0x3B) && (type
!= 00)) /* testing */
888 /* images are OK, but couldn't read to the end of the stream */
889 return wxGIF_TRUNCATED
;
896 #endif // wxUSE_STREAMS && wxUSE_GIF