home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Club Elmshorn Atari PD
/
CCE_PD.iso
/
pc
/
0400
/
CCE_0483.ZIP
/
CCE_0483.PD
/
LZH_SOUR.CE
/
LHUF5.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-10
|
23KB
|
962 lines
#include "lh5.h"
#include <stdlib.h>
#include <string.h> /* memmove() */
#ifdef __TOS__
#include "goodputc.h"
#endif
/* #define _lhufs_ */
extern uchar text_buf[DICSIZ];
#define buffer text_buf
/* static uchar buffer[DICSIZ]; */
#define CRCPOLY 0xA001 /* ANSI CRC-16 */
/* CCITT: 0x8408 */
#define UPDATE_CRC(c) \
crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
extern FILE *infile, *outfile;
extern uint crc;
ulong origsize,compsize;
#ifdef _lhufs_
uint bitbuf;
extern uint subbitbuf;
extern int bitcount;
extern ulong origsize,compsize;
#else
uint bitbuf;
uint subbitbuf;
int bitcount;
ulong origsize,compsize;
#endif
extern uchar flg_n;
ushort crctable[UCHAR_MAX + 1];
uint subbitbuf;
int bitcount;
static void error(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
putc('\n', stderr);
vfprintf(stderr, fmt, args);
putc('\n', stderr);
va_end(args);
exit(EXIT_FAILURE);
}
void make_crctable(void)
{
uint i, j, r;
static int crc_ready = 0;
if (crc_ready == 0) {
for (i = 0; i <= UCHAR_MAX; i++) {
r = i;
for (j = 0; j < CHAR_BIT; j++)
if (r & 1) r = (r >> 1) ^ CRCPOLY;
else r >>= 1;
crctable[i] = r;
}
crc_ready=1;
}
}
void fillbuf(int n) /* Shift bitbuf n bits left, read n bits */
{
bitbuf <<= n;
while (n > bitcount) {
bitbuf |= subbitbuf << (n -= bitcount);
if (compsize != 0) {
compsize--; subbitbuf = (uchar) getc(infile);
} else subbitbuf = 0;
bitcount = CHAR_BIT;
}
bitbuf |= subbitbuf >> (bitcount -= n);
}
static uint getbits(int n)
{
uint x;
x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
return x;
}
static void putbits(int n, uint x) /* Write rightmost n bits of x */
{
if (n < bitcount) {
subbitbuf |= x << (bitcount -= n);
} else {
if (compsize < origsize) {
if (putc(subbitbuf | (x >> (n -= bitcount)), outfile) == EOF) error("Unable to write");
compsize++;
} else unpackable = 1;
if (n < CHAR_BIT) {
subbitbuf = x << (bitcount = CHAR_BIT - n);
} else {
if (compsize < origsize) {
if (putc(x >> (n - CHAR_BIT), outfile) == EOF) error("Unable to write");
compsize++;
} else unpackable = 1;
subbitbuf = x << (bitcount = 2 * CHAR_BIT - n);
}
}
}
int fread_crc(uchar *p, int n, FILE *f)
{
int i;
i = n = fread(p, 1, n, f); origsize += n;
while (--i >= 0) UPDATE_CRC(*p++);
return n;
}
static void fwrite_crc(uchar *p, int n, FILE *f)
{
if (f!= NULL) if (fwrite(p, 1, n, f) < n) error("Unable to write");
while (--n >= 0) UPDATE_CRC(*p++);
}
static void init_getbits(void)
{
bitbuf = 0; subbitbuf = 0; bitcount = 0;
fillbuf(BITBUFSIZ);
}
static void init_putbits(void)
{
bitcount = CHAR_BIT; subbitbuf = 0;
}
/* --------------------------- End of IO.C --------------------------- */
/***********************************************************
decode.c
***********************************************************/
/* ----------------------Start of huf.c ------------------------------- */
/***********************************************************
huf.c -- static Huffman
***********************************************************/
#define NP (DICBIT + 1)
#define NT (CODE_BIT + 3)
#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
#if NT > NP
#define NPT NT
#else
#define NPT NP
#endif
extern ushort left[2 * NC - 1], right[2 * NC - 1];
extern uchar *buf, c_len[NC], pt_len[NPT];
extern int bufsiz = 0, blocksize;
extern ushort c_freq[2 * NC - 1], c_table[4096], c_code[NC],
p_freq[2 * NP - 1], pt_table[256], pt_code[NPT],
t_freq[2 * NT - 1];
extern ushort dad[4096];
#define c_table dad
/***** encoding *****/
void count_t_freq(void)
{
int i, k, n, count;
for (i = 0; i < NT; i++) t_freq[i] = 0;
n = NC;
while (n > 0 && c_len[n - 1] == 0) n--;
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) { i++; count++; }
if (count <= 2) t_freq[0] += count;
else if (count <= 18) t_freq[1]++;
else if (count == 19) { t_freq[0]++; t_freq[1]++; }
else t_freq[2]++;
} else t_freq[k + 2]++;
}
}
void write_pt_len(int n, int nbit, int i_special)
{
int i, k;
while (n > 0 && pt_len[n - 1] == 0) n--;
putbits(nbit, n);
i = 0;
while (i < n) {
k = pt_len[i++];
if (k <= 6) putbits(3, k);
else putbits(k - 3, (1U << (k - 3)) - 2);
if (i == i_special) {
while (i < 6 && pt_len[i] == 0) i++;
putbits(2, (i - 3) & 3);
}
}
}
void write_c_len(void)
{
int i, k, n, count;
n = NC;
while (n > 0 && c_len[n - 1] == 0) n--;
putbits(CBIT, n);
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) { i++; count++; }
if (count <= 2) {
for (k = 0; k < count; k++)
putbits(pt_len[0], pt_code[0]);
} else if (count <= 18) {
putbits(pt_len[1], pt_code[1]);
putbits(4, count - 3);
} else if (count == 19) {
putbits(pt_len[0], pt_code[0]);
putbits(pt_len[1], pt_code[1]);
putbits(4, 15);
} else {
putbits(pt_len[2], pt_code[2]);
putbits(CBIT, count - 20);
}
} else putbits(pt_len[k + 2], pt_code[k + 2]);
}
}
void encode_c(int c)
{
putbits(c_len[c], c_code[c]);
}
void encode_p(uint p)
{
uint c, q;
c = 0; q = p; while (q) { q >>= 1; c++; }
putbits(pt_len[c], pt_code[c]);
if (c > 1) putbits(c - 1, p & (0xFFFFU >> (17 - c)));
}
void send_block(void)
{
uint i, k, flags, root, pos, size;
root = make_tree(NC, c_freq, c_len, c_code);
size = c_freq[root]; putbits(16, size);
if (root >= NC) {
count_t_freq();
root = make_tree(NT, t_freq, pt_len, pt_code);
if (root >= NT) {
write_pt_len(NT, TBIT, 3);
} else {
putbits(TBIT, 0); putbits(TBIT, root);
}
write_c_len();
} else {
putbits(TBIT, 0); putbits(TBIT, 0);
putbits(CBIT, 0); putbits(CBIT, root);
}
root = make_tree(NP, p_freq, pt_len, pt_code);
if (root >= NP) {
write_pt_len(NP, PBIT, -1);
} else {
putbits(PBIT, 0); putbits(PBIT, root);
}
pos = 0;
for (i = 0; i < size; i++) {
if (i % CHAR_BIT == 0) flags = buf[pos++]; else flags <<= 1;
if (flags & (1U << (CHAR_BIT - 1))) {
encode_c(buf[pos++] + (1U << CHAR_BIT));
k = buf[pos++] << CHAR_BIT; k += buf[pos++];
encode_p(k);
} else encode_c(buf[pos++]);
if (unpackable) return;
}
for (i = 0; i < NC; i++) c_freq[i] = 0;
for (i = 0; i < NP; i++) p_freq[i] = 0;
}
uint output_pos, output_mask;
#ifdef _lhufs_
extern void output5(uint c, uint p);
#else
void output5(uint c, uint p)
{
static uint cpos;
if ((output_mask >>= 1) == 0) {
output_mask = 1U << (CHAR_BIT - 1);
if (output_pos >= bufsiz - 3 * CHAR_BIT) {
send_block();
if (unpackable) return;
output_pos = 0;
}
cpos = output_pos++; buf[cpos] = 0;
}
buf[output_pos++] = (uchar) c; c_freq[c]++;
if (c >= (1U << CHAR_BIT)) {
buf[cpos] |= output_mask;
buf[output_pos++] = (uchar)(p >> CHAR_BIT);
buf[output_pos++] = (uchar) p;
c = 0; while (p) { p >>= 1; c++; }
p_freq[c]++;
}
}
#endif
void start_huf(void)
{
int i;
if (bufsiz == 0) {
bufsiz = 16 * 1024U;
while ((buf = malloc(bufsiz)) == NULL) {
bufsiz = (bufsiz / 10U) * 9U;
if (bufsiz < 4 * 1024U) error("Out of memory.");
}
}
buf[0] = 0;
for (i = 0; i < NC; i++) c_freq[i] = 0;
for (i = 0; i < NP; i++) p_freq[i] = 0;
output_pos = output_mask = 0;
init_putbits();
}
void end_huf(void)
{
if (! unpackable) {
send_block();
putbits(CHAR_BIT - 1, 0); /* flush remaining bits */
}
}
/***** decoding *****/
static void read_pt_len(int nn, int nbit, int i_special)
{
int i, c, n;
uint mask;
n = getbits(nbit);
if (n == 0) {
c = getbits(nbit);
for (i = 0; i < nn; i++) pt_len[i] = 0;
for (i = 0; i < 256; i++) pt_table[i] = c;
} else {
i = 0;
while (i < n) {
c = bitbuf >> (BITBUFSIZ - 3);
if (c == 7) {
mask = 1U << (BITBUFSIZ - 1 - 3);
while (mask & bitbuf) { mask >>= 1; c++; }
}
fillbuf((c < 7) ? 3 : c - 3);
pt_len[i++] = c;
if (i == i_special) {
c = getbits(2);
while (--c >= 0) pt_len[i++] = 0;
}
}
while (i < nn) pt_len[i++] = 0;
make_table(nn, pt_len, 8, pt_table);
}
}
static void read_c_len(void)
{
int i, c, n;
uint mask;
n = getbits(CBIT);
if (n == 0) {
c = getbits(CBIT);
for (i = 0; i < NC; i++) c_len[i] = 0;
for (i = 0; i < 4096; i++) c_table[i] = c;
} else {
i = 0;
while (i < n) {
c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
if (c >= NT) {
mask = 1U << (BITBUFSIZ - 1 - 8);
do {
if (bitbuf & mask) c = right[c];
else c = left [c];
mask >>= 1;
} while (c >= NT);
}
fillbuf(pt_len[c]);
if (c <= 2) {
if (c == 0) c = 1;
else if (c == 1) c = getbits(4) + 3;
else c = getbits(CBIT) + 20;
while (--c >= 0) c_len[i++] = 0;
} else c_len[i++] = c - 2;
}
while (i < NC) c_len[i++] = 0;
make_table(NC, c_len, 12, c_table);
}
}
static uint decode_c(void)
{
uint j, mask;
if (blocksize == 0) {
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
read_pt_len(NP, PBIT, -1);
}
blocksize--;
j = c_table[bitbuf >> (BITBUFSIZ - 12)];
if (j >= NC) {
mask = 1U << (BITBUFSIZ - 1 - 12);
do {
if (bitbuf & mask) j = right[j];
else j = left [j];
mask >>= 1;
} while (j >= NC);
}
fillbuf(c_len[j]);
return j;
}
static uint decode_p(void)
{
uint j, mask;
j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
if (j >= NP) {
mask = 1U << (BITBUFSIZ - 1 - 8);
do {
if (bitbuf & mask) j = right[j];
else j = left [j];
mask >>= 1;
} while (j >= NP);
}
fillbuf(pt_len[j]);
if (j != 0) j = (1U << (j - 1)) + getbits(j - 1);
return j;
}
static void huf_decode_start(void)
{
init_getbits(); blocksize = 0;
}
/* ----------------------End of huf.c ------------------------------- */
/* ----------------------Start of maketre.c---------------------------- */
/***********************************************************
maketree.c -- make Huffman tree
***********************************************************/
static int n, heapsize;
static short heap[NC + 1];
static ushort *freq, *sortptr, len_cnt[17];
static uchar *len;
static void count_len(int i) /* call with i = root */
{
static int depth = 0;
if (i < n) len_cnt[(depth < 16) ? depth : 16]++;
else {
depth++;
count_len(left [i]);
count_len(right[i]);
depth--;
}
}
static void make_len(int root)
{
int i, k;
uint cum;
for (i = 0; i <= 16; i++) len_cnt[i] = 0;
count_len(root);
cum = 0;
for (i = 16; i > 0; i--)
cum += len_cnt[i] << (16 - i);
while (cum != (1U << 16)) {
fprintf(stderr, "17");
len_cnt[16]--;
for (i = 15; i > 0; i--) {
if (len_cnt[i] != 0) {
len_cnt[i]--; len_cnt[i+1] += 2; break;
}
}
cum--;
}
for (i = 16; i > 0; i--) {
k = len_cnt[i];
while (--k >= 0) len[*sortptr++] = i;
}
}
static void downheap(int i)
/* priority queue; send i-th entry down heap */
{
int j, k;
k = heap[i];
while ((j = 2 * i) <= heapsize) {
if (j < heapsize && freq[heap[j]] > freq[heap[j + 1]])
j++;
if (freq[k] <= freq[heap[j]]) break;
heap[i] = heap[j]; i = j;
}
heap[i] = k;
}
static void make_code(int n, uchar len[], ushort code[])
{
int i;
ushort start[18];
start[1] = 0;
for (i = 1; i <= 16; i++)
start[i + 1] = (start[i] + len_cnt[i]) << 1;
for (i = 0; i < n; i++) code[i] = start[len[i]]++;
}
int make_tree(int nparm, ushort freqparm[],
uchar lenparm[], ushort codeparm[])
/* make tree, calculate len[], return root */
{
int i, j, k, avail;
n = nparm; freq = freqparm; len = lenparm;
avail = n; heapsize = 0; heap[1] = 0;
for (i = 0; i < n; i++) {
len[i] = 0;
if (freq[i]) heap[++heapsize] = i;
}
if (heapsize < 2) {
codeparm[heap[1]] = 0; return heap[1];
}
for (i = heapsize / 2; i >= 1; i--)
downheap(i); /* make priority queue */
sortptr = codeparm;
do { /* while queue has at least two entries */
i = heap[1]; /* take out least-freq entry */
if (i < n) *sortptr++ = i;
heap[1] = heap[heapsize--];
downheap(1);
j = heap[1]; /* next least-freq entry */
if (j < n) *sortptr++ = j;
k = avail++; /* generate new node */
freq[k] = freq[i] + freq[j];
heap[1] = k; downheap(1); /* put into queue */
left[k] = i; right[k] = j;
} while (heapsize > 1);
sortptr = codeparm;
make_len(k);
make_code(nparm, lenparm, codeparm);
return k; /* return root */
}
/* ----------------------End of maketre.c---------------------------- */
/* ----------------------End of maketbl.c---------------------------- */
/***********************************************************
maketbl.c -- make table for decoding
***********************************************************/
static void make_table(int nchar, uchar bitlen[], int tablebits, ushort table[])
{
ushort count[17], weight[17], start[18], *p;
uint i, k, len, ch, jutbits, avail, nextcode, mask;
for (i = 1; i <= 16; i++) count[i] = 0;
for (i = 0; i < nchar; i++) count[bitlen[i]]++;
start[1] = 0;
for (i = 1; i <= 16; i++)
start[i + 1] = start[i] + (count[i] << (16 - i));
if (start[17] != (ushort)(1U << 16)) error("Bad table");
jutbits = 16 - tablebits;
for (i = 1; i <= tablebits; i++) {
start[i] >>= jutbits;
weight[i] = 1U << (tablebits - i);
}
while (i <= 16) weight[i++] = 1U << (16 - i);
i = start[tablebits + 1] >> jutbits;
if (i != (ushort)(1U << 16)) {
k = 1U << tablebits;
while (i != k) table[i++] = 0;
}
avail = nchar;
mask = 1U << (15 - tablebits);
for (ch = 0; ch < nchar; ch++) {
if ((len = bitlen[ch]) == 0) continue;
nextcode = start[len] + weight[len];
if (len <= tablebits) {
for (i = start[len]; i < nextcode; i++) table[i] = ch;
} else {
k = start[len];
p = &table[k >> jutbits];
i = len - tablebits;
while (i != 0) {
if (*p == 0) {
right[avail] = left[avail] = 0;
*p = avail++;
}
if (k & mask) p = &right[*p];
else p = &left[*p];
k <<= 1; i--;
}
*p = ch;
}
start[len] = nextcode;
}
}
/* ----------------------End of maketbl.c---------------------------- */
/* --------------------- start of decode.c ---------------------------- */
static int dec_j; /* remaining bytes to copy */
static void decode_start(void)
{
huf_decode_start();
dec_j = 0;
}
static void decode5(uint count, uchar buffer[])
/* The calling function must keep the number of
bytes to be processed. This function decodes
either 'count' bytes or 'DICSIZ' bytes, whichever
is smaller, into the array 'buffer[]' of size
'DICSIZ' or more.
Call decode_start() once for each new file
before calling this function. */
{
static uint i;
uint r, c;
r = 0;
while (--dec_j >= 0) {
buffer[r] = buffer[i];
i = (i + 1) & (DICSIZ - 1);
if (++r == count) return;
}
for ( ; ; ) {
c = decode_c();
if (c <= UCHAR_MAX) {
buffer[r] = c;
if (++r == count) return;
} else {
dec_j = c - (UCHAR_MAX + 1 - THRESHOLD);
i = (r - decode_p() - 1) & (DICSIZ - 1);
while (--dec_j >= 0) {
buffer[r] = buffer[i];
i = (i + 1) & (DICSIZ - 1);
if (++r == count) return;
}
}
}
}
void decode_lh5(ulong orgsize, ulong pacsize)
{
int n;
make_crctable();
origsize=orgsize;
compsize=pacsize;
crc = INIT_CRC;
decode_start();
while (origsize != 0) {
n = (uint)((origsize > DICSIZ) ? DICSIZ : origsize);
decode5(n, buffer);
fwrite_crc(buffer, n, outfile);
if (outfile != stdout) if (!flg_n) putc('*', stdout);
origsize -= n;
}
}
/* ------------------------End of Deocde.c- --------------------------- */
/* ----------------------Start of Encode.c ---------------------------- */
/***********************************************************
encode.c -- sliding dictionary with percolating update
***********************************************************/
#define PERCOLATE 1
#define NIL 0
#define MAX_HASH_VAL (3 * DICSIZ + (DICSIZ / 512 + 1) * UCHAR_MAX)
typedef short node;
extern uchar *text, *childcount;
extern node pos, matchpos, avail, *position, *parent, *prev, *next = NULL;
extern int remainder, matchlen;
#if MAXMATCH <= (UCHAR_MAX + 1)
extern uchar *level;
#else
extern ushort *level;
#endif
void allocate_memory(void)
{
if (next != NULL) return;
text = malloc(DICSIZ * 2 + MAXMATCH);
level = malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*level));
childcount = malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*childcount));
#if PERCOLATE
position = malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*position));
#else
position = malloc(DICSIZ * sizeof(*position));
#endif
parent = malloc(DICSIZ * 2 * sizeof(*parent));
prev = malloc(DICSIZ * 2 * sizeof(*prev));
next = malloc((MAX_HASH_VAL + 1) * sizeof(*next));
if (next == NULL) error("Out of memory.");
}
#ifdef _lhufs_
/* extern void split(node old);
extern void insert_node(void);
extern void delete_node(void);
extern void get_next_match(void);
extern ulong encode5(ulong orgsize); */
#else
void init_slide(void)
{
node i;
for (i = DICSIZ; i <= DICSIZ + UCHAR_MAX; i++) {
level[i] = 1;
#if PERCOLATE
position[i] = NIL; /* sentinel */
#endif
}
for (i = DICSIZ; i < DICSIZ * 2; i++) parent[i] = NIL;
avail = 1;
for (i = 1; i < DICSIZ - 1; i++) next[i] = i + 1;
next[DICSIZ - 1] = NIL;
for (i = DICSIZ * 2; i <= MAX_HASH_VAL; i++) next[i] = NIL;
}
#define HASH(p, c) ((p) + ((c) << (DICBIT - 9)) + DICSIZ * 2)
node child(node q, uchar c)
/* q's child for character c (NIL if not found) */
{
node r;
r = next[HASH(q, c)];
parent[NIL] = q; /* sentinel */
while (parent[r] != q) r = next[r];
return r;
}
void makechild(node q, uchar c, node r)
/* Let r be q's child for character c. */
{
node h, t;
h = HASH(q, c);
t = next[h]; next[h] = r; next[r] = t;
prev[t] = r; prev[r] = h;
parent[r] = q; childcount[q]++;
}
static void split(node old)
{
node new, t;
new = avail; avail = next[new]; childcount[new] = 0;
t = prev[old]; prev[new] = t; next[t] = new;
t = next[old]; next[new] = t; prev[t] = new;
parent[new] = parent[old];
level[new] = matchlen;
position[new] = pos;
makechild(new, text[matchpos + matchlen], old);
makechild(new, text[pos + matchlen], pos);
}
static void insert_node(void)
{
node q, r, j, t;
uchar c, *t1, *t2;
int matchl;
matchl=matchlen;
if (matchl >= 4) {
matchl--;
r = (matchpos + 1) | DICSIZ;
while ((q = parent[r]) == NIL) r = next[r];
while (level[q] >= matchl) {
r = q; q = parent[q];
}
#if PERCOLATE
t = q;
while (position[t] < 0) {
position[t] = pos; t = parent[t];
}
if (t < DICSIZ) position[t] = pos | PERC_FLAG;
#else
t = q;
while (t < DICSIZ) {
position[t] = pos; t = parent[t];
}
#endif
} else {
q = text[pos] + DICSIZ; c = text[pos + 1];
matchlen=matchl;
if ((r = child(q, c)) == NIL) {
makechild(q, c, pos); matchl = 1;
return;
}
matchl = 2;
}
for ( ; ; ) {
if (r >= DICSIZ) {
j = MAXMATCH; matchpos = r;
} else {
j = level[r];
matchpos = position[r] & ~PERC_FLAG;
}
if (matchpos >= pos) matchpos -= DICSIZ;
t1 = &text[pos + matchl]; t2 = &text[matchpos + matchl];
while (matchl < j) {
if (*t1 != *t2) { matchlen=matchl; split(r); return; }
matchl++; t1++; t2++;
}
if (matchl >= MAXMATCH) break;
position[r] = pos;
q = r;
if ((r = child(q, *t1)) == NIL) {
matchlen=matchl;
makechild(q, *t1, pos); return;
}
matchl++;
}
t = prev[r]; prev[pos] = t; next[t] = pos;
t = next[r]; next[pos] = t; prev[t] = pos;
parent[pos] = q; parent[r] = NIL;
next[r] = pos; /* special use of next[] */
matchlen=matchl;
}
static void delete_node(void)
{
#if PERCOLATE
node q, r, s, t, u;
#else
node r, s, t, u;
#endif
if (parent[pos] == NIL) return;
r = prev[pos]; s = next[pos];
next[r] = s; prev[s] = r;
r = parent[pos]; parent[pos] = NIL;
if (r >= DICSIZ || --childcount[r] > 1) return;
#if PERCOLATE
t = position[r] & ~PERC_FLAG;
#else
t = position[r];
#endif
if (t >= pos) t -= DICSIZ;
#if PERCOLATE
s = t; q = parent[r];
while ((u = position[q]) & PERC_FLAG) {
u &= ~PERC_FLAG; if (u >= pos) u -= DICSIZ;
if (u > s) s = u;
position[q] = (s | DICSIZ); q = parent[q];
}
if (q < DICSIZ) {
if (u >= pos) u -= DICSIZ;
if (u > s) s = u;
position[q] = s | DICSIZ | PERC_FLAG;
}
#endif
s = child(r, text[t + level[r]]);
t = prev[s]; u = next[s];
next[t] = u; prev[u] = t;
t = prev[r]; next[t] = s; prev[s] = t;
t = next[r]; prev[t] = s; next[s] = t;
parent[s] = parent[r]; parent[r] = NIL;
next[r] = avail; avail = r;
}
static void get_next_match(void)
{
int n;
remainder--;
if (++pos == DICSIZ * 2) {
memmove(&text[0], &text[DICSIZ], DICSIZ + MAXMATCH);
n = fread_crc(&text[DICSIZ + MAXMATCH], DICSIZ, infile);
remainder += n; pos = DICSIZ; if (!flg_n) putc('*', stdout);
}
delete_node(); insert_node();
}
void init_encode5(void)
{
allocate_memory(); init_slide(); start_huf();
}
ulong encode5(ulong orgsize)
{
int lastmatchlen;
node lastmatchpos;
unpackable=0;
make_crctable();
origsize=orgsize;
compsize=0;
remainder = fread_crc(&text[DICSIZ], DICSIZ + MAXMATCH, infile);
if (!flg_n) putc('*', stdout);
matchlen = 0;
pos = DICSIZ; insert_node();
if (matchlen > remainder) matchlen = remainder;
while (remainder > 0 && ! unpackable) {
lastmatchlen = matchlen; lastmatchpos = matchpos;
get_next_match();
if (matchlen > remainder) matchlen = remainder;
if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD)
output5(text[pos - 1], 0);
else {
output5(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
(pos - lastmatchpos - 2) & (DICSIZ - 1));
while (--lastmatchlen > 0) get_next_match();
if (matchlen > remainder) matchlen = remainder;
}
}
end_huf();
if (unpackable) compsize=orgsize+1;
return compsize;
}
#endif
/* ----------------------- End of Encode.c ---------------------------- */