⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncencodecorre.cpp

📁 Web VNC samples delphi
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
//  This file is part of the VNC system.
//
//  The VNC system is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
//
// If the source code for the VNC system is not available from the place 
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
// the authors on vnc@uk.research.att.com for information on obtaining it.


// vncEncodeCoRRE

// This file implements the vncEncoder-derived vncEncodeCoRRE class.
// This class overrides some vncEncoder functions to produce a
// Compact RRE encoder.  Compact RRE (CoRRE) uses fewer bytes to
// encode each subrect, which makes it faster in general.  It also
// splits large rectangles up into ones of at most 256 pixels width
// & height.  This results in better granularity to use for deciding
// whether to send RAW or CoRRE/RRE. 

#include "vncEncodeCoRRE.h"
#include "rfb.h"
#include "MinMax.h"
#include <stdlib.h>
#include <time.h>

vncEncodeCoRRE::vncEncodeCoRRE()
{
	m_buffer = NULL;
	m_bufflen = 0;

	// Set some sensible defaults
	m_maxwidth = 24;
	m_maxheight = 24;
	m_maxadjust = 1;

	// Set the threshold up/down probability
	m_threshold = 50;

	// Seed the random number generator
	srand((unsigned)time(NULL));

	m_statsready = FALSE;
	m_encodedbytes = 0;
	m_rectbytes = 0;
}

vncEncodeCoRRE::~vncEncodeCoRRE()
{
	if (m_buffer != NULL)
	{
		delete [] m_buffer;
		m_buffer = NULL;
	}
}

void vncEncodeCoRRE::Init()
{
	vncEncoder::Init();
}

UINT vncEncodeCoRRE::RequiredBuffSize(UINT width, UINT height)
{
	RECT fullscreen;
	UINT codedrects;

	// Work out how many rectangles the entire screen would
	// be re-encoded to...
	fullscreen.left = 0;
	fullscreen.top = 0;
	fullscreen.right = width;
	fullscreen.bottom = height;
	codedrects = NumCodedRects(fullscreen);

	// The buffer size required is the size of raw data for the whole
	// screen plus enough space for the required number of rectangle
	// headers.
	// This is inherently always greater than the RAW encoded size of
	// the whole screen!
	return (codedrects * sz_rfbFramebufferUpdateRectHeader) +
			(width * height * m_remoteformat.bitsPerPixel)/8;
}

UINT
vncEncodeCoRRE::NumCodedRects(RECT &rect)
{
	// If we have any statistical data handy then adjust the CoRRE sizes
	if (m_statsready)
	{
		m_statsready = FALSE;

		UINT newscore = m_encodedbytes * m_lastrectbytes;
		UINT oldscore = m_lastencodedbytes * m_rectbytes;

		if (newscore <= oldscore)
		{
			// The change was a good one, so adjust the threshold accordingly!
			m_threshold = Max(5, Min(95, m_threshold + m_maxadjust));

			m_maxwidth = Max(8, Min(255, m_maxwidth + m_maxadjust));
			m_maxheight = Max(8, Min(255, m_maxheight + m_maxadjust));
		}
		else
		{
			// The change was a bad one, so adjust the threshold accordingly!
			// m_threshold = Max(5, Min(95, m_threshold - m_maxadjust));
		}

		// Now calculate a new adjustment and apply it
		m_maxadjust = ((rand() % 99)<m_threshold) ? 1 : -1;
		
		// Prepare the stats data for next time...
		m_lastencodedbytes = m_encodedbytes;
		m_lastrectbytes = m_rectbytes;

		m_encodedbytes = 0;
		m_rectbytes = 0;
	}

	// Now return the number of rects that this one would encode to
    if ((rect.bottom-rect.top) > m_maxheight)
	{
		RECT subrect1, subrect2;

		// Find how many rects the two subrects would take
		subrect1.left = rect.left;
		subrect1.right = rect.right;
		subrect1.top = rect.top;
		subrect1.bottom = rect.top + m_maxheight;

		subrect2.left = rect.left;
		subrect2.right = rect.right;
		subrect2.top = rect.top + m_maxheight;
		subrect2.bottom = rect.bottom;

		return NumCodedRects(subrect1) + NumCodedRects(subrect2);
	}

    if ((rect.right-rect.left) > m_maxwidth)
	{
		RECT subrect1, subrect2;

		// Find how many rects the two subrects would take
		subrect1.left = rect.left;
		subrect1.right = rect.left + m_maxwidth;
		subrect1.top = rect.top;
		subrect1.bottom = rect.bottom;

		subrect2.left = rect.left + m_maxwidth;
		subrect2.right = rect.right;
		subrect2.top = rect.top;
		subrect2.bottom = rect.bottom;
		return NumCodedRects(subrect1) + NumCodedRects(subrect2);
	}

	// This rectangle is small enough not to require splitting
	return 1;
}

