]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/gifdecod.cpp
Improve wxCheckListBox appearance under Vista/Win7.
[wxWidgets.git] / src / common / gifdecod.cpp
index 9d8cc1dd71d9a7a1a8bf94ff5c56f9a917b81407..27669b8d2a7b8271cccd565ff580b78da92d469e 100644 (file)
 
 #ifndef WX_PRECOMP
     #include "wx/palette.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
 #endif
 
 #include <stdlib.h>
 #include <string.h>
 #include "wx/gifdecod.h"
-#include "wx/ptr_scpd.h"
+#include "wx/scopedptr.h"
 #include "wx/scopeguard.h"
 
 
@@ -51,7 +53,7 @@ public:
     unsigned char *pal;             // palette
     unsigned int ncolours;          // number of colours
 
-    DECLARE_NO_COPY_CLASS(GIFImage)
+    wxDECLARE_NO_COPY_CLASS(GIFImage);
 };
 
 wxDECLARE_SCOPED_PTR(GIFImage, GIFImagePtr)
@@ -573,15 +575,13 @@ as an End of Information itself)
 // CanRead:
 //  Returns true if the file looks like a valid GIF, false otherwise.
 //
-bool wxGIFDecoder::CanRead(wxInputStream &stream) const
+bool wxGIFDecoder::DoCanRead(wxInputStream &stream) const
 {
     unsigned char buf[3];
 
     if ( !stream.Read(buf, WXSIZEOF(buf)) )
         return false;
 
-    stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent);
-
     return memcmp(buf, "GIF", WXSIZEOF(buf)) == 0;
 }
 
@@ -720,12 +720,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
             {
                 while ((i = (unsigned char)stream.GetC()) != 0)
                 {
-                    if (stream.Eof() || (stream.LastRead() == 0))
+                    if (stream.Eof() || (stream.LastRead() == 0) ||
+                        stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
                     {
                         done = true;
                         break;
                     }
-                    stream.SeekI(i, wxFromCurrent);
                 }
             }
         }
@@ -756,9 +756,30 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
             pimg->w = buf[4] + 256 * buf[5];
             pimg->h = buf[6] + 256 * buf[7];
 
-            if ( anim && ((pimg->w == 0) || (pimg->w > (unsigned int)m_szAnimation.GetWidth()) ||
-                  (pimg->h == 0) || (pimg->h > (unsigned int)m_szAnimation.GetHeight())) )
-                return wxGIF_INVFORMAT;
+            if ( anim )
+            {
+                // some GIF images specify incorrect animation size but we can
+                // still open them if we fix up the animation size, see #9465
+                if ( m_nFrames == 0 )
+                {
+                    if ( pimg->w > (unsigned)m_szAnimation.x )
+                        m_szAnimation.x = pimg->w;
+                    if ( pimg->h > (unsigned)m_szAnimation.y )
+                        m_szAnimation.y = pimg->h;
+                }
+                else // subsequent frames
+                {
+                    // check that we have valid size
+                    if ( (!pimg->w || pimg->w > (unsigned)m_szAnimation.x) ||
+                            (!pimg->h || pimg->h > (unsigned)m_szAnimation.y) )
+                    {
+                        wxLogError(_("Incorrect GIF frame size (%u, %d) for "
+                                     "the frame #%u"),
+                                   pimg->w, pimg->h, m_nFrames);
+                        return wxGIF_INVFORMAT;
+                    }
+                }
+            }
 
             interl = ((buf[8] & 0x40)? 1 : 0);
             size = pimg->w * pimg->h;
@@ -834,12 +855,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
             // skip all data
             while ((i = (unsigned char)stream.GetC()) != 0)
             {
-                if (stream.Eof() || (stream.LastRead() == 0))
+                if (stream.Eof() || (stream.LastRead() == 0) ||
+                    stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
                 {
                     Destroy();
                     return wxGIF_INVFORMAT;
                 }
-                stream.SeekI(i, wxFromCurrent);
             }
         }
         else if (type == 0x2C)
@@ -858,7 +879,11 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
             {
                 unsigned int local_ncolors = 2 << (buf[8] & 0x07);
                 wxFileOffset numBytes = 3 * local_ncolors;
-                stream.SeekI(numBytes, wxFromCurrent);
+                if (stream.SeekI(numBytes, wxFromCurrent) == wxInvalidOffset)
+                {
+                    Destroy();
+                    return wxGIF_INVFORMAT;
+                }
             }
 
             // initial code size
@@ -872,12 +897,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
             // skip all data
             while ((i = (unsigned char)stream.GetC()) != 0)
             {
-                if (stream.Eof() || (stream.LastRead() == 0))
+                if (stream.Eof() || (stream.LastRead() == 0) ||
+                    stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
                 {
                     Destroy();
                     return wxGIF_INVFORMAT;
                 }
-                stream.SeekI(i, wxFromCurrent);
             }
         }
         else if ((type != 0x3B) && (type != 00)) // testing