⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzw.cpp

📁 lzw的压缩程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int ret_val = -1;
	unsigned long cur_pos, byte_offset, old_byte_offset, bit_offset;
	unsigned short old_code, new_code, old_state;
	tt_entry_t tmp_string;
	translated_string_t cur_string;
	unsigned long string_num;
	unsigned char character;

	unsigned long tmp_var;

	tt_entry_t **tmp_ptr1=NULL, *tmp_ptr2=NULL;
	int flag;
	
	if( !translation_table )
	{	
		tmp_ptr1 = new tt_entry_t *[MAX_ST_ENTRIES];
		if( !tmp_ptr1 )
		{
			goto err_out;
		}
		translation_table = tmp_ptr1;
	}
	
	if( !tt_entries )
	{
		tmp_ptr2 = new tt_entry_t[MAX_ST_ENTRIES];
		if( !tmp_ptr2 )
		{
			goto err_out;
		}
		tt_entries = tmp_ptr2;
	}

	memset(translation_table, 0, sizeof(tt_entry_t *) * MAX_STR_NUM);
	memset(tt_entries, 0, sizeof(tt_entry_t) * MAX_ST_ENTRIES);

	bit_offset = 0;
	read_data_from_bs((unsigned char *)&old_code, CODE_LENGTH, in_data_buffer, bit_offset);
	assert( old_code < 256 );
	dbg_print("byte offset=0, code=%d, string length=1\n", old_code);
	out_data_buffer[0] = (unsigned char)old_code;
	character = (unsigned char)old_code;

	string_num = 0;
	
	byte_offset=1, old_state = STA_CHAR, old_byte_offset = 0;
	for(cur_pos=1; cur_pos<code_num; cur_pos++)
	{

		dbg_print("byte offset=%d, ", byte_offset);
		if( byte_offset==1947 )
		{
			byte_offset = byte_offset;
		}
		
		read_data_from_bs(&new_code, CODE_LENGTH, in_data_buffer, bit_offset);
		tmp_var = byte_offset;

		if( search_translation_table(translation_table, new_code) < 0 )
		{	
			translate_code(translation_table, old_code, cur_string);
			flag = 0;

			tmp_string.the_string.start_pos = (unsigned short)byte_offset;
			tmp_string.the_string.str_len = ( -1 == cur_string.character ?
				cur_string.the_string.str_len + 1 : 2 );

			old_state = STA_STRING;
		}
		else
		{
			tmp_string.the_string.start_pos = (unsigned short)old_byte_offset;

			if( STA_CHAR==old_state )
			{
				tmp_string.the_string.str_len = 2;
			}
			else if( STA_STRING==old_state )
			{
				tmp_string.the_string.str_len =
					translation_table[old_code-256]->the_string.str_len + 1;
			}
			else
			{
				assert(0);
			}

			translate_code(translation_table, new_code, cur_string);
			flag = 1;
			
			old_state = -1 != cur_string.character ? STA_CHAR : STA_STRING;
		}

		if( -1 == cur_string.character )
		{
			memcpy(out_data_buffer + byte_offset,
				out_data_buffer + cur_string.the_string.start_pos,
				cur_string.the_string.str_len);
			byte_offset += cur_string.the_string.str_len;
		}
		else
		{
			out_data_buffer[byte_offset] = (unsigned char)cur_string.character;
			byte_offset++;
		}


		if( 0==flag )
		{
			out_data_buffer[byte_offset] = character;
			byte_offset++;
		}


		character = ( -1 == cur_string.character ?
			out_data_buffer[cur_string.the_string.start_pos] : 
			(unsigned char) cur_string.character );
 
		dbg_print("code=%d, string length=%d\n", new_code,
			0==flag ? tmp_string.the_string.str_len : 
				-1==cur_string.character ? cur_string.the_string.str_len : 1
			);

		addto_translation_table(translation_table, tt_entries, tmp_string, string_num);
		
		old_code = new_code;
		old_byte_offset = tmp_var;
	}

	assert( bit_offset == code_num*CODE_LENGTH );
	*out_data_len = byte_offset;

	ret_val = 0;

