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

📄 cpixeldepthchanger.cpp

📁 ARM_显示器_键盘_源代码
💻 CPP
字号:

// ARM Ltd
// Copyright 1998 All Rights reserved

// David Earlam 22.9.1998
// helper class to change the color-depth (bits per pixel) of uncompresed bitmap image bits while keeping
// the original width and height

// assumes that the first (leftmost) pixel in a row is encoded in the <srcBpp> most significant
// bits of a byte  

// limitations: currently can only keep or increase effective color depth 1:1, 1:2, 1:4, not reduce it

#include <afxwin.h>
#include "CPixelDepthChanger.h"

// DR DEBUG
#define LEFT_TO_RIGHT

#define BOTTOM_TO_TOP

IMPLEMENT_SERIAL(CPixelDepthChanger, CObject, 0);

CPixelDepthChanger::CPixelDepthChanger()
{
m_pdstBits = NULL;
m_psrcBits = NULL;
m_srcSize = NULL;
m_lookup = NULL;
m_bDelete_pdstBits=FALSE;
}

CPixelDepthChanger::CPixelDepthChanger( int srcWidth, int srcHeight, int srcBpp, void *psrcBits, CDib& rDstCDib  )
{	
	m_psrcBits = (LPBYTE)psrcBits;

	m_srcSize = VolumeFromWidthHeightDepth(srcWidth, srcHeight, srcBpp);
	
	//m_pshadowsrcBits = new BYTE[m_srcSize];
//	memcpy (m_pshadowsrcBits, m_psrcBits, m_srcSize); //make a copy of the source to detect what has changed since last update

	m_bDelete_pdstBits=FALSE;

	DWORD dstSize;
	if ((dstSize = rDstCDib.GetSizeImage() )!=0)
	{
		if (rDstCDib.m_lpImage == NULL)
		{ 
			rDstCDib.m_lpImage = new BYTE[dstSize];
			
			m_bDelete_pdstBits=TRUE;
		}
		m_pdstBits = (LPBYTE) rDstCDib.m_lpImage;
	}

    CreateLookupTable(srcBpp, rDstCDib.m_lpBMIH->biBitCount);
}

void CPixelDepthChanger::CreateLookupTable(int srcBpp, int dstBpp)
{
	int nLookupTableEntries  =  256; // 2^ bits in a byte, we'll lookup by byte

	m_magnification = dstBpp / srcBpp;

	switch (m_magnification)
	{
	case 1: case 2: case 4: break;
			default:	
			AfxMessageBox("Bit per pixel magnification factors of 1:1, 1:2 and 1:4 only supported");
	}

	m_lookup = new BYTE[nLookupTableEntries * m_magnification];
	LPWORD p_lookup16bits = (LPWORD)m_lookup ;
	LPDWORD p_lookup32bits = (LPDWORD)m_lookup ;
	LPBYTE p_lookup8bits = (LPBYTE)m_lookup ;

	int pixelmask =(1 << srcBpp) -1;


	int i=0;
	while ( i < nLookupTableEntries)
	{
		int pixel0,pixel1,pixel2,pixel3;
		int bits = i;
		int dst_pixel;

		// DEBUG
		pixelmask =(1 << srcBpp) -1;
		
		pixel3 = bits & pixelmask;
		//bits <<= srcBpp;
		bits >>= srcBpp;
		
		pixel2 = bits & pixelmask;
		bits >>= srcBpp;
		
		pixel1 = bits & pixelmask;
		bits >>= srcBpp;
	
		pixel0 = bits & pixelmask;
		bits >>= srcBpp;

#ifdef LEFT_TO_RIGHT
		dst_pixel = (((((pixel0 << dstBpp)	| pixel1) << dstBpp) | pixel2) << dstBpp) | pixel3;
#else
		dst_pixel = (((((pixel3 << dstBpp)	| pixel2) << dstBpp) | pixel1) << dstBpp) | pixel0;
#endif

		switch (m_magnification)
		{
		case 1:
			*p_lookup8bits++ =dst_pixel;
				break;
		case 2:
			*p_lookup16bits++ =dst_pixel;
				break;
		case 4:
			*p_lookup32bits++ =dst_pixel;
		}

		++i;
	}
}

