From 2446ed081f1631e7feaca9e89c7fb4024bf62eb2 Mon Sep 17 00:00:00 2001 From: george82 Date: Sat, 10 Mar 2007 08:55:35 +0000 Subject: [PATCH] Fixed the bug with crashing vncviewer when it works in the scaling mode and scale < 10%. Scale part of vncviewer code improvements. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2232 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- common/rfb/ScaleFilters.cxx | 3 ++- common/rfb/ScaleFilters.h | 2 +- common/rfb/ScaledPixelBuffer.cxx | 34 +++++++++++++----------- common/rfb/ScaledPixelBuffer.h | 12 +++++---- win/rfb_win32/ScaledDIBSectionBuffer.cxx | 16 +++++------ win/rfb_win32/ScaledDIBSectionBuffer.h | 5 ++-- win/vncviewer/DesktopWindow.cxx | 14 +++++----- win/vncviewer/DesktopWindow.h | 3 +-- 8 files changed, 48 insertions(+), 41 deletions(-) diff --git a/common/rfb/ScaleFilters.cxx b/common/rfb/ScaleFilters.cxx index cd08f674..2e6b88da 100644 --- a/common/rfb/ScaleFilters.cxx +++ b/common/rfb/ScaleFilters.cxx @@ -87,9 +87,10 @@ SFilter ScaleFilters::create(char *name_, double radius_, filter_func func_) { return filter; } -void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, double ratio, SFilterWeightTab **pWeightTabs) { +void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, SFilterWeightTab **pWeightTabs) { double sxc; double offset = 0.5; + double ratio = (double)dst_x / src_x; SFilter sFilter = filters[filter_id]; diff --git a/common/rfb/ScaleFilters.h b/common/rfb/ScaleFilters.h index 75b1e7f1..62075d54 100644 --- a/common/rfb/ScaleFilters.h +++ b/common/rfb/ScaleFilters.h @@ -60,7 +60,7 @@ namespace rfb { SFilter &operator[](unsigned int filter_id); - void makeWeightTabs(int filter, int src_x, int dst_x, double ratio, SFilterWeightTab **weightTabs); + void makeWeightTabs(int filter, int src_x, int dst_x, SFilterWeightTab **weightTabs); protected: void initFilters(); diff --git a/common/rfb/ScaledPixelBuffer.cxx b/common/rfb/ScaledPixelBuffer.cxx index 6b95058f..1be029df 100644 --- a/common/rfb/ScaledPixelBuffer.cxx +++ b/common/rfb/ScaledPixelBuffer.cxx @@ -30,7 +30,7 @@ using namespace rfb; ScaledPixelBuffer::ScaledPixelBuffer(U8 **src_data_, int src_width_, int src_height_, int scale, PixelFormat pf_) - : scale_ratio(1), scaleFilterID(scaleFilterBicubic), + : scale(100), scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBicubic), xWeightTabs(0), yWeightTabs(0), scaled_data(0) { setSourceBuffer(src_data_, src_width_, src_height_); @@ -38,8 +38,8 @@ ScaledPixelBuffer::ScaledPixelBuffer(U8 **src_data_, int src_width_, } ScaledPixelBuffer::ScaledPixelBuffer() - : src_width(0), src_height(0), scaled_width(0), scaled_height(0), - scale_ratio(1), scaleFilterID(scaleFilterBicubic), + : src_width(0), src_height(0), scaled_width(0), scaled_height(0), scale(100), + scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBicubic), xWeightTabs(0), yWeightTabs(0), src_data(0), scaled_data(0) { memset(&pf, 0, sizeof(pf)); } @@ -67,8 +67,8 @@ void ScaledPixelBuffer::setSourceBuffer(U8 **src_data_, int w, int h) { src_width = w; src_height = h; calculateScaledBufferSize(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, scale_ratio, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, scale_ratio, &yWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); } void ScaledPixelBuffer::setPF(const PixelFormat &pf_) { @@ -76,13 +76,13 @@ void ScaledPixelBuffer::setPF(const PixelFormat &pf_) { pf = pf_; } -void ScaledPixelBuffer::setScaleRatio(double scale_ratio_) { - if (scale_ratio != scale_ratio_) { +void ScaledPixelBuffer::setScale(int scale_) { + if (scale != scale_ && scale_ > 0) { freeWeightTabs(); - scale_ratio = scale_ratio_; + scale = scale_; calculateScaledBufferSize(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, scale_ratio, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, scale_ratio, &yWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); } } @@ -166,11 +166,12 @@ 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 = 0.5*scale_ratio - 0.5; - x_start = (int)ceil(scale_ratio*(r.tl.x-radius) + translate); - y_start = (int)ceil(scale_ratio*(r.tl.y-radius) + translate); - x_end = (int)ceil(scale_ratio*(r.br.x+radius) + translate); - y_end = (int)ceil(scale_ratio*(r.br.y+radius) + translate); + 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); if (x_start < 0) x_start = 0; if (y_start < 0) y_start = 0; if (x_end > scaled_width) x_end = scaled_width; @@ -179,6 +180,9 @@ Rect ScaledPixelBuffer::calculateScaleBoundary(const Rect& r) { } void ScaledPixelBuffer::calculateScaledBufferSize() { + double scale_ratio = (double)scale / 100; scaled_width = (int)ceil(src_width * scale_ratio); scaled_height = (int)ceil(src_height * scale_ratio); + scale_ratio_x = (double)scaled_width / src_width; + scale_ratio_y = (double)scaled_height / src_height; } diff --git a/common/rfb/ScaledPixelBuffer.h b/common/rfb/ScaledPixelBuffer.h index ca0ddf56..b41c59ad 100644 --- a/common/rfb/ScaledPixelBuffer.h +++ b/common/rfb/ScaledPixelBuffer.h @@ -49,8 +49,9 @@ namespace rfb { int getSrcWidth() const { return src_width; } int getSrcHeight() const { return src_height; } int area() const { return scaled_width * scaled_height; } - int getScale() const { return int(scale_ratio * 100 + 0.5); } - double getScaleRatio() const { return scale_ratio; } + int getScale() const { return scale; } + double getScaleRatioX() const { return scale_ratio_x; } + double getScaleRatioY() const { return scale_ratio_y; } // Pixel manipulation routines inline U32 getSourcePixel(int x, int y); @@ -74,8 +75,7 @@ namespace rfb { void setPF(const PixelFormat &pf); // Set the new scale, in percent - virtual void setScale(int scale) { setScaleRatio(double(scale)/100.0); } - virtual void setScaleRatio(double scale_ratio); + virtual void setScale(int scale); // Scale rect from the source image buffer to the destination buffer // using the current interpolation method @@ -99,8 +99,10 @@ namespace rfb { int src_height; int scaled_width; int scaled_height; + int scale; + double scale_ratio_x; + double scale_ratio_y; PixelFormat pf; - double scale_ratio; unsigned int scaleFilterID; ScaleFilters scaleFilters; SFilterWeightTab *xWeightTabs; diff --git a/win/rfb_win32/ScaledDIBSectionBuffer.cxx b/win/rfb_win32/ScaledDIBSectionBuffer.cxx index 1a287c06..5ac83614 100644 --- a/win/rfb_win32/ScaledDIBSectionBuffer.cxx +++ b/win/rfb_win32/ScaledDIBSectionBuffer.cxx @@ -39,19 +39,19 @@ ScaledDIBSectionBuffer::~ScaledDIBSectionBuffer() { if (src_buffer) delete src_buffer; } -void ScaledDIBSectionBuffer::setScaleRatio(double scale_ratio_) { - if (scale_ratio == scale_ratio_ || scale_ratio <= 0) return; +void ScaledDIBSectionBuffer::setScale(int scale_) { + if (scale == scale_ || scale_ <= 0) return; - scale_ratio = scale_ratio_; - if (scale_ratio == 1) scaling = false; + scale = 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, scale_ratio, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, scale_ratio, &yWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); recreateBuffers(); } @@ -86,8 +86,8 @@ void ScaledDIBSectionBuffer::setSize(int src_width_, int src_height_) { // Calculate the scale weight tabs must be in the ScalePixelBuffer class freeWeightTabs(); calculateScaledBufferSize(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, scale_ratio, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, scale_ratio, &yWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); + scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); recreateBuffers(); } diff --git a/win/rfb_win32/ScaledDIBSectionBuffer.h b/win/rfb_win32/ScaledDIBSectionBuffer.h index eb1d093f..509411c0 100644 --- a/win/rfb_win32/ScaledDIBSectionBuffer.h +++ b/win/rfb_win32/ScaledDIBSectionBuffer.h @@ -50,9 +50,8 @@ namespace rfb { virtual const PixelFormat& getPixelFormat() const { return pf; } virtual const PixelFormat& getScaledPixelFormat() const { return getPF(); } virtual void setSize(int w, int h); - virtual void setScale(int scale) { setScaleRatio(double(scale)/100.0); }; - virtual void setScaleRatio(double scale_ratio); - + virtual void setScale(int scale); + virtual void calculateScaledBufferSize(); Rect getRect() const { return ScaledPixelBuffer::getRect(); } diff --git a/win/vncviewer/DesktopWindow.cxx b/win/vncviewer/DesktopWindow.cxx index 5aba7802..4a316ad5 100644 --- a/win/vncviewer/DesktopWindow.cxx +++ b/win/vncviewer/DesktopWindow.cxx @@ -858,8 +858,8 @@ DesktopWindow::processMouseMessage(UINT msg, WPARAM wParam, LPARAM lParam) // Send a pointer event to the server oldpos = p; if (buffer->isScaling()) { - p.x /= buffer->getScaleRatio(); - p.y /= buffer->getScaleRatio(); + p.x /= buffer->getScaleRatioX(); + p.y /= buffer->getScaleRatioY(); } ptr.pointerEvent(callback, p, mask); #ifdef WM_MOUSEWHEEL @@ -1005,13 +1005,15 @@ DesktopWindow::setSize(int w, int h) { void DesktopWindow::setAutoScaling(bool as) { autoScaling = as; + if (isToolbarEnabled()) refreshToolbarButtons(); if (as) fitBufferToWindow(); } -void DesktopWindow::setDesktopScaleRatio(double scale_ratio) { - buffer->setScaleRatio(scale_ratio); - if (!isAutoScaling()) resizeDesktopWindowToBuffer(); +void DesktopWindow::setDesktopScale(int scale_) { + if (buffer->getScale() == scale_ || scale_ <= 0) return; + buffer->setScale(scale_); if (isToolbarEnabled()) refreshToolbarButtons(); + if (!isAutoScaling()) resizeDesktopWindowToBuffer(); char *newTitle = new char[strlen(desktopName)+20]; sprintf(newTitle, "%s @ %i%%", desktopName, getDesktopScale()); SetWindowText(handle, TStr(newTitle)); @@ -1037,7 +1039,7 @@ void DesktopWindow::fitBufferToWindow(bool repaint) { } else { scale_ratio = double(client_size.width()) / buffer->getSrcWidth(); } - setDesktopScaleRatio(scale_ratio); + setDesktopScale(int(scale_ratio * 100)); } void diff --git a/win/vncviewer/DesktopWindow.h b/win/vncviewer/DesktopWindow.h index bce7cf72..7a8fa2c3 100644 --- a/win/vncviewer/DesktopWindow.h +++ b/win/vncviewer/DesktopWindow.h @@ -88,8 +88,7 @@ namespace rfb { void setColour(int i, int r, int g, int b) {buffer->setColour(i, r, g, b);} void setAutoScaling(bool as); bool isAutoScaling() const { return autoScaling; } - void setDesktopScaleRatio(double scale_ratio); - void setDesktopScale(int scale) { setDesktopScaleRatio(double(scale)/100); } + void setDesktopScale(int scale); int getDesktopScale() const { return buffer->getScale(); } void fitBufferToWindow(bool repaint = true); -- 2.39.5