32bitTGA的rle压缩以及解压算法(二)

原创 2006年06月26日 21:56:00

闲话少说,直接先看代码

void CompressData(void * pSrc, void * pDst, int srcSize, DWORD & dstSize)
{
 if( (pSrc == NULL) || (pDst == NULL) )
 {
  return ;
 }
 
 int totalCompress = 0;
 int repCount = 1;
 DWORD blockHead = 0;
 
 DWORD * pComData = (DWORD *)pDst;
 DWORD * pRawData = (DWORD *)pSrc;
 
 //////////////////////////////////////////////////////////////////////////
 /// DWORD Size = BYTE Size / 4
 int len = srcSize >> 2;
 dstSize = 0;
 
 while(totalCompress < len)
 {
  if( !(*(pRawData+repCount-1)&0xff000000) && !(*(pRawData+repCount)&0xff000000) )
  {
   while( !(*(pRawData+repCount-1)&0xff000000) && !(*(pRawData+repCount)&0xff000000)
     && ((totalCompress+repCount)<len) )
   {
    ++repCount;
   }
   
   blockHead = 0x11000000 | repCount;
   *pComData++ = blockHead;
   *pComData++ = 0;
   dstSize += 2;
   
  }
  /// 看是否是0x10@@@@@@的情况
  else if( *pRawData == *(pRawData+repCount) )
  {
   while( *pRawData == *(pRawData+repCount)
    && ((totalCompress+repCount)<len))
   {
    ++repCount;
   }
   blockHead = 0x10000000 | repCount;
   *pComData++ = blockHead;
   *pComData++ = *pRawData;
   
   dstSize += 2;
  }
  /// 看是否为0x00@@@@@@的情况
  else //if( (*(pRawData+repCount-1) != *(pRawData+repCount)) && (*(pRawData+repCount)&0xff000000) )
  {
   while( *(pRawData+repCount-1) != *(pRawData+repCount)
    && ((totalCompress+repCount)<len) )
   {
    if( !(*(pRawData+repCount-1)&0xff000000) &&
     !(*(pRawData+repCount)&0xff000000) )
    {
     break;
    }
    ++repCount;
   }
   
   blockHead = 0x00000000 | repCount;
   *pComData++ = blockHead;
   memcpy(pComData, pRawData, sizeof(DWORD)*repCount);
   pComData += repCount;
   
   dstSize += repCount+1;
  }
  pRawData += repCount;
  totalCompress += repCount;
  repCount = 1;
 }
 
 dstSize *= 4;
}

稍显繁琐,代码写的不够整齐,不过基本意思就是这样了

解压代码:

void DeCompress(void * pSrc, void * pDst, DWORD srcSize, DWORD & dstSize)
{
 DWORD nowSize = 0;
 DWORD tSize = srcSize;// >> 2;
 DWORD * pDSrc = (DWORD *)pSrc;
 DWORD * pDstData = (DWORD *)pDst;

 dstSize = 0;

 DWORD dSize = 0;
 
 // C++版本
// while(nowSize < tSize)
// {
//  DWORD blockData = 0;  
//  blockData = *pDSrc++;
//  if( !(blockData & 0xff000000) )
//  {
//   int len = blockData & 0x00ffffff;
//   //fread(pDstData, sizeof(DWORD), len, m_pANMFile);
//   memcpy(pDstData, pDSrc, sizeof(DWORD)*len);
//   pDstData += len;
//   pDSrc += len;
//   nowSize += len+1;
//
//   dstSize += len;
//  }
//  else
//  {
//   int len = blockData & 0x00ffffff;
//   DWORD CompData;
//   CompData = *pDSrc++;
//   for(int i=0; i<len; ++i)
//   {
//    *pDstData++ = CompData;
//   }
//   nowSize += 2;
//
//   dstSize += len;
//  }
// }
// dstSize *= 4;


 // asm 版本
 __asm
 {
   mov  esi, pDSrc
   mov  edi, pDstData
loop_start: 
   lodsd     ; 将block读取到eax中
   mov  ebx, eax
   and  ebx, 0x00ffffff ; ebx 存放数据的长度信息
   and  eax, 0xff000000
   jnz  compress
   
   ; 原始数据
   mov  ecx, ebx
   
   cld
   rep  movsd
   
   mov  edx, ebx  ; 获取length + 1
   inc  edx    
   jmp  new_block
   
compress: 
         ; 压缩数据
   mov  ecx, ebx
   mov  edx, 0x02
   lodsd
   cld
   rep  stosd
new_block: 
   add  ebx, dSize  ; 计算总的长度信息
   lea  ecx, dSize
   mov  [ecx], ebx
   
   add  edx, nowSize ; 计算当前已经解压的长度
   lea  ecx, nowSize
   mov  [ecx], edx
   
   mov  eax, tSize
   cmp  edx, eax
   jnz  loop_start
 };  
 dstSize = 4 * dSize;

}

原理见另外一篇文章

相关文章推荐

RLE算法压缩解压源代码文件

  • 2011年11月10日 08:06
  • 2KB
  • 下载

RLE压缩算法

  • 2016年02月10日 19:49
  • 3.9MB
  • 下载

算法系列之八:RLE行程长度压缩算法

RLE(Run Length Encoding)行程长度压缩算法(也称游程长度压缩算法),是最早出现、也是最简单的无损数据压缩算法。RLE算法的基本思路是把数据按照线性序列分成两种情况:一种是连续的重...

数据压缩算法学习(一)---RLE算法

简介 RLE全称(run-length encoding),翻译为游程编码,又译行程长度编码,又称变动长度编码法(run coding),在控制论中对于二值图像而言是一种编码方法,对连续的黑、白像素数...

BMP文件格式及RlE压缩算法

6.1 BMP文件格式 6.1.1 简介 位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。Wi...

rle压缩算法的c#版

  • 2016年05月24日 17:26
  • 19KB
  • 下载

RLE压缩算法

RLE算法实现数据压缩 游程编码(Run-Length Encoding, RLE)又称行程长度编码或者变动长度编码法,在控制理论中对于二值图像而言是一种编码方法,对连续的黑,白向像素以不同的码字进...

RLE流压缩——简单算法

简单的说RLE压缩就是将一串连续的相同数据转化为特定的格式达到压缩的目的。  下面都对byte流压缩。  如输入数据  LPBTE pByte={1,1,1,1,1,1};  压缩的数据为...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:32bitTGA的rle压缩以及解压算法(二)
举报原因:
原因补充:

(最多只允许输入30个字)