home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume25
/
freeze
/
part01
/
encode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-04
|
4KB
|
187 lines
#include "freeze.h"
#include "lz.h"
#include "huf.h"
#include "bitio.h"
/* for future versions ?... */
#define LENGTH_OFFSET 256
#define EncodeLiteral(l) EncodeChar(l)
#define EncodeLength(l) EncodeChar(l + LENGTH_OFFSET)
/*
* Freezes stdin to stdout
*/
void freeze ()
{
register u_short i, len, r, s;
register short c;
putchar(MAGIC1);
putchar(MAGIC2_2);
/* Huffman-dependent part */
write_header();
StartHuff(N_CHAR2);
init(Table2);
/* end of Huffman-dependent part */
InitTree(); /* LZ dependent */
InitIO();
s = 0;
r = N2 - F2;
for (i = s; i < r; i++)
text_buf[i] = ' ';
for (len = 0; len < F2 && (c = getchar()) != EOF; len++)
text_buf[r + len] = c;
/* check for magic header */
if(!topipe && !force && text_buf[r] == MAGIC1 &&
text_buf[r + 1] >= MAGIC2_1) {
if (quiet != 1)
fprintf(stderr, " already frozen ");
exit_stat = 2;
return;
}
in_count = len;
for (i = 0; i <= F2; i++)
InsertNode(r + i - F2);
while (len != 0) {
Get_Next_Match(r,1);
if (match_length > len)
match_length = len;
if (match_length <= THRESHOLD) {
match_length = 1;
EncodeLiteral(text_buf[r]);
#ifdef DEBUG
symbols_out ++;
if (verbose)
fprintf(stderr, "'%s'\n",
pr_char(text_buf[r]));
#endif /* DEBUG */
} else if (greedy) {
/* GREEDY parsing (compression rate 1.5% worse, but 40% faster) */
EncodeLength((u_short) (match_length - THRESHOLD));
EncodePosition((u_short)match_position);
} else {
register u_short orig_length, orig_position, oldchar;
/* This fragment (delayed coding, non-greedy) is due to ideas of
Jan Mark Wams' <jms@cs.vu.nl> COMIC:
*/
oldchar = text_buf[r];
orig_length = match_length;
orig_position = match_position;
DeleteNode(s);
Next_Char(N2, F2);
Get_Next_Match(r,2);
if (match_length > len) match_length = len;
if (orig_length > match_length) {
EncodeLength((u_short)
(orig_length - THRESHOLD));
EncodePosition((u_short)orig_position);
#ifdef DEBUG
match_position = orig_position;
#endif /* DEBUG */
match_length = orig_length - 1;
} else {
EncodeLiteral(oldchar);
#ifdef DEBUG
symbols_out ++;
if (verbose)
fprintf(stderr, "'%s'\n",
pr_char(oldchar));
#endif /* DEBUG */
EncodeLength(match_length - THRESHOLD);
EncodePosition(match_position);
}
#ifdef DEBUG
refers_out ++;
if (verbose) {
register short pos =
(r - 1 - match_position) & (N2 - 1),
leng = match_length;
fputc('"', stderr);
for(; leng; leng--, pos++)
fprintf(stderr, "%s",
pr_char(text_buf[pos]));
fprintf(stderr, "\"\n");
}
#endif /* DEBUG */
}
/* Process the rest of the matched sequence (insertion in the list
only, without any matching !!!)
*/
for (i = 0; i < match_length &&
(c = getchar()) != EOF; i++) {
DeleteNode(s);
text_buf[s] = c;
if (s < F2 - 1)
text_buf[s + N2] = c;
s = (s + 1) & (N2 - 1);
r = (r + 1) & (N2 - 1);
InsertNode(r);
}
in_count += i;
INDICATOR
while (i++ < match_length) {
DeleteNode(s);
s = (s + 1) & (N2 - 1);
r = (r + 1) & (N2 - 1);
if (--len) InsertNode(r);
}
}
/* to flush literals */
EncodeLength((short)ENDOF - LENGTH_OFFSET);
#ifdef DEBUG
symbols_out ++;
#endif
EncodeEnd();
/*
* Print out stats on stderr
*/
if(quiet != 1) {
#ifdef GATHER_STAT
fprintf(stderr, "Average number of steps: ");
prratio(stderr, node_steps, node_matches);
fprintf(stderr, "\n");
#endif
#ifdef DEBUG
fprintf( stderr,
"%ld chars in, %ld codes (%ld bytes) out, freezing factor: ",
in_count, symbols_out + refers_out, bytes_out);
prratio( stderr, in_count, bytes_out );
fprintf( stderr, "\n");
fprintf( stderr, "\tFreezing as in compact: " );
prratio( stderr, in_count-bytes_out, in_count );
prbits( stderr, in_count, bytes_out);
fprintf( stderr, "\n");
fprintf( stderr, "\tSymbols: %ld; references: %ld.\n",
symbols_out, refers_out);
#else /* !DEBUG */
fprintf( stderr, "Freezing: " );
prratio( stderr, in_count-bytes_out, in_count );
prbits( stderr, in_count, bytes_out);
#endif /* DEBUG */
}
if(bytes_out >= in_count) /* exit(2) if no savings */
exit_stat = 2;
return;
}