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 "PointScaler.h"
00021 #include "Manips.h"
00022
00023 namespace Pentagram {
00024
00025
00026 template<class uintX, class Manip, class uintS=uintX> class PointScalerInternal
00027 {
00028 public:
00029 static bool Scale( Texture *tex , sint32 sx, sint32 sy, sint32 sw, sint32 sh,
00030 uint8* pixel, sint32 dw, sint32 dh, sint32 pitch, bool clamp_src)
00031 {
00032
00033 uintS *texel = reinterpret_cast<uintS*>(tex->buffer) + (sy * tex->width + sx);
00034 int tpitch = tex->width;
00035 uintS *tline_end = texel + sw;
00036 uintS *tex_end = texel + sh*tex->width;
00037 int tex_diff = tex->width - sw;
00038
00039
00040
00041 bool x_intscale = ((dw / sw) * sw) == dw;
00042 bool y_intscale = ((dh / sh) * sh) == dh;
00043
00044
00045
00046
00047 if ((sw*2 == dw) && (sh*2 == dh))
00048 {
00049 uint8 *pixel2 = pixel+pitch;
00050 int p_diff = (pitch*2)-(dw*sizeof(uintX));
00051
00052
00053 do {
00054
00055 do {
00056 uintX p = Manip::copy(*texel);
00057
00058 *(reinterpret_cast<uintX*>(pixel+0)) = p;
00059 *(reinterpret_cast<uintX*>(pixel+sizeof(uintX))) = p;
00060 *(reinterpret_cast<uintX*>(pixel2+0)) = p;
00061 *(reinterpret_cast<uintX*>(pixel2+sizeof(uintX))) = p;
00062 pixel += sizeof(uintX)*2;
00063 pixel2 += sizeof(uintX)*2;
00064 texel++;
00065 } while (texel != tline_end);
00066
00067 pixel += p_diff;
00068 pixel2 += p_diff;
00069
00070 texel += tex_diff;
00071 tline_end += tpitch;
00072 } while (texel != tex_end);
00073
00074 }
00075
00076
00077
00078 else if (x_intscale && y_intscale)
00079 {
00080 int xf = dw/sw;
00081 int yf = dh/sh;
00082
00083 uint8 *px_end = pixel + xf*sizeof(uintX);
00084 uint8 *py_end = pixel + yf*pitch;
00085
00086 int block_w = xf*sizeof(uintX);
00087 int block_h = pitch*yf;
00088 int block_xdiff = pitch - block_w;
00089 int p_diff = block_h - dw*sizeof(uintX);
00090
00091
00092 do {
00093
00094 do {
00095 uintX p = Manip::copy(*texel);
00096
00097
00098
00099
00100
00101
00102 do {
00103
00104 do {
00105 *(reinterpret_cast<uintX*>(pixel)) = p;
00106 pixel+=sizeof(uintX);
00107 } while (pixel != px_end);
00108
00109 pixel+=block_xdiff;
00110 px_end+=pitch;
00111 } while (pixel != py_end);
00112
00113 pixel += block_w-block_h;
00114 px_end += block_w-block_h;
00115 py_end += block_w;
00116 texel++;
00117 } while (texel != tline_end);
00118
00119 pixel += p_diff;
00120 py_end += p_diff;
00121 px_end += p_diff;
00122
00123 texel += tex_diff;
00124 tline_end += tpitch;
00125 } while (texel != tex_end);
00126
00127 }
00128
00129
00130
00131
00132 else if ((sw*2 == dw) && (dh >= sh))
00133 {
00134 uint32 pos_y;
00135 uint32 end_y = dh;
00136 uint32 dst_y = 0;
00137 uint8* next_block = 0;
00138
00139
00140 do
00141 {
00142 next_block = pixel;
00143
00144
00145 do
00146 {
00147 pos_y = dst_y;
00148
00149 uintX p = Manip::copy(*texel);
00150
00151
00152
00153
00154 pixel = next_block;
00155 next_block = next_block+sizeof(uintX)*2;
00156
00157
00158 do
00159 {
00160 *(reinterpret_cast<uintX*>(pixel+0)) = p;
00161 *(reinterpret_cast<uintX*>(pixel+sizeof(uintX))) = p;
00162 pixel += pitch;
00163 pos_y += sh;
00164 } while (pos_y < end_y);
00165
00166 texel++;
00167 } while (texel != tline_end);
00168
00169 pixel -= sizeof(uintX)*(dw-2);
00170 dst_y = pos_y;
00171 end_y += dh;
00172
00173 texel += tex_diff;
00174 tline_end += tpitch;
00175 } while (texel != tex_end);
00176 }
00177
00178
00179
00180
00181 else if ((sw == dw) && (dh >= sh))
00182 {
00183 uint32 pos_y;
00184 uint32 end_y = dh;
00185 uint32 dst_y = 0;
00186 uint8* next_block = 0;
00187
00188
00189 do
00190 {
00191 next_block = pixel;
00192
00193
00194 do
00195 {
00196 pos_y = dst_y;
00197
00198 uintX p = Manip::copy(*texel);
00199
00200
00201
00202
00203 pixel = next_block;
00204 next_block = next_block+sizeof(uintX);
00205
00206
00207 do
00208 {
00209 *(reinterpret_cast<uintX*>(pixel)) = p;
00210 pixel += pitch;
00211 pos_y += sh;
00212 } while (pos_y < end_y);
00213
00214 texel++;
00215 } while (texel != tline_end);
00216
00217 pixel -= sizeof(uintX)*(dw-1);
00218 dst_y = pos_y;
00219 end_y += dh;
00220
00221 texel += tex_diff;
00222 tline_end += tpitch;
00223 } while (texel != tex_end);
00224 }
00225
00226
00227
00228 else
00229 {
00230 uint32 pos_y, pos_x;
00231 uint32 end_y = dh;
00232 uint32 dst_y = 0;
00233 uint8* blockline_start = 0;
00234 uint8* next_block = 0;
00235
00236
00237 do
00238 {
00239 uint32 end_x = dw;
00240 uint32 dst_x = 0;
00241
00242 next_block = pixel;
00243
00244
00245 do
00246 {
00247 pos_y = dst_y;
00248
00249 uintX p = Manip::copy(*texel);
00250
00251
00252
00253
00254 blockline_start = next_block;
00255 next_block = 0;
00256
00257
00258 while (pos_y < end_y)
00259 {
00260 pos_x = dst_x;
00261 pixel = blockline_start;
00262
00263
00264 while (pos_x < end_x)
00265 {
00266 *(reinterpret_cast<uintX*>(pixel)) = p;
00267
00268 pixel+=sizeof(uintX);
00269 pos_x += sw;
00270 }
00271 if (!next_block) next_block = pixel;
00272
00273 blockline_start += pitch;
00274
00275 pos_y += sh;
00276 }
00277
00278 dst_x = pos_x;
00279 end_x += dw;
00280 texel++;
00281 } while (texel != tline_end);
00282
00283 pixel += pitch - sizeof(uintX)*(dw);
00284
00285 dst_y = pos_y;
00286 end_y += dh;
00287
00288 texel += tex_diff;
00289 tline_end += tpitch;
00290 } while (texel != tex_end);
00291 }
00292
00293 return true;
00294 }
00295
00296 };
00297
00298
00299 PointScaler::PointScaler() : Scaler()
00300 {
00301 Scale16Nat = PointScalerInternal<uint16, Manip_Nat2Nat_16, uint16>::Scale;
00302 Scale16Sta = PointScalerInternal<uint16, Manip_Sta2Nat_16, uint32>::Scale;
00303
00304 Scale32Nat = PointScalerInternal<uint32, Manip_Nat2Nat_32, uint32>::Scale;
00305 Scale32Sta = PointScalerInternal<uint32, Manip_Sta2Nat_32, uint32>::Scale;
00306 Scale32_A888 = PointScalerInternal<uint32, Manip_32_A888, uint32>::Scale;
00307 Scale32_888A = PointScalerInternal<uint32, Manip_32_888A, uint32>::Scale;
00308 }
00309
00310 const uint32 PointScaler::ScaleBits() const { return 0xFFFFFFFF; }
00311 const bool PointScaler::ScaleArbitrary() const { return true; }
00312
00313 const char *PointScaler::ScalerName() const { return "point"; }
00314 const char *PointScaler::ScalerDesc() const { return "Fast Simple Point Scaler"; }
00315 const char *PointScaler::ScalerCopyright() const { return "Copyright (C) 2005 The Pentagram Team"; }
00316
00317 const PointScaler point_scaler;
00318
00319 };