err_out:
	
	if( tmp_ptr1 )
	{
		delete []tmp_ptr1;
	}
	
	if( tmp_ptr2 )
	{
		delete []tmp_ptr2;
	}

	return ret_val;
}

int Lzwc(char *src_file, char *dest_file)
{
	int ret_val = -1;

	unsigned char data_buff[MAX_CB_ONECE];
	unsigned char compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];
	
	FILE *fp_src=NULL, *fp_dest=NULL;
	unsigned long total_bytes_to_compress, bytes_to_compress, bits_compressed;
	int rc;

	fp_src = fopen(src_file, "rb");
	if( !fp_src )
	{
		goto err_out;
	}

	fp_dest = fopen(dest_file, "wb");
	if( !fp_dest )
	{
		goto err_out;
	}

	fseek(fp_src,0, SEEK_END);
	total_bytes_to_compress = ftell(fp_src);
	fseek(fp_src, 0, SEEK_SET);

	do 
	{
		lzw_info_t lzwinfo;

		bytes_to_compress = total_bytes_to_compress > MAX_CB_ONECE ? 
			MAX_CB_ONECE : total_bytes_to_compress;

		fread(data_buff, 1, bytes_to_compress, fp_src);

		rc = lzw_compress(lzw_string_table, lzw_string_table_entries, 
				data_buff, bytes_to_compress, compressed_data_buff, &bits_compressed);

		
		if( RCFAILED==rc )
		{
			goto err_out;
		}
		else 
		{
			if( RCOK_DATA_UNC==rc )
			{
				lzwinfo.code_num = (unsigned long) (bits_compressed / 8);
				lzwinfo.data_compressed = 0;
			}
			else if( RCOK_DATA_COM==rc  )
			{
				lzwinfo.code_num = (unsigned long) (bits_compressed / CODE_LENGTH);
				lzwinfo.data_compressed = 1;
			}

			fwrite(&lzwinfo, 1, sizeof(lzw_info_t), fp_dest);
			fwrite(compressed_data_buff, 1, (bits_compressed+7)/8, fp_dest);

			total_bytes_to_compress -= bytes_to_compress;
		}
		
	}	while( total_bytes_to_compress > 0);
	
	ret_val = 0;

err_out:

	if( fp_src )
	{
		fclose(fp_src);
	}

	if( fp_dest )
	{
		fclose(fp_dest);
	}

	return ret_val;
}

int Lzwd(char *src_file, char *dest_file)
{
	int ret_val = -1;

	unsigned char data_buff[MAX_CB_ONECE];
	unsigned char compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];

	FILE *fp_src=NULL, *fp_dest=NULL;
	unsigned long bytes_decompressed, file_size, file_pos;

	fp_src = fopen(src_file, "rb");
	if( !fp_src )
	{
		goto err_out;
	}

	fp_dest = fopen(dest_file, "wb");
	if( !fp_dest )
	{
		goto err_out;
	}

	fseek(fp_src,0, SEEK_END);
	file_size = ftell(fp_src);
	fseek(fp_src, 0, SEEK_SET);

	file_pos = 0;
	while(1)
	{
		lzw_info_t lzwinfo;
		unsigned long bytes_to_read;

		if( file_pos >= file_size )
		{
			break;
		}
		fread(&lzwinfo, 1, sizeof(lzwinfo), fp_src);
		file_pos += sizeof(long);

		if( file_pos >= file_size )
		{
			break;
		}

		if( lzwinfo.data_compressed )		
		{
			bytes_to_read = ((unsigned long)lzwinfo.code_num * CODE_LENGTH + 7) / 8;
		}
		else
		{
			bytes_to_read = (unsigned long)lzwinfo.code_num ;
		}
		
		fread(compressed_data_buff, 1, bytes_to_read, fp_src);
		file_pos += bytes_to_read;

		if( lzwinfo.data_compressed )
		{
			lzw_decompress(lzw_translation_table, lzw_translation_table_entries,
				compressed_data_buff, (unsigned long)lzwinfo.code_num,
				data_buff, &bytes_decompressed);
		}
		else
		{
			memcpy(data_buff, compressed_data_buff, bytes_to_read);
			bytes_decompressed = bytes_to_read;
		}
		

		fwrite(data_buff, 1, bytes_decompressed, fp_dest);
	}
	
	ret_val = 0;	

