00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <fs/ras/fsRle8Enc.h>
00015
00016
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
00048
00049 #include <vector>
00050 #include <algorithm>
00051
00052
00053 #if defined(FS_HAS_FSMEMMGR)
00054 # include <fs/sys/fsMemMgr.h>
00055 #endif
00056
00057 using namespace fs::ras;
00058
00059
00060
00061 namespace {
00062
00063
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;
00119 bool bTrNx = x < nW - 1 ? (pSrc + 1)->a == 0 : !bTr;
00120
00121
00122 if(bTr != bTrNx || uN >= 127)
00123 {
00124
00125 m_Rle.push_back(uN << 1 | (bTr ? 0 : 1));
00126
00127
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
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 }
00228
00229
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