4
* Routines to implement Hextile Encoding
8
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
9
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
10
* All Rights Reserved.
12
* This is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* This software is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this software; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
30
static rfbBool sendHextiles8(rfbClientPtr cl, int x, int y, int w, int h);
31
static rfbBool sendHextiles16(rfbClientPtr cl, int x, int y, int w, int h);
32
static rfbBool sendHextiles32(rfbClientPtr cl, int x, int y, int w, int h);
36
* rfbSendRectEncodingHextile - send a rectangle using hextile encoding.
40
rfbSendRectEncodingHextile(cl, x, y, w, h)
44
rfbFramebufferUpdateRectHeader rect;
46
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
47
if (!rfbSendUpdateBuf(cl))
51
rect.r.x = Swap16IfLE(x);
52
rect.r.y = Swap16IfLE(y);
53
rect.r.w = Swap16IfLE(w);
54
rect.r.h = Swap16IfLE(h);
55
rect.encoding = Swap32IfLE(rfbEncodingHextile);
57
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
58
sz_rfbFramebufferUpdateRectHeader);
59
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
61
cl->rfbRectanglesSent[rfbEncodingHextile]++;
62
cl->rfbBytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader;
64
switch (cl->format.bitsPerPixel) {
66
return sendHextiles8(cl, x, y, w, h);
68
return sendHextiles16(cl, x, y, w, h);
70
return sendHextiles32(cl, x, y, w, h);
73
rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel);
78
#define PUT_PIXEL8(pix) (cl->updateBuf[cl->ublen++] = (pix))
80
#define PUT_PIXEL16(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \
81
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1])
83
#define PUT_PIXEL32(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \
84
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1], \
85
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[2], \
86
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[3])
89
#define DEFINE_SEND_HEXTILES(bpp) \
92
static rfbBool subrectEncode##bpp(rfbClientPtr cli, uint##bpp##_t *data, int w, int h, \
93
uint##bpp##_t bg, uint##bpp##_t fg, rfbBool mono); \
94
static void testColours##bpp(uint##bpp##_t *data, int size, rfbBool *mono, \
95
rfbBool *solid, uint##bpp##_t *bg, uint##bpp##_t *fg); \
103
sendHextiles##bpp(cl, rx, ry, rw, rh) \
105
int rx, ry, rw, rh; \
110
uint##bpp##_t bg = 0, fg = 0, newBg, newFg; \
111
rfbBool mono, solid; \
112
rfbBool validBg = FALSE; \
113
rfbBool validFg = FALSE; \
114
uint##bpp##_t clientPixelData[16*16*(bpp/8)]; \
116
for (y = ry; y < ry+rh; y += 16) { \
117
for (x = rx; x < rx+rw; x += 16) { \
119
if (rx+rw - x < 16) \
121
if (ry+rh - y < 16) \
124
if ((cl->ublen + 1 + (2 + 16 * 16) * (bpp/8)) > \
126
if (!rfbSendUpdateBuf(cl)) \
130
fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) \
131
+ (x * (cl->screen->bitsPerPixel / 8))); \
133
(*cl->translateFn)(cl->translateLookupTable, &(cl->screen->rfbServerFormat), \
134
&cl->format, fbptr, (char *)clientPixelData, \
135
cl->screen->paddedWidthInBytes, w, h); \
137
startUblen = cl->ublen; \
138
cl->updateBuf[startUblen] = 0; \
141
testColours##bpp(clientPixelData, w * h, \
142
&mono, &solid, &newBg, &newFg); \
144
if (!validBg || (newBg != bg)) { \
147
cl->updateBuf[startUblen] |= rfbHextileBackgroundSpecified; \
148
PUT_PIXEL##bpp(bg); \
152
cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \
156
cl->updateBuf[startUblen] |= rfbHextileAnySubrects; \
159
if (!validFg || (newFg != fg)) { \
162
cl->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \
163
PUT_PIXEL##bpp(fg); \
167
cl->updateBuf[startUblen] |= rfbHextileSubrectsColoured; \
170
if (!subrectEncode##bpp(cl, clientPixelData, w, h, bg, fg, mono)) { \
171
/* encoding was too large, use raw */ \
174
cl->ublen = startUblen; \
175
cl->updateBuf[cl->ublen++] = rfbHextileRaw; \
176
(*cl->translateFn)(cl->translateLookupTable, \
177
&(cl->screen->rfbServerFormat), &cl->format, fbptr, \
178
(char *)clientPixelData, \
179
cl->screen->paddedWidthInBytes, w, h); \
181
memcpy(&cl->updateBuf[cl->ublen], (char *)clientPixelData, \
184
cl->ublen += w * h * (bpp/8); \
187
cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \
196
subrectEncode##bpp(rfbClientPtr cl, uint##bpp##_t *data, int w, int h, \
197
uint##bpp##_t bg, uint##bpp##_t fg, rfbBool mono) \
202
int hx=0,hy,vx=0,vy; \
204
uint##bpp##_t *seg; \
205
uint##bpp##_t *line; \
207
int thex,they,thew,theh; \
210
int nSubrectsUblen; \
212
nSubrectsUblen = cl->ublen; \
215
for (y=0; y<h; y++) { \
217
for (x=0; x<w; x++) { \
218
if (line[x] != bg) { \
222
for (j=y; j<h; j++) { \
224
if (seg[x] != cl2) {break;} \
226
while ((seg[i] == cl2) && (i < w)) i += 1; \
228
if (j == y) vx = hx = i; \
229
if (i < vx) vx = i; \
230
if ((hyflag > 0) && (i >= hx)) { \
238
/* We now have two possible subrects: (x,y,hx,hy) and \
239
* (x,y,vx,vy). We'll choose the bigger of the two. \
249
if ((hw*hh) > (vw*vh)) { \
258
newLen = cl->ublen - nSubrectsUblen + 2; \
260
newLen = cl->ublen - nSubrectsUblen + bpp/8 + 2; \
263
if (newLen > (w * h * (bpp/8))) \
268
if (!mono) PUT_PIXEL##bpp(cl2); \
270
cl->updateBuf[cl->ublen++] = rfbHextilePackXY(thex,they); \
271
cl->updateBuf[cl->ublen++] = rfbHextilePackWH(thew,theh); \
274
* Now mark the subrect as done. \
276
for (j=they; j < (they+theh); j++) { \
277
for (i=thex; i < (thex+thew); i++) { \
285
cl->updateBuf[nSubrectsUblen] = numsubs; \
292
* testColours() tests if there are one (solid), two (mono) or more \
293
* colours in a tile and gets a reasonable guess at the best background \
294
* pixel, and the foreground pixel for mono. \
298
testColours##bpp(data,size,mono,solid,bg,fg) \
299
uint##bpp##_t *data; \
306
uint##bpp##_t colour1 = 0, colour2 = 0; \
307
int n1 = 0, n2 = 0; \
311
for (; size > 0; size--, data++) { \
316
if (*data == colour1) { \
326
if (*data == colour2) { \
344
DEFINE_SEND_HEXTILES(8)
345
DEFINE_SEND_HEXTILES(16)
346
DEFINE_SEND_HEXTILES(32)