blob: 0b7dffd87a1ae5144396e5f2844e5801f6c4df2b [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2006 TightVNC Team. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 *
18 * TightVNC distribution homepage on the Web: http://www.tightvnc.com/
19 *
20 */
21
22// -=- ScaledDIBSectionBuffer.cxx
23
24#include <math.h>
25
26#include <rfb_win32/ScaledDIBSectionBuffer.h>
27
28using namespace rfb;
29using namespace win32;
30
31ScaledDIBSectionBuffer::ScaledDIBSectionBuffer(HWND window)
32 : src_buffer(0), scaling(false), DIBSectionBuffer(window) {
george82df9f31c2006-09-16 11:06:07 +000033 scaled_data = &data;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000034}
35
36ScaledDIBSectionBuffer::~ScaledDIBSectionBuffer() {
37 if (src_buffer) delete src_buffer;
38}
39
george82bf0adb32006-07-29 10:29:41 +000040void ScaledDIBSectionBuffer::setScaleRatio(double scale_ratio_) {
41 if (scale_ratio == scale_ratio_) return;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000042
george82e4b3c2c2006-09-05 06:43:28 +000043 if (format.depth != 24 && format.depth != 0) throw rfb::UnsupportedPixelFormatException();
george822ac935e2006-05-29 13:57:39 +000044
george82e4b3c2c2006-09-05 06:43:28 +000045 if (scale_ratio_ != 1) scaling = true;
46 else scaling = false;
george82bf0adb32006-07-29 10:29:41 +000047 ScaledPixelBuffer::setScaleRatio(scale_ratio_);
george8296b17b92006-09-05 15:44:35 +000048 calculateScaledBufferSize();
george82e4b3c2c2006-09-05 06:43:28 +000049 recreateBuffers();
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000050}
51
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000052void ScaledDIBSectionBuffer::setPF(const PixelFormat &pf_) {
george82e4b3c2c2006-09-05 06:43:28 +000053 if (memcmp(&(ScaledPixelBuffer::pf), &pf_, sizeof(pf_)) == 0) return;
george82e3341e72006-08-02 15:23:39 +000054
george82e4b3c2c2006-09-05 06:43:28 +000055 ScaledPixelBuffer::pf = pf_;
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000056 if (scaling) {
george82e4b3c2c2006-09-05 06:43:28 +000057 if (src_buffer) src_buffer->setPF(pf_);
58 else {
59 src_buffer = new ManagedPixelBuffer(pf_, src_width, src_height);
60 src_data = &(src_buffer->data);
61 }
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000062 }
63 DIBSectionBuffer::setPF(pf_);
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000064}
65
66void ScaledDIBSectionBuffer::setSize(int src_width_, int src_height_) {
george82e3341e72006-08-02 15:23:39 +000067 if (src_width == src_width_ && src_height == src_height_) return;
68
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000069 src_width = src_width_;
70 src_height = src_height_;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000071 calculateScaledBufferSize();
george82e4b3c2c2006-09-05 06:43:28 +000072 recreateBuffers();
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000073}
74
75void ScaledDIBSectionBuffer::recreateScaledBuffer() {
george82e3341e72006-08-02 15:23:39 +000076 if (width_ && height_ && (format.depth != 0)) {
77 DIBSectionBuffer::recreateBuffer();
george82e3341e72006-08-02 15:23:39 +000078 }
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000079}
80
george82e4b3c2c2006-09-05 06:43:28 +000081void ScaledDIBSectionBuffer::recreateBuffers() {
george82e4b3c2c2006-09-05 06:43:28 +000082 if (scaled_width && scaled_height && format.depth != 0 && scale_ratio != 0) {
83 if (scaling) {
84 if (src_buffer) {
85 if (src_buffer->width() != src_width || src_buffer->width() != src_height)
86 src_buffer->setSize(src_width, src_height);
87 if (memcmp(&src_buffer->getPF(), &pf, sizeof(pf)) == 0)
88 src_buffer->setPF(pf);
89 } else {
90 src_buffer = new ManagedPixelBuffer(format, src_width, src_height);
91 src_data = &(src_buffer->data);
92 memcpy(src_buffer->data, data, src_width * src_height * (getPF().bpp/8));
93 }
94 }
95 recreateScaledBuffer();
96 if (scaling) {
97 scaleRect(Rect(0, 0, src_width, src_height));
98 } else {
99 memcpy(data, src_buffer->data, src_buffer->area() * (src_buffer->getPF().bpp/8));
100 if (src_buffer) {
101 delete src_buffer;
102 src_buffer = 0;
103 src_data = 0;
104 }
105 }
106 }
107}
108
george8296b17b92006-09-05 15:44:35 +0000109void ScaledDIBSectionBuffer::calculateScaledBufferSize() {
110 ScaledPixelBuffer::calculateScaledBufferSize();
111 width_ = scaled_width;
112 height_ = scaled_height;
113}
114
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000115void ScaledDIBSectionBuffer::fillRect(const Rect &dest, Pixel pix) {
116 if (scaling) {
117 src_buffer->fillRect(dest, pix);
118 scaleRect(dest);
119 } else {
120 DIBSectionBuffer::fillRect(dest, pix);
121 }
122}
123
124void ScaledDIBSectionBuffer::imageRect(const Rect &dest, const void* pixels, int stride) {
125 if (scaling) {
126 src_buffer->imageRect(dest, pixels, stride);
127 scaleRect(dest);
128 } else {
129 DIBSectionBuffer::imageRect(dest, pixels, stride);
130 }
131}
132
133void ScaledDIBSectionBuffer::copyRect(const Rect &dest, const Point &move_by_delta) {
134 if (scaling) {
135 src_buffer->copyRect(dest, move_by_delta);
136 scaleRect(dest);
137 } else {
138 DIBSectionBuffer::copyRect(dest, move_by_delta);
139 }
140}
141
142void ScaledDIBSectionBuffer::maskRect(const Rect& r, const void* pixels, const void* mask_) {
143 if (scaling) {
144 src_buffer->maskRect(r, pixels, mask_);
145 scaleRect(r);
146 } else {
147 DIBSectionBuffer::maskRect(r, pixels, mask_);
148 }
149}
150
151void ScaledDIBSectionBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask_) {
152 if (scaling) {
153 src_buffer->maskRect(r, pixel, mask_);
154 scaleRect(r);
155 } else {
156 DIBSectionBuffer::maskRect(r, pixel, mask_);
157 }
158}