- 注册时间
- 2005-8-2
- 最后登录
- 1970-1-1
|
为什么这个程序编译后只能在电脑端运行,无法在nc3000上运行?
明明没有用什么特殊的语句啊,郁闷~/* Basic LZW Data Compression program published in DDJ October 1989 issue.
* Original Author: Mark R. Nelson
* Updated by: Shawn M. Regan, January 1990
* Added: - Method to clear table when compression ratio degrades
* - Self adjusting code size capability (up to 14 bits)
* Updated functions are marked with "MODIFIED". main() has been updated also
* Compile with -ml (large model) for MAX_BITS == 14 only
* The lavax release version by tmzhjw
*/
#define INIT_BITS 9
#define MAX_BITS 9 //14 /* Do not exceed 14 with this program 在这个程序中不能超过14*/
#define HASHING_SHIFT 1
#define TABLE_SIZE 4096 //4096
#define CLEAR_TABLE 256 /* Code to flush the string table */
#define TERMINATOR 257 /* To mark EOF Condition, instead of MAX_VALUE */
#define FIRST_CODE 258 /* First available code for code_value table */
#define CHECK_TIME 100 /* Check comp ratio every CHECK_TIME chars input */
int code_value[TABLE_SIZE]; /* This is the code value array */
int prefix_code[TABLE_SIZE]; /* This array holds the prefix codes */
char append_character[TABLE_SIZE]; /* This array holds the appended chars */
char decode_stack[1000]; /* This array holds the decoded string */
int num_bits=INIT_BITS; /* Starting with 9 bit codes */
long bytes_in=0,bytes_out=0; /* Used to monitor compression ratio */
int max_code; /* old MAX_CODE */
long checkpoint=CHECK_TIME; /* For compression ratio monitoring */
int input_bit_count=0;
long input_bit_buffer=0;
int output_bit_count=0;
long output_bit_buffer=0;
char in_filename[30];
char out_filename[30];
long inlen;
long outlen;
struct TIME
{
int year;
char month;
char day;
char hour;
char minute;
char second;
char week;
};
struct TIME time_start,time_end;
int MAXVAL(int n)
{
return (( 1 <<( n )) -1); /* max_value formula macro */
}
/* UNCHANGED from original
* This is the hashing routine.
*/
int find_match(int hash_prefix, int hash_character)
{
int index, offset;
index = (hash_character << HASHING_SHIFT ) ^ hash_prefix;
if (index == 0 )
offset=1;
else
offset = TABLE_SIZE - index;
while(1) {
if (code_value[index] == -1 )
return(index);
if (prefix_code[index] == hash_prefix &&
append_character[index] == hash_character)
return(index);
index =index - offset;
if (index < 0)
index =index + TABLE_SIZE;
}
}
/* MODIFIED Output a variable length code.
*/
void output_code(int output, int code)
{
output_bit_buffer =output_bit_buffer |code << (32 - num_bits - output_bit_count);
output_bit_count =output_bit_count + num_bits;
while (output_bit_count >= 8) {
putc(output_bit_buffer >> 24, output);
output_bit_buffer =output_bit_buffer << 8;
output_bit_count =output_bit_count - 8;
bytes_out++; /* ADDED for compression monitoring */
}
}
/* MODIFIED This is the new compression routine. The first two 9-bit codes
* have been reserved for communication between the compressor and expander.
*/
int compress(int input, int output)
{
int next_code;
int character;
int string_code;
int index;
int i, /* All purpose integer */
ratio_new, /* New compression ratio as a percentage */
ratio_old; /* Original ratio at 100% */
next_code=FIRST_CODE;
ratio_old=100;
SetScreen(1);
for (i=0;i<TABLE_SIZE;i++) /* Initialize the string table first */
code_value=-1;
printf("Compressing\n");
string_code=getc(input); /* Get the first code */
/* This is the main compression loop. Notice when the table is full we try
* to increment the code size. Only when num_bits == MAX_BITS and the code
* value table is full do we start to monitor the compression ratio.
*/
while(!feof(input))
{
if(Inkey()==27)
{
fclose(input);
fclose(output);
DeleteFile(out_filename);
printf("\ncompress %s error!",in_filename);
getchar();
exit(1);
}
character=getc(input);
if (!(++bytes_in % 1000))
{ /* Count input bytes and pacifier */
putchar('.');
}
/////////////////
index=find_match(string_code,character);
if (code_value[index] != -1)
string_code=code_value[index];
else {
if (next_code <= max_code )
{
code_value[index]=next_code++;
prefix_code[index]=string_code;
append_character[index]=character;
}
output_code(output,string_code); /* Send out current code */
string_code=character;
if (next_code > max_code)
{ /* Is table Full? */
if ( num_bits < MAX_BITS)
{ /* Any more bits? */
putchar('+');
max_code = MAXVAL(++num_bits); /* Increment code size then */
}
else if (bytes_in > checkpoint)
{ /* At checkpoint? */
if (num_bits == MAX_BITS )
{
ratio_new = bytes_out*100/bytes_in; /* New compression ratio */
if (ratio_new > ratio_old)
{ /* Has ratio degraded? */
output_code(output,CLEAR_TABLE); /* YES,flush string table */
putchar('C');
num_bits=INIT_BITS;
next_code=FIRST_CODE; /* Reset to FIRST_CODE */
max_code = MAXVAL(num_bits); /* Re-Initialize this stuff */
bytes_in = bytes_out = 0;
ratio_old=100; /* Reset compression ratio */
for (i=0;i<TABLE_SIZE;i++) /* Reset code value array */
code_value=-1;
}
else /* NO, then save new */
ratio_old = ratio_new; /* compression ratio */
}
checkpoint = bytes_in + CHECK_TIME; /* Set new checkpoint */
}
}
}
}
output_code(output,string_code); /* Output the last code */
if (next_code == max_code)
{ /* Handles special case for bit */
++num_bits; /* increment on EOF */
putchar('+');
}
output_code(output,TERMINATOR); /* Output the end of buffer code */
output_code(output,0); /* Flush the output buffer */
output_code(output,0);
output_code(output,0);
putchar('\n');
return 1;
}
/* UNCHANGED from original
* Input a variable length code.
*/
int input_code(int input)
{
int return_value;
while (input_bit_count <= 24 ) {
input_bit_buffer =input_bit_buffer | getc(input) << (24 - input_bit_count);
input_bit_count =input_bit_count + 8;
}
return_value=input_bit_buffer >> (32-num_bits);
input_bit_buffer =input_bit_buffer << num_bits;
input_bit_count =input_bit_count - num_bits;
return(return_value);
}
/* UNCHANGED from original
* Decode a string from the string table, storing it in a buffer.
* The buffer can then be output in reverse order by the expansion
* program.
*/
long decode_string(long buffer, int code)
{
int i;
i=0;
while(code > 255 ) {
*buffer++ = append_character[code];
code=prefix_code[code];
if (i++ >= 1000 ) {//1000
SetScreen(1);
printf("Error during code expansion\n");
getchar();
exit(1);
}
}
*buffer=code;
return(buffer);
}
/* MODIFIED This is the modified expansion routine. It must now check for the
* CLEAR_TABLE code and know when to increment the code size.
*/
int expand(int input, int output)
{
int next_code;
int new_code;
int old_code;
int character,
counter,
clear_flag; /* Need to clear the code value array */
long string;
next_code=FIRST_CODE;
counter=0;
clear_flag=1;
SetScreen(1);
printf("Expanding\n");
while((new_code=input_code(input)) != TERMINATOR) {
if(Inkey()==27)
{
fclose(input);
fclose(output);
DeleteFile(out_filename);
printf("\nexpand %s error!",in_filename);
getchar();
exit(1);
}
if (clear_flag) { /* Initialize or Re-Initialize */
clear_flag=0;
old_code=new_code; /* The next three lines have been moved */
character=old_code; /* from the original */
putc(old_code,output);
continue;
}
if (new_code == CLEAR_TABLE) { /* Clear string table */
clear_flag=1;
num_bits=INIT_BITS;
next_code=FIRST_CODE;
putchar('C');
max_code = MAXVAL(num_bits);
continue;
}
if (++counter == 1000) { /* Pacifier */
counter=0;
putchar('.');
}
if (new_code >= next_code) { /* Check for string+char+string */
*decode_stack=character;
string=decode_string(decode_stack+1,old_code);
}
else
string=decode_string(decode_stack,new_code);
character = *string; /* Output decoded string in reverse */
while (string >= decode_stack)
putc(*string--,output);
if (next_code <= max_code) { /* Add to string table if not full */
prefix_code[next_code]=old_code;
append_character[next_code++]=character;
if (next_code == max_code && num_bits < MAX_BITS) {
putchar('+');
max_code = MAXVAL(++num_bits);
}
}
old_code=new_code;
}
putchar('\n');
return 1;
}
void ListFile(long filename)
{
ChDir("/");
for(;;)
{
if(!FileList(filename))
{
return;
}
if(!strcmp(filename,".."))
{
ChDir("..");
continue;
}
if(ChDir(filename))
continue;
break;
}
}
void initial()
{
num_bits=INIT_BITS;
bytes_in=0;
bytes_out=0;
max_code=0;
checkpoint=CHECK_TIME;
input_bit_count=0;
input_bit_buffer=0;
output_bit_count=0;
output_bit_buffer=0;
strcpy(in_filename,"");
strcpy(out_filename,"");
}
long gftitle(long file)
{
int i;
char name[30];
for(i=0;i<strlen(file);i++)
{
if(*(file+i)=='.')
break;
name=*(file+i);
}
return name;
}
long Timer()
{
return (time_end.hour-time_start.hour)*60*60+
(time_end.minute-time_start.minute)*60+(time_end.second-time_start.second);
}
void main()
{
int input_file, output_file, lzw_file;
char c;
int rs;
for(;;){
initial();
SetScreen(1);
printf(" Lzw compression tool\n a.compress\n b.expand\n c.about\n d.exit");
c=getchar();
if(c=='a')
{
ListFile(in_filename);
if(!strcmp(in_filename,""))
continue;
GetTime(&time_start);
input_file=fopen(in_filename,"rb");
fseek(input_file,0,2);
inlen=ftell(input_file);
rewind(input_file);
strcpy(out_filename,gftitle(in_filename));
strcat(out_filename,".lzw");
lzw_file=fopen(out_filename,"wb");
fwrite("lw",1,2,lzw_file);
putc(strlen(in_filename),lzw_file);
fwrite(in_filename,1,strlen(in_filename),lzw_file);
if (input_file == NULL || lzw_file == NULL) {
SetScreen(1);
printf("Error opening files\n");
getchar();
exit(1);
}
max_code = MAXVAL(num_bits); /* Initialize max_value & max_code */
rs=compress(input_file,lzw_file); /* Call compression routine */
outlen=ftell(lzw_file);
fclose(input_file);
fclose(lzw_file);
GetTime(&time_end);
if(rs)
{
SetScreen(1);
printf("Compress success\nFile:%s\nIn:%d bytes\nOut:%d bytes\nOut/In:%d.%d\nTime:%ds",
in_filename,inlen,outlen,outlen/inlen,(outlen%inlen)*10000/inlen,Timer());
getchar();
return;
}
}
else if(c=='b')
{
ListFile(in_filename);
if(!strcmp(in_filename,""))
continue;
GetTime(&time_start);
lzw_file=fopen(in_filename,"rb");
if(getc(lzw_file)!='l' && getc(lzw_file)!='w')
{
SetScreen(1);
printf("Not a lzw file!");
getchar();
return;
}
strcpy(out_filename,"");
fread(out_filename,1,getc(lzw_file),lzw_file);
output_file=fopen(out_filename,"wb");
if (lzw_file == NULL || output_file == NULL) {
SetScreen(1);
printf("Error opening files\n");
getchar();
return;
}
num_bits=INIT_BITS; /* Re-initialize for expansion */
max_code = MAXVAL(num_bits);
rs=expand(lzw_file,output_file); /* Call expansion routine */
fclose(lzw_file); /* Clean it all up */
fclose(output_file);
GetTime(&time_end);
if(rs)
{
SetScreen(1);
printf("\nExpand success!\nTime:%ds",Timer());
getchar();
return;
}
}
else if(c=='c')
{
SetScreen(1);
printf("\n Lzw compression tool \n tmzhjw@126.com\n by Mark R. Nelson \n updated by Shawn M. Regan");
getchar();
}
else if(c=='d')
return;
}
} |
|