]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/anidecod.cpp
Better place for coordinate mirroring and removal
[wxWidgets.git] / src / common / anidecod.cpp
index 61cfb664d5821a771ba655099f2721e7545dfd0a..7d502ae52a4ed898c83572ad25ed848422421725 100644 (file)
@@ -14,7 +14,9 @@
     #pragma hdrstop
 #endif
 
-#if wxUSE_STREAMS && wxUSE_GIF
+#if wxUSE_STREAMS && wxUSE_ICO_CUR
+
+#include "wx/anidecod.h"
 
 #ifndef WX_PRECOMP
     #include "wx/palette.h"
 
 #include <stdlib.h>
 #include <string.h>
-#include "wx/anidecod.h"
 
 // static
 wxCURHandler wxANIDecoder::sm_handler;
 
-
-
 //---------------------------------------------------------------------------
 // wxANIFrameInfo
 //---------------------------------------------------------------------------
@@ -36,20 +35,18 @@ wxCURHandler wxANIDecoder::sm_handler;
 class wxANIFrameInfo
 {
 public:
-    wxANIFrameInfo(size_t delay = 0, int idx = -1) 
+    wxANIFrameInfo(size_t delay = 0, int idx = -1)
         { m_delay=delay; m_imageIndex=idx; }
 
     size_t m_delay;
     int m_imageIndex;
 };
 
-#include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
-WX_DEFINE_OBJARRAY(wxImageArray);
-
-#include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
-WX_DEFINE_OBJARRAY(wxANIFrameInfoArray);
-
+#include "wx/arrimpl.cpp" // this is a magic incantation which must be done!
+WX_DEFINE_OBJARRAY(wxImageArray)
 
+#include "wx/arrimpl.cpp" // this is a magic incantation which must be done!
+WX_DEFINE_OBJARRAY(wxANIFrameInfoArray)
 
 
 //---------------------------------------------------------------------------
@@ -68,7 +65,7 @@ bool wxANIDecoder::ConvertToImage(size_t frame, wxImage *image) const
 {
     size_t idx = m_info[frame].m_imageIndex;
     *image = m_images[idx];       // copy
-    return image->Ok();
+    return image->IsOk();
 }
 
 
@@ -99,6 +96,18 @@ long wxANIDecoder::GetDelay(size_t frame) const
     return m_info[frame].m_delay;
 }
 
+wxColour wxANIDecoder::GetTransparentColour(size_t frame) const
+{
+    size_t idx = m_info[frame].m_imageIndex;
+
+    if (!m_images[idx].HasMask())
+        return wxNullColour;
+
+    return wxColour(m_images[idx].GetMaskRed(),
+                    m_images[idx].GetMaskGreen(),
+                    m_images[idx].GetMaskBlue());
+}
+
 
 //---------------------------------------------------------------------------
 // ANI reading and decoding
@@ -134,7 +143,7 @@ bool wxANIDecoder::CanRead(wxInputStream& stream) const
         // we always have a data size:
         stream.Read(&datalen, 4);
         datalen = wxINT32_SWAP_ON_BE(datalen) ;
-        
+
         // data should be padded to make even number of bytes
         if (datalen % 2 == 1) datalen ++ ;
 
@@ -160,7 +169,7 @@ bool wxANIDecoder::CanRead(wxInputStream& stream) const
 }
 
 // the "anih" RIFF chunk
-struct wxANIHeader 
+struct wxANIHeader
 {
     wxInt32 cbSizeOf;     // Num bytes in AniHeader (36 bytes)
     wxInt32 cFrames;      // Number of unique Icons in this cursor
@@ -171,6 +180,25 @@ struct wxANIHeader
     wxInt32 cPlanes;      // 1
     wxInt32 JifRate;      // Default Jiffies (1/60th of a second) if rate chunk not present.
     wxInt32 flags;        // Animation Flag (see AF_ constants)
+
+    // ANI files are always little endian so we need to swap bytes on big
+    // endian architectures
+#ifdef WORDS_BIGENDIAN
+    void AdjustEndianness()
+    {
+        // this works because all our fields are wxInt32 and they must be
+        // packed without holes between them (if they're not, they wouldn't map
+        // to the file header!)
+        wxInt32 * const start = (wxInt32 *)this;
+        wxInt32 * const end = start + sizeof(wxANIHeader)/sizeof(wxInt32);
+        for ( wxInt32 *p = start; p != end; p++ )
+        {
+            *p = wxINT32_SWAP_ALWAYS(*p);
+        }
+    }
+#else
+    void AdjustEndianness() { }
+#endif
 };
 
 bool wxANIDecoder::Load( wxInputStream& stream )
@@ -228,16 +256,17 @@ bool wxANIDecoder::Load( wxInputStream& stream )
 
             struct wxANIHeader header;
             stream.Read(&header, sizeof(wxANIHeader));
+            header.AdjustEndianness();
 
             // we should have a global frame size
             m_szAnimation = wxSize(header.cx, header.cy);
 
             // save interesting info from the header
             m_nFrames = header.cSteps;   // NB: not cFrames!!
-            if (m_nFrames==0)
+            if ( m_nFrames == 0 )
                 return false;
 
-            globaldelay = wxINT32_SWAP_ON_BE(header.JifRate) * 1000 / 60;
+            globaldelay = header.JifRate * 1000 / 60;
 
             m_images.Alloc(header.cFrames);
             m_info.Add(wxANIFrameInfo(), m_nFrames);
@@ -247,7 +276,7 @@ bool wxANIDecoder::Load( wxInputStream& stream )
             // did we already process the anih32 chunk?
             if (m_nFrames == 0)
                 return false;       // rate chunks should always be placed after anih chunk
-            
+
             wxASSERT(m_info.GetCount() == m_nFrames);
             for (size_t i=0; i<m_nFrames; i++)
             {
@@ -278,7 +307,9 @@ bool wxANIDecoder::Load( wxInputStream& stream )
             m_images.Add(image);
         }
         else
+        {
             stream.SeekI(stream.TellI() + datalen);
+        }
 
         // try to read next data chunk:
         stream.Read(&FCC1, 4);
@@ -308,7 +339,7 @@ bool wxANIDecoder::Load( wxInputStream& stream )
         m_szAnimation.GetHeight() == 0)
         m_szAnimation = wxSize(m_images[0].GetWidth(), m_images[0].GetHeight());
 
-    return m_szAnimation!=wxDefaultSize;
+    return m_szAnimation != wxDefaultSize;
 }
 
-#endif // wxUSE_STREAMS && wxUSE_GIF
+#endif // wxUSE_STREAMS && wxUSE_ICO_CUR