]>
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  12 #pragma implementation "gifdecod.h" 
  15 // For compilers that support precompilation, includes "wx.h". 
  16 #include "wx/wxprec.h" 
  24 #  include "wx/palette.h" 
  27 #if wxUSE_STREAMS && wxUSE_GIF 
  31 #include "wx/gifdecod.h" 
  34 //--------------------------------------------------------------------------- 
  35 // GIFImage constructor 
  36 //--------------------------------------------------------------------------- 
  46     p 
= (unsigned char *) NULL
; 
  47     pal 
= (unsigned char *) NULL
; 
  48     next 
= (GIFImage 
*) NULL
; 
  49     prev 
= (GIFImage 
*) NULL
; 
  52 //--------------------------------------------------------------------------- 
  53 // wxGIFDecoder constructor and destructor 
  54 //--------------------------------------------------------------------------- 
  56 wxGIFDecoder::wxGIFDecoder(wxInputStream 
*s
, bool anim
) 
  72 wxGIFDecoder::~wxGIFDecoder() 
  77 void wxGIFDecoder::Destroy() 
  79     GIFImage 
*pimg
, *paux
; 
 100 //--------------------------------------------------------------------------- 
 101 // Convert this image to a wxImage object 
 102 //--------------------------------------------------------------------------- 
 104 // This function was designed by Vaclav Slavik 
 106 bool wxGIFDecoder::ConvertToImage(wxImage 
*image
) const 
 108     unsigned char *src
, *dst
, *pal
; 
 112     /* just in case... */ 
 115     /* create the image */ 
 116     image
->Create(GetWidth(), GetHeight()); 
 123     dst 
= image
->GetData(); 
 124     transparent 
= GetTransparentColour(); 
 126     /* set transparent colour mask */ 
 127     if (transparent 
!= -1) 
 129         for (i 
= 0; i 
< 256; i
++) 
 131             if ((pal
[3 * i 
+ 0] == 255) && 
 132                 (pal
[3 * i 
+ 1] == 0) && 
 133                 (pal
[3 * i 
+ 2] == 255)) 
 135                 pal
[3 * i 
+ 2] = 254; 
 139         pal
[3 * transparent 
+ 0] = 255, 
 140         pal
[3 * transparent 
+ 1] = 0, 
 141         pal
[3 * transparent 
+ 2] = 255; 
 143         image
->SetMaskColour(255, 0, 255); 
 146         image
->SetMask(FALSE
); 
 151         unsigned char r
[256]; 
 152         unsigned char g
[256]; 
 153         unsigned char b
[256]; 
 155         for (i 
= 0; i 
< 256; i
++) 
 162         image
->SetPalette(wxPalette(256, r
, g
, b
)); 
 164 #endif // wxUSE_PALETTE 
 166     /* copy image data */ 
 167     for (i 
= 0; i 
< (GetWidth() * GetHeight()); i
++, src
++) 
 169         *(dst
++) = pal
[3 * (*src
) + 0]; 
 170         *(dst
++) = pal
[3 * (*src
) + 1]; 
 171         *(dst
++) = pal
[3 * (*src
) + 2]; 
 178 //--------------------------------------------------------------------------- 
 180 //--------------------------------------------------------------------------- 
 182 // Get data for current frame 
 184 int wxGIFDecoder::GetFrameIndex() const         { return m_image
; } 
 185 unsigned char* wxGIFDecoder::GetData() const    { return (m_pimage
->p
); } 
 186 unsigned char* wxGIFDecoder::GetPalette() const { return (m_pimage
->pal
); } 
 187 unsigned int wxGIFDecoder::GetWidth() const     { return (m_pimage
->w
); } 
 188 unsigned int wxGIFDecoder::GetHeight() const    { return (m_pimage
->h
); } 
 189 unsigned int wxGIFDecoder::GetTop() const       { return (m_pimage
->top
); } 
 190 unsigned int wxGIFDecoder::GetLeft() const      { return (m_pimage
->left
); } 
 191 int wxGIFDecoder::GetTransparentColour() const  { return (m_pimage
->transparent
); } 
 192 int wxGIFDecoder::GetDisposalMethod() const     { return (m_pimage
->disposal
); } 
 193 long wxGIFDecoder::GetDelay() const             { return (m_pimage
->delay
); } 
 197 unsigned int wxGIFDecoder::GetLogicalScreenWidth() const    { return m_screenw
; } 
 198 unsigned int wxGIFDecoder::GetLogicalScreenHeight() const   { return m_screenh
; } 
 199 int wxGIFDecoder::GetBackgroundColour() const   { return m_background
; } 
 200 int wxGIFDecoder::GetNumberOfFrames() const     { return m_nimages
; } 
 201 bool wxGIFDecoder::IsAnimation() const          { return (m_nimages 
> 1); } 
 204 //--------------------------------------------------------------------------- 
 205 // Functions to move through the animation 
 206 //--------------------------------------------------------------------------- 
 208 bool wxGIFDecoder::GoFirstFrame() 
 218 bool wxGIFDecoder::GoLastFrame() 
 228 bool wxGIFDecoder::GoNextFrame(bool cyclic
) 
 233     if ((m_image 
< m_nimages
) || (cyclic
)) 
 235         m_pimage 
