vncEncodeHexT.cpp
Upload User: sbftbdw
Upload Date: 2007-01-03
Package Size: 379k
Code Size: 13k
Category:

Remote Control

Development Platform:

Visual C++

  1. //  Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
  2. //
  3. //  This file is part of the VNC system.
  4. //
  5. //  The VNC system 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 program 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 program; if not, write to the Free Software
  17. //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  18. //  USA.
  19. //
  20. // If the source code for the VNC system is not available from the place 
  21. // whence you received this file, check http://www.orl.co.uk/vnc or contact
  22. // the authors on vnc@orl.co.uk for information on obtaining it.
  23. // vncEncodeHexT
  24. // This file implements the vncEncoder-derived vncEncodeHexT class.
  25. // This class overrides some vncEncoder functions to produce a
  26. // Hextile encoder.  Hextile splits all top-level update rectangles
  27. // into smaller, 16x16 rectangles and encodes these using the
  28. // optimised Hextile sub-encodings.
  29. #include "vncEncodeHexT.h"
  30. #include "rfb.h"
  31. #include "MinMax.h"
  32. #include <stdlib.h>
  33. #include <time.h>
  34. vncEncodeHexT::vncEncodeHexT()
  35. {
  36. }
  37. vncEncodeHexT::~vncEncodeHexT()
  38. {
  39. }
  40. void
  41. vncEncodeHexT::Init()
  42. {
  43. vncEncoder::Init();
  44. }
  45. UINT
  46. vncEncodeHexT::RequiredBuffSize(UINT width, UINT height)
  47. {
  48. return vncEncoder::RequiredBuffSize(width, height) + (((width/16)+1) * ((height/16)+1));
  49. }
  50. UINT
  51. vncEncodeHexT::NumCodedRects(RECT &rect)
  52. {
  53. return 1;
  54. }
  55. /*
  56.  * hextile.c
  57.  *
  58.  * Routines to implement Hextile Encoding
  59.  */
  60. #include <stdio.h>
  61. #include "rfb.h"
  62. /*
  63.  * vncEncodeHexT::EncodeRect - send a rectangle using hextile encoding.
  64.  */
  65. UINT
  66. vncEncodeHexT::EncodeRect(BYTE *source, BYTE *dest, const RECT &rect)
  67. {
  68. const rectW = rect.right - rect.left;
  69. const rectH = rect.bottom - rect.top;
  70. // Create the rectangle header
  71. rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest;
  72. surh->r.x = (CARD16) rect.left;
  73. surh->r.y = (CARD16) rect.top;
  74. surh->r.w = (CARD16) (rectW);
  75. surh->r.h = (CARD16) (rectH);
  76. surh->r.x = Swap16IfLE(surh->r.x);
  77. surh->r.y = Swap16IfLE(surh->r.y);
  78. surh->r.w = Swap16IfLE(surh->r.w);
  79. surh->r.h = Swap16IfLE(surh->r.h);
  80. surh->encoding = Swap32IfLE(rfbEncodingHextile);
  81. // Do the encoding
  82.     switch (m_remoteformat.bitsPerPixel)
  83. {
  84. case 8:
  85. return sz_rfbFramebufferUpdateRectHeader +
  86. EncodeHextiles8(source, dest + sz_rfbFramebufferUpdateRectHeader,
  87. rect.left, rect.top, rectW, rectH);
  88.     case 16:
  89. return sz_rfbFramebufferUpdateRectHeader +
  90. EncodeHextiles16(source, dest + sz_rfbFramebufferUpdateRectHeader,
  91. rect.left, rect.top, rectW, rectH);
  92.     case 32:
  93. return sz_rfbFramebufferUpdateRectHeader +
  94. EncodeHextiles32(source, dest + sz_rfbFramebufferUpdateRectHeader,
  95. rect.left, rect.top, rectW, rectH);
  96.     }
  97. return vncEncoder::EncodeRect(source, dest, rect);
  98. }
  99. #define PUT_PIXEL8(pix) (dest[destoffset++] = (pix))
  100. #define PUT_PIXEL16(pix) (dest[destoffset++] = ((char*)&(pix))[0],
  101.   dest[destoffset++] = ((char*)&(pix))[1])
  102. #define PUT_PIXEL32(pix) (dest[destoffset++] = ((char*)&(pix))[0],
  103.   dest[destoffset++] = ((char*)&(pix))[1],
  104.   dest[destoffset++] = ((char*)&(pix))[2],
  105.   dest[destoffset++] = ((char*)&(pix))[3])
  106. #define DEFINE_SEND_HEXTILES(bpp)
  107. static UINT subrectEncode##bpp(CARD##bpp *src, BYTE *dest,
  108. int w, int h, CARD##bpp bg,
  109.     CARD##bpp fg, BOOL mono);
  110. static void testColours##bpp(CARD##bpp *data, int size, BOOL *mono,
  111.      BOOL *solid, CARD##bpp *bg, CARD##bpp *fg);
  112. /*
  113.  * rfbSendHextiles
  114.  */
  115. UINT
  116. vncEncodeHexT::EncodeHextiles##bpp(BYTE *source, BYTE *dest,
  117.   int rx, int ry, int rw, int rh)
  118. {
  119.     int x, y, w, h;
  120.     int rectoffset, destoffset;
  121.     CARD##bpp bg, fg, newBg, newFg;
  122.     BOOL mono, solid;
  123.     BOOL validBg = FALSE;
  124.     CARD##bpp clientPixelData[16*16*(bpp/8)];
  125.     BOOL validFg = FALSE;
  126. destoffset = 0;
  127.     for (y = ry; y < ry+rh; y += 16)
  128. {
  129. for (x = rx; x < rx+rw; x += 16)
  130. {
  131.     w = h = 16;
  132.     if (rx+rw - x < 16)
  133. w = rx+rw - x;
  134.     if (ry+rh - y < 16)
  135. h = ry+rh - y;
  136. RECT hexrect;
  137. hexrect.left = x;
  138. hexrect.top = y;
  139. hexrect.right = x+w;
  140. hexrect.bottom = y+h;
  141. Translate(source, (BYTE *) &clientPixelData, hexrect);
  142. rectoffset = destoffset;
  143. dest[rectoffset] = 0;
  144. destoffset++;
  145. testColours##bpp(clientPixelData, w * h,
  146.      &mono, &solid, &newBg, &newFg);
  147. if (!validBg || (newBg != bg))
  148. {
  149. validBg = TRUE;
  150. bg = newBg;
  151. dest[rectoffset] |= rfbHextileBackgroundSpecified;
  152. PUT_PIXEL##bpp(bg);
  153. }
  154. if (solid)
  155. continue;
  156. dest[rectoffset] |= rfbHextileAnySubrects;
  157. if (mono)
  158. {
  159. if (!validFg || (newFg != fg))
  160. {
  161. validFg = TRUE;
  162. fg = newFg;
  163. dest[rectoffset] |= rfbHextileForegroundSpecified;
  164. PUT_PIXEL##bpp(fg);
  165. }
  166. }
  167. else
  168. {
  169. validFg = FALSE;
  170. dest[rectoffset] |= rfbHextileSubrectsColoured;     
  171. }
  172. int encodedbytes = subrectEncode##bpp(clientPixelData,
  173.    dest + destoffset,
  174.    w, h, bg, fg, mono);
  175. destoffset += encodedbytes;
  176. if (encodedbytes == 0)
  177. {
  178. /* encoding was too large, use raw */
  179. validBg = FALSE;
  180. validFg = FALSE;
  181. destoffset = rectoffset;
  182. dest[destoffset++] = rfbHextileRaw;
  183. Translate(source, (BYTE *) &clientPixelData, hexrect);
  184. memcpy(dest + destoffset, (char *)clientPixelData,
  185.        w * h * (bpp/8));
  186. destoffset += w * h * (bpp/8);
  187.     }
  188. }
  189.     }
  190.     return destoffset;
  191. }
  192. static UINT
  193. subrectEncode##bpp(CARD##bpp *src, BYTE *dest, int w, int h, CARD##bpp bg,
  194.    CARD##bpp fg, BOOL mono)
  195. {
  196.     CARD##bpp cl;
  197.     int x,y;
  198.     int i,j;
  199.     int hx=0,hy,vx=0,vy;
  200.     int hyflag;
  201.     CARD##bpp *seg;
  202.     CARD##bpp *line;
  203.     int hw,hh,vw,vh;
  204.     int thex,they,thew,theh;
  205.     int numsubs = 0;
  206.     int newLen;
  207.     int rectoffset;
  208. int destoffset;
  209. destoffset = 0;
  210.     rectoffset = destoffset;
  211.     destoffset++;
  212.     for (y=0; y<h; y++)
  213. {
  214. line = src+(y*w);
  215. for (x=0; x<w; x++)
  216. {
  217.     if (line[x] != bg)
  218. {
  219. cl = line[x];
  220. hy = y-1;
  221. hyflag = 1;
  222. for (j=y; j<h; j++)
  223. {
  224. seg = src+(j*w);
  225. if (seg[x] != cl) {break;}
  226. i = x;
  227. while ((seg[i] == cl) && (i < w)) i += 1;
  228. i -= 1;
  229. if (j == y) vx = hx = i;
  230. if (i < vx) vx = i;
  231. if ((hyflag > 0) && (i >= hx))
  232. {
  233. hy += 1;
  234. }
  235. else
  236. {
  237. hyflag = 0;
  238. }
  239. }
  240. vy = j-1;
  241. /* We now have two possible subrects: (x,y,hx,hy) and
  242.  * (x,y,vx,vy).  We'll choose the bigger of the two.
  243.  */
  244. hw = hx-x+1;
  245. hh = hy-y+1;
  246. vw = vx-x+1;
  247. vh = vy-y+1;
  248. thex = x;
  249. they = y;
  250. if ((hw*hh) > (vw*vh))
  251. {
  252.     thew = hw;
  253.     theh = hh;
  254. }
  255. else
  256. {
  257.     thew = vw;
  258.     theh = vh;
  259. }
  260. if (mono)
  261. {
  262.     newLen = destoffset - rectoffset + 2;
  263. }
  264. else
  265. {
  266.     newLen = destoffset - rectoffset + bpp/8 + 2;
  267. }
  268. if (newLen > (w * h * (bpp/8)))
  269.     return 0;
  270. numsubs += 1;
  271. if (!mono) PUT_PIXEL##bpp(cl);
  272. dest[destoffset++] = rfbHextilePackXY(thex,they);
  273. dest[destoffset++] = rfbHextilePackWH(thew,theh);
  274. /*
  275.  * Now mark the subrect as done.
  276.  */
  277. for (j=they; j < (they+theh); j++)
  278. {
  279. for (i=thex; i < (thex+thew); i++)
  280. {
  281. src[j*w+i] = bg;
  282. }
  283. }
  284.     }
  285. }
  286.     }
  287.     dest[rectoffset] = numsubs;
  288.     return destoffset;
  289. }
  290. /*
  291.  * testColours() tests if there are one (solid), two (mono) or more
  292.  * colours in a tile and gets a reasonable guess at the best background     
  293.  * pixel, and the foreground pixel for mono.
  294.  */
  295. static void
  296. testColours##bpp(CARD##bpp *data, int size,
  297.  BOOL *mono, BOOL *solid,
  298.  CARD##bpp *bg, CARD##bpp *fg)
  299. {
  300.     CARD##bpp colour1, colour2;
  301.     int n1 = 0, n2 = 0;
  302.     *mono = TRUE;
  303.     *solid = TRUE;
  304.     for (; size > 0; size--, data++)
  305. {
  306. if (n1 == 0)
  307.     colour1 = *data;
  308. if (*data == colour1)
  309. {
  310.     n1++;
  311.     continue;
  312. }
  313. if (n2 == 0)
  314. {
  315.     *solid = FALSE;
  316.     colour2 = *data;
  317. }
  318. if (*data == colour2)
  319. {
  320.     n2++;
  321.     continue;
  322. }
  323. *mono = FALSE;
  324. break;
  325. }
  326.     if (n1 > n2)
  327. {
  328. *bg = colour1;
  329. *fg = colour2;
  330.     }
  331. else
  332. {
  333. *bg = colour2;
  334. *fg = colour1;
  335.     }
  336. }
  337. DEFINE_SEND_HEXTILES(8)
  338. DEFINE_SEND_HEXTILES(16)
  339. DEFINE_SEND_HEXTILES(32)