转自:http://blog.csdn.net/chief1985/archive/2009/01/02/3687243.aspx
VNC
1. 功能
在本机显示和控制别一台计算机的桌面,就像直接用那台计算机一样
2. VNC的编码方式主要有
a) Raw(0):不进行编码,直接传送数据,是最慢的一种
b) Copyrect(1):对于客户端,在已经有了相同象素数据的时候比较有效,比如移动或窗口内容滚动时
c) RRE(2):将象素颜色相同的某一个矩形区域作为一个整体传输
d) Hextile(5):是RRE编码的变种,把屏幕分成16x16象素的小块,每块用Raw或RRE方式转送
e) ZRLE(16):它结合了zlib压缩
二、Hextile原理
通过解释Hextile算法,说明了简单而常用的屏幕传送和压缩算法,希望对屏幕监测、传送相关的工作有所启发
1. 分割
a) 传送的图像区域被分为若干个大小为16×16象素的块,如果整个矩形不是16的倍数,则最后1行(或列)的块宽度(或高度)变小
b) 这些块按从左到右,从上到下的顺序排列,屏幕中变化的块被传送,不变的不被传送
c) 由于块大小是16x16,所以块内坐标XY可用一字节表示,WH可用一个字节表示
2. 标志位:
传送每块数据的之前,先要传送一个字节的标志位,标记出该块的传送的格式,它的每一位意义如下
a) 右一:Raw数据:不压缩,直接传送,一般此位置1时其它位都置0
b) 右二:包含背景色数据:标志位之后需要接收背景色数据
c) 右三:包含前景色数据:背景色之后需要接收前景色数据
d) 右四:是否含有子块:只要该块中含有两种及两种以上颜色,则此位置1
e) 右五:子块的颜色:如果含有两种颜色,此位置0,子块颜色用前景色;若该块中含有两种以上的颜色,此位置1,子块颜色需要单独指明
3. 块内部的编码:
a) 计算块内部的颜色数:一种、两种、多种,并记录出现频率最多的颜色为背景色,如果仅有两种颜色,则另一颜色记为前景色
b) 判断块内颜色数是否为一种,如果是,则先修改传送标志位,然后传送整块大小(0,0,w,h)和背景色,此块传送即完成
c) 如果不是一种,则把块拆分成颜色不同的小矩形,方法如下:
i. 先把块复制到一块内存区中,以免破坏原始数据,暂称tmpBuf
ii. 从第一个象素开始判断,该点颜色是否与背景色相同
iii. 如果不同,则分别向右和向下求得与该点颜色连续的色块
iv. 对比右色块和下色块,取出其中较大的一个,做为一个矩形色块
v. 在tmpBuf中把此矩形填成背景色,以避免重复判断
vi. 继续判断下一象素点……
d) 记录各个矩形色块的位置(x,y,w,h),如果块内含两种以上颜色,还要记录矩形色块的颜色值
e) 一边取得矩形色块,一边判断矩形色块描述数据的总长是否大于原始数据,如果大于原始数据,则放弃取色块,标志字节Raw位(右一)置1,以Raw方式直接传送原始数据,此块传送完成
f) 如果块含两种以上颜色,则将标志位的子块位(右五)置1,否则置0
g) 传送标志位,传送矩形色块个数,然后传送各矩形块数据,块中颜色数为2时不需要传送每个矩形块的颜色数据,只传位置即可
h) 注意:如果背景色或前景色与前一块(16x16块)相同,则可以不传送背景色或前景色,客户端会默认延用前一块的
三、参考实例
1. 源码:
a) 源码包:tightvnc-1.2.9.orig.tar.gz
b) 编码程序:tightvnc-1.2.9.orig/Xvnc/programs/Xserver/hw/vnc/hextile.c
c) 解码程序:rightvnc-1.2.9.orig/vncviewer/hextile.c
2. 参考文档
a) VNC协议简单分析-beta+4.9.pdf (CSDN可下载)
b) http://blogimg.chinaunix.net/blog/upfile/070613090634.pdf
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chief1985/archive/2009/01/02/3687243.aspx