00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "rfb/rfb.h"
00028 #include "private.h"
00029 #include "zrleoutstream.h"
00030
00031
00032 #define GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf) \
00033 { char *fbptr = (cl->scaledScreen->frameBuffer \
00034 + (cl->scaledScreen->paddedWidthInBytes * ty) \
00035 + (tx * (cl->scaledScreen->bitsPerPixel / 8))); \
00036 \
00037 (*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat,\
00038 &cl->format, fbptr, (char*)buf, \
00039 cl->scaledScreen->paddedWidthInBytes, tw, th); }
00040
00041 #define EXTRA_ARGS , rfbClientPtr cl
00042
00043 #define ENDIAN_LITTLE 0
00044 #define ENDIAN_BIG 1
00045 #define ENDIAN_NO 2
00046 #define BPP 8
00047 #define ZYWRLE_ENDIAN ENDIAN_NO
00048 #include <zrleencodetemplate.c>
00049 #undef BPP
00050 #define BPP 15
00051 #undef ZYWRLE_ENDIAN
00052 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
00053 #include <zrleencodetemplate.c>
00054 #undef ZYWRLE_ENDIAN
00055 #define ZYWRLE_ENDIAN ENDIAN_BIG
00056 #include <zrleencodetemplate.c>
00057 #undef BPP
00058 #define BPP 16
00059 #undef ZYWRLE_ENDIAN
00060 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
00061 #include <zrleencodetemplate.c>
00062 #undef ZYWRLE_ENDIAN
00063 #define ZYWRLE_ENDIAN ENDIAN_BIG
00064 #include <zrleencodetemplate.c>
00065 #undef BPP
00066 #define BPP 32
00067 #undef ZYWRLE_ENDIAN
00068 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
00069 #include <zrleencodetemplate.c>
00070 #undef ZYWRLE_ENDIAN
00071 #define ZYWRLE_ENDIAN ENDIAN_BIG
00072 #include <zrleencodetemplate.c>
00073 #define CPIXEL 24A
00074 #undef ZYWRLE_ENDIAN
00075 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
00076 #include <zrleencodetemplate.c>
00077 #undef ZYWRLE_ENDIAN
00078 #define ZYWRLE_ENDIAN ENDIAN_BIG
00079 #include <zrleencodetemplate.c>
00080 #undef CPIXEL
00081 #define CPIXEL 24B
00082 #undef ZYWRLE_ENDIAN
00083 #define ZYWRLE_ENDIAN ENDIAN_LITTLE
00084 #include <zrleencodetemplate.c>
00085 #undef ZYWRLE_ENDIAN
00086 #define ZYWRLE_ENDIAN ENDIAN_BIG
00087 #include <zrleencodetemplate.c>
00088 #undef CPIXEL
00089 #undef BPP
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w, int h)
00105 {
00106 zrleOutStream* zos;
00107 rfbFramebufferUpdateRectHeader rect;
00108 rfbZRLEHeader hdr;
00109 int i;
00110 char *zrleBeforeBuf;
00111
00112 if (cl->zrleBeforeBuf == NULL) {
00113 cl->zrleBeforeBuf = (char *) malloc(rfbZRLETileWidth * rfbZRLETileHeight * 4 + 4);
00114 }
00115 zrleBeforeBuf = cl->zrleBeforeBuf;
00116
00117 if (cl->preferredEncoding == rfbEncodingZYWRLE) {
00118 if (cl->tightQualityLevel < 0) {
00119 cl->zywrleLevel = 1;
00120 } else if (cl->tightQualityLevel < 3) {
00121 cl->zywrleLevel = 3;
00122 } else if (cl->tightQualityLevel < 6) {
00123 cl->zywrleLevel = 2;
00124 } else {
00125 cl->zywrleLevel = 1;
00126 }
00127 } else
00128 cl->zywrleLevel = 0;
00129
00130 if (!cl->zrleData)
00131 cl->zrleData = zrleOutStreamNew();
00132 zos = cl->zrleData;
00133 zos->in.ptr = zos->in.start;
00134 zos->out.ptr = zos->out.start;
00135
00136 switch (cl->format.bitsPerPixel) {
00137
00138 case 8:
00139 zrleEncode8NE(x, y, w, h, zos, zrleBeforeBuf, cl);
00140 break;
00141
00142 case 16:
00143 if (cl->format.greenMax > 0x1F) {
00144 if (cl->format.bigEndian)
00145 zrleEncode16BE(x, y, w, h, zos, zrleBeforeBuf, cl);
00146 else
00147 zrleEncode16LE(x, y, w, h, zos, zrleBeforeBuf, cl);
00148 } else {
00149 if (cl->format.bigEndian)
00150 zrleEncode15BE(x, y, w, h, zos, zrleBeforeBuf, cl);
00151 else
00152 zrleEncode15LE(x, y, w, h, zos, zrleBeforeBuf, cl);
00153 }
00154 break;
00155
00156 case 32: {
00157 rfbBool fitsInLS3Bytes
00158 = ((cl->format.redMax << cl->format.redShift) < (1<<24) &&
00159 (cl->format.greenMax << cl->format.greenShift) < (1<<24) &&
00160 (cl->format.blueMax << cl->format.blueShift) < (1<<24));
00161
00162 rfbBool fitsInMS3Bytes = (cl->format.redShift > 7 &&
00163 cl->format.greenShift > 7 &&
00164 cl->format.blueShift > 7);
00165
00166 if ((fitsInLS3Bytes && !cl->format.bigEndian) ||
00167 (fitsInMS3Bytes && cl->format.bigEndian)) {
00168 if (cl->format.bigEndian)
00169 zrleEncode24ABE(x, y, w, h, zos, zrleBeforeBuf, cl);
00170 else
00171 zrleEncode24ALE(x, y, w, h, zos, zrleBeforeBuf, cl);
00172 }
00173 else if ((fitsInLS3Bytes && cl->format.bigEndian) ||
00174 (fitsInMS3Bytes && !cl->format.bigEndian)) {
00175 if (cl->format.bigEndian)
00176 zrleEncode24BBE(x, y, w, h, zos, zrleBeforeBuf, cl);
00177 else
00178 zrleEncode24BLE(x, y, w, h, zos, zrleBeforeBuf, cl);
00179 }
00180 else {
00181 if (cl->format.bigEndian)
00182 zrleEncode32BE(x, y, w, h, zos, zrleBeforeBuf, cl);
00183 else
00184 zrleEncode32LE(x, y, w, h, zos, zrleBeforeBuf, cl);
00185 }
00186 }
00187 break;
00188 }
00189
00190 rfbStatRecordEncodingSent(cl, rfbEncodingZRLE, sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out),
00191 + w * (cl->format.bitsPerPixel / 8) * h);
00192
00193 if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader
00194 > UPDATE_BUF_SIZE)
00195 {
00196 if (!rfbSendUpdateBuf(cl))
00197 return FALSE;
00198 }
00199
00200 rect.r.x = Swap16IfLE(x);
00201 rect.r.y = Swap16IfLE(y);
00202 rect.r.w = Swap16IfLE(w);
00203 rect.r.h = Swap16IfLE(h);
00204 rect.encoding = Swap32IfLE(cl->preferredEncoding);
00205
00206 memcpy(cl->updateBuf+cl->ublen, (char *)&rect,
00207 sz_rfbFramebufferUpdateRectHeader);
00208 cl->ublen += sz_rfbFramebufferUpdateRectHeader;
00209
00210 hdr.length = Swap32IfLE(ZRLE_BUFFER_LENGTH(&zos->out));
00211
00212 memcpy(cl->updateBuf+cl->ublen, (char *)&hdr, sz_rfbZRLEHeader);
00213 cl->ublen += sz_rfbZRLEHeader;
00214
00215
00216
00217 for (i = 0; i < ZRLE_BUFFER_LENGTH(&zos->out);) {
00218
00219 int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
00220
00221 if (i + bytesToCopy > ZRLE_BUFFER_LENGTH(&zos->out)) {
00222 bytesToCopy = ZRLE_BUFFER_LENGTH(&zos->out) - i;
00223 }
00224
00225 memcpy(cl->updateBuf+cl->ublen, (uint8_t*)zos->out.start + i, bytesToCopy);
00226
00227 cl->ublen += bytesToCopy;
00228 i += bytesToCopy;
00229
00230 if (cl->ublen == UPDATE_BUF_SIZE) {
00231 if (!rfbSendUpdateBuf(cl))
00232 return FALSE;
00233 }
00234 }
00235
00236 return TRUE;
00237 }
00238
00239
00240 void rfbFreeZrleData(rfbClientPtr cl)
00241 {
00242 if (cl->zrleData) {
00243 zrleOutStreamFree(cl->zrleData);
00244 }
00245 cl->zrleData = NULL;
00246
00247 if (cl->zrleBeforeBuf) {
00248 free(cl->zrleBeforeBuf);
00249 }
00250 cl->zrleBeforeBuf = NULL;
00251
00252 if (cl->paletteHelper) {
00253 free(cl->paletteHelper);
00254 }
00255 cl->paletteHelper = NULL;
00256 }
00257