From c79c7bb5b3c87908ae5a1c93fc8d1c6e9aa9d474 Mon Sep 17 00:00:00 2001 From: george82 Date: Mon, 5 Nov 2007 11:22:14 +0000 Subject: [PATCH] Added the improvements of the ScaledPixelBuffer class - increased scaled image quality when scale < 100%. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2365 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- common/rfb/ScaleFilters.cxx | 10 ++++++---- common/rfb/ScaleFilters.h | 1 + common/rfb/ScaledPixelBuffer.cxx | 15 +++++++++------ win/rfb_win32/ScaledDIBSectionBuffer.cxx | 11 +---------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/common/rfb/ScaleFilters.cxx b/common/rfb/ScaleFilters.cxx index 50b9bd90..a3ee53e8 100644 --- a/common/rfb/ScaleFilters.cxx +++ b/common/rfb/ScaleFilters.cxx @@ -95,6 +95,8 @@ void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, SFilterWe 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; @@ -108,20 +110,20 @@ void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, SFilterWe 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); } } } diff --git a/common/rfb/ScaleFilters.h b/common/rfb/ScaleFilters.h index 0a8c482b..570dc516 100644 --- a/common/rfb/ScaleFilters.h +++ b/common/rfb/ScaleFilters.h @@ -24,6 +24,7 @@ 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 diff --git a/common/rfb/ScaledPixelBuffer.cxx b/common/rfb/ScaledPixelBuffer.cxx index 5b6e310b..12658f7b 100644 --- a/common/rfb/ScaledPixelBuffer.cxx +++ b/common/rfb/ScaledPixelBuffer.cxx @@ -94,8 +94,8 @@ void ScaledPixelBuffer::setPF(const PixelFormat &pf_) { 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); @@ -204,13 +204,16 @@ void ScaledPixelBuffer::scaleRect(const Rect& rect) { 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; diff --git a/win/rfb_win32/ScaledDIBSectionBuffer.cxx b/win/rfb_win32/ScaledDIBSectionBuffer.cxx index f607d348..efa27a0b 100644 --- a/win/rfb_win32/ScaledDIBSectionBuffer.cxx +++ b/win/rfb_win32/ScaledDIBSectionBuffer.cxx @@ -41,18 +41,9 @@ ScaledDIBSectionBuffer::~ScaledDIBSectionBuffer() { 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(); } -- 2.39.5