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

📄 gpcbmp.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
	return GPC_ERR_OK;
}

//-------------------------------------------------------------------------
// 函数名:		SysGetBMPPixel
// 功能说明:	从一幅位图中获取指定位置的像素色彩
// 参数说明:
//      gc				-GC句柄.
//		x				-显示区域在位图中的左上角横坐标
//		y				-显示区域在位图中的左上角纵坐标
//		hbmp			-获取对象的位图句柄
//		color			-用于存放所获取色彩的地址
// 返回值说明:
//		GPC_ERR_OK		-成功
//		GPC_ERR_FAILED	-失败
//-------------------------------------------------------------------------
STATUS SysGetBMPPixel( DWORD gc, WORD x, WORD y, DWORD hbmp, DWORD *color )
{
	GC		*pGC = (GC *)gc;
	BITMAP	*bmp = (BITMAP *)hbmp;
	BYTE	*pixelPos, bitOffset;
	DWORD	totalOffset;

	// 参数检查
	if( pGC == NULL || pGC->symbol != GPC_GC_SYMBOL )
		return GPC_ERR_FAILED;

	if( bmp == NULL || bmp->info.type != GPC_BMP_SYMBOL ||
		bmp->data == NULL || bmp->palette == NULL )
		return GPC_ERR_FAILED;

	if( color == NULL )
		return GPC_ERR_FAILED;

	if( x > bmp->info.width -1 || y > bmp->info.height -1 )
		return GPC_ERR_FAILED;

	totalOffset = ( y * bmp->info.width + x ) * bmp->info.bitcount;
	pixelPos = (BYTE *)( bmp->data->ad + ( totalOffset >> 3 ) );
	bitOffset = (BYTE)( totalOffset & 0x7 );
	
	*color = bmp->palette[ seGetBMPPixelV( pixelPos, bitOffset, bmp->info.bitcount ) ];

	return GPC_ERR_OK;
}

////////////////////////////////////////////////////////////////////////////////////////////
void seDisplayBMP( GC *gc, WORD x, WORD y, WORD width, WORD height, BITMAP *bmp )
{
	PIXEL	*lineAd;
	CHAR	bitOffset;

	GetPixelPosition( &lineAd, &bitOffset, gc->vram, x, y );
	BlockOp( lineAd, bitOffset, bmp->data->ad, 0, width, height, GPC_REPLACE_STYLE, gc->vram, bmp->data );
/*
	DWORD	i, j;
//	PIXEL	colorIndex;
	PIXEL	*lineAd, *nextDesLineAd, *nextDesPixelPos;
	CHAR	bitOffset, nextDesLineOffset, nextDesPixelOffset;
	BYTE	*nextSrcLineAd, *nextSrcPixelPos;
	CHAR	nextSrcLineOffset, nextSrcPixelOffset;
	PIXEL	palette[8];
	DWORD	lineOffset;
	DWORD	index;
	PIXEL	*srctemp = (PIXEL *)SysLmalloc( BITS_PER_PIXEL * width);
	
	// 区域左上角在VRAM中的地址
	GetPixelPosition( &lineAd, &bitOffset, gc->vram, x, y );
	nextDesLineAd = lineAd;
	nextDesLineOffset = bitOffset;

	// 位图数据区首地址
	nextSrcLineAd = bmp->data;
	nextSrcLineOffset = 0;

	// 位图使用的调色板
//	palette = (PIXEL *)SysLmalloc( bmp->info.colorused * sizeof(PIXEL) );
//	if( palette == NULL )
//		return;
	for( i = 0; i < bmp->info.colorused; i++ )
		seRGBtoIndex( bmp->palette[i], &palette[i] );
	//palette = bmp->palette;

	lineOffset = bmp->info.width * bmp->info.bitcount;
	
	for( i = 0; i < height; i++ )
	{
		nextSrcPixelPos = nextSrcLineAd;
		nextSrcPixelOffset = nextSrcLineOffset;
		nextDesPixelPos = nextDesLineAd;
		nextDesPixelOffset = nextDesLineOffset;
		// 扫描一行
		for( j = 0; j < width; j++ )
		{	
			// 将位图的色彩索引值转换为设备的色彩索引值
			index = seGetBMPPixelV( nextSrcPixelPos, nextSrcPixelOffset, bmp->info.bitcount );
//			if( palette == SysPalette0 )
//				color = seBMPIndexToRGB( bmp->info.bitcount, index );
//			else
//				color = palette[index];
//			seRGBtoIndex( color, &colorIndex );
			
			// 设置VRAM中的像素值
			newSetPixel( nextDesPixelPos, nextDesPixelOffset, palette[index] );
		  	// 取下一个像素
			nextSrcPixelOffset += bmp->info.bitcount;
			if( nextSrcPixelOffset >= 8 )
			{
				nextSrcPixelOffset = 0;
				nextSrcPixelPos++;
			}
			GetNextPixelPosition( &nextDesPixelPos, &nextDesPixelOffset, nextDesPixelPos, nextDesPixelOffset );
			index += BITS_PER_PIXEL;
		}
//		LineOp( PIXEL *desLinePos, CHAR desBitOffset, PIXEL *srcLinePos, CHAR srcBitOffset, WORD len, WORD op );
		// 取下一行
		nextSrcLineAd += ( ( nextSrcLineOffset + lineOffset ) >> 3 );
		nextSrcLineOffset = (CHAR)(( nextSrcLineOffset + lineOffset ) & 0x7);
		GetNextLine( &nextDesLineAd, &nextDesLineOffset, nextDesLineAd, nextDesLineOffset, gc->vram );
	}
	
//	SysLfree( palette );
*/	
	return;

}

