📄 unhuf.cpp
字号:
#include <stdio.h>
#include <math.h>
#define FALSE 0
#define TRUE 1
#define MAX_DECODE_TABLE_SIZE 520 /* 512 should be enough */
//#define DEBUG
#define EXACT
struct decode_table_element {
unsigned char letter;
char spare; /* force 16-bit word alignment */
short left; /* index of lower left element from tree */
short right; /* index of lower right element from tree */
};
short array_max_index; /* max number of elements in array (to be */
/* determined in create_decode_table() ) */
unsigned long total; /* total number of unencoded bytes */
FILE *infile; /* file ptr to SYSTEM.HUF (compressed) */
FILE *outfile; /* file ptr to SYSTEM.UNH (decompressed) */
char *infilename; /* name of the input file */
char origfilename[13]; /* name of the original file */
decode_table_element decode_table[MAX_DECODE_TABLE_SIZE];
short read_header(void);
void show_bit_sequences(short index);
short uncompress(void);
//-------------------------------------------------------------------------------
int main(int argc, char **argv)
{
if (argc != 2) {
puts("'unhuf file' decodes file.");
return 1;
}
infilename=argv[1];
if (read_header() != 0)
return 1;
#ifdef DEBUG
show_bit_sequences(0);
#endif
if (uncompress() != 0)
return 1;
fclose(infile);
return 0;
}
//-----------------------------------------------------------------------------------
short read_header(void)
{
if ((infile=fopen(infilename, "rb")) == NULL)
{
printf("Unable to open %s\n", infilename);
return 1;
}
if (fread((void *)origfilename, 1, 13, infile)< 13)
{
printf("Unable to read original filename from %s\n", infilename);
fclose(infile);
return 1;
}
if (fread((void *)&array_max_index,sizeof(short), 1, infile)< 1)
{
printf("Unable to read number of array elements from %s\n", infilename);
fclose(infile);
return 1;
}
if (fread((void *)&total, sizeof(unsigned long), 1, infile)< 1)
{
printf("Unable to read original byte count from %s\n", infilename);
fclose(infile);
return 1;
}
printf("Decoding %ld bytes to %s.\n", total, origfilename);
printf("Decode table contains %d elements.\n",array_max_index + 1);
if (fread((void *)decode_table, sizeof(decode_table_element), array_max_index + 1, infile)
< (array_max_index + 1))
{
printf("Unable to read decode table from %s\n", infilename);
fclose(infile);
return 1;
}
return 0;
}
//-----------------------------------------------------------------------------
#ifdef DEBUG
short seq_len=0;
void show_bit_sequences(short index)
{
static short temp_index=0;
static char bit_sequence[32];
if (decode_table[index].left != 0)
{
bit_sequence[seq_len++]='1';
show_bit_sequences(decode_table[index].left);
seq_len--;
}
if (decode_table[index].right != 0)
{
bit_sequence[seq_len++]='0';
show_bit_sequences(decode_table[index].right);
seq_len--;
}
if (decode_table[index].left != NULL)
return;
bit_sequence[seq_len] = 0;
printf("[%3d] %3d == %16s == %3d\n", temp_index, decode_table[index].letter, bit_sequence, seq_len);
temp_index++;
}
#endif
//--------------------------------------------------------------------------------
/*
* all the fputc() calls are unrolled for speed.
*
*/
short uncompress(void)
{
register short index = 0;
register unsigned int buffer = 0;
register unsigned short fastleft;
register unsigned short fastleft0; /* fast ptr to left of root */
register long running_total = 0L;
if ((outfile=fopen(origfilename, "wb")) == NULL)
{
printf("Unable to open %s\n", origfilename);
return 1;
}
fastleft0 = decode_table[0].left; /* setup frequently used vars */
fastleft = fastleft0;
while (1)
{
buffer=fgetc(infile);
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1; /* rotate next bit to test postion */
fastleft = decode_table[index].left; /* set up frequently used var */
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index=0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if(fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
index = ( (buffer & 0x0080) ? fastleft : decode_table[index].right);
buffer <<= 1;
fastleft = decode_table[index].left;
if (fastleft == 0)
{
if (fputc((int)decode_table[index].letter, outfile)== EOF)
{
puts("Error writing to output file, out of disk space?");
return 1;
}
index = 0;
fastleft = fastleft0;
#ifdef EXACT
if (++running_total == total) goto finished;
#endif EXACT
#ifndef EXACT
++running_total;
#endif EXACT
}
#ifndef EXACT
if(running_total >= total)
goto finished;
#endif EXACT
}
finished:
fclose(outfile);
printf("Decoded %ld bytes.", running_total);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -