double sxc;
double offset = 0.5;
double ratio = (double)dst_x / src_x;
+ double sourceScale = __rfbmax(1.0, 1.0/ratio);
+ double sourceRadius = __rfbmax(0.5, sourceScale * filters[filter_id].radius);
double sum, nc;
int i, ci;
sxc = (double(x)+offset) / ratio;
// Calculate the scale filter interval, [i0, i1)
- int i0 = int(__rfbmax(sxc-sFilter.radius+0.5, 0));
- int i1 = int(__rfbmin(sxc+sFilter.radius+0.5, src_x));
+ int i0 = int(__rfbmax(sxc-sourceRadius+0.5, 0));
+ int i1 = int(__rfbmin(sxc+sourceRadius+0.5, src_x));
weightTabs[x].i0 = i0; weightTabs[x].i1 = i1;
weightTabs[x].weight = new short[i1-i0];
// Calculate coeff to normalize the filter weights
- for (sum = 0, i = i0; i < i1; i++) sum += sFilter.func(double(i)-sxc+0.5);
+ for (sum = 0, i = i0; i < i1; i++) sum += sFilter.func((double(i)-sxc+0.5)/sourceScale);
if (sum == 0.) nc = (double)(WEIGHT_OF_ONE); else nc = (double)(WEIGHT_OF_ONE)/sum;
// Calculate the weight coeffs on the scale filter interval
for (ci = 0, i = i0; i < i1; i++) {
- weightTabs[x].weight[ci++] = (short)floor((sFilter.func(double(i)-sxc+0.5) * nc) + 0.5);
+ weightTabs[x].weight[ci++] = (short)floor((sFilter.func((double(i)-sxc+0.5)/sourceScale) * nc) + 0.5);
}
}
}
namespace rfb {
+ #define SCALE_ERROR 1e-7
#define BITS_OF_CHANEL 8
#define BITS_OF_WEIGHT 14
#define FINALSHIFT 2 * BITS_OF_WEIGHT - BITS_OF_CHANEL
void ScaledPixelBuffer::setScale(int scale_) {
if (scale != scale_ && scale_ > 0) {
- freeWeightTabs();
scale = scale_;
+ freeWeightTabs();
calculateScaledBufferSize();
scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
Rect ScaledPixelBuffer::calculateScaleBoundary(const Rect& r) {
int x_start, y_start, x_end, y_end;
- double radius = scaleFilters[scaleFilterID].radius;
double translate_x = 0.5*scale_ratio_x - 0.5;
double translate_y = 0.5*scale_ratio_y - 0.5;
- x_start = (int)ceil(scale_ratio_x*(r.tl.x-radius) + translate_x);
- y_start = (int)ceil(scale_ratio_y*(r.tl.y-radius) + translate_y);
- x_end = (int)ceil(scale_ratio_x*(r.br.x+radius) + translate_x);
- y_end = (int)ceil(scale_ratio_y*(r.br.y+radius) + translate_y);
+ double sourceXScale = __rfbmax(1.0, 1.0/scale_ratio_x);
+ double sourceYScale = __rfbmax(1.0, 1.0/scale_ratio_y);
+ double sourceXRadius = __rfbmax(0.5, sourceXScale*scaleFilters[scaleFilterID].radius);
+ double sourceYRadius = __rfbmax(0.5, sourceYScale*scaleFilters[scaleFilterID].radius);
+ x_start = (int)ceil(scale_ratio_x*(r.tl.x-sourceXRadius) + translate_x + SCALE_ERROR);
+ y_start = (int)ceil(scale_ratio_y*(r.tl.y-sourceYRadius) + translate_y + SCALE_ERROR);
+ x_end = (int)floor(scale_ratio_x*((r.br.x-1)+sourceXRadius) + translate_x - SCALE_ERROR) + 1;
+ y_end = (int)floor(scale_ratio_y*((r.br.y-1)+sourceXRadius) + translate_y - SCALE_ERROR) + 1;
if (x_start < 0) x_start = 0;
if (y_start < 0) y_start = 0;
if (x_end > scaled_width) x_end = scaled_width;
void ScaledDIBSectionBuffer::setScale(int scale_) {
if (scale == scale_ || scale_ <= 0) return;
-
- scale = scale_;
+ ScaledPixelBuffer::setScale(scale_);
if (scale == 100) scaling = false;
else scaling = true;
-
- // FIXME:
- // Calculate the scale weight tabs must be in the ScalePixelBuffer class
- freeWeightTabs();
- calculateScaledBufferSize();
- scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
- scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-
recreateBuffers();
}