void seDisplayBMPEx( GC *gc, WORD x, WORD y, WORD width, WORD height, BITMAP *bmp, WORD style, PIXEL trIndex )
{
	DWORD	i, j;
//	PIXEL	colorIndex;
	PIXEL	*lineAd, *nextDesLineAd, *nextDesPixelPos;
	CHAR	bitOffset, nextDesLineOffset, nextDesPixelOffset;
	PIXEL	*nextSrcLineAd, *nextSrcPixelPos;
	CHAR	nextSrcLineOffset, nextSrcPixelOffset;
	PIXEL	index;
	WORD	frtMode = LOWORD(gc->fillmode), bkMode = HIWORD(gc->fillmode);
	WORD	mode;
	
	// 区域左上角在VRAM中的地址
	GetPixelPosition( &lineAd, &bitOffset, gc->vram, x, y );
   	nextDesLineAd = lineAd;
	nextDesLineOffset = bitOffset;

	// 位图数据区首地址
	nextSrcLineAd = bmp->data->ad;
	nextSrcLineOffset = 0;

	for( i = 0; i < height; i++ )
	{
		nextSrcPixelPos = nextSrcLineAd;
		nextSrcPixelOffset = nextSrcLineOffset;
		nextDesPixelPos = nextDesLineAd;
		nextDesPixelOffset = nextDesLineOffset;
		// 扫描一行
		for( j = 0; j < width; j++ )
		{	
			newGetPixel( &index, nextSrcPixelPos, nextSrcPixelOffset );
			// VRAM中的像素处理
			if( style != GPC_TRANSPARENT_STYLE )
				mode = style;
			else
			{
				if( index != trIndex )
				{
					if( frtMode != GPC_TRANSPARENT_STYLE )
						mode = frtMode;
					else
						mode = GPC_TRANSPARENT_STYLE;
				}
				else
				{
					if( bkMode != GPC_TRANSPARENT_STYLE )
						mode = bkMode;
					else
						mode = GPC_TRANSPARENT_STYLE;
				}
			}
			
			if( mode != GPC_TRANSPARENT_STYLE )
				PixelOp( nextDesPixelPos, nextDesPixelOffset, index, mode );

		  	// 取下一个像素
			GetNextPixelPosition( &nextSrcPixelPos, &nextSrcPixelOffset, nextSrcPixelPos, nextSrcPixelOffset );
			GetNextPixelPosition( &nextDesPixelPos, &nextDesPixelOffset, nextDesPixelPos, nextDesPixelOffset );
		}
		// 取下一行
		GetNextLine( &nextSrcLineAd, &nextSrcLineOffset, nextSrcLineAd, nextSrcLineOffset, bmp->data );
		GetNextLine( &nextDesLineAd, &nextDesLineOffset, nextDesLineAd, nextDesLineOffset, gc->vram );
	}

//	SysLfree( palette );

	return;
}