= m_pimage
->next
; 
 250 bool wxGIFDecoder::GoPrevFrame(bool cyclic
) 
 255     if ((m_image 
> 1) || (cyclic
)) 
 257         m_pimage 
= m_pimage
->prev
; 
 272 bool wxGIFDecoder::GoFrame(int which
) 
 279     if ((which 
>= 1) && (which 
<= m_nimages
)) 
 283         for (i 
= 0; i 
< which
; i
++) 
 284             m_pimage 
= m_pimage
->next
; 
 293 //--------------------------------------------------------------------------- 
 294 // GIF reading and decoding 
 295 //--------------------------------------------------------------------------- 
 298 //  Reads the next code from the file stream, with size 'bits' 
 300 int wxGIFDecoder::getcode(int bits
, int ab_fin
) 
 302     unsigned int mask
;          /* bit mask */ 
 303     unsigned int code
;          /* code (result) */ 
 306     /* get remaining bits from last byte read */ 
 307     mask 
= (1 << bits
) - 1; 
 308     code 
= (m_lastbyte 
>> (8 - m_restbits
)) & mask
; 
 310     /* keep reading new bytes while needed */ 
 311     while (bits 
> m_restbits
) 
 313         /* if no bytes left in this block, read the next block */ 
 316             m_restbyte 
= (unsigned char)m_f
->GetC(); 
 318             /* Some encoders are a bit broken: instead of issuing 
 319              * an end-of-image symbol (ab_fin) they come up with 
 320              * a zero-length subblock!! We catch this here so 
 321              * that the decoder sees an ab_fin code. 
 330             m_f
->Read((void *) m_buffer
, m_restbyte
); 
 331             if (m_f
->LastRead() != m_restbyte
) 
 339         /* read next byte and isolate the bits we need */ 
 340         m_lastbyte 
= (unsigned char) (*m_bufp
++); 
 341         mask       
= (1 << (bits 
- m_restbits
)) - 1; 
 342         code       
= code 
+ ((m_lastbyte 
& mask
) << m_restbits
); 
 345         /* adjust total number of bits extracted from the buffer */ 
 346         m_restbits 
= m_restbits 
+ 8; 
 349     /* find number of bits remaining for next code */ 
 350     m_restbits 
= (m_restbits 
- bits
); 
 357 //  GIF decoding function. The initial code size (aka root size) 
 358 //  is 'bits'. Supports interlaced images (interl == 1). 
 359 //  Returns wxGIF_OK (== 0) on success, or an error code if something 
 360 // fails (see header file for details) 
 361 int wxGIFDecoder::dgif(GIFImage 
*img
, int interl
, int bits
) 
 363     static const int allocSize 
= 4096 + 1; 
 364     int *ab_prefix 
= new int[allocSize
]; /* alphabet (prefixes) */ 
 365     if (ab_prefix 
== NULL
) 
 370     int *ab_tail 
= new int[allocSize
];   /* alphabet (tails) */ 
 377     int *stack 
= new int[allocSize
];     /* decompression stack */ 
 385     int ab_clr
;                     /* clear code */ 
 386     int ab_fin
;                     /* end of info code */ 
 387     int ab_bits
;                    /* actual symbol width, in bits */ 
 388     int ab_free
;                    /* first free position in alphabet */ 
 389     int ab_max
;                     /* last possible character in alphabet */ 
 390     int pass
;                       /* pass number in interlaced images */ 
 391     int pos
;                        /* index into decompresion stack */ 
 392     unsigned int x
, y
;              /* position in image buffer */ 
 394     int code
, readcode
, lastcode
, abcabca
; 
 396     /* these won't change */ 
 397     ab_clr 
