fs/ras/fsRle8Enc.cpp

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*     [fsRle8Enc]        / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev. 6          / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    6th Feb 2007      /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [x] stable              /_/ (c) 2006-7 Filip STOKLAS (FipS)         */
00008 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~       http://HOLE.4FipS.com/fips_code.php          */
00009 /*                                                                         */
00010 /* This code is free for personal and commercial use. You may redistribute */
00011 /* it by any means. If you use the code for your own projects please give  */
00012 /* me credit. Please send a bug report. Don't alter or remove this header! */
00013 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00014 #include <fs/ras/fsRle8Enc.h>
00015 
00016 // >>> COMMON SUPPORT BLOCK (rev. 6)
00017 #if defined(FS_HAS_FSASSERT)
00018 #   include <fs/sys/fsAssert.h>
00019 #else
00020 #   include <cassert>
00021 #   if !defined(FS_ASSERT)
00022 #       define FS_ASSERT(exp) assert(exp)
00023 #   endif
00024 #   if !defined(FS_ASSERT_MSG)
00025 #       define FS_ASSERT_MSG(exp, msg) assert(exp && msg)
00026 #   endif
00027 #   if !defined(FS_VERIFY)
00028 #       define FS_VERIFY(exp) \
00029         { bool bExp = !!(exp); assert(bExp && #exp); bExp; }
00030 #   endif
00031 #   if !defined(FS_VERIFY_MSG)
00032 #       define FS_VERIFY_MSG(exp, msg) \
00033         { bool bExp = !!(exp); assert(bExp && #exp && msg); bExp; }
00034 #   endif
00035 #   if !defined(FS_STATIC_ASSERT)
00036 #       define FS_STATIC_ASSERT(exp) { char error[(exp) ? 1 : 0]; error; }
00037 #   endif
00038 #endif
00039 #if !defined(FS_VERIFY_RETURN)
00040 #   define FS_VERIFY_RETURN(exp) \
00041     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<return>"); return; }
00042 #endif
00043 #if !defined(FS_VERIFY_RETURN_VAL)
00044 #   define FS_VERIFY_RETURN_VAL(exp, ret) \
00045     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<returns:>" #ret); return (ret); }
00046 #endif
00047 // <<< COMMON SUPPORT BLOCK (rev. 6)
00048 
00049 #include <vector>
00050 #include <algorithm>
00051 
00052 // provide detailed memory tracking information
00053 #if defined(FS_HAS_FSMEMMGR)
00054 #   include <fs/sys/fsMemMgr.h>
00055 #endif
00056 //---------------------------------------------------------------------------
00057 using namespace fs::ras;
00058 //---------------------------------------------------------------------------
00059 //--- ANONYMOUS NAMESPACE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00060 //---------------------------------------------------------------------------
00061 namespace {
00062 //---------------------------------------------------------------------------
00063 //--- CLASS Rle8EncImpl_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00064 //---------------------------------------------------------------------------
00065 class Rle8EncImpl_t
00066 {
00067 public:
00068     
00069     Rle8EncImpl_t(const Rle8Enc_t::PxFmt8888_t *pSrc, int nW, int nH);
00070     
00071     bool IsValid() const;
00072     
00073     bool GetSize(int &nW, int &nH) const;
00074     bool GetRle(const unsigned char *&pRle, int &nNum) const;
00075     bool GetPal(const Rle8Enc_t::PxFmt8888_t *&pPal, int &nNum) const;
00076     bool GetOff(const Rle8Enc_t::uint32 *&pOff, int &nNum)
00077      const;
00078 
00079 private:
00080     
00081     Rle8EncImpl_t();
00082     Rle8EncImpl_t(const Rle8EncImpl_t &);
00083     Rle8EncImpl_t & operator = (const Rle8EncImpl_t &);
00084     
00085     void Shrink();
00086     
00087     unsigned char GetClrIdx(const Rle8Enc_t::PxFmt8888_t &Clr) const;
00088     const Rle8Enc_t::PxFmt8888_t & GetClr(int nIdx) const;
00089     
00090     //---
00091     
00092     int m_nW, m_nH;
00093     
00094     typedef std::vector<unsigned char> TRle;
00095     TRle m_Rle;
00096     
00097     typedef std::vector<Rle8Enc_t::PxFmt8888_t> TPal;
00098     mutable TPal m_Pal;
00099             
00100     typedef std::vector<Rle8Enc_t::uint32> TOff;
00101     TOff m_Off;
00102 };
00103 //---------------------------------------------------------------------------
00104 Rle8EncImpl_t::Rle8EncImpl_t(const Rle8Enc_t::PxFmt8888_t *pSrc, int nW,
00105  int nH):
00106 m_nW(nW),
00107 m_nH(nH)
00108 {
00109     FS_VERIFY_RETURN(pSrc);
00110                 
00111     for(int y = 0; y < nH; ++y)
00112     {
00113         m_Off.push_back(static_cast<Rle8Enc_t::uint32>(m_Rle.size()));
00114     
00115         unsigned char uN = 1;
00116         for(int x = 0; x < nW; ++x)
00117         {
00118             bool bTr = pSrc->a == 0; // current
00119             bool bTrNx = x < nW - 1 ? (pSrc + 1)->a == 0 : !bTr; // next
00120             
00121             // end of coherent pixel sequence or the right edge
00122             if(bTr != bTrNx || uN >= 127)
00123             {
00124                 // write number of pixels + transparency flag
00125                 m_Rle.push_back(uN << 1 | (bTr ? 0 : 1));
00126                 
00127                 // write opaque pixel sequence
00128                 if(!bTr)
00129                 {
00130                     const Rle8Enc_t::PxFmt8888_t *pSrcB = pSrc - uN + 1;
00131                     while(pSrcB <= pSrc)
00132                     {
00133                         unsigned char uClrIdx = GetClrIdx(*pSrcB);
00134                         m_Rle.push_back(uClrIdx);
00135                         ++pSrcB;
00136                     }
00137                 }
00138                 
00139                 uN = 0;
00140             }
00141 
00142             // go to the next pixel
00143             ++uN;
00144             ++pSrc;
00145         }
00146     }
00147     
00148     Shrink();
00149 }
00150 //---------------------------------------------------------------------------
00151 bool Rle8EncImpl_t::IsValid() const
00152 {
00153     return !m_Rle.empty();
00154 }
00155 //---------------------------------------------------------------------------
00156 bool Rle8EncImpl_t::GetSize(int &nW, int &nH) const
00157 {
00158     FS_VERIFY_RETURN_VAL(IsValid(), false);
00159 
00160     nW = m_nW;
00161     nH = m_nH;
00162     
00163     return true;
00164 }
00165 //---------------------------------------------------------------------------
00166 bool Rle8EncImpl_t::GetRle(const unsigned char *&pRle, int &nNum)
00167  const
00168 {
00169     FS_VERIFY_RETURN_VAL(IsValid(), false);
00170 
00171     nNum = static_cast<int>(m_Rle.size());
00172     pRle = nNum ? &m_Rle[0] : 0;
00173         
00174     return true;
00175 }
00176 //---------------------------------------------------------------------------
00177 bool Rle8EncImpl_t::GetPal(const Rle8Enc_t::PxFmt8888_t *&pPal, int &nNum)
00178  const
00179 {
00180     FS_VERIFY_RETURN_VAL(IsValid(), false);
00181 
00182     nNum = static_cast<int>(m_Pal.size());
00183     pPal = nNum ? &m_Pal[0] : 0;
00184     
00185     return true;
00186 }
00187 //---------------------------------------------------------------------------
00188 bool Rle8EncImpl_t::GetOff(const Rle8Enc_t::uint32 *&pOff, int &nNum)
00189  const
00190 {
00191     FS_VERIFY_RETURN_VAL(IsValid(), false);
00192     FS_STATIC_ASSERT(sizeof(Rle8Enc_t::uint32) == 4);
00193     
00194     nNum = static_cast<Rle8Enc_t::uint32>(m_Off.size());
00195     pOff = nNum ? &m_Off[0] : 0;
00196         
00197     return true;
00198 }
00199 //---------------------------------------------------------------------------
00200 void Rle8EncImpl_t::Shrink()
00201 {
00202     TRle(m_Rle).swap(m_Rle);
00203     TPal(m_Pal).swap(m_Pal);
00204     TOff(m_Off).swap(m_Off);
00205 }
00206 //---------------------------------------------------------------------------
00208 unsigned char Rle8EncImpl_t::GetClrIdx(const Rle8Enc_t::PxFmt8888_t &Clr) const
00209 {
00210     TPal::const_iterator it = std::find(m_Pal.begin(), m_Pal.end(), Clr);
00211     
00212     if(it == m_Pal.end())
00213     {
00214         m_Pal.push_back(Clr);
00215         return static_cast<unsigned char>(m_Pal.size() - 1);
00216     }
00217     else
00218         return static_cast<unsigned char>(it - m_Pal.begin());
00219 }
00220 //---------------------------------------------------------------------------
00221 const Rle8Enc_t::PxFmt8888_t & Rle8EncImpl_t::GetClr(int nIdx) const
00222 {
00223     FS_ASSERT(nIdx >= 0 && nIdx < static_cast<int>(m_Pal.size()));
00224     return m_Pal[nIdx];
00225 }
00226 //---------------------------------------------------------------------------
00227 } // anonymous namespace
00228 //---------------------------------------------------------------------------
00229 //--- CLASS Rle8Enc_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00230 //---------------------------------------------------------------------------
00231 Rle8Enc_t::Rle8Enc_t(const PxFmt8888_t *pSrc, int nW, int nH):
00232 m_pImpl(new Rle8EncImpl_t(pSrc, nW, nH))
00233 {
00234     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00235 }
00236 //---------------------------------------------------------------------------
00237 Rle8Enc_t::~Rle8Enc_t()
00238 {
00239     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00240     delete static_cast<Rle8EncImpl_t *>(m_pImpl);
00241 }
00242 //---------------------------------------------------------------------------
00243 bool Rle8Enc_t::IsValid() const
00244 {
00245     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00246     return static_cast<Rle8EncImpl_t *>(m_pImpl)->IsValid();
00247 }
00248 //---------------------------------------------------------------------------
00249 bool Rle8Enc_t::GetSize(int &nW, int &nH) const
00250 {
00251     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00252     return static_cast<Rle8EncImpl_t *>(m_pImpl)->GetSize(nW, nH);
00253 }
00254 //---------------------------------------------------------------------------
00255 bool Rle8Enc_t::GetRle(const unsigned char *&pRle, int &nNum) const
00256 {
00257     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00258     return static_cast<Rle8EncImpl_t *>(m_pImpl)->GetRle(pRle, nNum);
00259 }
00260 //---------------------------------------------------------------------------
00261 bool Rle8Enc_t::GetPal(const PxFmt8888_t *&pPal, int &nNum)
00262  const
00263 {
00264     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00265     return static_cast<Rle8EncImpl_t *>(m_pImpl)->GetPal(pPal, nNum);
00266 }
00267 //---------------------------------------------------------------------------
00268 bool Rle8Enc_t::GetOff(const uint32 *&pOff, int &nNum) const
00269 {
00270     FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00271     return static_cast<Rle8EncImpl_t *>(m_pImpl)->GetOff(pOff, nNum);
00272 }
00273 //---------------------------------------------------------------------------

FipS' Code (Thu Feb 15 22:43:35 2007) - (c) Filip STOKLAS (FipS) - [ www ] [ Guest Book ]