/*
void seDisplayBMPEx( GC *gc, WORD x, WORD y, WORD width, WORD height, BITMAP *bmp, WORD style, PIXEL trIndex )
{
	DWORD	i, j;
//	PIXEL	colorIndex;
	PIXEL	*lineAd, *nextDesLineAd, *nextDesPixelPos;
	CHAR	bitOffset, nextDesLineOffset, nextDesPixelOffset;
	BYTE	*nextSrcLineAd, *nextSrcPixelPos;
	CHAR	nextSrcLineOffset, nextSrcPixelOffset;
	PIXEL	palette[8];
	DWORD	lineOffset, index;
	WORD	frtMode = LOWORD(gc->fillmode), bkMode = HIWORD(gc->fillmode);
	WORD	mode;
	
	// 区域左上角在VRAM中的地址
	GetPixelPosition( &lineAd, &bitOffset, gc->vram, x, y );
   	nextDesLineAd = lineAd;
	nextDesLineOffset = bitOffset;

	// 位图数据区首地址
	nextSrcLineAd = bmp->data;
	nextSrcLineOffset = 0;

	// 位图使用的调色板
//	palette = (PIXEL *)SysLmalloc( bmp->info.colorused * sizeof(PIXEL) );
//	if( palette == NULL )
//		return;
	for( i = 0; i < bmp->info.colorused; i++ )
		seRGBtoIndex( bmp->palette[i], &palette[i] );
//	palette = bmp->palette;

	lineOffset = bmp->info.width * bmp->info.bitcount;
	
	for( i = 0; i < height; i++ )
	{
		nextSrcPixelPos = nextSrcLineAd;
		nextSrcPixelOffset = nextSrcLineOffset;
		nextDesPixelPos = nextDesLineAd;
		nextDesPixelOffset = nextDesLineOffset;
		// 扫描一行
		for( j = 0; j < width; j++ )
		{	
			// 将位图的色彩索引值转换为设备的色彩索引值
			index = seGetBMPPixelV( nextSrcPixelPos, nextSrcPixelOffset, bmp->info.bitcount );
			
			// VRAM中的像素处理
			if( style != GPC_TRANSPARENT_STYLE )
				mode = style;
			else
			{
				if( index != trIndex )
				{
					if( frtMode != GPC_TRANSPARENT_STYLE )
						mode = frtMode;
					else
						mode = GPC_TRANSPARENT_STYLE;
				}
				else
				{
					if( bkMode != GPC_TRANSPARENT_STYLE )
						mode = bkMode;
					else
						mode = GPC_TRANSPARENT_STYLE;
				}
			}
			
			if( mode != GPC_TRANSPARENT_STYLE )
				PixelOp( nextDesPixelPos, nextDesPixelOffset, palette[index], mode );

		  	// 取下一个像素
		  	nextSrcPixelOffset += bmp->info.bitcount;
			if( nextSrcPixelOffset >= 8 )
			{
				nextSrcPixelOffset = 0;
				nextSrcPixelPos++;
			}
			GetNextPixelPosition( &nextDesPixelPos, &nextDesPixelOffset, nextDesPixelPos, nextDesPixelOffset );
		}
		// 取下一行
		nextSrcLineAd += ( ( nextSrcLineOffset + lineOffset ) >> 3 );
		nextSrcLineOffset = (CHAR)(( nextSrcLineOffset + lineOffset ) & 0x7);
		GetNextLine( &nextDesLineAd, &nextDesLineOffset, nextDesLineAd, nextDesLineOffset, gc->vram );
	}

//	SysLfree( palette );

	return;
}
*/

//-------------------------------------------------------------------------
// 函数名:		GetBMPPixelV
// 功能说明:	获取位图指定位置的像素索引值
// 参数说明:
//      pixelPos		-像素的字节位置.
//      bitOffset		-像素的偏移比特.
//      bits			-像素的比特数.
// 返回值说明:
//		像素索引值
//-------------------------------------------------------------------------
DWORD seGetBMPPixelV( BYTE *pixelPos, BYTE bitOffset, BYTE bits )
{
	DWORD v;
	DWORD mask;

	if( bitOffset + bits > 8 )	// 位图索引值超过一个字节
	{
		mask = MAKEMASK( 8 - bitOffset );
		v = (*pixelPos) & mask;

		bits = bits + bitOffset - 8;
		pixelPos++;
		while( bits > 8 )
		{
			v = ( v << 8 ) | ( *pixelPos );
			bits -= 8;
			pixelPos++;
		}
		mask = ~MAKEMASK( 8 - bits );
		v = ( v << 8 ) | ( ( *pixelPos ) & mask );
	}
	else	// 位图索引值不超过一个字节
	{
		mask = MAKEMASK( bits );
		v = ( (*pixelPos) >> ( 8 - bits - bitOffset ) ) & mask;
	}

	return v;
}

