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

📄 vncbuffer.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			unsigned char *c_block_ptr = c_row_ptr;

			const UINT blockright = min(x + nOptimizedBlockSize, ScaledRect.br.x);
			const UINT bytesPerBlockRow = (blockright-x) * bytesPerPixel;

			BOOL fCache = TRUE; // RDV@2002
			// Modif sf@2002 - v1.1.0
			// int nRowIndex = 0; // We don't reinit nRowIndex for each rect -> we don't always miss the same changed pixels
			int nOffset = (int)(bytesPerBlockRow / m_nAccuracyDiv);

			unsigned char *y_o_ptr = o_block_ptr;
			unsigned char *y_n_ptr = n_block_ptr;
			unsigned char *y_c_ptr = c_block_ptr;

			// Scan this block
			for (ay = y; ay < blockbottom; ay++)
			{
				if (
					memcmp(	n_block_ptr + (nRowIndex * nOffset),
							o_block_ptr + (nRowIndex * nOffset),
							nOffset
						  ) != 0
				   )
				{
					// A pixel has changed, so this block needs updating
					if (fSmallRect) // Ignore unchanged first rows (samll rect : less chance to miss changes when using nAccuracy div)
					{
						new_rect.tl.y = ay * m_nScale;
						y_n_ptr += ((ay-y) * m_bytesPerRow);
						y_o_ptr += ((ay-y) * m_bytesPerRow);
					}
					else
					{
						new_rect.tl.y = y * m_nScale;
					}
					new_rect.tl.x = x * m_nScale;
					new_rect.br.x = blockright * m_nScale;
					new_rect.br.y = blockbottom * m_nScale;

					for (by = ((fSmallRect) ? ay : y); by < blockbottom; by++)
					{
						// Until then, new rect and cached rect are equal.
						// So test the next row
						// TODO: send the common part as cached rect and the rest as changed rect
						if (fCache)
							if (memcmp(y_n_ptr, y_c_ptr, bytesPerBlockRow) != 0)
							{
								fCache = FALSE; // New rect and cached rect differ
							}
						memcpy(y_c_ptr, y_o_ptr, bytesPerBlockRow); // Save back buffer rect in cache
						memcpy(y_o_ptr, y_n_ptr, bytesPerBlockRow); // Save new rect in back buffer
						y_n_ptr += m_bytesPerRow;
						y_o_ptr += m_bytesPerRow;
						y_c_ptr += m_bytesPerRow;
					}
					if (fCache) // The Rect was in the cache
					{
						cacheRgn = cacheRgn.union_(rfb::Region2D(new_rect));
					}
					else // The Rect wasn't in the cache
					{
						dest = dest.union_ (new_rect);
					}

					break;
				}

				n_block_ptr += m_bytesPerRow;
				o_block_ptr += m_bytesPerRow;
				c_block_ptr += m_bytesPerRow;

				nRowIndex = (nRowIndex + 1) % m_nAccuracyDiv; // sf@2002 - v1.1.0
			}

			o_row_ptr += bytesPerBlockRow;
			n_row_ptr += bytesPerBlockRow;
			c_row_ptr += bytesPerBlockRow;
		}

		o_topleft_ptr += m_bytesPerRow * nOptimizedBlockSize;
		n_topleft_ptr += m_bytesPerRow * nOptimizedBlockSize;
		c_topleft_ptr += m_bytesPerRow * nOptimizedBlockSize;
	}
	}
	else
	{
	// Scan down the rectangle
	unsigned char *o_topleft_ptr = m_backbuff + (ScaledRect.tl.y * m_bytesPerRow) + (ScaledRect.tl.x * bytesPerPixel);
	unsigned char *n_topleft_ptr = TheBuffer  + (ScaledRect.tl.y * m_bytesPerRow) + (ScaledRect.tl.x * bytesPerPixel);
	for (y = ScaledRect.tl.y; y < ScaledRect.br.y; y += nOptimizedBlockSize)
	{
		// Work out way down the bitmap
		unsigned char * o_row_ptr = o_topleft_ptr;
		unsigned char * n_row_ptr = n_topleft_ptr;

		const UINT blockbottom = min(y + nOptimizedBlockSize, ScaledRect.br.y);
		for (x = ScaledRect.tl.x; x < ScaledRect.br.x; x += nOptimizedBlockSize)
		{
			// Work our way across the row
			unsigned char *n_block_ptr = n_row_ptr;
			unsigned char *o_block_ptr = o_row_ptr;

			const UINT blockright = min(x+nOptimizedBlockSize, ScaledRect.br.x);
			const UINT bytesPerBlockRow = (blockright-x) * bytesPerPixel;

			// Modif sf@2002 
			unsigned char *y_o_ptr = o_block_ptr;
			unsigned char *y_n_ptr = n_block_ptr;

			// int nRowIndex = 0;
			int nOffset = (int)(bytesPerBlockRow / m_nAccuracyDiv);

			// Scan this block
			for (ay = y; ay < blockbottom; ay++)
			{
				if (memcmp(	n_block_ptr + (nRowIndex * nOffset),
							o_block_ptr + (nRowIndex * nOffset),
							nOffset
						  ) != 0
				 )
				{
					// A pixel has changed, so this block needs updating
					if (fSmallRect) // Ignore unchanged first rows (samll rect : less chance to miss changes when using nAccuracy div)
					{
						new_rect.tl.y = ay * m_nScale;
						y_n_ptr += ((ay-y) * m_bytesPerRow);
						y_o_ptr += ((ay-y) * m_bytesPerRow);
					}
					else
					{
						new_rect.tl.y = y * m_nScale;
					}
					new_rect.tl.x = x * m_nScale;
					new_rect.br.x = (blockright * m_nScale);
					new_rect.br.y = (blockbottom * m_nScale);
					dest = dest.union_(new_rect);

					// Copy the changes to the back buffer
					for (by = ((fSmallRect) ? ay : y); by < blockbottom; by++)
					{
						memcpy(y_o_ptr, y_n_ptr, bytesPerBlockRow);
						y_n_ptr += m_bytesPerRow;
						y_o_ptr += m_bytesPerRow;
					}

					break;
				}
				// Last Run Ptr gets over de bounding
				// Boundcheker keeps complaining
				if (ay!=blockbottom-1)
				{
					n_block_ptr += m_bytesPerRow;
					o_block_ptr += m_bytesPerRow;
					nRowIndex = (nRowIndex + 1) % m_nAccuracyDiv;
				}
			}
			if (x != ScaledRect.br.x-1)
			{
				o_row_ptr += bytesPerBlockRow;
				n_row_ptr += bytesPerBlockRow;
			}
		}
		if (y != ScaledRect.br.y-1)
		{
			o_topleft_ptr += m_bytesPerRow * nOptimizedBlockSize;
			n_topleft_ptr += m_bytesPerRow * nOptimizedBlockSize;
		}
	}
	}
}

