00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "BilinearScalerInternal.h"
00021 #include "Manips.h"
00022
00023 namespace Pentagram {
00024
00025 template<class uintX, class Manip, class uintS>
00026 bool BilinearScalerInternal_Arb(Texture *tex, sint32 sx, sint32 sy, sint32 sw, sint32 sh,
00027 uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src)
00028 {
00029
00030 uintS *texel = reinterpret_cast<uintS*>(tex->buffer) + (sy * tex->width + sx);
00031 int tpitch = tex->width;
00032 uintS *tline_end = texel + (sw-1);
00033 uintS *tex_end = texel + (sh-4)*tex->width;
00034 int tex_diff = (tex->width*4) - sw;
00035
00036 uint8 a[4], b[4], c[4], d[4], e[4], f[4], g[4], h[4], i[4], j[4];
00037
00038 uint32 pos_y=0, pos_x=0;
00039
00040 uint32 add_y = (sh<<16)/dh;
00041 uint32 add_x = (sw<<16)/dw;
00042
00043 uint32 start_x = (sw<<16) - (add_x * dw);
00044 uint32 dst_y = (sh<<16) - (add_y * dh);
00045 uint32 end_y = 1<<16;
00046
00047 if (sw == dw*2) start_x += 0x8000;
00048 if (sh == dh*2) dst_y += 0x8000;
00049
00050 uint8* blockline_start = 0;
00051 uint8* next_block = 0;
00052
00053
00054
00055 bool clip_x = true;
00056 if (sw+sx < tex->width && clamp_src == false)
00057 {
00058 clip_x = false;
00059 tline_end = texel + (sw+1);
00060 tex_diff--;
00061 }
00062
00063 bool clip_y = true;
00064 if (sh+sy < tex->height && clamp_src == false)
00065 {
00066 clip_y = false;
00067 tex_end = texel + (sh)*tex->width;
00068 }
00069
00070
00071 do {
00072 Read5(a,b,c,d,e);
00073 texel++;
00074
00075 uint32 end_x = 1<<16;
00076 uint32 dst_x = start_x;
00077
00078 next_block = pixel;
00079
00080
00081 do {
00082 pos_y = dst_y;
00083
00084 Read5(f,g,h,i,j);
00085 texel++;
00086
00087 blockline_start = next_block;
00088 next_block = 0;
00089
00090 ArbInnerLoop(a, b, f, g);
00091 ArbInnerLoop(b, c, g, h);
00092 ArbInnerLoop(c, d, h, i);
00093 ArbInnerLoop(d, e, i, j);
00094
00095 end_y -= 4<<16;
00096 dst_x = pos_x;
00097 end_x += 1<<16;
00098 pos_y = dst_y;
00099
00100 Read5(a,b,c,d,e);
00101 texel++;
00102
00103 blockline_start = next_block;
00104 next_block = 0;
00105
00106 ArbInnerLoop(f,g,a,b);
00107 ArbInnerLoop(g,h,b,c);
00108 ArbInnerLoop(h,i,c,d);
00109 ArbInnerLoop(i,j,d,e);
00110
00111 end_y -= 4<<16;
00112 dst_x = pos_x;
00113 end_x += 1<<16;
00114 } while (texel != tline_end);
00115
00116
00117 if (clip_x) {
00118 pos_y = dst_y;
00119
00120 Read5(f,g,h,i,j);
00121 texel++;
00122
00123 blockline_start = next_block;
00124 next_block = 0;
00125
00126 ArbInnerLoop(a, b, f, g);
00127 ArbInnerLoop(b, c, g, h);
00128 ArbInnerLoop(c, d, h, i);
00129 ArbInnerLoop(d, e, i, j);
00130
00131 end_y -= 4<<16;
00132 dst_x = pos_x;
00133 end_x += 1<<16;
00134 pos_y = dst_y;
00135
00136 blockline_start = next_block;
00137 next_block = 0;
00138
00139 ArbInnerLoop(f,g,f,g);
00140 ArbInnerLoop(g,h,g,h);
00141 ArbInnerLoop(h,i,h,i);
00142 ArbInnerLoop(i,j,i,j);
00143
00144 end_y -= 4<<16;
00145 dst_x = pos_x;
00146 end_x += 1<<16;
00147 };
00148
00149 pixel += pitch - sizeof(uintX)*(dw);
00150
00151 dst_y = pos_y;
00152 end_y += 4<<16;
00153
00154 texel += tex_diff;
00155 tline_end += tpitch*4;
00156 } while (texel != tex_end);
00157
00158
00159
00160
00161
00162
00163
00164 if (clip_y) {
00165 Read5_Clipped(a,b,c,d,e);
00166 texel++;
00167
00168 uint32 end_x = 1<<16;
00169 uint32 dst_x = start_x;
00170
00171 next_block = pixel;
00172
00173
00174 do {
00175 pos_y = dst_y;
00176
00177 Read5_Clipped(f,g,h,i,j);
00178 texel++;
00179
00180 blockline_start = next_block;
00181 next_block = 0;
00182
00183 ArbInnerLoop(a, b, f, g);
00184 ArbInnerLoop(b, c, g, h);
00185 ArbInnerLoop(c, d, h, i);
00186 ArbInnerLoop(d, e, i, j);
00187
00188 end_y -= 4<<16;
00189 dst_x = pos_x;
00190 end_x += 1<<16;
00191 pos_y = dst_y;
00192
00193 Read5_Clipped(a,b,c,d,e);
00194 texel++;
00195
00196 blockline_start = next_block;
00197 next_block = 0;
00198
00199 ArbInnerLoop(f,g,a,b);
00200 ArbInnerLoop(g,h,b,c);
00201 ArbInnerLoop(h,i,c,d);
00202 ArbInnerLoop(i,j,d,e);
00203
00204 end_y -= 4<<16;
00205 dst_x = pos_x;
00206 end_x += 1<<16;
00207 } while (texel != tline_end);
00208
00209
00210 if (clip_x) {
00211 pos_y = dst_y;
00212
00213 Read5_Clipped(f,g,h,i,j);
00214 texel++;
00215
00216 blockline_start = next_block;
00217 next_block = 0;
00218
00219 ArbInnerLoop(a, b, f, g);
00220 ArbInnerLoop(b, c, g, h);
00221 ArbInnerLoop(c, d, h, i);
00222 ArbInnerLoop(d, e, i, j);
00223
00224 end_y -= 4<<16;
00225 dst_x = pos_x;
00226 end_x += 1<<16;
00227 pos_y = dst_y;
00228
00229 blockline_start = next_block;
00230 next_block = 0;
00231
00232 ArbInnerLoop(f,g,f,g);
00233 ArbInnerLoop(g,h,g,h);
00234 ArbInnerLoop(h,i,h,i);
00235 ArbInnerLoop(i,j,i,j);
00236
00237 end_y -= 4<<16;
00238 dst_x = pos_x;
00239 end_x += 1<<16;
00240 };
00241 }
00242
00243
00244 return true;
00245 }
00246
00247 InstantiateBilinearScalerFunc(BilinearScalerInternal_Arb);
00248
00249 };
00250