This is lz.c in view mode; [Download] [Up]
#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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.