fs/ras/fsRle8Blt.h

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*     [fsRle8Blt]        / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev. 3          / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    6th Feb 2007      /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [ ] 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 #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 } // namespace nsRle8Blt
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 /*nSrcH*/,
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, // -1 stands for nDstW
00099  int nDstClipY2 = -1  // -1 stands for nDstH
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     //--- PREPARE BUFFERS ---
00110     
00111     const nsRle8Blt::uint32 *pDstOffCur = pOff;
00112     DstPxFmt_t *pDstLnCur = pDst + nDstPosY * nDstW + nDstPosX;
00113         
00114     //--- APPLY CLIPPING ---
00115     
00116     nDstClipX2 = nDstClipX2 != -1 ? nDstClipX2 : nDstW;
00117     nDstClipY2 = nDstClipY2 != -1 ? nDstClipY2 : nDstH;
00118 
00119     // right
00120     if(nDstPosX + nRegW > nDstClipX2)
00121     {
00122         nRegW = nDstClipX2 - nDstPosX;
00123     }
00124 
00125     // bottom
00126     if(nDstPosY + nRegH > nDstClipY2)
00127     {
00128         nRegH = nDstClipY2 - nDstPosY;
00129     }    
00130 
00131     // left
00132     if(nDstPosX < nDstClipX1)
00133     {
00134         const int nLeftClip = nDstClipX1 - nDstPosX;
00135         nRegW -= nLeftClip;
00136         pDstLnCur += nLeftClip;
00137     }
00138 
00139     // top
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; // out of the clipping region
00150     
00151     //--- TRANSFER DATA ---
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; // cur pos in dst space
00159         unsigned char uN = (*pRleCur) >> 1; FS_ASSERT(uN > 0);
00160         bool bTr = ((*pRleCur) & 1) == 0;
00161         
00162         //--- LEFT CLIP ---
00163 
00164         if(nDstPosX < nDstClipX1)
00165         {
00166             for(;;)
00167             {
00168                 // the segment intersects the left bound, cut it
00169                 if(x + uN > nDstClipX1)
00170                 {
00171                     // skip the left part
00172                     pRleCur += bTr ? 0 : nDstClipX1 - x;
00173                 
00174                     uN = static_cast<unsigned char>(x + uN - nDstClipX1);
00175                     
00176                     x = nDstClipX1;
00177                     break;
00178                 }
00179                 // skip the whole segment
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         //--- BODY ---
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) // skip the transparent segment
00201             {
00202                 x += uN;
00203                 pDstCur += uN;
00204             }
00205             else // copy the segment
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         //--- COMPLETE RIGHT CLIP ----
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 }} // namespace fs::ras
00244 //---------------------------------------------------------------------------
00245 #endif // FS_RAS_FSRLE8BLT_H

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