= (1 << bits
); 
 398     ab_fin 
= (1 << bits
) + 1; 
 400     /* these will change through the decompression proccess */ 
 402     ab_free  
= (1 << bits
) + 2; 
 403     ab_max   
= (1 << ab_bits
) - 1; 
 409     /* reset decoder vars */ 
 417         readcode 
= code 
= getcode(ab_bits
, ab_fin
); 
 420         if (code 
== ab_fin
) break; 
 422         /* reset alphabet? */ 
 425             /* reset main variables */ 
 427             ab_free  
= (1 << bits
) + 2; 
 428             ab_max   
= (1 << ab_bits
) - 1; 
 432             /* skip to next code */ 
 436         /* unknown code: special case (like in ABCABCA) */ 
 439             code 
= lastcode
;            /* take last string */ 
 440             stack
[pos
++] = abcabca
;     /* add first character */ 
 443         /* build the string for this code in the stack */ 
 444         while (code 
> ab_clr
) 
 446             stack
[pos
++] = ab_tail
[code
]; 
 447             code         
= ab_prefix
[code
]; 
 449             // Don't overflow. This shouldn't happen with normal 
 450             // GIF files, the allocSize of 4096+1 is enough. This 
 451             // will only happen with badly formed GIFs. 
 452             if (pos 
>= allocSize
) 
 457                 return wxGIF_INVFORMAT
; 
 461         if (pos 
>= allocSize
) 
 466             return wxGIF_INVFORMAT
; 
 469         stack
[pos
] = code
;              /* push last code into the stack */ 
 470         abcabca    
= code
;              /* save for special case */ 
 472         /* make new entry in alphabet (only if NOT just cleared) */ 
 475             ab_prefix
[ab_free
] = lastcode
; 
 476             ab_tail
[ab_free
]   = code
; 
 479             if ((ab_free 
> ab_max
) && (ab_bits 
< 12)) 
 482                 ab_max 
= (1 << ab_bits
) - 1; 
 486         /* dump stack data to the image buffer */ 
 489             (img
->p
)[x 
+ (y 
* (img
->w
))] = (char) stack
[pos
]; 
 498                     /* support for interlaced images */ 
 501                         case 1: y 
+= 8; break; 
 502                         case 2: y 
+= 8; break; 
 503                         case 3: y 
+= 4; break; 
 504                         case 4: y 
+= 2; break; 
 507                     /* loop until a valid y coordinate has been 
 508                     found, Or if the maximum number of passes has 
 509                     been reached, exit the loop, and stop image 
 510                     decoding (At this point the image is succesfully 
 512                     If we don't loop, but merely set y to some other 
 513                     value, that new value might still be invalid depending 
 514                     on the height of the image. This would cause out of 
 517                     while (y 
>= (img
->h
)) 
 521                             case 2: y 
= 4; break; 
 522                             case 3: y 
= 2; break; 
 523                             case 4: y 
= 1; break; 
 527                                 It's possible we arrive here. For example this 
 528                                 happens when the image is interlaced, and the 
 529                                 height is 1. Looking at the above cases, the 
 530                                 lowest possible y is 1. While the only valid 
 531                                 one would be 0 for an image of height 1. So 
 532                                 'eventually' the loop will arrive here. 
 533                                 This case makes sure this while loop is 
 534                                 exited, as well as the 2 other ones. 
 537                                 // Set y to a valid coordinate so the local 
 538                                 // while loop will be exited. (y = 0 always 
 539                                 // is >= img->h since if img->h == 0 the 
 540                                 // image is never decoded) 
 543                                 // This will exit the other outer while loop 
 546                                 // This will halt image decoding. 
 558 Normally image decoding is finished when an End of Information code is 
 559 encountered (code == ab_fin) however some broken encoders write wrong 
 560 "block byte counts" (The first byte value after the "code size" byte), 
 561 being one value too high. It might very well be possible other variants 
 562 of this problem occur as well. The only sensible solution seems to 
 563 be to check for clipping. 
 564 Example of wrong encoding: 
 565 (1 * 1 B/W image, raster data stream follows in hex bytes) 
 567 02  << B/W images have a code size of 2 
 568 02  << Block byte count 
 570 00  << Zero byte count (terminates data stream) 
 572 Because the block byte count is 2, the zero byte count is used in the 
 573 decoding process, and decoding is continued after this byte. (While it 
 574 should signal an end of image) 
 580 01  << When decoded this correctly includes the End of Information code 
 588 (The 44 doesn't include an End of Information code, but at least the 
 589 decoder correctly skips to 00 now after decoding, and signals this 
 590 as an End of Information itself) 
 604     while (code 
!= ab_fin
); 
 606     delete [] ab_prefix 
; 
 615 //  Returns TRUE if the file looks like a valid GIF, FALSE otherwise. 
 617 bool wxGIFDecoder::CanRead() 
 619     unsigned char buf
[3]; 
 621     if ( !m_f
->Read(buf
, WXSIZEOF(buf
)) ) 
 624     m_f
->SeekI(-(off_t
)WXSIZEOF(buf
), wxFromCurrent
); 
 626     return memcmp(buf
, "GIF", WXSIZEOF(buf
)) == 0; 
 631 //  Reads and decodes one or more GIF images, depending on whether 
 632 //  animated GIF support is enabled. Can read GIFs with any bit 
 633 //  size (color depth), but the output images are always expanded 
 634 //  to 8 bits per pixel. Also, the image palettes always contain 
 635 //  256 colors, although some of them may be unused. Returns wxGIF_OK 
 636 //  (== 0) on success, or an error code if something fails (see 
 637 //  header file for details) 
 639 int wxGIFDecoder::ReadGIF() 
 641     unsigned int ncolors
; 
 642     int           bits
, interl
, transparent
, disposal
, i
; 
 645     unsigned char type 
= 0; 
 646     unsigned char pal
[768]; 
 647     unsigned char buf
[16]; 
 649     GIFImage      
*pimg
, *pprev
; 
 651     /* check GIF signature */ 
 653         return wxGIF_INVFORMAT
