// --------------------------------------------------------------------------
-// constants
+// Constants
// --------------------------------------------------------------------------
-// disposal method
+// Error codes:
+// Note that the error code wxGIF_TRUNCATED means that the image itself
+// is most probably OK, but the decoder didn't reach the end of the data
+// stream; this means that if it was not reading directly from file,
+// the stream will not be correctly positioned. the
+//
+enum
+{
+ wxGIF_OK = 0, /* everything was OK */
+ wxGIF_INVFORMAT, /* error in gif header */
+ wxGIF_MEMERR, /* error allocating memory */
+ wxGIF_TRUNCATED /* file appears to be truncated */
+};
+
+// Disposal method
+// Experimental; subject to change.
+//
enum
{
wxGIF_D_UNSPECIFIED = -1, /* not specified */
wxGIF_D_TOPREVIOUS = 2 /* restore to previous image */
};
-// error codes
-enum
-{
- wxGIF_OK = 0, /* everything was OK */
- wxGIF_INVFORMAT = 1, /* error in gif header */
- wxGIF_MEMERR = 2 /* error allocating memory */
-};
#define MAX_BLOCK_SIZE 256 /* max. block size */
// animated GIF support is enabled. Can read GIFs with any bit
// size (color depth), but the output images are always expanded
// to 8 bits per pixel. Also, the image palettes always contain
-// 256 colors, although some of them may be unused. Returns GIF_OK
+// 256 colors, although some of them may be unused. Returns wxGIF_OK
// (== 0) on success, or an error code if something fails (see
// header file for details)
//
if (!CanRead())
return wxGIF_INVFORMAT;
- /* check for and animated GIF support (ver. >= 89a) */
+ /* check for animated GIF support (ver. >= 89a) */
m_f->Read(buf, 6);
if (memcmp(buf + 3, "89a", 3) < 0)
pprev = NULL;
pimg = NULL;
-#if defined(__VISAGECPP__)
-// VA just can't stand while(1)
- bool bOs2var = TRUE;
- while(bOs2var)
-#else
- while (1)
-#endif
+ bool done = FALSE;
+
+ while(!done)
{
type = (unsigned char)m_f->GetC();
/* end of data? */
if (type == 0x3B)
- break;
-
+ {
+ done = TRUE;
+ }
+ else
/* extension block? */
if (type == 0x21)
{
{
while ((i = (unsigned char)m_f->GetC()) != 0)
{
- /* This line should not be neccessary!
- * Some images are not loaded correctly
- * without it. A bug in wxStream?
- * Yes. Fixed now.
- */
- // m_f->SeekI(m_f->TellI(), wxFromStart);
-
m_f->SeekI(i, wxFromCurrent);
}
}
}
-
+ else
/* image descriptor block? */
if (type == 0x2C)
{
/* decode image */
dgif(pimg, interl, bits);
-
m_nimages++;
- }
- /* if we have one image and no animated GIF support, exit */
- if (m_nimages == 1 && !m_anim)
- break;
+ /* if this is not an animated GIF, exit after first image */
+ if (!m_anim)
+ done = TRUE;
+ }
}
- /* finish successfully :-) */
+ /* setup image pointers */
if (m_nimages != 0)
{
m_image = 1;
m_pimage = m_pfirst;
}
+ /* try to read to the end of the stream */
+ while (type != 0x3B)
+ {
+ type = (unsigned char)m_f->GetC();
+
+ if (type == 0x21)
+ {
+ /* extension type */
+ (void) m_f->GetC();
+
+ /* skip all data */
+ while ((i = (unsigned char)m_f->GetC()) != 0)
+ {
+ m_f->SeekI(i, wxFromCurrent);
+ }
+ }
+ else if (type == 0x2C)
+ {
+ /* image descriptor block */
+ m_f->Read(buf, 9);
+
+ /* local color map */
+ if ((buf[8] & 0x80) == 0x80)
+ {
+ ncolors = 2 << (buf[8] & 0x07);
+ m_f->Read(pal, 3 * ncolors);
+ }
+
+ /* initial code size */
+ (void) m_f->GetC();
+
+ /* skip all data */
+ while ((i = (unsigned char)m_f->GetC()) != 0)
+ {
+ m_f->SeekI(i, wxFromCurrent);
+ }
+ }
+ else if (type != 0x3B)
+ {
+ /* images are OK, but couldn't read to the end of the stream */
+ return wxGIF_TRUNCATED;
+ }
+ }
+
return wxGIF_OK;
}
bool ok;
decod = new wxGIFDecoder(&stream, TRUE);
+ error = decod->ReadGIF();
- if ((error = decod->ReadGIF()) != wxGIF_OK)
+ if ((error != wxGIF_OK) && (error != wxGIF_TRUNCATED))
{
if (verbose)
{
switch (error)
{
- case wxGIF_INVFORMAT: wxLogError(_("wxGIFHandler: error in GIF image format")); break;
- case wxGIF_MEMERR: wxLogError(_("wxGIFHandler: couldn't allocate enough memory")); break;
- default: wxLogError(_("wxGIFHandler: unknown error !!!"));
+ case wxGIF_INVFORMAT:
+ wxLogError(_("wxGIFHandler: error in GIF image format."));
+ break;
+ case wxGIF_MEMERR:
+ wxLogError(_("wxGIFHandler: not enough memory."));
+ break;
+ default:
+ wxLogError(_("wxGIFHandler: unknown error!!!"));
+ break;
}
}
delete decod;
return FALSE;
}
+ if ((error == wxGIF_TRUNCATED) && verbose)
+ {
+ wxLogWarning(_("wxGIFHandler: data stream seems to be truncated."));
+ /* go on; image data is OK */
+ }
+
image->Destroy();
ok = decod->ConvertToImage(image);