~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to common/ivs/libvncserver/hextile.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mfrom: (1.2.1 upstream) (4.1.1 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080617134654-cl0gi4u524cv1ici
Tags: 1:1.0.9~rc3-1
* Package new upstream version
  - upstream ported the code to qt4.4 (Closes: #481974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * hextile.c
3
 
 *
4
 
 * Routines to implement Hextile Encoding
5
 
 */
6
 
 
7
 
/*
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.
11
 
 *
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.
16
 
 *
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.
21
 
 *
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,
25
 
 *  USA.
26
 
 */
27
 
 
28
 
#include <rfb/rfb.h>
29
 
 
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);
33
 
 
34
 
 
35
 
/*
36
 
 * rfbSendRectEncodingHextile - send a rectangle using hextile encoding.
37
 
 */
38
 
 
39
 
rfbBool
40
 
rfbSendRectEncodingHextile(cl, x, y, w, h)
41
 
    rfbClientPtr cl;
42
 
    int x, y, w, h;
43
 
{
44
 
    rfbFramebufferUpdateRectHeader rect;
45
 
 
46
 
    if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
47
 
        if (!rfbSendUpdateBuf(cl))
48
 
            return FALSE;
49
 
    }
50
 
 
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);
56
 
 
57
 
    memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
58
 
           sz_rfbFramebufferUpdateRectHeader);
59
 
    cl->ublen += sz_rfbFramebufferUpdateRectHeader;
60
 
 
61
 
    cl->rfbRectanglesSent[rfbEncodingHextile]++;
62
 
    cl->rfbBytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader;
63
 
 
64
 
    switch (cl->format.bitsPerPixel) {
65
 
    case 8:
66
 
        return sendHextiles8(cl, x, y, w, h);
67
 
    case 16:
68
 
        return sendHextiles16(cl, x, y, w, h);
69
 
    case 32:
70
 
        return sendHextiles32(cl, x, y, w, h);
71
 
    }
72
 
 
73
 
    rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel);
74
 
    return FALSE;
75
 
}
76
 
 
77
 
 
78
 
#define PUT_PIXEL8(pix) (cl->updateBuf[cl->ublen++] = (pix))
79
 
 
80
 
#define PUT_PIXEL16(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \
81
 
                          cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1])
82
 
 
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])
87
 
 
88
 
 
89
 
#define DEFINE_SEND_HEXTILES(bpp)                                               \
90
 
                                                                                \
91
 
                                                                                \
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);        \
96
 
                                                                                \
97
 
                                                                                \
98
 
/*                                                                              \
99
 
 * rfbSendHextiles                                                              \
100
 
 */                                                                             \
101
 
                                                                                \
102
 
static rfbBool                                                                     \
103
 
sendHextiles##bpp(cl, rx, ry, rw, rh)                                           \
104
 
    rfbClientPtr cl;                                                            \
105
 
    int rx, ry, rw, rh;                                                         \
106
 
{                                                                               \
107
 
    int x, y, w, h;                                                             \
108
 
    int startUblen;                                                             \
109
 
    char *fbptr;                                                                \
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)];                                   \
115
 
                                                                                \
116
 
    for (y = ry; y < ry+rh; y += 16) {                                          \
117
 
        for (x = rx; x < rx+rw; x += 16) {                                      \
118
 
            w = h = 16;                                                         \
119
 
            if (rx+rw - x < 16)                                                 \
120
 
                w = rx+rw - x;                                                  \
121
 
            if (ry+rh - y < 16)                                                 \
122
 
                h = ry+rh - y;                                                  \
123
 
                                                                                \
124
 
            if ((cl->ublen + 1 + (2 + 16 * 16) * (bpp/8)) >                     \
125
 
                UPDATE_BUF_SIZE) {                                              \
126
 
                if (!rfbSendUpdateBuf(cl))                                      \
127
 
                    return FALSE;                                               \
128
 
            }                                                                   \
129
 
                                                                                \
130
 
            fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y)   \
131
 
                     + (x * (cl->screen->bitsPerPixel / 8)));                     \
132
 
                                                                                \
133
 
            (*cl->translateFn)(cl->translateLookupTable, &(cl->screen->rfbServerFormat),      \
134
 
                               &cl->format, fbptr, (char *)clientPixelData,     \
135
 
                               cl->screen->paddedWidthInBytes, w, h);             \
136
 
                                                                                \
137
 
            startUblen = cl->ublen;                                             \
138
 
            cl->updateBuf[startUblen] = 0;                                      \
139
 
            cl->ublen++;                                                        \
140
 
                                                                                \
141
 
            testColours##bpp(clientPixelData, w * h,                            \
