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

« back to all changes in this revision

Viewing changes to common/ivs/libvncserver/zrle.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
 
 * Copyright (C) 2002 RealVNC Ltd.  All Rights Reserved.
3
 
 * Copyright (C) 2003 Sun Microsystems, Inc.
4
 
 *
5
 
 * This is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This software is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this software; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18
 
 * USA.
19
 
 */
20
 
 
21
 
/*
22
 
 * zrle.c
23
 
 *
24
 
 * Routines to implement Zlib Run-length Encoding (ZRLE).
25
 
 */
26
 
 
27
 
#include "rfb/rfb.h"
28
 
#include "zrleoutstream.h"
29
 
 
30
 
 
31
 
#define GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf)                                \
32
 
{  char *fbptr = (cl->screen->frameBuffer                                   \
33
 
                 + (cl->screen->paddedWidthInBytes * ty)                   \
34
 
                 + (tx * (cl->screen->bitsPerPixel / 8)));                 \
35
 
                                                                           \
36
 
  (*cl->translateFn)(cl->translateLookupTable, &cl->screen->rfbServerFormat,\
37
 
                     &cl->format, fbptr, (char*)buf,                       \
38
 
                     cl->screen->paddedWidthInBytes, tw, th); }
39
 
 
40
 
#define EXTRA_ARGS , rfbClientPtr cl
41
 
 
42
 
#define BPP 8
43
 
#include <zrleencodetemplate.c>
44
 
#undef BPP
45
 
#define BPP 16
46
 
#include <zrleencodetemplate.c>
47
 
#undef BPP
48
 
#define BPP 32
49
 
#include <zrleencodetemplate.c>
50
 
#define CPIXEL 24A
51
 
#include <zrleencodetemplate.c>
52
 
#undef CPIXEL
53
 
#define CPIXEL 24B
54
 
#include <zrleencodetemplate.c>
55
 
#undef CPIXEL
56
 
#undef BPP
57
 
 
58
 
 
59
 
/*
60
 
 * zrleBeforeBuf contains pixel data in the client's format.  It must be at
61
 
 * least one pixel bigger than the largest tile of pixel data, since the
62
 
 * ZRLE encoding algorithm writes to the position one past the end of the pixel
63
 
 * data.
64
 
 */
65
 
 
66
 
static char zrleBeforeBuf[rfbZRLETileWidth * rfbZRLETileHeight * 4 + 4];
67
 
 
68
 
 
69
 
 
70
 
/*
71
 
 * rfbSendRectEncodingZRLE - send a given rectangle using ZRLE encoding.
72
 
 */
73
 
 
74
 
 
75
 
rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w, int h)
76
 
{
77
 
  zrleOutStream* zos;
78
 
  rfbFramebufferUpdateRectHeader rect;
79
 
  rfbZRLEHeader hdr;
80
 
  int i;
81
 
 
82
 
  if (!cl->zrleData)
83
 
    cl->zrleData = zrleOutStreamNew();
84
 
  zos = cl->zrleData;
85
 
  zos->in.ptr = zos->in.start;
86
 
  zos->out.ptr = zos->out.start;
87
 
 
88
 
  switch (cl->format.bitsPerPixel) {
89
 
 
90
 
  case 8:
91
 
    zrleEncode8( x, y, w, h, zos, zrleBeforeBuf, cl);
92
 
    break;
93
 
 
94
 
  case 16:
95
 
    zrleEncode16(x, y, w, h, zos, zrleBeforeBuf, cl);
96
 
    break;
97
 
 
98
 
  case 32: {
99
 
    rfbBool fitsInLS3Bytes
100
 
      = ((cl->format.redMax   << cl->format.redShift)   < (1<<24) &&
101
 
         (cl->format.greenMax << cl->format.greenShift) < (1<<24) &&
102
 
         (cl->format.blueMax  << cl->format.blueShift)  < (1<<24));
103
 
 
104
 
    rfbBool fitsInMS3Bytes = (cl->format.redShift   > 7  &&
105
 
                           cl->format.greenShift > 7  &&
106
 
                           cl->format.blueShift  > 7);
107
 
 
108
 
    if ((fitsInLS3Bytes && !cl->format.bigEndian) ||
109
 
        (fitsInMS3Bytes && cl->format.bigEndian))
110
 
    {
111
 
      zrleEncode24A(x, y, w, h, zos, zrleBeforeBuf, cl);
112
 
    }
113
 
    else if ((fitsInLS3Bytes && cl->format.bigEndian) ||
114
 
             (fitsInMS3Bytes && !cl->format.bigEndian))
115
 
    {
116
 
      zrleEncode24B(x, y, w, h, zos, zrleBeforeBuf, cl);
117
 
    }
118
 
    else
119
 
    {
120
 
      zrleEncode32(x, y, w, h, zos, zrleBeforeBuf, cl);
121
 
    }
122
 
  }
123
 
    break;
124
 
  }
125
 
 
126
 
  cl->rfbRectanglesSent[rfbEncodingZRLE]++;
127
 
  cl->rfbBytesSent[rfbEncodingZRLE] += (sz_rfbFramebufferUpdateRectHeader
128
 
                                        + sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out));
129
 
 
130
 
  if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader
131
 
      > UPDATE_BUF_SIZE)
132
 
    {
133
 
      if (!rfbSendUpdateBuf(cl))
134
 
        return FALSE;
135
 
    }
136
 
 
137
 
  rect.r.x = Swap16IfLE(x);
138
 
  rect.r.y = Swap16IfLE(y);
139
 
  rect.r.w = Swap16IfLE(w);
140
 
  rect.r.h = Swap16IfLE(h);
141
 
  rect.encoding = Swap32IfLE(rfbEncodingZRLE);
142
 
 
143
 
  memcpy(cl->updateBuf+cl->ublen, (char *)&rect,
144
 
         sz_rfbFramebufferUpdateRectHeader);
145
 
  cl->ublen += sz_rfbFramebufferUpdateRectHeader;
146
 
 
147
 
  hdr.length = Swap32IfLE(ZRLE_BUFFER_LENGTH(&zos->out));
148
 
 
149
 
  memcpy(cl->updateBuf+cl->ublen, (char *)&hdr, sz_rfbZRLEHeader);
150
 
  cl->ublen += sz_rfbZRLEHeader;
151
 
 
152
 
  /* copy into updateBuf and send from there.  Maybe should send directly? */
153
 
 
154
 
  for (i = 0; i < ZRLE_BUFFER_LENGTH(&zos->out);) {
155
 
 
156
 
    int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
157
 
 
158
 
    if (i + bytesToCopy > ZRLE_BUFFER_LENGTH(&zos->out)) {
159
 
      bytesToCopy = ZRLE_BUFFER_LENGTH(&zos->out) - i;
160
 
    }
161
 
 
162
 
    memcpy(cl->updateBuf+cl->ublen, (uint8_t*)zos->out.start + i, bytesToCopy);
163
 
 
164
 
    cl->ublen += bytesToCopy;
165
 
    i += bytesToCopy;
166
 
 
167
 
    if (cl->ublen == UPDATE_BUF_SIZE) {
168
 
      if (!rfbSendUpdateBuf(cl))
169
 
        return FALSE;
170
 
    }
171
 
  }
172
 
 
173
 
  return TRUE;
174
 
}
175
 
 
176
 
 
177
 
void FreeZrleData(rfbClientPtr cl)
178
 
{
179
 
  if (cl->zrleData)
180
 
    zrleOutStreamFree(cl->zrleData);
181
 
  cl->zrleData = NULL;
182
 
}
183