www.pudn.com > LZ77.rar > LZ77.cpp
#include "stdafx.h" #include "lz77.h" #include#include #include const ULONG m=3; UCHAR __buffer1__[0x200000]; UCHAR __buffer2__[0x200000]; void Write1ToBitStream( PUCHAR pBuffer, ULONG ulBitOffset ) { ULONG ulByteBoundary; ULONG ulOffsetInByte; ulByteBoundary = ulBitOffset>>3 ; ulOffsetInByte = ulBitOffset&7; *(pBuffer+ulByteBoundary) |= (1< >3 ; ulOffsetInByte = ulBitOffset&7; *(pBuffer+ulByteBoundary) &= (~(1< >3 ; ulOffsetInByte = ulBitOffset&7; return ((*(PULONG)(pBuffer+ulByteBoundary))>>ulOffsetInByte)&1 ; } ULONG WINAPI WriteGolombCode( ULONG x, PUCHAR pBuffer, ULONG ulBitOffset ) { ULONG q, r; int i; q = (x-1)>>m; r = x-(q< >i)&1 ) { Write1ToBitStream(pBuffer, ulBitOffset); } else { Write0ToBitStream(pBuffer, ulBitOffset); } } return m+q+1; } ULONG ReadGolombCode( PULONG pulCodingLength, PUCHAR pBuffer, ULONG ulBitOffset ) { ULONG q, r; ULONG bit; int i; for(q=0; ;q++) { bit = (ULONG)ReadBitFromBitStream(pBuffer, ulBitOffset); ulBitOffset++; if( !bit ) { break; } } for(i=0, r=0; (ULONG)i 0 ) { length = CompareStrings(pSrc, pString, ulMaxLength); if( length>*pulSubstringLength ) { *pulSubstringLength = length; *pulSubstringOffset = offset; } pSrc++; offset++; ulMaxLength--; } } void WriteBits( PUCHAR pDataBuffer, ULONG ulOffsetToWrite, ULONG ulBits, ULONG ulBitLength ) { ULONG ulDwordsOffset; ULONG ulBitsOffset, ulBitsRemained; ulDwordsOffset = ulOffsetToWrite>>5; ulBitsOffset = ulOffsetToWrite&31; ulBitsRemained = 32 - ulBitsOffset; if( 0==ulBitsOffset ) { *((PULONG)pDataBuffer+ulDwordsOffset) = ulBits; } else if( ulBitsRemained>=ulBitLength ) { *((PULONG)pDataBuffer+ulDwordsOffset) |= (ulBits< >ulBitsRemained; } } void ReadBits( PUCHAR pDataBuffer, ULONG ulOffsetToRead, PULONG pulBits ) { ULONG ulDwordsOffset; ULONG ulBitsOffset, ulBitsLength; ulDwordsOffset = ulOffsetToRead>>5; ulBitsOffset = ulOffsetToRead&31; ulBitsLength = 32 - ulBitsOffset; *pulBits = *((PULONG)pDataBuffer+ulDwordsOffset); if( 0!=ulBitsOffset ) { (*pulBits) >>= ulBitsOffset; (*pulBits) |= (*((PULONG)pDataBuffer+ulDwordsOffset+1))< =0 ) { pSlideWindowPtr = pDataBuffer+iSlideWindowPtr; ulMaxlength = MAX_WND_SIZE; } else if( iSlideWindowPtr>=-MAX_WND_SIZE ) { pSlideWindowPtr = pDataBuffer; ulMaxlength = MAX_WND_SIZE + iSlideWindowPtr; } else { pSlideWindowPtr = NULL; ulMaxlength = 0; } pUnprocessedDataPtr = pDataBuffer + ulBytesCoded; if( ulMaxlength>ulDataLength-ulBytesCoded ) { ulMaxlength = ulDataLength-ulBytesCoded; } FindLongestSubstring( pSlideWindowPtr, pUnprocessedDataPtr, ulMaxlength, &offset, &length ); assert( length<=MAX_WND_SIZE ); assert( offset 1) { Write1ToBitStream(pOutputBuffer, ulBitOffset); ulBitOffset++; for(i=0; i >i)&1 ) { Write1ToBitStream(pOutputBuffer, ulBitOffset); } else { Write0ToBitStream(pOutputBuffer, ulBitOffset); } } ulCodingLength = WriteGolombCode(length, pOutputBuffer, ulBitOffset); ulBitOffset += ulCodingLength; iSlideWindowPtr += length; ulBytesCoded += length; } else { Write0ToBitStream(pOutputBuffer, ulBitOffset); ulBitOffset++; cc = (*pUnprocessedDataPtr); for(i=0; i<8; i++, ulBitOffset++) { if( (cc>>i)&1 ) { Write1ToBitStream(pOutputBuffer, ulBitOffset); } else { Write0ToBitStream(pOutputBuffer, ulBitOffset); } } iSlideWindowPtr++; ulBytesCoded++; } } if( ulBytesCoded!=ulDataLength ) { assert(ulBytesCoded==ulDataLength); } *pulNumberOfBits = ulBitOffset; } void lz77decompress( PUCHAR pDataBuffer, ULONG ulNumberOfBits, PUCHAR pOutputBuffer, PULONG pulNumberOfBytes ) { LONG iSlideWindowPtr; PUCHAR pSlideWindowPtr; ULONG length, offset; ULONG bit; UCHAR cc; int i; ULONG ulBytesDecoded; ULONG ulBitOffset; ULONG ulCodingLength; PUCHAR pWrite; iSlideWindowPtr = -MAX_WND_SIZE; pWrite = (PUCHAR)pOutputBuffer; ulBitOffset = 0; ulBytesDecoded = 0; while( ulBitOffset =0 ) { pSlideWindowPtr = pOutputBuffer + iSlideWindowPtr; } else if( iSlideWindowPtr>=-MAX_WND_SIZE ) { pSlideWindowPtr = pOutputBuffer; } else { pSlideWindowPtr = NULL; } for(i=0, offset=0; i MAX_WND_SIZE ) { assert(length<=MAX_WND_SIZE); } ulBitOffset += ulCodingLength; RtlMoveMemory(pWrite, pSlideWindowPtr+offset, length); pWrite+=length; iSlideWindowPtr+=length; ulBytesDecoded+=length; } else { for(i=0, cc=0; i<8 ; i++, ulBitOffset++) { bit = ReadBitFromBitStream(pDataBuffer, ulBitOffset); cc |= ((UCHAR)bit<>3); fp1=fopen(savepath, "wb+"); if( !fp1 ) { if( fp ) { fclose(fp); } return -1; } int len; BYTE extlen; char ext[10]; GetFileExt(filename,len,ext); extlen=(BYTE)len; fwrite(&extlen,1,sizeof(BYTE),fp1); fwrite(ext,1,extlen,fp1); fwrite(&ulNumberOfBits,1,sizeof(ULONG),fp1); fwrite(__buffer2__, 1, ulFileCompressedSize, fp1); fclose(fp1); } else { BYTE extlen; char ext[10]; fread(&extlen,1,sizeof(BYTE),fp); fread(ext,1,(int)extlen*sizeof(char),fp); fread(&ulNumberOfBits,1,sizeof(ULONG),fp); fread(__buffer2__,1,fsize,fp); lz77decompress(__buffer2__, ulNumberOfBits, __buffer1__, &ulFileDecompressedSize); fp1=fopen(savepath, "wb+"); if( !fp1 ) { if( fp ) { fclose(fp); } return -1; } fwrite(__buffer1__, 1, ulFileDecompressedSize, fp1); fclose(fp1); } fclose(fp); return 0; } void GetFileExt(LPTSTR lpszFileName,int &cExtLen,char *szFileExt) { CString temp(lpszFileName); int pos=temp.ReverseFind('.')+1; cExtLen=(temp.GetLength()-pos); strcpy(szFileExt,temp.Right(cExtLen).GetBuffer(0)); }