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

📄 unhuf.cpp

📁 作业
💻 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 + -