/*
 * corre.c
 *
 * Routines to implement Compact Rise-and-Run-length Encoding (CoRRE).  This
 * code is based on krw's original javatel rfbserver.
 */

/*
 * This version modified for WinVNC by jnw.
 */

static int rreAfterBufLen;

static int subrectEncode8 (CARD8 *source, CARD8 *dest, int w, int h, int max);
static int subrectEncode16 (CARD16 *source, CARD8 *dest, int w, int h, int max);
static int subrectEncode32 (CARD32 *source, CARD8 *dest, int w, int h, int max);
static CARD32 getBgColour (char *data, int size, int bpp);

/*
 * vncEncodeCoRRE::EncodeRect - send an arbitrary size rectangle using CoRRE
 * encoding.
 */

UINT
vncEncodeCoRRE::EncodeRect(BYTE *source, BYTE *dest, const RECT &rect, int offx, int offy)
{
	// Do the encoding
	UINT size = InternalEncodeRect(source, dest, rect);

	const int rectW = rect.right - rect.left;
	const int rectH = rect.bottom - rect.top;
	offsetx = offx;
	offsety = offy;

	// Will this rectangle have been split for encoding?
	if ((rectW>m_maxwidth) || (rectH>m_maxheight))
	{
		// Yes : Once we return, the stats will be valid!
		m_statsready = TRUE;

		// Update the stats
		m_encodedbytes += size;
		m_rectbytes += sz_rfbFramebufferUpdateRectHeader +
			(rectW*rectH*m_remoteformat.bitsPerPixel/8);
	}

	return size;
}

UINT
vncEncodeCoRRE::InternalEncodeRect(BYTE *source, BYTE *dest, const RECT &rect)
{
	int size = 0;

    if ((rect.bottom-rect.top) > m_maxheight)
	{
		RECT subrect;

		// Rectangle is too high - split it into two subrects to send
		subrect.left = rect.left;
		subrect.right = rect.right;
		subrect.top = rect.top;
		subrect.bottom = rect.top + m_maxheight;
		size += InternalEncodeRect(source, dest + size, subrect);

		subrect.left = rect.left;
		subrect.right = rect.right;
		subrect.top = rect.top + m_maxheight;
		subrect.bottom = rect.bottom;
		size += InternalEncodeRect(source, dest + size, subrect);

		return size;
    }

    if ((rect.right-rect.left) > m_maxwidth)
	{
		RECT subrect;

		// Rectangle is too high - split it into two subrects to send
		subrect.left = rect.left;
		subrect.right = rect.left + m_maxwidth;
		subrect.top = rect.top;
		subrect.bottom = rect.bottom;
		size += InternalEncodeRect(source, dest + size, subrect);

		subrect.left = rect.left + m_maxwidth;
		subrect.right = rect.right;
		subrect.top = rect.top;
		subrect.bottom = rect.bottom;
		size += InternalEncodeRect(source, dest + size, subrect);

		return size;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -