首 页最新软件下载排行文章资讯投稿发布下载专题
维维下载站
您的位置:首页编程开发网络编程编程其它 → 用于VC++ RLE压缩算法示例代码(PCX,TGA图像)

用于VC++ RLE压缩算法示例代码(PCX,TGA图像)

来源:维维整理 发布时间:2017-8-16 16:11:29 人气:

用于VC++ RLE压缩算法示例代码(PCX,TGA图像)是小编最近给大家整理放出的一个用于VC++ 的RLE 压缩算法(PCX, TGA图像)编程代码例子,功能:RLE压 / 解压缩 ( PCX, TGA 图像 ) ,说 明 :PCX图像 :1,4,8位色位图按字节处理,24位色分成3通道处理TGA图像:支持8, 16, 24, 32色, 不支持15位色,压缩时OutBuffer至少两倍InBuffer大小,赶紧来详细了解一下吧。

#ifndef		__FOO_RLE_COMPRESS_H__
#define		__FOO_RLE_COMPRESS_H__
#include <windows.h>
#pragma once
//====================================================================
//	RLE - 压缩算法
//====================================================================
//////////////////////////////////////////////////////////////////////
//	功  能 :RLE压 / 解压缩 ( PCX, TGA 图像 )			//
//								//
//	参  数 :iColorBit 为像素颜色位数				//
//					PCX为 :1, 4, 8, 24	//
//					TGA为 :8, 16, 24, 32	//
//			 iNumPixel 为写入OutBuffer中的像素个数		//
//								//
//	返回值 :EncodeLine 返回编码后 OutBuffer 的指针		  //
//			 DecodeLine 返回解码后 InBuffer 的指针		//
//								//
//	说  明 :PCX图像 :1,4,8位色位图按字节处理,24位色分成3通道处理 //
//			 TGA图像 :支持8, 16, 24, 32色, 不支持15位色	//
//			 压缩时OutBuffer至少两倍InBuffer大小	 //
//////////////////////////////////////////////////////////////////////
BYTE * RLE_PCX_EncodeLine (BYTE * InBuffer, int iColorBit,
						   int iNumPixel,  // iNumPixel即为图像宽
						   BYTE * OutBuffer) ;
BYTE * RLE_PCX_DecodeLine (BYTE * InBuffer, int iColorBit,
						   int iNumPixel, // iNumPixel即为图像宽
						   BYTE * OutBuffer) ;
BYTE * RLE_TGA_EncodeLine (BYTE * InBuffer, int iColorBit,
						   int iNumPixel,  // iNumPixel即为图像宽
						   BYTE * OutBuffer) ;
BYTE * RLE_TGA_DecodeLine (BYTE * InBuffer, int iColorBit,
						   int iNumPixel,  // iNumPixel即为图像宽
						   BYTE * OutBuffer) ;
