算了,直接贴关键部分吧搏州。这个有一点竖锋C++成分,很容易改的。
bool CompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen, int nBitsPerSample, void* nRuns, int nRunCount, int nRunSize)
bool DecompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen)
#define GetDWORD(buf,bit,mask) ((*(DWORD*)(((BYTE*)buf)+((bit)>>3)))>>((bit)&7)&(mask))
#define GetWORD(buf,bit,mask) ((*(WORD*)(((BYTE*)buf)+((bit)>>3)))>>((bit)&7)&(mask))
int GetBitCount(int n)
{
int nBitCount = 0
while(n)
n >>= 1, nBitCount++
return nBitCount
}
int BinarySearch(void* pValue, int nVlaueSize, void* pArray, int nCount)
{
int nIndex, nResult, nStart = 0, nEnd = nCount-1
while(nStart <= nEnd)
{
nIndex = (nEnd+nStart)/2
if((nResult = memcmp((BYTE*)pArray+nIndex*nVlaueSize, pValue, nVlaueSize)) == 0)
return nIndex
if(nResult >0)
nEnd = nIndex-1
else
nStart = nIndex+1
}
return -1
}
bool CompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen, int nBitsPerSample, void* nRuns, int nRunCount, int nRunSize)
{
pDes = (BYTE*)malloc(nSrcLen*2)
memset(pDes, 0, nSrcLen*2)
nDesLen = sizeof(DWORD)
*(DWORD*)pDes = nSrcLen // save source length
*(pDes+nDesLen++) = nBitsPerSample// save bits per sample
*(pDes+nDesLen++) = nRunCount // save runs count
*(pDes+nDesLen++) = nRunSize // save run bytes
memcpy(pDes+nDesLen, nRuns, nRunCount*nRunSize)// save runs
nDesLen += nRunCount*nRunSize
nDesLen <<= 3// bytes to bits
if(nRunCount == 0)
nRunCount = 256, nRunSize = 1, nRuns = NULL
int nBitsPerTypeIndex = GetBitCount(nRunCount-1)
int nMaxRunLength = (1 <<nBitsPerSample)-1, nRunLength, nRunIndex, nByte = 0
// loop in the source buffer
while(nByte <nSrcLen)
if((nRuns &&(nRunIndex = BinarySearch(pSrc+nByte, nRunSize, nRuns, nRunCount)) != -1 &&
memcmp(pSrc+nByte+nRunSize, (BYTE*)nRuns+nRunIndex*nRunSize, nRunSize) == 0) ||
(!nRuns &&(nRunIndex = *(pSrc+nByte)) == *(pSrc+nByte+1)))
{ // set bit to 1 to indicate type found
*(pDes+(nDesLen>>3)) |= 1 <<(nDesLen&7)
*(DWORD*)(pDes+(++nDesLen>>3)) |= nRunIndex <<(nDesLen&7)
nDesLen += nBitsPerTypeIndex
// skip the two repeated runs
nByte += nRunSize*2
// get run length - 2 (without the two repeated runs)
nRunLength = 0
while(nRunLength <nMaxRunLength &&nByte <nSrcLen &&
((nRuns &&memcmp(pSrc+nByte, (BYTE*)nRuns+nRunIndex*nRunSize, nRunSize) == 0) || (!nRuns &&(BYTE)nRunIndex == *(pSrc+nByte))))
nRunLength++, nByte += nRunSize
// save run length and increment destination length by bits per sample
*(DWORD*)(pDes+(nDesLen>>3)) |= nRunLength <<(nDesLen&7)
nDesLen += nBitsPerSample
}
else // copy one byte
*(WORD*)(pDes+(++nDesLen>>3)) |= *(pSrc+nByte++) <<(nDesLen&7), nDesLen += 8
nDesLen = (nDesLen+7)/8// bits to bytes
pDes = (BYTE*)realloc(pDes, nDesLen)
return true
}
bool DecompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen)
{
if(nSrcLen == 0)
return true
// allocate destination buffer
nDesLen = *(DWORD*)pSrc
pDes = (BYTE*)malloc(nDesLen)
memset(pDes, 0, nDesLen)
// copy compression information
int nSrcIndex = sizeof(DWORD)
int nBitsPerSample = *(pSrc+nSrcIndex++)
int nRunCount = *(pSrc+nSrcIndex++)
int nRunSize = *(pSrc+nSrcIndex++)
void* nRuns = pSrc+nSrcIndex
nSrcIndex += nRunSize*nRunCount
nSrcIndex <<= 3// bytes to bits
if(nRunCount == 0)
nRunCount = 256, nRunSize = 1, nRuns = NULL
int nBitsPerTypeIndex = GetBitCount(nRunCount-1)
int nMaxTypeIndex = (1 <<nBitsPerTypeIndex)-1
int nMaxRunLength = (1 <<nBitsPerSample)-1
int nDesIndex = 0, nRunLength, nRunIndex, nRun, nByte
nSrcLen <<= 3// bytes to bits
while(nSrcIndex <nSrcLen-8)
if((*(pSrc+(nSrcIndex>>3)) >>(nSrcIndex++&7)) &1)
{
nRunIndex = GetDWORD(pSrc, nSrcIndex, nMaxTypeIndex), nSrcIndex += nBitsPerTypeIndex
nRunLength = GetDWORD(pSrc, nSrcIndex, nMaxRunLength)+2, nSrcIndex += nBitsPerSample
for(nRun = 0nRun <nRunLengthnRun++)
for(nByte = 0nByte <nRunSizenByte++, nDesIndex += 8)
*(WORD*)(pDes+(nDesIndex>>3)) |= nRuns ? GetWORD(nRuns+nRunSize*nRunIndex, nByte<<3, 0xff) : (BYTE)nRunIndex
}
else // copy one byte
*(WORD*)(pDes+(nDesIndex>>3)) |= GetWORD(pSrc, nSrcIndex, 0xff), nDesIndex += 8, nSrcIndex += 8
return true
}
游程编码又称“运行长度编码”或“行程编码”,是一种统计编码,该编码属于无损压缩编码,是栅格数据压缩的重要编码方法。对于二值图有效。行程编码的基本原理是:用一罩族个符号值或串长代替具有相同值的连续符号(连续符号构成了一段连续的“行程”。行程编码因此而得名),使符号长度少于原始数据的长度。只在各行或者各列数据的代码发生变化时,一次记录该代码及相同代码重复的个数,从而实现数据的压缩。
常见的游程编码格式包括TGA,Packbits,PCX以及ILBM。
行程编码是连续精确的编码,在传输过程中,如果其中一位符号发生错误,即可影响整个编码序列,使行程编码无法还原回原始数据。
游程长度在栅格加密时,做闷祥数据量没有明显增加,压缩效率纯搏较高,且易于检索、叠加合并等 *** 作,运算简单,适用于机器存储容量小,数据需大量压缩,而又要避免复杂的编码和解码运算,增加处理和 *** 作时间的情况。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)