void CPixelDepthChanger::Update(void)
{
	if (m_pdstBits == NULL) return;
	
	DWORD nByte = 0;
	

	switch (m_magnification)
	{
	case 1:
		{
		LPBYTE p_lookup8bits = (LPBYTE)m_lookup ;
		LPBYTE pdstBits8bits = (LPBYTE)m_pdstBits ;
		LPBYTE psrcBits8bits = (LPBYTE)m_psrcBits ;

#ifndef BOTTOM_TO_TOP
		int count = m_dwBytes;
		psrcBits8bits += m_srcSize - m_dwBytes;
#endif

		BYTE index;

		while (nByte < m_srcSize)
		{
			index = *psrcBits8bits++;
			//byte_lookup = p_lookup8bits[index];
			//pdstBits8bits[nByte] = byte_lookup; //why use the lookup, we could just copy?
			
			pdstBits8bits[nByte] = index;

#ifndef BOTTOM_TO_TOP
			if (--count == 0) {
				count = m_dwBytes;
				psrcBits8bits -= 2*m_dwBytes;
			}
#endif
			++nByte;
		}
		break;
		}
	case 2:
		{
		LPWORD p_lookup16bits = (LPWORD)m_lookup ;
		LPWORD pdstBits16bits = (LPWORD)m_pdstBits ;
		LPBYTE psrcBits8bits = (LPBYTE)m_psrcBits ;

#ifndef BOTTOM_TO_TOP
		int count = m_dwBytes;
		psrcBits8bits += m_srcSize - m_dwBytes;
#endif

		while (nByte < m_srcSize)
		{

//			char buf[30]; sprintf(buf,"%d %d",nByte,psrcBits8bits-m_psrcBits); AfxMessageBox(buf);

			pdstBits16bits[nByte] = p_lookup16bits[*psrcBits8bits++];

#ifndef BOTTOM_TO_TOP
			if (--count == 0) {
				count = m_dwBytes;
				psrcBits8bits -= 2*m_dwBytes;
			}
#endif

			++nByte;
		}
		break;
		}
	 case 4: 
		{
		LPDWORD p_lookup32bits = (LPDWORD)m_lookup ;
		LPDWORD pdstBits32bits = (LPDWORD)m_pdstBits ;
		while (nByte < m_srcSize)
		{

			pdstBits32bits[nByte] = p_lookup32bits[m_psrcBits[nByte]];

			++nByte;
		}
		break;
		 }
	}


}


CPixelDepthChanger::~CPixelDepthChanger()
{
	if (m_lookup !=NULL)
	{
		delete[] m_lookup;
	}
	if (m_bDelete_pdstBits)
	{
		delete[] m_pdstBits;
	}
	delete[] m_pshadowsrcBits;
}

DWORD CPixelDepthChanger::VolumeFromWidthHeightDepth(int srcWidth, int srcHeight, int srcBpp)
{
		/* DR modified - this is dodgy! */
		m_srcWidth = srcWidth;
		m_srcHeight = srcHeight;
		m_srcBpp = srcBpp;
	
		
		m_dwBytes = ((DWORD) srcWidth * srcBpp) / 32;


		if(((DWORD) srcWidth * srcBpp) % 32) {
			m_dwBytes++;
		}
		m_dwBytes *= 4;  //rows are multiples of four bytes
		return m_dwBytes * srcHeight; // no compression
		
}

#if 0
CRect CPixelDepthChanger::GetInvalidRect()
{
	//compare shadow buffer with src buffer bits starting top left
	// stop at the left most upper most byte that is different
	// then compore staring bottom right
	// returns the larget rectangle containing differences
	// once the shadow buffer has been updated with those differences

	CRect rectBounding;
	rectBounding.SetRectEmpty();

    return rectBounding;

	//test memset ( m_pshadowsrcBits + 4* m_srcWidth '0', m_srcWidth); //make some lines black (actually srcbits will have been changed by other process)

	// for very large unchanging screen this might return faster; slower refreshTimer interval is probably more sensible
	//if (memcmp(m_psrcBits,	m_pshadowsrcBits,m_srcSize)==0)
	//{
	//	return rectBounding;  
	//}

	DWORD nByte =0; 
	while (nByte  < m_srcSize && m_psrcBits[nByte] == m_pshadowsrcBits[nByte])
	{
		++nByte;
	}
	if (nByte == m_srcSize)
	{
		return rectBounding;  
	}

	DWORD leftmost = nByte;

	CPoint pttopleft(nByte * m_srcBpp % m_srcWidth, (nByte * m_srcBpp / m_srcWidth));

	nByte = m_srcSize-1;
	while (nByte  > 0 && m_psrcBits[nByte] == m_pshadowsrcBits[nByte])
	{
		--nByte;
	}
	
	DWORD rightmost = nByte;

	CPoint ptbottomright(nByte * m_srcBpp % m_srcWidth, (nByte * m_srcBpp / m_srcWidth) + m_srcBpp);


	rectBounding = CRect( pttopleft.x, pttopleft.y, ptbottomright.x, ptbottomright.y );

	//test rectBounding= CRect (0,0,m_srcWidth/2, m_srcHeight/2) ; //will flash top left quarter of window any size if logical/device coords correct

	memcpy (&m_pshadowsrcBits[leftmost] ,&m_psrcBits[leftmost], rightmost - leftmost +1 ); //validate the shadow buffer  

	return rectBounding;
}
#endif

CSize CPixelDepthChanger::GetSrcSize()
{
	return CSize(m_srcWidth, m_srcHeight);
}

⌨️ 快捷键说明

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