1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include "macunpack.h"
#ifdef JDW
#define DEHUFFMAN
#endif /* JDW */
#ifdef STF
#define DEHUFFMAN
#endif /* STF */
#ifdef PIT
#define DEHUFFMAN
#endif /* PIT */
#ifdef SIT
#define DEHUFFMAN
#endif /* SIT */
#ifdef CPT
#define DEHUFFMAN
#endif /* CPT */
#ifdef DEHUFFMAN
#include "globals.h"
#include "../util/masks.h"
#include "../fileio/wrfile.h"
#include "huffman.h"
#include "../util/util.h"
int (*get_bit)();
int bytesread;
/* 515 because StuffIt Classic needs more than the needed 511 */
struct node nodelist[515];
static int getbit_be();
static int getbit_le();
static int getdecodebyte();
static node *nodeptr, *read_sub_tree();
static int bit;
void de_huffman(obytes)
unsigned long obytes;
{
while(obytes != 0) {
*out_ptr++ = gethuffbyte(nodelist);
obytes--;
}
return;
}
void de_huffman_end(term)
unsigned int term;
{
int c;
while((c = gethuffbyte(nodelist)) != term) {
*out_ptr++ = c;
}
}
void set_huffman(endian)
int endian;
{
if(endian == HUFF_LE) {
get_bit = getbit_le;
} else if(endian == HUFF_BE) {
get_bit = getbit_be;
}
}
void read_tree()
{
nodeptr = nodelist;
bit = 0; /* put us on a boundary */
(void)read_sub_tree();
}
/* This routine recursively reads the Huffman encoding table and builds
a decoding tree. */
static node *read_sub_tree()
{
node *np;
np = nodeptr++;
if((*get_bit)() == 1) {
np->flag = 1;
np->byte = getdecodebyte();
} else {
np->flag = 0;
np->zero = read_sub_tree();
np->one = read_sub_tree();
}
return np;
}
/* This routine returns the next bit in the input stream (MSB first) */
static int getbit_be()
{
static int b;
if(bit == 0) {
b = getb(infp) & BYTEMASK;
bit = 8;
bytesread++;
}
bit--;
return (b >> bit) & 1;
}
/* This routine returns the next bit in the input stream (LSB first) */
static int getbit_le()
{
static int b;
if(bit == 0) {
b = getb(infp) & BYTEMASK;
bit = 8;
bytesread++;
}
bit--;
return (b >> (7 - bit)) & 1;
}
void clrhuff()
{
bit = 0;
}
int gethuffbyte(l_nodelist)
node *l_nodelist;
{
register node *np;
np = l_nodelist;
while(np->flag == 0) {
np = (*get_bit)() ? np->one : np->zero;
}
return np->byte;
}
int getihuffbyte()
{
return gethuffbyte(nodelist);
}
static int getdecodebyte()
{
register int i, b;
b = 0;
for(i = 8; i > 0; i--) {
b = (b << 1) + (*get_bit)();
}
return b;
}
#else /* DEHUFFMAN */
int dehuffman; /* keep lint and some compilers happy */
#endif /* DEHUFFMAN */
|