; 
 655     /* check for animated GIF support (ver. >= 89a) */ 
 657     static const size_t headerSize 
= (3 + 3); 
 658     m_f
->Read(buf
, headerSize
); 
 659     if (m_f
->LastRead() != headerSize
) 
 661         return wxGIF_INVFORMAT
; 
 664     if (memcmp(buf 
+ 3, "89a", 3) < 0) 
 669     /* read logical screen descriptor block (LSDB) */ 
 670     static const size_t lsdbSize 
= (2 + 2 + 1 + 1 + 1); 
 671     m_f
->Read(buf
, lsdbSize
); 
 672     if (m_f
->LastRead() != lsdbSize
) 
 674         return wxGIF_INVFORMAT
; 
 677     m_screenw 
= buf
[0] + 256 * buf
[1]; 
 678     m_screenh 
= buf
[2] + 256 * buf
[3]; 
 680     /* load global color map if available */ 
 681     if ((buf
[4] & 0x80) == 0x80) 
 683         m_background 
= buf
[5]; 
 685         ncolors 
= 2 << (buf
[4] & 0x07); 
 686         size_t numBytes 
= 3 * ncolors
; 
 687         m_f
->Read(pal
, numBytes
); 
 688         if (m_f
->LastRead() != numBytes
) 
 690             return wxGIF_INVFORMAT
; 
 694     /* transparent colour, disposal method and delay default to unused */ 
 708         type 
= (unsigned char)m_f
->GetC(); 
 711         If the end of file has been reached (or an error) and a ";" 
 712         (0x3B) hasn't been encountered yet, exit the loop. (Without this 
 713         check the while loop would loop endlessly.) Later on, in the next while 
 714         loop, the file will be treated as being truncated (But still 
 715         be decoded as far as possible). returning wxGIF_TRUNCATED is not 
 716         possible here since some init code is done after this loop. 
 718         if (m_f
->Eof())// || !m_f->IsOk()) 
 721             type is set to some bogus value, so there's no 
 722             need to continue evaluating it. 
 724             break; // Alternative : "return wxGIF_INVFORMAT;" 
 733         /* extension block? */ 
 736             if (((unsigned char)m_f
->GetC()) == 0xF9) 
 737             /* graphics control extension, parse it */ 
 739                 static const size_t gceSize 
= 6; 
 740                 m_f
->Read(buf
, gceSize
); 
 741                 if (m_f
->LastRead() != gceSize
) 
 744                     return wxGIF_INVFORMAT
; 
 747                 /* read delay and convert from 1/100 of a second to ms */ 
 748                 delay 
= 10 * (buf
[2] + 256 * buf
[3]); 
 750                 /* read transparent colour index, if used */ 
 752                     transparent 
= buf
[4]; 
 754                 /* read disposal method */ 
 755                 disposal 