//rdv modif scaled and videodriver
void
vncBuffer::GrabRegion(rfb::Region2D &src,BOOL driver)
{
	rfb::RectVector rects;
	rfb::RectVector::iterator i;
	rfb::Rect grabRect;

	//
	// - Are there any rectangles to check?
	//
	src.get_rects(rects, 1, 1);
	if (rects.empty()) return;

	//
	// - Grab the rectangles that may have changed
	//
	//
	//************ Added extra cliprect check
	int x,y,w,h;
	for (i = rects.begin(); i != rects.end(); i++)
	{
		rfb::Rect rect = *i;
		x=rect.tl.x;
		y=rect.tl.y;
		w=rect.br.x-rect.tl.x;
		h=rect.br.y-rect.tl.y;
		src.subtract(rect);
		if (ClipRect(&x, &y, &w, &h, m_desktop->m_Cliprect.tl.x, m_desktop->m_Cliprect.tl.y,
				m_desktop->m_Cliprect.br.x-m_desktop->m_Cliprect.tl.x, m_desktop->m_Cliprect.br.y-m_desktop->m_Cliprect.tl.y))
			{
				rect.tl.x=x;
				rect.tl.y=y;
				rect.br.x=x+w;
				rect.br.y=y+h;
				src.union_(rect);
			}
	}
	src.get_rects(rects, 1, 1);
	if (rects.empty()) 
		{
			return;
		}

	// The rectangles should have arrived in order of height
	for (i = rects.begin(); i != rects.end(); i++)
	{
		rfb::Rect current = *i;


		// Check that this rectangle is part of this capture region
		if (current.tl.y > grabRect.br.y)
		{
			// If the existing rect is non-null the capture it
			if (!grabRect.is_empty()) GrabRect(grabRect,driver);

			grabRect = current;
		} else {
			grabRect = current.union_boundary(grabRect);
		}
	}

	// If there are still some rects to be done then do them
	if (!grabRect.is_empty()) GrabRect(grabRect,driver);
}

void
vncBuffer::CheckRegion(rfb::Region2D &dest,rfb::Region2D &cacheRgn ,const rfb::Region2D &src)
{
	rfb::RectVector rects;
	rfb::RectVector::iterator i;

	// If there is nothing to do then do nothing...
	src.get_rects(rects, 1, 1);
	if (rects.empty()) return;

	//
	// - Scan the specified rectangles for changes
	//
	// Block desactivation mainbuff while running
	// No Lock Needed, only called from vncdesktopthread
	for (i = rects.begin(); i != rects.end(); i++)
	{
		CheckRect(dest,cacheRgn, *i);
	}
}



