📄 lzw.cpp
字号:
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 + -