//===================================================================
//	Implement
//===================================================================
inline BYTE *  RLE_PCX_DecodeLine (BYTE * InBuffer, int iColorBit,
								   int iNumPixel, BYTE * OutBuffer) {
	register BYTE	  Data, Num, Pack = 8 / iColorBit ;
	if (iColorBit <= 8) // 1,4,8位色
		while (iNumPixel > 0)
		{
			Data = *InBuffer++ ; // Next Byte
			if ( (Data & 0xC0) == 0xC0 ) // Data >= 0xC0
			{
				Num = Data & 0x3F ; // 重复字节
				memset (OutBuffer, *InBuffer++, Num) ;
				OutBuffer += Num ; iNumPixel -= Num * Pack ;
			}
			else
			{
				*OutBuffer++ = Data ;
				iNumPixel -= Pack ;
			}
		}
	else // 24位色分Channel
		for (int i = 2 ; i >= 0 ; i--) // RGB channel
		{
			int		iCount = iNumPixel ;
			BYTE	* pChannel = OutBuffer + i ;
			while (iCount-- > 0) // 一定会写入一个像素(--)
			{
				Data = *InBuffer++ ; // Next Byte
				if ( (Data & 0xC0) == 0xC0 ) // Data >= 0xC0
				{
					Num = Data & 0x3F ; // 重复像素
					for (int x = 0 ; x < Num ; x++, pChannel += 3)
						*pChannel = *InBuffer ;
					InBuffer++ ;
					iCount -= Num - 1 ;
				}
				else
				{	*pChannel = Data ; pChannel += 3 ;	}
			}
		}
	return InBuffer ;
}
//===================================================================
inline BYTE * RLE_PCX_EncodeLine (BYTE * InBuffer, int iColorBit,
								  int iNumPixel,  // iNumPixel即为图像宽
								  BYTE * OutBuffer) {
	register BYTE	data, cCount ;
	int 			PcxRow = 2 * ( (iNumPixel * (iColorBit % 16) + 15) / 16 ) ;
	if (iColorBit <= 8) // 1,4,8位色
		while (PcxRow > 0)
		{
			cCount = 1 ; data = *InBuffer++ ; PcxRow-- ;
			while ( (cCount < 0x3F) && (PcxRow != 0) )
				if (*InBuffer != data)// 统计重复字节个数
					break ;
				else
				{
					cCount++ ; InBuffer++ ; PcxRow-- ;
				}
			if (cCount == 1) // 无重复像素
				if ( (data & 0xC0) == 0xC0 ) // Data >= 0xC0
				{
					*OutBuffer++ = 0xC1 ;
					*OutBuffer++ = data ;
				}
				else
					*OutBuffer++ = data ; // Data < 0xC0, 直接写字节
			else // 重复像素
			{
				*OutBuffer++ = 0xC0 | cCount ;
				*OutBuffer++ = data ;
			}
		} // 1,4,8位色结束
	else // 24位色分Channel
		for (int i = 2 ; i >= 0 ; i--) // RGB channel
		{
			DWORD	RowBak = PcxRow ; // 每Channel字节数
			BYTE	* pChannel = InBuffer + i ;
			while (RowBak > 0)
			{
				cCount = 1 ; data = *pChannel ; pChannel += 3 ; RowBak-- ;
				while ( (cCount < 0x3F) && (RowBak != 0) )
					if (*pChannel != data) // 统计重复字节个数
						break ;
					else
					{
						cCount++ ; pChannel += 3 ; RowBak-- ;
					}
				if (cCount == 1) // 无重复像素
					if ( (data & 0xC0) == 0xC0 ) // Data >= 0xC0
					{
						*OutBuffer++ = 0xC1 ;
						*OutBuffer++ = data ;
					}
					else
						*OutBuffer++ = data ;
				else // 重复像素
				{
					*OutBuffer++ = 0xC0 | cCount ;
					*OutBuffer++ = data ;
				}
			}
		}
	return OutBuffer ;
}
//===================================================================
inline BYTE * RLE_TGA_DecodeLine (BYTE * InBuffer, int iColorBit,
								  int iNumPixel, BYTE * OutBuffer) {
	register BYTE	  Data ;
	register int	  Num ;
	iColorBit /= 8 ; // 转换为字节数
	while (iNumPixel > 0)
	{
		Data = *InBuffer++ ; // Next Byte
		if (Data & 0x80) // Data >= 0x80
		{
			iNumPixel -= (Num = (Data & 0x7F) + 1) ;
			for (int i = 0 ; i < Num ; i++, OutBuffer += iColorBit)
				memcpy (OutBuffer, InBuffer, iColorBit) ;
			InBuffer += iColorBit ;
		}
		else // 直接copy Num个像素
		{
			iNumPixel -= (Num = ++Data) ;
			Num *= iColorBit ;
			memcpy (OutBuffer, InBuffer, Num) ;
			OutBuffer += Num ;
			InBuffer += Num ;
		}
	} // End of while
	return InBuffer ;
}
//===================================================================
inline BYTE * RLE_TGA_EncodeLine (BYTE * InBuffer, int iColorBit,
								  int iNumPixel, BYTE * OutBuffer) {
	DWORD			Data, Next ;
	BYTE			* pBak ;
	register DWORD	Count ;
	iColorBit /= 8 ; // 转换为字节数
	while (iNumPixel > 0)
	{
		pBak = InBuffer ; // 记数指针
		memcpy (&Data, InBuffer, iColorBit) ; // 第一个像素
		InBuffer += iColorBit ; iNumPixel-- ; Count = 1 ;
		while ((Count < 0x7F) && (iNumPixel > 0)) // 统计重复像素
		{
			memcpy (&Next, InBuffer, iColorBit) ; // 下一个像素
			if (Next != Data)
				break ;
			InBuffer += iColorBit ; iNumPixel-- ; Count++ ;
		}
		if (Count == 1) // 无重复像素
		{
			while ((Count < 0x7F) && (iNumPixel > 0)) // 统计不重复像素
			{
				Count++ ; Data = Next ;
				InBuffer += iColorBit ; iNumPixel-- ;
				memcpy (&Next, InBuffer, iColorBit) ; // 下一个像素
				if (Data == Next)
					break ;
			}
			// 直接copy不重复像素
			*OutBuffer++ = (BYTE)(Count - 1) ;
			Count = InBuffer - pBak ; // Count->临时变量
			memcpy (OutBuffer, pBak, Count) ;
			OutBuffer += Count ;
		}
		else // 重复像素
		{
			*OutBuffer++ = 0x80 | (BYTE)--Count ;
			memcpy (OutBuffer, &Data, iColorBit) ;
			OutBuffer += iColorBit ;
		}
	} // End of while
	return OutBuffer ;
}
//===================================================================
#endif
相关下载
栏目导航
本类热门阅览