= (buf
[1] & 0x1C) - 1; 
 758             /* other extension, skip */ 
 760                 while ((i 
= (unsigned char)m_f
->GetC()) != 0) 
 762                     m_f
->SeekI(i
, wxFromCurrent
); 
 772         /* image descriptor block? */ 
 775             /* allocate memory for IMAGEN struct */ 
 776             pimg 
= (*ppimg
) = new GIFImage(); 
 784             /* fill in the data */ 
 785             static const size_t idbSize 
= (2 + 2 + 2 + 2 + 1); 
 786             m_f
->Read(buf
, idbSize
); 
 787             if (m_f
->LastRead() != idbSize
) 
 790                 return wxGIF_INVFORMAT
; 
 793             pimg
->left 
= buf
[0] + 256 * buf
[1]; 
 794             pimg
->top 
= buf
[2] + 256 * buf
[3]; 
 796             pimg->left = buf[4] + 256 * buf[5]; 
 797             pimg->top = buf[4] + 256 * buf[5]; 
 799             pimg
->w 
= buf
[4] + 256 * buf
[5]; 
 800             pimg
->h 
= buf
[6] + 256 * buf
[7]; 
 802             if (pimg
->w 
== 0 || pimg
->h 
== 0) 
 805                 return wxGIF_INVFORMAT
; 
 808             interl 
= ((buf
[8] & 0x40)? 1 : 0); 
 809             size 
= pimg
->w 
* pimg
->h
; 
 811             pimg
->transparent 
= transparent
; 
 812             pimg
->disposal 
= disposal
; 
 819             /* allocate memory for image and palette */ 
 820             pimg
->p   
= (unsigned char *) malloc((size_t)size
); 
 821             pimg
->pal 
= (unsigned char *) malloc(768); 
 823             if ((!pimg
->p
) || (!pimg
->pal
)) 
 829             /* load local color map if available, else use global map */ 
 830             if ((buf
[8] & 0x80) == 0x80) 
 832                 ncolors 
= 2 << (buf
[8] & 0x07); 
 833                 size_t numBytes 
= 3 * ncolors
; 
 834                 m_f
->Read(pimg
->pal
, numBytes
); 
 835                 if (m_f
->LastRead() != numBytes
) 
 838                     return wxGIF_INVFORMAT
; 
 843                 memcpy(pimg
->pal
, pal
, 768); 
 846             /* get initial code size from first byte in raster data */ 
 847             bits 
= (unsigned char)m_f
->GetC(); 
 850             int result 
= dgif(pimg
, interl
, bits
); 
 851             if (result 
!= wxGIF_OK
) 
 858             /* if this is not an animated GIF, exit after first image */ 
 867         return wxGIF_INVFORMAT
; 
 870     /* setup image pointers */ 
 875     /* try to read to the end of the stream */ 
 879             return wxGIF_TRUNCATED
; 
 881         type 
= (unsigned char)m_f
->GetC(); 
 889             while ((i 
= (unsigned char)m_f
->GetC()) != 0) 
 891                 m_f
->SeekI(i
, wxFromCurrent
); 
 894         else if (type 
== 0x2C) 
 896             /* image descriptor block */ 
 897             static const size_t idbSize 
= (2 + 2 + 2 + 2 + 1); 
 898             m_f
->Read(buf
, idbSize
); 
 899             if (m_f
->LastRead() != idbSize
) 
 902                 return wxGIF_INVFORMAT
; 
 905             /* local color map */ 
 906             if ((buf
[8] & 0x80) == 0x80) 
 908                 ncolors 
= 2 << (buf
[8] & 0x07); 
 909                 off_t pos 
= m_f
->TellI(); 
 910                 off_t numBytes 
= 3 * ncolors
; 
 911                 m_f
->SeekI(numBytes
, wxFromCurrent
); 
 912                 if (m_f
->TellI() != (pos 
+ numBytes
)) 
 915                     return wxGIF_INVFORMAT
; 
 919             /* initial code size */ 
 923             while ((i 
= (unsigned char)m_f
->GetC()) != 0) 
 925                 m_f
->SeekI(i
, wxFromCurrent
); 
 928         else if ((type 
!= 0x3B) && (type 
!= 00)) /* testing */ 
 930             /* images are OK, but couldn't read to the end of the stream */ 
 931             return wxGIF_TRUNCATED
; 
 938 #endif // wxUSE_STREAMS && wxUSE_GIF