142
 
                             &mono, &solid, &newBg, &newFg);                    \
143
 
                                                                                \
144
 
            if (!validBg || (newBg != bg)) {                                    \
145
 
                validBg = TRUE;                                                 \
146
 
                bg = newBg;                                                     \
147
 
                cl->updateBuf[startUblen] |= rfbHextileBackgroundSpecified;     \
148
 
                PUT_PIXEL##bpp(bg);                                             \
149
 
            }                                                                   \
150
 
                                                                                \
151
 
            if (solid) {                                                        \
152
 
                cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \
153
 
                continue;                                                       \
154
 
            }                                                                   \
155
 
                                                                                \
156
 
            cl->updateBuf[startUblen] |= rfbHextileAnySubrects;                 \
157
 
                                                                                \
158
 
            if (mono) {                                                         \
159
 
                if (!validFg || (newFg != fg)) {                                \
160
 
                    validFg = TRUE;                                             \
161
 
                    fg = newFg;                                                 \
162
 
                    cl->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \
163
 
                    PUT_PIXEL##bpp(fg);                                         \
164
 
                }                                                               \
165
 
            } else {                                                            \
166
 
                validFg = FALSE;                                                \
167
 
                cl->updateBuf[startUblen] |= rfbHextileSubrectsColoured;        \
168
 
            }                                                                   \
169
 
                                                                                \
170
 
            if (!subrectEncode##bpp(cl, clientPixelData, w, h, bg, fg, mono)) { \
171
 
                /* encoding was too large, use raw */                           \
172
 
                validBg = FALSE;                                                \
173
 
                validFg = FALSE;                                                \
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);         \
180
 
                                                                                \
181
 
                memcpy(&cl->updateBuf[cl->ublen], (char *)clientPixelData,      \
182
 
                       w * h * (bpp/8));                                        \
183
 
                                                                                \
184
 
                cl->ublen += w * h * (bpp/8);                                   \
185
 
            }                                                                   \
186
 
                                                                                \
187
 
            cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen;     \
188
 
        }                                                                       \
189
 
    }                                                                           \
190
 
                                                                                \
191
 
    return TRUE;                                                                \
192
 
}                                                                               \
193
 
                                                                                \
194
 
                                                                                \
195
 
static rfbBool                                                                     \
196
 
subrectEncode##bpp(rfbClientPtr cl, uint##bpp##_t *data, int w, int h,              \
197
 
                   uint##bpp##_t bg, uint##bpp##_t fg, rfbBool mono)                       \
198
 
