00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef FS_RAS_FSRLE8BLT_H
00015 #define FS_RAS_FSRLE8BLT_H
00016
00017 #if defined(FS_INCLUDE_USERDEFS) // inject user definition file on request
00018 # include <fs/fsUserDefs.h>
00019 #endif
00020
00021 #if defined(FS_HAS_FSASSERT)
00022 # include <fs/utils/fsAssert.h>
00023 #else
00024 # include <cassert>
00025 # if !defined(FS_ASSERT)
00026 # define FS_ASSERT(exp) assert(exp)
00027 # endif
00028 # if !defined(FS_ASSERT_MSG)
00029 # define FS_ASSERT_MSG(exp, msg) assert(exp)
00030 # endif
00031 # if !defined(FS_STATIC_ASSERT)
00032 # define FS_STATIC_ASSERT(exp) { char array[(exp) ? 1 : 0]; array; }
00033 # endif
00034 #endif
00035
00036 namespace fs { namespace ras {
00037
00039 namespace nsRle8Blt {
00040
00042 struct PxFmt8888_t { unsigned char r, g, b, a; };
00043 typedef unsigned int uint32;
00044
00046 struct Cl8888TrCpPcy_t
00047 {
00048 typedef PxFmt8888_t SrcPxFmt_t;
00049 typedef PxFmt8888_t DstPxFmt_t;
00050 static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00051 {
00052 FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 4);
00053 FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 4);
00054 Dst = Src;
00055 }
00056 };
00057
00059 struct Cl8888BlCpPcy_t
00060 {
00061 typedef PxFmt8888_t SrcPxFmt_t;
00062 typedef PxFmt8888_t DstPxFmt_t;
00063 static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00064 {
00065 FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 4);
00066 FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 4);
00067
00069 const float a = Src.a / 255.f;
00070 const float b = (255 - Src.a) / 255.f;
00071 Dst.r = static_cast<unsigned char>(a * Src.r + b * Dst.r);
00072 Dst.g = static_cast<unsigned char>(a * Src.g + b * Dst.g);
00073 Dst.b = static_cast<unsigned char>(a * Src.b + b * Dst.b);
00074 }
00075 };
00076
00077 }
00078
00080
00082 template <typename TCpPcy>
00083 void Rle8Blt(
00084 const unsigned char *pRle,
00085 const nsRle8Blt::PxFmt8888_t *pPal,
00086 const nsRle8Blt::uint32 *pOff,
00087 int nSrcW,
00088 int ,
00089 int nRegW,
00090 int nRegH,
00091 typename TCpPcy::DstPxFmt_t *pDst,
00092 int nDstW,
00093 int nDstH,
00094 int nDstPosX,
00095 int nDstPosY,
00096 int nDstClipX1 = 0,
00097 int nDstClipY1 = 0,
00098 int nDstClipX2 = -1,
00099 int nDstClipY2 = -1
00100 )
00101 {
00102 FS_ASSERT(pRle);
00103 FS_ASSERT(pPal);
00104 FS_ASSERT(pOff);
00105
00106 typedef typename TCpPcy::SrcPxFmt_t SrcPxFmt_t;
00107 typedef typename TCpPcy::DstPxFmt_t DstPxFmt_t;
00108
00109
00110
00111 const nsRle8Blt::uint32 *pDstOffCur = pOff;
00112 DstPxFmt_t *pDstLnCur = pDst + nDstPosY * nDstW + nDstPosX;
00113
00114
00115
00116 nDstClipX2 = nDstClipX2 != -1 ? nDstClipX2 : nDstW;
00117 nDstClipY2 = nDstClipY2 != -1 ? nDstClipY2 : nDstH;
00118
00119
00120 if(nDstPosX + nRegW > nDstClipX2)
00121 {
00122 nRegW = nDstClipX2 - nDstPosX;
00123 }
00124
00125
00126 if(nDstPosY + nRegH > nDstClipY2)
00127 {
00128 nRegH = nDstClipY2 - nDstPosY;
00129 }
00130
00131
00132 if(nDstPosX < nDstClipX1)
00133 {
00134 const int nLeftClip = nDstClipX1 - nDstPosX;
00135 nRegW -= nLeftClip;
00136 pDstLnCur += nLeftClip;
00137 }
00138
00139
00140 if(nDstPosY < nDstClipY1)
00141 {
00142 const int nTopClip = nDstClipY1 - nDstPosY;
00143 nRegH -= nTopClip;
00144 pDstLnCur += nTopClip * nDstW;
00145 pDstOffCur += nTopClip;
00146 }
00147
00148 if(nRegW <= 0 || nRegH <= 0)
00149 return;
00150
00151
00152
00153 for(int y = nRegH; y != 0; --y)
00154 {
00155 const unsigned char *pRleCur = pRle + *pDstOffCur;
00156 DstPxFmt_t *pDstCur = pDstLnCur;
00157
00158 int x = nDstPosX;
00159 unsigned char uN = (*pRleCur) >> 1; FS_ASSERT(uN > 0);
00160 bool bTr = ((*pRleCur) & 1) == 0;
00161
00162
00163
00164 if(nDstPosX < nDstClipX1)
00165 {
00166 for(;;)
00167 {
00168
00169 if(x + uN > nDstClipX1)
00170 {
00171
00172 pRleCur += bTr ? 0 : nDstClipX1 - x;
00173
00174 uN = static_cast<unsigned char>(x + uN - nDstClipX1);
00175
00176 x = nDstClipX1;
00177 break;
00178 }
00179
00180 else
00181 {
00182 x += uN;
00183 pRleCur += bTr ? 1 : uN + 1;
00184
00185 uN = (*pRleCur) >> 1;
00186 bTr = ((*pRleCur) & 1) == 0;
00187 }
00188 }
00189 }
00190
00191
00192
00193 const int nDataX = nDstPosX + nSrcW;
00194 const int nStopX = nDataX < nDstClipX2 ? nDataX : nDstClipX2;
00195
00196 while(x + uN < nStopX)
00197 {
00198 ++pRleCur;
00199
00200 if(bTr)
00201 {
00202 x += uN;
00203 pDstCur += uN;
00204 }
00205 else
00206 {
00207 for(int j = 0; j < uN; ++j)
00208 {
00209 TCpPcy::Copy(pPal[*pRleCur], *pDstCur);
00210
00211 ++x;
00212 ++pRleCur;
00213 ++pDstCur;
00214 }
00215 }
00216
00217 uN = (*pRleCur) >> 1;
00218 bTr = ((*pRleCur) & 1) == 0;
00219 }
00220
00221
00222
00223 if(x < nStopX && !bTr)
00224 {
00225 ++pRleCur;
00226
00227 for(;x < nStopX; ++x)
00228 {
00229 TCpPcy::Copy(pPal[*pRleCur], *pDstCur);
00230
00231 ++pRleCur;
00232 ++pDstCur;
00233 }
00234 }
00235
00236
00237
00238 ++pDstOffCur;
00239 pDstLnCur += nDstW;
00240 }
00241 }
00242
00243 }}
00244
00245 #endif // FS_RAS_FSRLE8BLT_H