home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume25
/
freeze
/
part02
/
lz.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-04
|
3KB
|
146 lines
#include "freeze.h"
#include "lz.h"
/*----------------------------------------------------------------------*/
/* */
/* LZSS ENCODING */
/* */
/*----------------------------------------------------------------------*/
uchar text_buf[N2 + F2 - 1]; /* cyclic buffer with an overlay */
u_short match_position, match_length; /* current characteristics of a
matched pattern */
/* next[N+1..] is used as hash table,
the rest of next is a link down,
prev is a link up.
*/
hash_t prev[N2 + 1];
#ifndef __XENIX__
#ifdef __TURBOC__
u_short huge * next = (u_short huge *) NULL;
#else /* __TURBOC__ */
u_short next[array_size]; /* a VERY large array :-) */
#endif /* __TURBOC__ */
#else /* __XENIX__ */
#if parts == 2
u_short next0[32768L], next1[8193];
#else
# if parts == 3
u_short next0[32768L], next1[32768L], next2[8193];
# else
# if parts == 5
u_short next0[32768L], next1[32768L], next2[32768L], next3[32768L], next4[8193];
# else
u_short next0[32768L], next1[32768L], next2[32768L], next3[32768L], next4[32768L],
next5[32768L], next6[32768L], next7[32768L], next8[8193];
# endif
# endif
#endif /* parts */
/* A list of `next's parts */
u_short *next[parts] = {
next0, next1
#if parts > 2
,next2
#if parts > 3
,next3, next4
#if parts > 5
,next5, next6,
next7, next8
#endif
#endif
#endif
};
#endif /* __XENIX__ */
#ifdef GATHER_STAT
long node_steps, node_matches;
#endif /* GATHER_STAT */
/* Initialize the data structures and allocate memory, if needed.
Although there is no more trees in the LZ algorithm
implementation, routine name is kept intact :-)
*/
void InitTree ()
{
long i;
#ifdef GATHER_STAT
node_steps = node_matches = 0;
#endif /* GATHER_STAT */
#ifdef __TURBOC__
if (!next && (next = (u_short huge *) farmalloc(
(unsigned long)array_size * sizeof(u_short))) == NULL) {
fprintf(stderr, "Not enough memory (%luK wanted)\n",
(unsigned long)array_size * sizeof(u_short) / 1024);
exit(3);
}
#endif /* __TURBOC__ */
for (i = N2 + 1; i < array_size; i++ )
nextof(i) = NIL;
for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ )
prev[i] = NIL;
}
/* Get the longest nearest match of the string beginning in text_buf[r]
to the cyclic buffer. Result (length & position) is returned
in correspondent global variables (`match_length' &
`match_position'). `match_length' == 0 denotes failure.
*/
#ifndef FAST
void get_next_match (r)
u_short r;
{
register u_short p = r;
register int m;
register uchar *key FIX_SI, *pattern FIX_DI;
#ifdef GATHER_STAT
node_matches++;
#endif
key = text_buf + r;
match_length = 0;
do {
do {
if ((p = nextof(p)) == NIL)
return;
pattern = text_buf + p;
MATCHING;
} while NOT_YET;
#ifdef GATHER_STAT
node_steps++;
#endif
for (m = match_length;
++m < F2 && key[m] == pattern[m]; );
match_length = m;
match_position = ((r - p) & (N2 - 1)) - 1;
} while (m < F2);
/* There are two equal F-char sequences, the oldest one must be
deleted from the list.
*/
#ifdef DEBUG
if (verbose)
fprintf(stderr, "Replacing node: %d -> %d\n", p, r);
#endif
nextof(prev[p]) = nextof(p);
prev[nextof(p)] = prev[p];
prev[p] = NIL; /* remove p, it is further than r */
return;
}
#endif