// Reduce possible colors to 8 shades of gray
int To8GreyColors(int r, int g, int b)
{
    int Value;
    Value = (r*11 + g*16 +b*5 ) / 32;
	
	if (Value <= 0x20)
		return 0x101010;
	else if (Value <= 0x40)
		return 0x303030;
	else if (Value <= 0x60)
		return 0x505050;
	else if (Value <= 0x80)
		return 0x707070;
	else if (Value <= 0xa0)
		return 0x909090;
	else if (Value <= 0xc0)
		return 0xb0b0b0;
	else if (Value <= 0xe0)
		return 0xd0d0d0;
	else
		return 0xf0f0f0;  
}
 

// Modif sf@2002 - Scaling
void vncBuffer::ScaleRect(rfb::Rect &rect)
{
    bool fCanReduceColors = true;

    //JK 26th Jan, 2005: Color conversion to 8 shades of gray added,
	//at the moment only works if server has 24/32-bit color
	if ((m_scrinfo.format.redMax == 255) 
		&& 
		(m_scrinfo.format.blueMax == 255)
		&&
		(m_scrinfo.format.greenMax == 255)
		&&
		m_fGreyPalette
		)
		fCanReduceColors = true;
	else
		fCanReduceColors = false;
	//End JK

	// called from grabrect and grabmouse
	// grabmouse is only called from desktopthread, no lock needed
	// grebrect called from grabregion called from desktopthread, no lock needed
	// no lock needed
	if (!FastCheckMainbuffer())
		return;
	///////////
	rect.tl.y = (rect.tl.y - (rect.tl.y % m_nScale));
	rect.br.y = (rect.br.y - (rect.br.y % m_nScale)) + m_nScale - 1;
	rect.tl.x = (rect.tl.x - (rect.tl.x % m_nScale));
	rect.br.x = (rect.br.x - (rect.br.x % m_nScale)) + m_nScale - 1;

	rfb::Rect ScaledRect;
	ScaledRect.tl.y = rect.tl.y / m_nScale;
	ScaledRect.br.y = rect.br.y / m_nScale;
	ScaledRect.tl.x = rect.tl.x / m_nScale;
	ScaledRect.br.x = rect.br.x / m_nScale;

	// Copy and scale data from screen Main buffer to Scaled buffer
	BYTE *pMain   =	m_mainbuff + (rect.tl.y * m_bytesPerRow) + 
					(rect.tl.x * m_scrinfo.format.bitsPerPixel / 8);
	BYTE *pScaled = m_ScaledBuff + (ScaledRect.tl.y * m_bytesPerRow) +
					(ScaledRect.tl.x * m_scrinfo.format.bitsPerPixel / 8);

	// We keep one pixel for m_Scale*m_nScale pixels in the Main buffer
	// and copy it in the Scaled Buffer

	// TrueColor Case.
	// Pixels Blending (takes the "medium" pixel of each m_Scale*m_nScale square)
	// This TrueColor Pixel blending routine comes from the Harakan's WinVNC with Server Side Scaling
	// Extension. It replaces my own buggy Blending function that given *ugly* results.
	if (m_scrinfo.format.trueColour)
	{
		unsigned long lRed;
		unsigned long lGreen;
		unsigned long lBlue;
		unsigned long lScaledPixel;
		UINT nBytesPerPixel = (m_scrinfo.format.bitsPerPixel / 8);

		// For each line of the Destination ScaledRect
		for (int y = ScaledRect.tl.y; y < ScaledRect.br.y; y++)
		{
			// For each Pixel of the line 
			for (int x = 0; x < (ScaledRect.br.x - ScaledRect.tl.x); x++)
			{
				lRed   = 0; 
				lGreen = 0;
				lBlue  = 0;
				// Take a m_Scale*m_nScale square of pixels in the Main Buffer
				// and get the global Red, Green, Blue values for this square
				for (int r = 0; r < m_nScale; r++)
				{
					for (int c = 0; c < m_nScale; c++)
					{
						lScaledPixel = 0;
						for (int b = 0; b < nBytesPerPixel; b++)
						{
							lScaledPixel += (pMain[(((x * m_nScale) + c) * nBytesPerPixel) + (r * m_bytesPerRow) + b]) << (8 * b);
						}
						lRed   += (lScaledPixel >> m_scrinfo.format.redShift) & m_scrinfo.format.redMax;
						lGreen += (lScaledPixel >> m_scrinfo.format.greenShift) & m_scrinfo.format.greenMax;
						lBlue  += (lScaledPixel >> m_scrinfo.format.blueShift) & m_scrinfo.format.blueMax;
					}
				}
				// Get the medium R,G,B values for the sqare
				lRed   /= m_nScale * m_nScale;
				lGreen /= m_nScale * m_nScale;
				lBlue  /= m_nScale * m_nScale;
				// Calculate the resulting "medium" pixel
				// lScaledPixel = (lRed << m_scrinfo.format.redShift) + (lGreen << m_scrinfo.format.greenShift) + (lBlue << m_scrinfo.format.blueShift);
                // JK 26th Jan, 2005: Reduce possible colors to 8 shades of gray

⌨️ 快捷键说明

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