00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 \
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
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 };