LZSS(LZ77)压缩

新代码地址:

https://zhuanlan.zhihu.com/p/677199239

别人的帖子:
lzss原理和代码例子

简单的例子解析:
在这里插入图片描述

I am Sam  Sam I am  That Sam-I-am! That Sam-I-am! I do not like that Sam I am!  Do you like green eggs and ham?  I do not like them, Sam-I-am. I do not like green eggs and ham. 

我自己写的代码。代码好像有点问题,执行结果老是不正确。事情太多了,暂时不想纠结了,先放下吧,以后有机会再查找错误。

#include <windows.h>

#include <stdio.h>

#define BLOCKSIZE  0x10000
char* srcfilename = "src.txt";
char* dstfilename = "dst.txt";


//#define WINDOW_FIXED

#pragma pack(1)

typedef struct
{
	WORD offset;
	WORD size;

}DATASTRUCT;

#pragma pack()



int search(unsigned char* data, int size, unsigned char* flag, int flaglen) {
	if (size < flaglen || flaglen == 0 || size == 0)
	{
		return -1;
	}

	int total = size - flaglen;
	for (int i = 0; i < total; i++)
	{
		if (memcmp(data + i, flag, flaglen) == 0)
		{
			return  i;
		}
	}

	return -1;
}




int writelog(char* filename, char* data, int size) {
	int result = 0;
	HANDLE hf = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
	if (hf == INVALID_HANDLE_VALUE) {
		return FALSE;
	}
	DWORD filesize = GetFileSize(hf, 0);

	result = SetFilePointer(hf, filesize, 0, FILE_BEGIN);

	DWORD cnt = 0;
	result = WriteFile(hf, data, size, &cnt, 0);

	CloseHandle(hf);

	return cnt;
}


int lzss_compress(unsigned char* data, int size, unsigned char* buf, int bufsize, unsigned char* datamap, int mapsize) {

	unsigned char* window = data;

	unsigned char* dst = buf;

	unsigned char* src = data;

	int windowsize = 0;

	int result = 0;

	while (src < data + size)
	{
		unsigned long findsize = 4 - 1;
		unsigned long offset = 0;
		while (findsize < BLOCKSIZE)
		{
			int least = data + size - src;

			if (findsize >= least)
			{
				memmove(dst, src, least);
				dst += least;
				src += least;
				windowsize++;
				if (windowsize >= BLOCKSIZE)
				{
					window = window + BLOCKSIZE;
					windowsize = 0;
				}
				return dst - buf;
			}

			result = search(window, windowsize, src, findsize + 1);
			if (result != -1)
			{
				offset = result;
				findsize++;
			}
			else {
				break;
			}
		}

		if (findsize > 4)
		{

			*(WORD*)dst = offset;
			*(WORD*)(dst + sizeof(WORD)) = findsize;

			int byte_offset = dst - buf;
			int bit_off_mod = byte_offset % 8;
			int bit_off = byte_offset / 8;

			DWORD value = *(datamap + bit_off);
			DWORD orvalue = 0xf;
			if (bit_off_mod)
			{
				orvalue = 0xf << (bit_off_mod);
			}

			orvalue = orvalue | value;
			*(datamap + bit_off) = (unsigned char)orvalue;
			*(datamap + bit_off + 1) = (unsigned char)(orvalue >> 8);

#ifdef		WINDOW_FIXED
			if (windowsize < BLOCKSIZE)
			{
				windowsize += findsize;
				if (windowsize > BLOCKSIZE)
				{
					windowsize = windowsize % BLOCKSIZE;
					window += BLOCKSIZE;
				}
			}
			else {
				window = window + findsize;
			}
#else
			windowsize += findsize;
			if (windowsize >= BLOCKSIZE)
			{
				windowsize = windowsize % BLOCKSIZE;
				window = window + BLOCKSIZE;
			}
#endif
			dst += 4;
			src += findsize;

			DATASTRUCT mydatastruct;
			mydatastruct.offset = offset;
			mydatastruct.size = findsize;
			writelog(srcfilename, (char*)&mydatastruct, sizeof(DATASTRUCT));
		}
		else {

			*dst = *src;
			dst++;
			src++;

#ifdef WINDOW_FIXED
			if (windowsize < BLOCKSIZE)
			{
				windowsize++;
			}
			else {
				window++;
			}
#else
			windowsize++;
			if (windowsize >= BLOCKSIZE)
			{
				window = window + BLOCKSIZE;
				windowsize = 0;
			}
#endif
		}
	}

	return dst - buf;

}


int lzss_decompress(unsigned char* data, int size, unsigned char* buf, int bufsize, unsigned char* datamap, int mapsize) {

	unsigned char* window = buf;

	int windowsize = 0;

	unsigned char* dst = buf;

	unsigned char* src = data;

	int offset = 0;

	while (src < data + size)
	{

		DWORD value = *(datamap + offset) + (*(datamap + offset + 1) << 8);

		for (DWORD i = 0; i < 8 && i >= 0; i++)
		{
			DWORD testkey = (0xf << i);

			int data_off = offset * 8 + i;

			int src_off = src - data;

			if ((value & testkey) == testkey)
			{
				WORD* structdata = (WORD*)(data_off + data);
				WORD window_offset = *structdata;
				int findsize = *(WORD*)(structdata + 1);
				if (findsize > 100 || findsize < 4)
				{
					printf("error\r\n");
				}

				memmove(dst, window + window_offset, findsize);
				//src += 4;
				dst += findsize;

#ifdef		WINDOW_FIXED
				if (windowsize < BLOCKSIZE)
				{
					windowsize += findsize;
					if (windowsize > BLOCKSIZE)
					{
						windowsize = windowsize % BLOCKSIZE;
						window += BLOCKSIZE;
					}
				}
				else {
					window = window + findsize;
				}


#else
				windowsize += findsize;
				if (windowsize >= BLOCKSIZE)
				{
					windowsize = windowsize % BLOCKSIZE;
					window = window + BLOCKSIZE;
				}
#endif

				i += 4;
				if (i >= 8)
				{
					//i -= 8;

					//offset++;
					//continue;
				}
				//value = (~testkey) & value;
				//value = *(datamap + offset) + (*(datamap + offset + 1) << 8);
			}
			else {
				*dst = *src;
				dst++;
				src++;

#ifdef WINDOW_FIXED
				if (windowsize < BLOCKSIZE)
				{
					windowsize++;
				}
				else {
					window++;
				}
#else
				windowsize++;
				if (windowsize >= BLOCKSIZE)
				{
					window = window + BLOCKSIZE;
					windowsize = 0;
				}
#endif
			}
		}
		offset++;
	}
	return dst - buf;
}


int test_lgzz()
{

	HANDLE hf = CreateFileA("test.txt", GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
	if (hf == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}


	int filesize = GetFileSize(hf, 0);
	char* data = new char[filesize + 1024];


	int result = 0;
	DWORD cnt = 0;
	result = ReadFile(hf, data, filesize, &cnt, 0);

	CloseHandle(hf);

	unsigned char* dstbuf = new unsigned char[filesize + 1024];

	unsigned char* datamap = new unsigned char[filesize + 1024];
	memset(datamap, 0, filesize);
	int  compsize = lzss_compress((unsigned char*)data, filesize, dstbuf, filesize + 1024, datamap, filesize);

	unsigned char* dstbuf2 = new unsigned char[filesize + 1024];

	lzss_decompress(dstbuf, compsize, dstbuf2, filesize + 1024, datamap, filesize);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值