闲话少说,直接先看代码
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;
}
原理见另外一篇文章