// 灰化位图
// 用户定义的灰化调色板必须是两色的
DWORD SysGrizzleBitmap( BYTE *resource, DWORD *userpal )
{
	BMPHEADER	*info = (BMPHEADER *)resource;
	BITMAP		*bmp;
	VRAM		*desData;		//2002
	PIXEL		*dataAd, value, *LineAd;		//2002
	BYTE		*srcData;
	CHAR		desOffset, srcOffset, bits, LineOffset;
	DWORD		index, mask, i, j;		//2002
	PIXEL		palette[2];				//2002
	WORD		type;

	// 参数检查
	if( info == NULL || userpal == NULL )
		return 0;
	
	memcpy( &type, info, 2 );
	if( type != GPC_BMP_SYMBOL )
		return 0;
	
	bmp = (BITMAP *)SysLmalloc( sizeof( BITMAP ) );
	if( bmp == NULL )
		return 0;

	memcpy( &bmp->info, info, sizeof(BMPHEADER) );
	// 复制位图头信息
#ifdef BIG_ENDIAN_ORDER
	bmp->info.width = SWAPWORD(bmp->info.width);
	bmp->info.height = SWAPWORD(bmp->info.height);
	bmp->info.offset = INVERTDWORD(bmp->info.offset);
#endif
	bmp->info.bitcount = 1;
	bmp->info.flag = bmp->info.flag;
	bmp->info.colorused = 2;
	
	bmp->palette = userpal;

//	bmp->data = resource + info->offset;
	//变换调色板
	seRGBtoIndex( bmp->palette[0], &palette[0] );
	seRGBtoIndex( bmp->palette[1], &palette[1] );

	// 获取位图数据
	srcData = resource + bmp->info.offset;//2002word
	srcOffset = 0;
	desData = GetVRAM( bmp->info.width, bmp->info.height );
	if( desData == NULL )
	{
		SysLfree( bmp );
		return 0;
	}
	LineAd = desData->ad;
	dataAd = LineAd;//2002word
	LineOffset = 0;
	desOffset = 0;

	bits = info->bitcount;
	mask = MAKEMASK( bits );
	for ( i = 0; i < bmp->info.height; i++ )
	{
		dataAd = LineAd;
		desOffset = LineOffset;
		for ( j = 0; j < bmp->info.width; j++ )
		{
			//将位图的索引值转为系统的索引值			
			if( bits < 8 )
			{
				index = ( (*srcData) >> ( 8 - bits - srcOffset ) ) & mask;
				srcOffset += bits;
				if ( srcOffset >= 8 )
				{
					srcOffset = 0;
					srcData++;
				}				
			}
			else
			{
				CHAR	k, num = bits >> 3;
				
				index = *srcData;
				srcData++;
				for( k = 1; k < num; k++, srcData++ )
					index = ( index << 8 ) | ( *srcData );
			}
//			value = palette[index];
			if( index > 0 )
				value = palette[1];
			else
				value = palette[0];

			{
			#ifdef	BIG_ENDIAN_ORDER
				PIXEL	vmask = PixelMask << ( PIXEL_UNIT - BITS_PER_PIXEL - desOffset );
			#else
				PIXEL	vmask = PixelMask << desOffset;
			#endif
			
			#ifdef	BIG_ENDIAN_ORDER
				(*dataAd) = ( (*dataAd) & ~vmask ) | ( value << ( PIXEL_UNIT - BITS_PER_PIXEL - desOffset ) );
			#else
				(*dataAd) = ( (*dataAd) & ~vmask ) | ( value << desOffset );
			#endif
			}
			desOffset += BITS_PER_PIXEL;
			if( desOffset >= PIXEL_UNIT )
			{
				desOffset -= PIXEL_UNIT;
				dataAd++;
			}
		}
		GetNextLine( &LineAd, &LineOffset, LineAd, LineOffset, desData )
	}
	
	bmp->data = desData;
	
	return (DWORD)bmp;
}

⌨️ 快捷键说明

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