+ if (!stream.IsOk())
+ return wxGIF_TRUNCATED;
+
+ type = (unsigned char)stream.GetC();
+
+ if (type == 0x21)
+ {
+ // extension type
+ (void) stream.GetC();
+
+ // skip all data
+ while ((i = (unsigned char)stream.GetC()) != 0)
+ {
+ if (stream.Eof() || (stream.LastRead() == 0) ||
+ stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+ }
+ }
+ else if (type == 0x2C)
+ {
+ // image descriptor block
+ static const unsigned int idbSize = (2 + 2 + 2 + 2 + 1);
+ stream.Read(buf, idbSize);
+ if (stream.LastRead() != idbSize)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+
+ // local color map
+ if ((buf[8] & 0x80) == 0x80)
+ {
+ unsigned int local_ncolors = 2 << (buf[8] & 0x07);
+ wxFileOffset numBytes = 3 * local_ncolors;
+ if (stream.SeekI(numBytes, wxFromCurrent) == wxInvalidOffset)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+ }
+
+ // initial code size
+ (void) stream.GetC();
+ if (stream.Eof() || (stream.LastRead() == 0))
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+
+ // skip all data
+ while ((i = (unsigned char)stream.GetC()) != 0)
+ {
+ if (stream.Eof() || (stream.LastRead() == 0) ||
+ stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+ }
+ }
+ else if ((type != 0x3B) && (type != 00)) // testing
+ {
+ // images are OK, but couldn't read to the end of the stream
+ return wxGIF_TRUNCATED;
+ }