{                                                                               \
199
 
    uint##bpp##_t cl2;                                                              \
200
 
    int x,y;                                                                    \
201
 
    int i,j;                                                                    \
202
 
    int hx=0,hy,vx=0,vy;                                                        \
203
 
    int hyflag;                                                                 \
204
 
    uint##bpp##_t *seg;                                                             \
205
 
    uint##bpp##_t *line;                                                            \
206
 
    int hw,hh,vw,vh;                                                            \
207
 
    int thex,they,thew,theh;                                                    \
208
 
    int numsubs = 0;                                                            \
209
 
    int newLen;                                                                 \
210
 
    int nSubrectsUblen;                                                         \
211
 
                                                                                \
212
 
    nSubrectsUblen = cl->ublen;                                                 \
213
 
    cl->ublen++;                                                                \
214
 
                                                                                \
215
 
    for (y=0; y<h; y++) {                                                       \
216
 
        line = data+(y*w);                                                      \
217
 
        for (x=0; x<w; x++) {                                                   \
218
 
            if (line[x] != bg) {                                                \
219
 
                cl2 = line[x];                                                  \
220
 
                hy = y-1;                                                       \
221
 
                hyflag = 1;                                                     \
222
 
                for (j=y; j<h; j++) {                                           \
223
 
                    seg = data+(j*w);                                           \
224
 
                    if (seg[x] != cl2) {break;}                                 \
225
 
                    i = x;                                                      \
226
 
                    while ((seg[i] == cl2) && (i < w)) i += 1;                  \
227
 
                    i -= 1;                                                     \
228
 
                    if (j == y) vx = hx = i;                                    \
229
 
                    if (i < vx) vx = i;                                         \
230
 
                    if ((hyflag > 0) && (i >= hx)) {                            \
231
 
                        hy += 1;                                                \
232
 
                    } else {                                                    \
233
 
                        hyflag = 0;                                             \
234
 
                    }                                                           \
235
 
                }                                                               \
236
 
                vy = j-1;                                                       \
237
 
                                                                                \
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.            \
240
 
                 */                                                             \
241
 
                hw = hx-x+1;                                                    \
242
 
                hh = hy-y+1;                                                    \
243
 
                vw = vx-x+1;                                                    \
244
 
                vh = vy-y+1;                                                    \
245
 
                                                                                \
246
 
                thex = x;                                                       \
247
 
                they = y;                                                       \
248
 
                                                                                \
249
 
                if ((hw*hh) > (vw*vh)) {                                        \
250
 
                    thew = hw;                                                  \
251
 
                    theh = hh;                                                  \
252
 
                } else {                                                        \
253
 
                    thew = vw;                                                  \
254
 
                    theh = vh;                                                  \
255
 
                }                                                               \
256
 
                                                                                \
257
 
                if (mono) {                                                     \
258
 
                    newLen = cl->ublen - nSubrectsUblen + 2;                    \
259
 
                } else {                                                        \
260
 
                    newLen = cl->ublen - nSubrectsUblen + bpp/8 + 2;            \
261
 
                }                                                               \
262
 
                                                                                \
263
 
                if (newLen > (w * h * (bpp/8)))                                 \
264
 
                    return FALSE;                                               \
265
 
                                                                                \
266
 
                numsubs += 1;                                                   \
267
 
                                                                                \
268
 
                if (!mono) PUT_PIXEL##bpp(cl2);                                 \
269
 
                                                                                \
270
 
                cl->updateBuf[cl->ublen++] = rfbHextilePackXY(thex,they);       \
271
 
                cl->updateBuf[cl->ublen++] = rfbHextilePackWH(thew,theh);       \
272
 
                                                                                \
273
 
                /*                                                              \
274
 
                 * Now mark the subrect as done.                                \
275
 
                 */                                                             \
276
 
                for (j=they; j < (they+theh); j++) {                            \
277
 
                    for (i=thex; i < (thex+thew); i++) {                        \
278
 
                        data[j*w+i] = bg;                                       \
279
 
                    }                                                           \
280
 
                }                                                               \
281
 
            }                                                                   \
282
 
        }                                                                       \
283
 
    }                                                                           \
284
 
                                                                                \
285
 
    cl->updateBuf[nSubrectsUblen] = numsubs;                                    \
286
 
                                                                                \
287
 
    return TRUE;                                                                \
288
 
}                                                                               \
289
 
                                                                                \
290
 
                                                                                \
291
 
/*                                                                              \
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.                                    \
295
 
 */                                                                             \
296
 
                                                                                \
297
 
static void                                                                     \
298
 
testColours##bpp(data,size,mono,solid,bg,fg)                                    \
299
 
    uint##bpp##_t *data;                                                            \
300
 
    int size;                                                                   \
301
 
    rfbBool *mono;                                                                 \
302
 
    rfbBool *solid;                                                                \
303
 
    uint##bpp##_t *bg;                                                              \
304
 
    uint##bpp##_t *fg;                                                              \
305
 
{                                                                               \
306
 
    uint##bpp##_t colour1 = 0, colour2 = 0;                                         \
307
 
    int n1 = 0, n2 = 0;                                                         \
308
 
    *mono = TRUE;                                                               \
309
 
    *solid = TRUE;                                                              \
310
 
                                                                                \
311
 
    for (; size > 0; size--, data++) {                                          \
312
 
                                                                                \
313
 
        if (n1 == 0)                                                            \
314
 
            colour1 = *data;                                                    \
315
 
                                                                                \
316
 
        if (*data == colour1) {                                                 \
317
 
            n1++;                                                               \
318
 
            continue;                                                           \
319
 
        }                                                                       \
320
 
                                                                                \
321
 
        if (n2 == 0) {                                                          \
322
 
            *solid = FALSE;                                                     \
323
 
            colour2 = *data;                                                    \
324
 
        }                                                                       \
325
 
                                                                                \
326
 
        if (*data == colour2) {                                                 \
327
 
            n2++;                                                               \
328
 
            continue;                                                           \
329
 
        }                                                                       \
330
 
                                                                                \
331
 
        *mono = FALSE;                                                          \
332
 
        break;                                                                  \
333
 
    }                                                                           \
334
 
                                                                                \
335
 
    if (n1 > n2) {                                                              \
336
 
        *bg = colour1;                                                          \
337
 
        *fg = colour2;                                                          \
338
 
    } else {                                                                    \
339
 
        *bg = colour2;                                                          \
340
 
        *fg = colour1;                                                          \
341
 
    }                                                                           \
342
 
}
343
 
 
344
 
DEFINE_SEND_HEXTILES(8)
345
 
DEFINE_SEND_HEXTILES(16)
346
 
DEFINE_SEND_HEXTILES(32)