wxGIFDecoder::wxGIFDecoder(wxInputStream *s, bool anim)
{
- m_f = s;
+ m_f = s;
m_anim = anim;
m_background = -1;
delete pimg;
pimg = paux;
}
+
+ m_pimage = NULL;
+ m_pfirst = NULL;
+ m_plast = NULL;
+ m_image = 0;
+ m_nimages = 0;
}
else
image->SetMask(FALSE);
+#if wxUSE_PALETTE
+ if (pal)
+ {
+ unsigned char r[256];
+ unsigned char g[256];
+ unsigned char b[256];
+
+ for (i = 0; i < 256; i++)
+ {
+ r[i] = pal[3*i + 0];
+ g[i] = pal[3*i + 1];
+ b[i] = pal[3*i + 2];
+ }
+
+ image->SetPalette(wxPalette(256, r, g, b));
+ }
+#endif // wxUSE_PALETTE
+
/* copy image data */
for (i = 0; i < (GetWidth() * GetHeight()); i++, src++)
{
//
int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits)
{
- int ab_prefix[4096]; /* alphabet (prefixes) */
- int ab_tail[4096]; /* alphabet (tails) */
- int stack[4096]; /* decompression stack */
-
- int ab_clr; /* clear code */
- int ab_fin; /* end of info code */
- int ab_bits; /* actual symbol width, in bits */
- int ab_free; /* first free position in alphabet */
- int ab_max; /* last possible character in alphabet */
- int pass; /* pass number in interlaced images */
- int pos; /* index into decompresion stack */
- unsigned int x, y; /* position in image buffer */
+ int *ab_prefix = new int[4096]; /* alphabet (prefixes) */
+ int *ab_tail = new int[4096]; /* alphabet (tails) */
+ int *stack = new int[4096]; /* decompression stack */
+ int ab_clr; /* clear code */
+ int ab_fin; /* end of info code */
+ int ab_bits; /* actual symbol width, in bits */
+ int ab_free; /* first free position in alphabet */
+ int ab_max; /* last possible character in alphabet */
+ int pass; /* pass number in interlaced images */
+ int pos; /* index into decompresion stack */
+ unsigned int x, y; /* position in image buffer */
int code, readcode, lastcode, abcabca;
{
/* non-interlaced */
y++;
+/*
+Normally image decoding is finished when an End of Information code is
+encountered (code == ab_fin) however some broken encoders write wrong
+"block byte counts" (The first byte value after the "code size" byte),
+being one value too high. It might very well be possible other variants
+of this problem occur as well. The only sensible solution seems to
+be to check for clipping.
+Example of wrong encoding:
+(1 * 1 B/W image, raster data stream follows in hex bytes)
+
+02 << B/W images have a code size of 2
+02 << Block byte count
+44 << LZW packed
+00 << Zero byte count (terminates data stream)
+
+Because the block byte count is 2, the zero byte count is used in the
+decoding process, and decoding is continued after this byte. (While it
+should signal an end of image)
+
+It should be:
+02
+02
+44
+01 << When decoded this correctly includes the End of Information code
+00
+
+Or (Worse solution):
+02
+01
+44
+00
+(The 44 doesn't include an End of Information code, but at least the
+decoder correctly skips to 00 now after decoding, and signals this
+as an End of Information itself)
+*/
+ if (y >= img->h)
+ {
+ code = ab_fin;
+ break;
+ }
}
}
}
}
while (code != ab_fin);
+ delete [] ab_prefix ;
+ delete [] ab_tail ;
+ delete [] stack ;
+
return 0;
}
int ncolors, bits, interl, transparent, disposal, i;
long size;
long delay;
- unsigned char type;
+ unsigned char type = 0;
unsigned char pal[768];
unsigned char buf[16];
- GIFImage **ppimg, *pimg, *pprev;
+ GIFImage **ppimg;
+ GIFImage *pimg, *pprev;
/* check GIF signature */
if (!CanRead())
/* fill in the data */
m_f->Read(buf, 9);
+ pimg->left = buf[0] + 256 * buf[1];
+ pimg->top = buf[2] + 256 * buf[3];
+/*
pimg->left = buf[4] + 256 * buf[5];
pimg->top = buf[4] + 256 * buf[5];
+*/
pimg->w = buf[4] + 256 * buf[5];
pimg->h = buf[6] + 256 * buf[7];
interl = ((buf[8] & 0x40)? 1 : 0);
/* try to read to the end of the stream */
while (type != 0x3B)
{
+ if (!m_f->IsOk())
+ return wxGIF_TRUNCATED;
+
type = (unsigned char)m_f->GetC();
if (type == 0x21)
if ((buf[8] & 0x80) == 0x80)
{
ncolors = 2 << (buf[8] & 0x07);
- m_f->Read(pal, 3 * ncolors);
+ m_f->SeekI(3 * ncolors, wxFromCurrent);
}
/* initial code size */
m_f->SeekI(i, wxFromCurrent);
}
}
- else if (type != 0x3B)
+ else if ((type != 0x3B) && (type != 00)) /* testing */
{
/* images are OK, but couldn't read to the end of the stream */
return wxGIF_TRUNCATED;