err_out:

	if( fp_src )
	{
		fclose(fp_src);
	}

	if( fp_dest )
	{
		fclose(fp_dest);
	}

	return ret_val;
}

static N=0;

int Lzwc_test(char *src_file, char *dest_file)
{
	int ret_val = -1;

	unsigned char data_buff[MAX_CB_ONECE];
	unsigned char compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];

	FILE *fp_src=NULL, *fp_dest=NULL;
	unsigned long bits_compressed;

	fp_src = fopen(src_file, "rb");
	if( !fp_src )
	{
		goto err_out;
	}

	fp_dest = fopen(dest_file, "wb");
	if( !fp_dest )
	{
		goto err_out;
	}

	do 
	{
		lzw_info_t lzwinfo;
		int rc;
	
		fseek(fp_src, N*MAX_CB_ONECE, SEEK_SET);
		fread(data_buff, 1, MAX_CB_ONECE, fp_src);

		FILE *fp_tmp = fopen("test.tmp", "wb");
		fwrite(data_buff, 1, MAX_CB_ONECE, fp_tmp);
		fclose(fp_tmp);
		
		rc = lzw_compress(lzw_string_table, lzw_string_table_entries, 
				data_buff, MAX_CB_ONECE, compressed_data_buff, &bits_compressed);

		if( RCFAILED==rc )
		{
			goto err_out;
		}
		else 
		{
			if( RCOK_DATA_UNC==rc )
			{
				lzwinfo.code_num = (unsigned long) (bits_compressed / 8);
				lzwinfo.data_compressed = 0;
			}
			else if( RCOK_DATA_COM==rc  )
			{
				lzwinfo.code_num = (unsigned long) (bits_compressed / CODE_LENGTH);
				lzwinfo.data_compressed = 1;
			}

			fwrite(&lzwinfo, 1, sizeof(lzw_info_t), fp_dest);
			fwrite(compressed_data_buff, 1, (bits_compressed+7)/8, fp_dest);
		}

	}	while( 0 );
	
	ret_val = 0;

err_out:

	if( fp_src )
	{
		fclose(fp_src);
	}

	if( fp_dest )
	{
		fclose(fp_dest);
	}


	return ret_val;

}

int main(int argc, char *argv[])
{
	int ret_val;
	
	if( 4 != argc )
	{
		printf("您的输入格式错误!\n");
		printf("附:\n");
		printf("参考用法: lzw [/c | /d] <源文件名> <目标文件名>\n");
		printf("例: lzw -c sourcefile.txt destinationfile\n");
		printf("    lzw /c sourcefile.txt destinationfile\n");
		printf("    lzw -d destinationfile sourcefile.txt\n");
		return -1;
	}
	
	unsigned long t1, t2;
	t1 = GetTickCount();

	if( 'c/' == *(unsigned short *)argv[1] || 'C/' == *(unsigned short *)argv[1] ||
		'c-' == *(unsigned short *)argv[1] || 'C-' == *(unsigned short *)argv[1]
		)
	{	
		printf("正在执行压缩操作,请稍候...\n");
		ret_val = Lzwc(argv[2], argv[3]);
	}

	if( 'd/' == *(unsigned short *)argv[1] || 'D/' == *(unsigned short *)argv[1] ||
		'd-' == *(unsigned short *)argv[1] || 'D-' == *(unsigned short *)argv[1]
		)
	{	
		printf("正在执行解压缩操作,请稍候...\n");
		ret_val = Lzwd(argv[2], argv[3]);
	}

	t2 = GetTickCount();

	if( 0==ret_val )
	{
		printf("操作成功!\n");
		printf("耗时%ld毫秒\n", t2-t1);
	}
	else
	{
		printf("操作失败\n");
	}

	return ret_val;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -