BilinearScalerInternal.h

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2005 The Pentagram Team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include "BilinearScaler.h"
00020 #include "Manips.h"
00021 
00022 
00023 namespace Pentagram {
00024 
00025 #define SimpleLerp(a,b,fac) ((b<<8)+((a)-(b))*(fac))
00026 #define SimpleLerp2(a,b,fac) ((b<<16)+((a)-(b))*(fac))
00027 
00028 #define CopyLerp(d,a,b,f) { \
00029                         (d)[0] = SimpleLerp2(b[0],a[0],f)>>16;\
00030                         (d)[1] = SimpleLerp2(b[1],a[1],f)>>16;\
00031                         (d)[2] = SimpleLerp2(b[2],a[2],f)>>16;\
00032                         (d)[3] = SimpleLerp2(b[3],a[3],f)>>16;}
00033 
00034 #define FilterPixel(a,b,f,g,fx,fy) { \
00035                 *reinterpret_cast<uintX*>(pixel) = Manip::merge( \
00036                         SimpleLerp(SimpleLerp(a[0],f[0],fx),SimpleLerp(b[0],g[0],fx),fy)>>16,\
00037                         SimpleLerp(SimpleLerp(a[1],f[1],fx),SimpleLerp(b[1],g[1],fx),fy)>>16,\
00038                         SimpleLerp(SimpleLerp(a[2],f[2],fx),SimpleLerp(b[2],g[2],fx),fy)>>16,\
00039                         SimpleLerp(SimpleLerp(a[3],f[3],fx),SimpleLerp(b[3],g[3],fx),fy)>>16);}
00040 
00041 #define ScalePixel2x(a,b,f,g) { \
00042                 *(reinterpret_cast<uintX*>(pixel)) = Manip::merge(a[0], a[1], a[2], a[3]); \
00043                 *(reinterpret_cast<uintX*>(pixel+sizeof(uintX))) = Manip::merge((a[0]+f[0])>>1, (a[1]+f[1])>>1, (a[2]+f[2])>>1, (a[3]+f[3])>>1); \
00044                 pixel+=pitch; \
00045                 *(reinterpret_cast<uintX*>(pixel)) = Manip::merge((a[0]+b[0])>>1, (a[1]+b[1])>>1, (a[2]+b[2])>>1, (a[3]+b[3])>>1);\
00046                 *(reinterpret_cast<uintX*>(pixel+sizeof(uintX))) = Manip::merge((a[0]+b[0]+f[0]+g[0])>>2, (a[1]+b[1]+f[1]+g[1])>>2, (a[2]+b[2]+f[2]+g[2])>>2, (a[3]+b[3]+f[3]+g[3])>>2);\
00047                 pixel+=pitch; } \
00048 
00049 #define X2Xy24xLerps(c0,c1,y)   \
00050                         *(reinterpret_cast<uintX*>(pixel)) = Manip::merge(                                              \
00051                                 cols[c0][y][0], cols[c0][y][1], cols[c0][y][2], cols[c0][y][3]);        \
00052                         *(reinterpret_cast<uintX*>(pixel+sizeof(uintX))) = Manip::merge(                \
00053                                 (cols[c0][y][0]+cols[c1][y][0])>>1,                                                             \
00054                                 (cols[c0][y][1]+cols[c1][y][1])>>1,                                                             \
00055                                 (cols[c0][y][2]+cols[c1][y][2])>>1,                                                             \
00056                                 (cols[c0][y][3]+cols[c1][y][3])>>1);
00057 
00058 #define X2xY24xInnerLoop(c0,c1) {                       \
00059         X2Xy24xLerps(c0,c1,0); pixel+=pitch;    \
00060         X2Xy24xLerps(c0,c1,1); pixel+=pitch;    \
00061         X2Xy24xLerps(c0,c1,2); pixel+=pitch;    \
00062         X2Xy24xLerps(c0,c1,3); pixel+=pitch;    \
00063         X2Xy24xLerps(c0,c1,4); pixel+=pitch;    \
00064         X2Xy24xLerps(c0,c1,5); pixel+=pitch;    \
00065         X2Xy24xLerps(c0,c1,6); pixel+=pitch;    \
00066         X2Xy24xLerps(c0,c1,7); pixel+=pitch;    \
00067         X2Xy24xLerps(c0,c1,8); pixel+=pitch;    \
00068         X2Xy24xLerps(c0,c1,9); pixel+=pitch;    \
00069         X2Xy24xLerps(c0,c1,10); pixel+=pitch;   \
00070         X2Xy24xLerps(c0,c1,11); pixel+=pitch;   }
00071 
00072 #define X2xY24xDoColsA() {      \
00073         CopyLerp(cols[0][0],a,b, 0x0000);       \
00074         CopyLerp(cols[0][1],a,b, 0x6AAA);       \
00075         CopyLerp(cols[0][2],a,b, 0xD554);       \
00076         CopyLerp(cols[0][3],b,c, 0x3FFE);       \
00077         CopyLerp(cols[0][4],b,c, 0xAAA8);       \
00078         CopyLerp(cols[0][5],c,d, 0x1552);       \
00079         CopyLerp(cols[0][6],c,d, 0x7FFC);       \
00080         CopyLerp(cols[0][7],c,d, 0xEAA6);       \
00081         CopyLerp(cols[0][8],d,e, 0x5550);       \
00082         CopyLerp(cols[0][9],d,e, 0xBFFA);       \
00083         CopyLerp(cols[0][10],e,l, 0x2AA4);      \
00084         CopyLerp(cols[0][11],e,l, 0x954E);      }
00085 
00086 #define X2xY24xDoColsB() {      \
00087         CopyLerp(cols[1][0],f,g, 0x0000);       \
00088         CopyLerp(cols[1][1],f,g, 0x6AAA);       \
00089         CopyLerp(cols[1][2],f,g, 0xD554);       \
00090         CopyLerp(cols[1][3],g,h, 0x3FFE);       \
00091         CopyLerp(cols[1][4],g,h, 0xAAA8);       \
00092         CopyLerp(cols[1][5],h,i, 0x1552);       \
00093         CopyLerp(cols[1][6],h,i, 0x7FFC);       \
00094         CopyLerp(cols[1][7],h,i, 0xEAA6);       \
00095         CopyLerp(cols[1][8],i,j, 0x5550);       \
00096         CopyLerp(cols[1][9],i,j, 0xBFFA);       \
00097         CopyLerp(cols[1][10],j,k, 0x2AA4);      \
00098         CopyLerp(cols[1][11],j,k, 0x954E); }
00099 
00100 #define X1xY12xCopy(y)  \
00101                         *(reinterpret_cast<uintX*>(pixel)) = Manip::merge(                                              \
00102                                 cols[y][0], cols[y][1], cols[y][2], cols[y][3]);
00103 
00104 #define X1xY12xInnerLoop() {            \
00105         X1xY12xCopy(0); pixel+=pitch;   \
00106         X1xY12xCopy(1); pixel+=pitch;   \
00107         X1xY12xCopy(2); pixel+=pitch;   \
00108         X1xY12xCopy(3); pixel+=pitch;   \
00109         X1xY12xCopy(4); pixel+=pitch;   \
00110         X1xY12xCopy(5); pixel+=pitch;   }
00111 
00112 #define X1xY12xDoCols() {       \
00113         CopyLerp(cols[0],a,b, 0x0000);  \
00114         CopyLerp(cols[1],a,b, 0xD554);  \
00115         CopyLerp(cols[2],b,c, 0xAAA8);  \
00116         CopyLerp(cols[3],c,d, 0x7FFC);  \
00117         CopyLerp(cols[4],d,e, 0x5550);  \
00118         CopyLerp(cols[5],e,l, 0x2AA4);  }
00119 
00120 #define ArbInnerLoop(a,b,f,g) {         \
00121         if (pos_y < end_y) do {                 \
00122                 pos_x = dst_x;                          \
00123                 pixel = blockline_start;        \
00124                 /* Dest Loop X */                       \
00125                 if (pos_x < end_x) do {         \
00126                         FilterPixel(a,b,f,g,(end_x-pos_x)>>8,(end_y-pos_y)>>8);\
00127                         pixel+=sizeof(uintX);   \
00128                         pos_x += add_x;                 \
00129                 } while (pos_x < end_x);        \
00130                 if (!next_block) next_block = pixel;    \
00131                 blockline_start += pitch;       \
00132                 pos_y += add_y;                         \
00133         } while (pos_y < end_y);                \
00134         end_y += 1 << 16; }
00135 
00136 
00137 #define Read5(a,b,c,d,e) {      \
00138         Manip::split(*(texel+tpitch*0), a[0], a[1], a[2], a[3]);\
00139         Manip::split(*(texel+tpitch*1), b[0], b[1], b[2], b[3]);\
00140         Manip::split(*(texel+tpitch*2), c[0], c[1], c[2], c[3]);\
00141         Manip::split(*(texel+tpitch*3), d[0], d[1], d[2], d[3]);\
00142         Manip::split(*(texel+tpitch*4), e[0], e[1], e[2], e[3]); }
00143 
00144 #define Read5_Clipped(a,b,c,d,e) {      \
00145         Manip::split(*(texel+tpitch*0), a[0], a[1], a[2], a[3]);\
00146         Manip::split(*(texel+tpitch*1), b[0], b[1], b[2], b[3]);\
00147         Manip::split(*(texel+tpitch*2), c[0], c[1], c[2], c[3]);\
00148         Manip::split(*(texel+tpitch*3), d[0], d[1], d[2], d[3]);\
00149         e[0]=d[0]; e[1]=d[1], e[2]=d[2], e[3]=d[3]; }
00150 
00151 #define Read6(a,b,c,d,e,l) {    \
00152         Manip::split(*(texel+tpitch*0), a[0], a[1], a[2], a[3]);\
00153         Manip::split(*(texel+tpitch*1), b[0], b[1], b[2], b[3]);\
00154         Manip::split(*(texel+tpitch*2), c[0], c[1], c[2], c[3]);\
00155         Manip::split(*(texel+tpitch*3), d[0], d[1], d[2], d[3]);\
00156         Manip::split(*(texel+tpitch*4), e[0], e[1], e[2], e[3]);\
00157         Manip::split(*(texel+tpitch*5), l[0], l[1], l[2], l[3]); }
00158 
00159 #define Read6_Clipped(a,b,c,d,e,l) {    \
00160         Manip::split(*(texel+tpitch*0), a[0], a[1], a[2], a[3]);\
00161         Manip::split(*(texel+tpitch*1), b[0], b[1], b[2], b[3]);\
00162         Manip::split(*(texel+tpitch*2), c[0], c[1], c[2], c[3]);\
00163         Manip::split(*(texel+tpitch*3), d[0], d[1], d[2], d[3]);\
00164         Manip::split(*(texel+tpitch*4), e[0], e[1], e[2], e[3]);\
00165         l[0]=e[0]; l[1]=e[1]; l[2]=e[2]; l[3]=e[3]; }
00166 
00167 // Very very simple point scaler
00168 template<class uintX, class Manip, class uintS> 
00169 bool BilinearScalerInternal_2x(Texture *tex, sint32 sx, sint32 sy, sint32 sw, sint32 sh, 
00170                                         uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src);
00171 
00172 template<class uintX, class Manip, class uintS> 
00173 bool BilinearScalerInternal_X2Y24(Texture *tex, sint32 sx, sint32 sy, sint32 sw, sint32 sh, 
00174                                         uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src);
00175 
00176 template<class uintX, class Manip, class uintS> 
00177 bool BilinearScalerInternal_X1Y12(Texture *tex, sint32 sx, sint32 sy, sint32 sw, sint32 sh, 
00178                                         uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src);
00179 
00180 template<class uintX, class Manip, class uintS> 
00181 bool BilinearScalerInternal_Arb(Texture *tex, sint32 sx, sint32 sy, sint32 sw, sint32 sh, 
00182                                         uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src);
00183 
00184 #ifdef COMPILE_GAMMA_CORRECT_SCALERS
00185 #define InstantiateFunc(func,a,b,c) \
00186         template bool func<a,b,c> (Texture*,sint32,sint32,sint32,sint32,uint8*,sint32,sint32,sint32,bool); \
00187         template bool func<a,b##_GC,c> (Texture*,sint32,sint32,sint32,sint32,uint8*,sint32,sint32,sint32,bool)
00188 #else
00189 #define InstantiateFunc(func,a,b,c) \
00190         template bool func<a,b,c> (Texture*,sint32,sint32,sint32,sint32,uint8*,sint32,sint32,sint32,bool)
00191 #endif
00192 
00193 #ifdef COMPILE_ALL_BILINEAR_SCALERS
00194 #define InstantiateBilinearScalerFunc(func) \
00195         InstantiateFunc(func,uint16,Manip_Nat2Nat_16,uint16); \
00196         InstantiateFunc(func,uint16,Manip_Sta2Nat_16,uint32); \
00197         InstantiateFunc(func,uint32,Manip_Nat2Nat_32,uint32); \
00198         InstantiateFunc(func,uint32,Manip_Sta2Nat_32,uint32); \
00199         InstantiateFunc(func,uint32,Manip_32_A888,uint32); \
00200         InstantiateFunc(func,uint32,Manip_32_888A,uint32)
00201 #else
00202 #define InstantiateBilinearScalerFunc(func) \
00203         InstantiateFunc(func,uint32,Manip_Nat2Nat_32,uint32); \
00204         InstantiateFunc(func,uint32,Manip_Sta2Nat_32,uint32)
00205 #endif
00206 };

Generated on Fri Jul 27 22:27:10 2007 for pentagram by  doxygen 1.4.7