]> git.saurik.com Git - wxWidgets.git/commitdiff
Now wxGIFDecoder always tries to read to the end of the GIF data.
authorGuillermo Rodriguez Garcia <guille@iies.es>
Thu, 17 Feb 2000 23:39:35 +0000 (23:39 +0000)
committerGuillermo Rodriguez Garcia <guille@iies.es>
Thu, 17 Feb 2000 23:39:35 +0000 (23:39 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6131 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gifdecod.h
src/common/gifdecod.cpp
src/common/imaggif.cpp

index 09a8927f9959d9482b726be0221f61bff045371e..769169fd4c2f5e6599a650ff52fddda659b3eb9e 100644 (file)
 
 
 // --------------------------------------------------------------------------
-// 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 */
 
index 66c9aad915b90b6f252fc7553e6c5c9eb3e51c66..c746a8574f276eda5a968ca2a562e1cbc76b3a08 100644 (file)
@@ -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;
 }
 
index 07a1067ca30469815187d96b1af7466042501b0a..74e573df34173d361ac0f14d8891f24e64064aa2 100644 (file)
@@ -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);