From 8141573c1ed2d7f02b201c7b78f32ffca2925eeb Mon Sep 17 00:00:00 2001 From: Guillermo Rodriguez Garcia Date: Thu, 17 Feb 2000 23:39:35 +0000 Subject: [PATCH] Now wxGIFDecoder always tries to read to the end of the GIF data. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6131 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gifdecod.h | 27 ++++++++----- src/common/gifdecod.cpp | 84 +++++++++++++++++++++++++++++------------ src/common/imaggif.cpp | 21 +++++++++-- 3 files changed, 94 insertions(+), 38 deletions(-) diff --git a/include/wx/gifdecod.h b/include/wx/gifdecod.h index 09a8927f99..769169fd4c 100644 --- a/include/wx/gifdecod.h +++ b/include/wx/gifdecod.h @@ -24,10 +24,26 @@ // -------------------------------------------------------------------------- -// 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 */ @@ -36,13 +52,6 @@ enum 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 */ diff --git a/src/common/gifdecod.cpp b/src/common/gifdecod.cpp index 66c9aad915..c746a8574f 100644 --- a/src/common/gifdecod.cpp +++ b/src/common/gifdecod.cpp @@ -461,7 +461,7 @@ bool wxGIFDecoder::CanRead() // 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) // @@ -479,7 +479,7 @@ int wxGIFDecoder::ReadGIF() 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) @@ -509,20 +509,18 @@ int wxGIFDecoder::ReadGIF() 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) { @@ -546,18 +544,11 @@ int wxGIFDecoder::ReadGIF() { 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) { @@ -611,16 +602,15 @@ int wxGIFDecoder::ReadGIF() /* 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; @@ -628,6 +618,50 @@ int wxGIFDecoder::ReadGIF() 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; } diff --git a/src/common/imaggif.cpp b/src/common/imaggif.cpp index 07a1067ca3..74e573df34 100644 --- a/src/common/imaggif.cpp +++ b/src/common/imaggif.cpp @@ -45,22 +45,35 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose 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); -- 2.45.2