jms@cs.vu.nl (Jan-Mark Wams) (08/01/90)
This is version 1.0 of COMIC. It supports DOS (TCC) and it's a little faster. (Getinput() is the bad thing now. 8-) Endjoy........ : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. : --------------------------- cut here -------------------------- PATH=/bin:/usr/bin:/usr/ucb echo Extracting 'bits.c' sed 's/^X//' > 'bits.c' << '+ END-OF-FILE ''bits.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Bits.c: Read and write bits on stdin and out. X** X** Just define DEBUG to get characters '1' and '0'. X** The bits are put on a file, first bit in the high bit of the X** first byte. `Flus_bits ()' will add a `1' and padd the byte X** up to a full byte with zero's. When reading back the last bit X** in the last byte is the eof indicator. X*/ X X#include <errno.h> X#include "comic.h" X#include "bits.h" X X#ifdef DEBUG /* Use characters '1' and '0'. */ X X/* X** Putbit: put a bit on stdout. X*/ Xvoid putbit (bit) Xint bit; X{ X assert (bit == 1 || bit == 0); X X Nout += 1; X putchar ('0' + bit); X} X X/* X** Getbit: get a bit from stdin. X*/ Xint getbit () X{ X switch (getchar ()) { X case '0' : return 0; X case '1' : return 1; X case EOF : return EOF; X default : return 2; X } X} X X/* X** Init_bits: Init the bit package. X*/ Xvoid init_bits () X{ X /* Noting to do in DEBUG mode. */ X} X X X/* X** Flush_bits: Flush the buffered bits to stdout. X*/ Xvoid flush_bits () X{ X fflush (stdout); X} X X X#else /* No debug, so use 8 bits per byte. */ X X#define IO_BUFF_SIZE 1024 Xstatic char io_buff [IO_BUFF_SIZE]; X#define eo_buff (io_buff + IO_BUFF_SIZE) Xstatic char *io_index = io_buff; Xstatic char *eof_index = io_buff; Xstatic int put_bits = 1; Xstatic int get_bits = 0; X X#define next() (io_index++) /* The next char. */ X#define nonext() (io_index == eof_index) /* There is no next. */ X#define io_buff_full (io_index == eo_buff) /* Buffer full. */ X X X/* X** fatal: Print a error on stderr, and exit. X*/ Xstatic void fatal (failed) Xchar *failed; X{ X fprintf (stderr, "\r%s: Fatal couldn't %s", pname, failed); X if (errno != 0) X perror(""); /* Prints EOLN to ;-( */ X else X printf ("\n"); X exit (-1); X} X X X/* X** Write_io_buff: to stdout. X*/ Xstatic void write_io_buff () X{ X if (write (1, io_buff, io_index - io_buff) != io_index - io_buff) X fatal ("write"); X Nout += io_index - io_buff; X io_index = io_buff; X} X X/* X** Read_io_buff: from stdin. X*/ Xstatic void read_io_buff () X{ X if ((eof_index = io_buff + read (0, io_buff, IO_BUFF_SIZE)) < io_buff) X fatal ("read"); X X Nin += eof_index - io_buff; X X io_index = io_buff; X} X X X/* X** Putbit: put a bit on stdout. X*/ Xvoid putbit (bit) Xint bit; X{ X assert (bit == 1 || bit == 0); X X put_bits = (put_bits << 1) | bit; X X if (put_bits > 0xFF) { X *next() = put_bits; X if (io_buff_full) X write_io_buff (); X put_bits = 1; /* Flag. */ X } X} X X X/* X** Getbit: get a bit from stdin. X*/ Xint getbit () X{ X if ((get_bits & 0x7F) == 0) { X if (get_bits == 0) { /* First time only. */ X read_io_buff (); X if (nonext ()) { X fprintf (stderr, "\r%s: Warning empty file.\n", pname); X fflush (stderr); X return EOF; X } X } X X if (nonext ()) return EOF; X get_bits = (0xFF & (int)*next ()) << 1; X if (nonext ()) read_io_buff (); X if (nonext ()) { X if (get_bits == 0x100) return EOF;/* Bad luck, think ;-) */ X } X else X get_bits |= 1; /* Last byte has own EOF marker. */ X } X else X get_bits <<= 1; X X return (get_bits >> 8) & 1; X} X X/* X** Init_bits: Init the bits package. X*/ Xvoid init_bits () X{ X io_index = io_buff; /* Not ness, but nice. */ X eof_index = io_buff; X put_bits = 1; /* Very ness. */ X get_bits = 0; X} X X X/* X** Flush_bits: Flush the buffered bits to stdout. X*/ Xvoid flush_bits () X{ X int i; X putbit (1); /* Eof marker. */ X for (i = 0; i < 7; i++) putbit (0); /* Fillup byte. */ X write_io_buff (); X} X X#endif /* DEBUG */ /* Next routines just call get/putbit(). */ X X/* X** Putnbit: put low `n' bits from code on stream. X*/ Xvoid putnbit (code, n) Xlong code; Xint n; X{ X int uggy_buggy; /* The C compiler doesn't handle longs properly */ X X assert (n >= 0 && n < sizeof (long) * 8); X X while (n -- > 0) { X uggy_buggy = (int)(code >> n) & 1; X putbit (uggy_buggy); X } X} X X/* X** Getnbit: Get `n' bits form stdin. X*/ Xint getnbit (n) Xint n; X{ X int ret = 0; /* Return value. */ X X assert (n > 0 && n < sizeof (int) * 8); X X while (n -- > 0) { X ret <<= 1; X switch (getbit ()) { X case 1: X ret |= 1; X break; X case 0: X break; X case EOF: X fprintf (stderr, "\r%s: Unexpected EOF\n", pname); X exit (-1); X default: X fprintf (stderr, "\r%s: funny bit\n", pname); X exit (-1); X } X } X return ret; X} X X/* That's all folks. */ + END-OF-FILE bits.c chmod 'u=rw,g=r,o=r' 'bits.c' set `wc -c 'bits.c'` count=$1 case $count in 4233) :;; *) echo 'Bad character count in ''bits.c' >&2 echo 'Count should be 4233' >&2 esac echo Extracting 'comic.c' sed 's/^X//' > 'comic.c' << '+ END-OF-FILE ''comic.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Comic.c: COmpress MInix C (main routine) X** X** `Comic' is tuned to compress the minix source (kernel, fs, mm, commands) X** it might be usable for other minix c programs, it might even be usable X** for c programs or plain text, but it will not be optimal for other data. X*/ X X#define VERSION "1.0" X X#include <string.h> /* Included for strxxx (). */ X#include <ctype.h> /* For isupper() and tolower (). */ X#include "comic.h" X#include "buffer.h" X#include "hash.h" /* So we can print the hash sizes. */ X X#ifdef DOS X# define TTY "CON" /* The console device under SM-DOS. */ X# include <dir.h> /* For find first/next. *// X static int index = 0; X static struct ffblk ffblk; X X /* X ** Bug: findnext() returns the basename of the filename ;-( X */ X# define nextarg() \ X ( \ X argc >= 0 \ X ? (index == 0 || findnext (&ffblk) != 0) \ X && findfirst (argv [index ++], &ffblk, 0) != 0 \ X ? argv [index - 1] \ X : ffblk.ff_name \ X : (char *) NULL \ X ) X#else /* DOS */ X# define TTY "/dev/tty" X# define nextarg()\ X (argc-- <= 0 ? (char *) NULL : *(argv++)) X#endif /* DOS */ X X#define streq(s1,s2) (strcmp (s1, s2) == 0) X/* X** Max length for file names. X*/ X#define NAMELEN_MAX 30 /* 30 Sould be einnough. */ X#define FILE_SUFFIX "-X" /* Suffix for comiced files. */ X Xchar *COMIC = "comic"; Xchar *XCAT = "xcat"; /* Names for the executable. */ Xchar *DECOMIC = "decomic"; X Xchar *STDIN = "stdin"; /* Names for in en output files. */ Xchar *STDOUT = "stdout"; X X/* X** Global variables. X*/ Xchar *pname; /* Name of program. */ Xstatic pair_t pairs [2]; /* Buffer for pair descriptors. */ Xpair_p p0 = &(pairs [0]); /* Short hands. */ Xpair_p p1 = &(pairs [1]); Xchar Buff [BUFF_SIZE]; /* The Buffer. */ Xchar *Bend; /* Pointer to the last char in Buff. */ Xchar *Bp = Buff; /* Pointer to unproccessed char. */ Xchar *Binputend = Buff; /* End of read ahead input. */ Xint Bsize; Xlong Nin, Nout; /* Total # of bytes read/written. */ Xint v_flag = 0; /* Verbose flag given. */ X#ifdef DOS Xint a_flag = 0; /* Ascii option, cast \r\n to \n. */ X#endif X Xstatic int c_flag = 0; /* Cat (output to stdout) flag. */ Xstatic int f_flag = 0; /* Force flag. */ Xstatic int d_flag = 0; /* Decomic flag. */ X X#ifdef DOS X X/* X** Stoupper: Convert the string to upper case. X*/ Xvoid stoupper (s) Xchar *s; X{ X while (*s != '\0') { X if (isalpha (*s)) X *s = toupper (*s); X s++; X } X} X X/* X** Stolower: Convert the string to lower case. X*/ Xvoid stolower (s) Xchar *s; X{ X while (*s != '\0') { X if (isalpha (*s)) X *s = tolower (*s); X s++; X } X} X X#endif /* DOS */ X X/* X** Basename: Do a check on name, only comic and decomic are allowed. X*/ Xstatic char *basename (name) Xchar *name; X{ X char *p; X#ifdef DOS X /* X ** DOS needs special atention. Upercase letters and leading path X ** must be removed. Also .com or .exe suffixes have to be removed. X */ X p = strrchr (name, '\\'); X if (p != (char *) NULL) X name = p + 1; /* Kill path prefix. */ X X stolower (p); /* Make name lower case. */ X X p = strrchr (name, '.'); X if (p != (char *) NULL) { X if (! streq (p, ".exe") && ! streq (p, ".com")) { X fprintf (stderr, "\r%s: Warning funny suffix %s\n", pname, p); X } X *p = '\0'; /* Kill the .exe or .com suffix. */ X } X else X fprintf (stderr, "\r%s: Warning no DOS suffix\n", pname); X X#else /* Non DOS. */ X p = strrchr (name, '/'); X if (p != (char *) NULL) X name = p + 1; /* Kill path prefix. */ X#endif X if (strncmp (name, "[de]comic", 9) == 0) { X printf ("\rWHOEHAHAHAHAHAHAHAHAHAHAHAHA.\n"); X exit (-99); X } X if (! streq (name, COMIC) X && ! streq (name, DECOMIC) X && ! streq (name, XCAT)) { X fprintf (stderr, "\rThis program must be called [de]comic "); X fprintf (stderr, "or xcat, not %s.\n", name); X#ifndef DEBUG X exit (1); /* In debug mode, allow other names. */ X#endif X } X return name; X} X X X/* X** Newname: generate new output name according to the given name. X*/ Xstatic char *newname (fname) Xchar *fname; X{ X static char ret_name [NAMELEN_MAX]; /* Buffer for return value. */ X char *p; X X /* X ** Check the tail. If the suffix is presend, just return it. X */ X if ((p = strrchr (fname, FILE_SUFFIX [0])) != (char *)NULL X && streq (p, FILE_SUFFIX)) X return fname; X X strncpy (ret_name, fname, NAMELEN_MAX); X ret_name [(NAMELEN_MAX - 1) - strlen (FILE_SUFFIX)] = '\0'; /* Truckate. */ X#ifdef DOS X /* X ** Truncate suffix to be able to hold the FILE_SUFFIX. X ** If there is no suffix, add a "." string. X */ X if ((p = strrchr (ret_name, '.')) != (char *)NULL) X p [4 - strlen (FILE_SUFFIX)] = '\0'; /* truncate. */ X else X strcat (ret_name, "."); X#endif /* DOS */ X strcat (ret_name, FILE_SUFFIX); X X return ret_name; X} X X/* X** Orgname: generate original name according to the given name. X*/ Xstatic char *orgname (fname) Xchar *fname; X{ X static char ret_name [NAMELEN_MAX]; /* Buffer for return value. */ X char *p; X X strncpy (ret_name, fname, NAMELEN_MAX); /* Make private copy. */ X ret_name [NAMELEN_MAX - 1] = '\0'; /* Terminate. */ X X /* X ** If the suffix is there delete it. X ** If this is a DOS machine, and the file name has no suffix, kill the dot. X */ X if ((p = strrchr (ret_name, FILE_SUFFIX [0])) != (char *)NULL X && streq (p, FILE_SUFFIX)) { X *p = '\0'; X#ifdef DOS X if (*--p == '.') X *p = '\0'; X#endif /* DOS */ X } X return ret_name; X} X X/* X** Stdin_out: Set stdin and stdout to newin and newout. X** Return succes or fail. X*/ Xstatic int stdin_out (newin, newout) Xchar *newin, *newout; X{ X FILE *tty; /* File pointer for "/dev/tty" */ X static char buf [2]; X char *ans = buf; /* To contain the answer, "y" or "n" */ X X /* X ** Reopen stdin. X */ X if (freopen (newin, "r", stdin) == (FILE *)NULL) { X fprintf (stderr, "\r%s: Can't open \"%s\" for reading", pname, newin); X perror (""); X fflush (stderr); X return 0; /* Report error. */ X } X STDIN = newin; X X /* X ** If the cat flag is set, don't reopen stdout. X */ X if (c_flag) X return 1; /* Return success. */ X X /* X ** Check if we will overwrite a file. (Unless the -f flag was given.) X */ X if (! f_flag && access (newout, 0) == 0) { X if (! isatty (2) || (tty = fopen (TTY, "r")) == (FILE *)NULL) { X fprintf (stderr, "\r%s: Won't overwrite %s\n", pname, newout); X fflush (stderr); X return 0; X } X fprintf (stderr, "\r%s: Overwrite %s (y/n)? ", pname, newout); X fflush (stderr); X ans = fgets (ans, 2, tty); X fclose (tty); X if (ans == (char *)NULL || *ans != 'y') X return 0; X } X X /* X ** Reopen stdout. X */ X if (freopen (newout, "w", stdout) == (FILE *)NULL) { X fprintf (stderr, "\r%s: Can't open \"%s\" for writing", pname, newout); X perror (""); X fflush (stderr); X return 0; /* Report fail. */ X } X STDOUT = newout; X return 1; /* Return success. */ X} X X/* X** Pr_ratio: print the compression ratio if its negative, or the X** verbose flag (v_flag) is TRUE. X** Divide Nin and Nout by 2 as long as they are to big, to X** prevent overflowing the rat variable. X*/ Xstatic void pr_ratio () X{ X long rat; X X if (Nin == 0) { X if (! v_flag) X fprintf (stderr, "\r%s: Warning %s ", pname, STDIN); X fprintf (stderr, "is empty\n"); X return; X } X X while (Nin > 10000 || Nout > 10000) { /* Get smaller value. */ X Nin >>= 1; X Nout >>= 1; X } X rat = ((Nin - Nout) * 10000) / Nin; X X if (rat < 0L) { X if (! v_flag) X fprintf (stderr, "\r%s: ", pname); X fprintf (stderr, "Warning "); X if (! v_flag) X fprintf (stderr, "%s ", STDIN); X } X X if (rat < 0L || v_flag) { X fprintf (stderr, "compression: %d", (int)(rat / 100)); X fprintf (stderr, ".%02d%%\n", abs ((int)(rat % 100))); X } X} X X X/* X** Vinfo: Give verbose information about this program. X*/ Xstatic void vinfo () X{ X fprintf (stderr, "\rThis is comic Version %s\t ", VERSION); X fprintf (stderr, "(p) Jan-Mark Wams (email: jms@cs.vu.nl)\n"); X#ifdef __DATE__ X fprintf (stderr, "Compiled on: %s\t ", __DATE__); X#endif X fprintf (stderr, "Flags: "); X#ifdef DEBUG X fprintf (stderr, "DEBUG "); X#endif X#ifdef NDEBUG X fprintf (stderr, "NDEBUG "); X#endif X#ifdef C89 X fprintf (stderr, "C89 "); X#endif X#ifdef MINIX X fprintf (stderr, "MINIX "); X#endif X#ifdef UNIX X fprintf (stderr, "UNIX "); X#endif X#ifdef AMOEBA X fprintf (stderr, "AMOEBA "); X#endif X#ifdef M68 X fprintf (stderr, "M68 "); X#endif X#ifdef GCC X fprintf (stderr, "GCC "); X#endif X#ifdef DOS X fprintf (stderr, "DOS "); X#endif X#ifdef __TURBOC__ X fprintf (stderr, "__TURBOC__ "); X#else X# ifdef __STDC__ X# if ! __STDC__ X fprintf (stderr, "!"); X# endif X fprintf (stderr, "__STDC__ "); X# endif X#endif X#ifdef _POSIX_SOURCE X fprintf (stderr, "_POSIX_SOURCE "); X#endif X fprintf (stderr, "Hash table: %d.%d\n", H1_SIZE, H2_SIZE); X} X X/* X** Usage: print the usage of comic. X*/ Xstatic void usage () X{ X fprintf (stderr, "Usage: %s [-", pname); X#ifdef DOS X fprintf (stderr, "a"); /* Dos has ascii flag. */ X#endif X if (! streq (pname, XCAT)) X fprintf (stderr, "cf"); X if (streq (pname, COMIC)) /* Comic has an extra flag. */ X fprintf (stderr, "v"); X#ifdef DEBUG X fprintf (stderr, "v"); /* Debug mode has extra v. */ X#endif X fprintf (stderr, "vV?] [<file>[-X]...]\n"); X X#ifdef DOS /* DOS has no manual pages. */ X fprintf (stderr, " -a: Ascii; %ss ascii files only.\n", pname); X if (! streq (pname, XCAT)) { X fprintf (stderr, " -c: Cat; generate ouput on stdout.\n"); X fprintf (stderr, " -f: Force; overwrite output files without asking.\n"); X } X fprintf (stderr, " -v: Verbose; give extra info while %sing.\n", pname); X if (streq (pname, COMIC)) X fprintf (stderr, " -vv: Ver-verbose; extra verbose option.\n"); X# ifdef DEBUG X if (streq (pname, COMIC)) X fprintf (stderr, " -vvv: Ver-v"); X else X fprintf (stderr, " -vv: V"); X fprintf (stderr, "er-verbose; generate debug output.\n"); X# endif X fprintf (stderr, " -V: Version; give %ss version.\n", pname); X fprintf (stderr, " -?: What; give usage of %s.\n", pname); X#endif X} X X X/* X** File_start: Print a message if verbose option. X*/ Xvoid file_start () X{ X if (v_flag) { X fprintf (stderr, "%s: ", STDIN); X if (d_flag) X fprintf (stderr, "decomicing"); X } X fflush (stderr); X} X X/* X** File_done: Print a message if verbose option. X*/ Xvoid file_done () X{ X if (v_flag && d_flag) X fprintf (stderr, "\b\b\bed to %s\n", STDOUT); X if (! d_flag) X pr_ratio (); X fflush (stderr); X} X X X/* X** main: Parce arguments, call propper (en/de) code routine. X*/ Xvoid main (argc, argv) Xint argc; Xchar **argv; X{ X char *p; /* Used for flag processing etc. */ X char *fname; X X pname = basename (*argv); X X argc --; X argv ++; /* Skip pname. */ X X if (streq (pname, DECOMIC)) /* If this program is called */ X d_flag = -1; /* decomic set the decode flag. */ X X if (streq (pname, "xcat")) { /* If this program is called */ X d_flag = -1; /* xcat set the decode */ X c_flag = -1; /* and cat flag. */ X } X X while (argc > 0 && (*argv) [0] == '-' && (*argv) [1] != '\0') { X for (p = *argv + 1; *p != '\0'; p++) { X switch (*p) { X case 'd': d_flag = 1; break; /* decode flag on. */ X case 'v': v_flag ++; break; /* Verbose flag inc. */ X case 'f': f_flag = 1; break; /* Force flag on. */ X#ifdef DOS X case 'a': a_flag = 1; break; /* Ascii mode. */ X#endif X case 'c': c_flag = 1; break; /* Cat flag on. */ X case '?': usage (); exit (0); /* Usage and exit. */ X case 'V': vinfo (); exit (0); /* Give verbose info. */ X default : X fprintf (stderr, "\r%s: -%c ignored\n", pname, *p); X fflush (stderr); X } X } X argc --; argv ++; /* Next please. */ X } X X#ifndef DEBUG X if (v_flag /* Don't allow vv flag if stderr */ X && ! (isatty (2) && isatty (1))) /* and stdin are not the tty. */ X v_flag = 1; X#endif X X if (argc == 0) { /* No args, do stin to stout. */ X if (c_flag == 1 || f_flag) { /* Silly flags. */ X fprintf (stderr, "\r%s: -", pname); X if (c_flag == 1) putc ('c', stderr); X if (f_flag) putc ('f', stderr); X fprintf (stderr, " ignored\n"); X } X c_flag = 1; /* Cat mode. */ X file_start (); X if (d_flag) X decode (); X else X encode (); X file_done (); X } X else { X if (c_flag && f_flag) { /* -c makes -f silly ;-) */ X fprintf (stderr, "\r%s: -f ignored\n", pname); X fflush (stderr); X } X#ifdef DOS /* DOS-file names are in UPPER case. */ X stoupper (FILE_SUFFIX); X#endif /* DOS */ X } X X while ((fname = nextarg ()) != (char *)NULL) { X if (d_flag) { /* Decode. */ X if ( ! stdin_out (newname (fname), orgname (fname))) X continue; /* If not reopened, do next file. */ X file_start (); X decode (); /* Decode stdin. */ X file_done (); X } X else /* No d_flag */ { /* Encode. */ X if (streq (fname, newname (fname))) { X if (v_flag) { X fprintf (stderr, "\r%s: ", pname); X fprintf (stderr, "%s already has ", fname); X fprintf (stderr, "%s suffix\n", FILE_SUFFIX); X fflush (stderr); X } X continue; X } X if ( ! stdin_out (orgname (fname), newname (fname))) X continue; /* If not reopened, do next file. */ X file_start (); X encode (); /* Put data on stdout. */ X file_done (); X } X } X} + END-OF-FILE comic.c chmod 'u=rw,g=r,o=r' 'comic.c' set `wc -c 'comic.c'` count=$1 case $count in 13070) :;; *) echo 'Bad character count in ''comic.c' >&2 echo 'Count should be 13070' >&2 esac echo Extracting 'decode.c' sed 's/^X//' > 'decode.c' << '+ END-OF-FILE ''decode.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Decode.c: decode stdin to stdout. X** Get a bit, if it's a 0, decode a pair, if it's a 1, decode a char. X** If it's no 1 nor a 0, fly the broomstick. *8-) X*/ X X#include "comic.h" X#include "buffer.h" X#include "huffman.h" /* Data structures of huffman trees and codes. */ X#include "bits.h" X#include "header.h" X X/* X** De_pair: Read offset and length, and put substring on stout. X*/ Xstatic void de_pair () X{ X int len, off = Hdecode (Hoff); X char *p; X X off = off << LOW_OFFSET_BITS; X off |= getnbit (LOW_OFFSET_BITS); X off += OFFSET_MIN; X len = Hdecode (Hlen) + LENGTH_MIN; X#ifdef DEBUG X if (v_flag > 1) X printf ("<%d,%d>\"", off, len); X#endif X p = Bsub (Bp, off); X while (len --) { X putchar (*p); X *Bp = *p; X p = Bsucc (p); X Bp = Bsucc (Bp); X } X#ifdef DEBUG X if (v_flag > 1) X# ifdef DOS X printf ("\"\r\n"); X# else X printf ("\"\n"); X# endif X#endif X} X X/* X** De_char: Get a huffman encoded char and put in on stdout. X*/ Xstatic void de_char () X{ X int c = Hdecode (Hchar); X putchar (c); X#ifdef DEBUG X if (v_flag > 1) { X# ifdef DOS X putchar ('\r'); X# endif X putchar ('\n'); X } X#endif X *Bp = c; X Bp = Bsucc (Bp); X} X X X/* X** Decode: decode stdin. Read a bit from stdin, if it's a 0, decode a pair, X** if it's a 1 decode a char, if it's EOF, return. X*/ Xvoid decode () X{ X Bsize = OFFSET_SIZE + OFFSET_MIN; X Bend = &(Buff [OFFSET_MAX]); X Bp = Binputend = Buff; /* Not ness, but.. */ X Nin = 0; Nout = 0; X Binit (); /* Init the buffer. */ X Hinit (); /* Init the huffman tables. */ X init_bits (); /* Init the bit package. */ X X#ifdef DOS X setmode (0, O_BINARY); /* And you wonder why they call it SM_DOS. */ X if (a_flag) X setmode (1, O_TEXT); X else X setmode (1, O_BINARY); X#endif X X if (! magic_ok ()) { X fprintf (stderr, "\r%s: Wrong magic in header\n", pname); X exit (-1); X } X X for (;;) { X switch (getbit ()) { X case 0: X de_pair(); X break; X case 1: X de_char(); X break; X case EOF: X fflush (stdout); X return; /* EOF, were done. */ X default: X fprintf (stderr, "\r%s: Funny bit\n", pname); X exit (-1); X } X } X} + END-OF-FILE decode.c chmod 'u=rw,g=r,o=r' 'decode.c' set `wc -c 'decode.c'` count=$1 case $count in 2119) :;; *) echo 'Bad character count in ''decode.c' >&2 echo 'Count should be 2119' >&2 esac echo Extracting 'encode.c' sed 's/^X//' > 'encode.c' << '+ END-OF-FILE ''encode.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Encode.c: parce stdin, write huffman codes and bits on stdout. X** Get next two longest strings, if the second one is longer, X** or the first one isn't long innough, encode a char, else X** encode a pair, (offset, lenght). X*/ X X#include "comic.h" X#include "buffer.h" X#include "huffman.h" X#include "bits.h" X#include "header.h" X#include "hash.h" X X/* X** Outpair: Output part p0's length and offset. X*/ Xstatic void outpair (done) Xint *done; /* Set to False if pair codes are longer than char codes. */ X{ X int offset = Bdelta (Bp, p0-> start) - OFFSET_MIN; X int length = p0-> length; X X assert (offset >= 0); X assert (offset < OFFSET_SIZE); X assert (length >= LENGTH_MIN); X assert (length - LENGTH_MIN < HUFFMAN_SIZE); X X#if LENGTH_MIN <= 2 X if (length == 2 X && X Hcodelen (Hoff, offset >> LOW_OFFSET_BITS) + LOW_OFFSET_BITS X + Hcodelen (Hlen, 2 - LENGTH_MIN) X > X Hcodelen (Hchar, *Bp) + Hcodelen (Hchar, *Bsucc (Bp))) { X *done = 0; X return; X } X#endif X X putbit (0); /* Put a 0. */ X Hencode (Hoff, offset >> LOW_OFFSET_BITS); /* Put offset high. */ X putnbit ((long)offset, LOW_OFFSET_BITS); /* Put offset low. */ X Hencode (Hlen, length - LENGTH_MIN); /* Put index length. */ X X#ifdef DEBUG X if (v_flag > 2) { X fprintf (stderr, "(%d,%d)", offset + OFFSET_MIN, length); X putc ('"', stderr); X } X#endif X while (length -- > 0) { X#ifdef DEBUG X if (v_flag > 2) putc (*Bp, stderr); X#endif X hash_update (); /* Update hash tables. */ X Bp = Bsucc (Bp); X } X#ifdef DEBUG X if (v_flag > 2) { X fprintf (stderr, "\"\n"); X fflush (stderr); X } X#endif /* DEBUG */ X assert (done); X} X X/* X** Outchar: Output char *Bp. X*/ Xstatic void outchar () X{ X putbit (1); /* Put a 1. */ X Hencode (Hchar, (0xFF & (int)*Bp)); /* Put this char. */ X#ifdef DEBUG X if (v_flag > 2) { X putc ('`', stderr); X putc (*Bp, stderr); X putc ('\'', stderr); X putc ('\n', stderr); X } X#endif /* DEBUG */ X hash_update (); X Bp = Bsucc (Bp); /* Increase Bp. */ X} X X X/* X** Encode: parce stdin, write huffman codes and bits on stdout. X*/ Xvoid encode () X{ X /* X ** Pairout indicates the pair p0 will be outputed, not just char *Bp. X */ X int pairout = 1; X Bsize = BUFF_SIZE; X Bend = &(Buff [BUFF_MAX]); X Bp = Binputend = Buff; /* Not ness, but.. */ X Nin = 0; Nout = 0; X Binit (); /* Init the buffer. */ X Hinit (); /* Init the huffman tables. */ X init_bits (); /* Init the bit package. */ X hash_init (); /* Init the hash tables. */ X X#ifdef DOS X if (a_flag) X setmode (0, O_TEXT); X else X setmode (0, O_BINARY); /* And you wonder why they call it SM_DOS. */ X X setmode (1, O_BINARY); X#endif X X put_magic (); /* Put magic on stdout. */ X X while (getinput () != EOF) { X gettoken (pairout); /* Find matching strings. */ X pairout = p0-> length >= LENGTH_MIN X && p0-> length >= p1-> length; /* See if it's long innough. */ X if (pairout) X outpair (&pairout); /* If so, ouput it's pair. */ X if (! pairout) X outchar (); /* Else do one char. */ X } X flush_bits (); /* Flush buffered bits. */ X} + END-OF-FILE encode.c chmod 'u=rw,g=r,o=r' 'encode.c' set `wc -c 'encode.c'` count=$1 case $count in 3076) :;; *) echo 'Bad character count in ''encode.c' >&2 echo 'Count should be 3076' >&2 esac echo Extracting 'getinput.c' sed 's/^X//' > 'getinput.c' << '+ END-OF-FILE ''getinput.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Getinput.c: Get input into the buffer. X** Read stdin till Blookupend. This code look's complicated, but it X** isn't; Most of it is about printing. X*/ X X#include <sys/types.h> /* Included for stat (). */ X#include <sys/stat.h> /* Idem. */ X X#include "comic.h" X#include "buffer.h" X X/* X** getinput: Get input buffer full, return EOF if end of file, SPC other wise. X*/ Xint getinput () X{ X static unsigned long fsize = 0L; X static struct stat st [1]; X static int printed = -1; /* -1 Means don't print. */ X int percent, c; X char *stop = Blookupstart (), *Oinputend = Binputend; X X if (v_flag > 1 && Nin == 0 && ! isatty (0) && fstat (0, st) == 0) { X fsize = (unsigned long) (st [0].st_size); X fprintf (stderr, " 0%%"); X fflush (stderr); X printed = 0; X } X X while (Binputend != stop && (c = getchar ()) != EOF) { X *Binputend = c; X#ifdef DOS X if (a_flag && c == '\n') /* Size of file is including \r. */ X Nin += 1; /* But we don't read it, so adjust. */ X#endif X Binputend = Bsucc (Binputend); /* Increase the input end marker. */ X } X Nin += Bdelta (Binputend, Oinputend); /* Count the number of char's read. */ X X if (Nin < fsize) { /* Note 0 <= Nin < fsize A thus 0 < fsize */ X percent = 100 - (int)((fsize - Nin) / (fsize / 100)); X if (percent > printed) { X fprintf (stderr, "\b\b\b\b%3d%%", percent); X fflush (stderr); X printed = percent; X } X } X X if (Bp == Binputend) { X assert (Oinputend == Binputend); X#ifdef DOS X /* X ** This assertion will fail if one comics a binary file. X */ X assert (fsize == 0 || Nin == fsize || Nin == fsize - 1); /* ^Z */ X#else X assert (fsize == 0 || Nin == fsize); X#endif /* DOS */ X if (printed != -1) { X fprintf (stderr, "\b\b\b\b"); X fflush (stderr); X } X return EOF; X } X else X return (int) ' '; X} + END-OF-FILE getinput.c chmod 'u=rw,g=r,o=r' 'getinput.c' set `wc -c 'getinput.c'` count=$1 case $count in 1858) :;; *) echo 'Bad character count in ''getinput.c' >&2 echo 'Count should be 1858' >&2 esac echo Extracting 'gettoken.c' sed 's/^X//' > 'gettoken.c' << '+ END-OF-FILE ''gettoken.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Gettoken.c: Find the best (logest) part to output. X** We try to find the longest part in the lookup buffer, matching the X** input. Well actually, we look for two srings, one, matching the X** current input, starting at the current buffer start, and one X** matching the string starting at the next input byte, (asif we X** decoded a char.) This just incase decoding two pairs could have X** been done, using one char and pair. (This will save some %s extra.) X** To show what I mean, consider; X** X** xxxxx.AxAxxxxx X** This would be parced x xxxx . A x Ax xxxx X** but xxxx costs (about) as X** mutch as xxxxx. So x xxxx . A x A xxxxx X** will be better. X** X*/ X X#include "comic.h" X#include "buffer.h" X#include "hash.h" X X/* X** Eqlen: Return the number of bytes, p[i] en q[i] are the same. X*/ Xstatic int eqlen (p, q, count) Xchar *p; Xchar *q; Xint count; X{ X char *r = p; X char *stop = Badd (p, count); X X assert (p != q); X X while (*r == *q && r != stop) { X r = Bsucc (r); X q = Bsucc (q); X } X assert (Bdelta (r, p) <= count); X return Bdelta (r, p); X} X X X/* X** gettoken: Find the best (logest) part to output. X*/ Xvoid gettoken (p0used) Xint p0used; /* Indicate if p0 was used. */ X{ X X index_t i, itail = Bindex (Bsub (Bp, OFFSET_MAX)); X int len; X int maxlen = Bdelta (Binputend, Bp); X char *Bp1 = Bsucc (Bp); /* Succesort of Bp. */ X char *Bp2 = Bsucc (Bp1); /* Gess... */ X char *Bp_1 = Bpred (Bp); X X if (maxlen < LENGTH_MIN) { X p0-> length = 0; X return; X } X X if (maxlen > LENGTH_MAX) { X assert (maxlen <= LENGTH_MAX + PAIR_MAX + 1); X maxlen = LENGTH_MAX; X } X X if (! p0used) { /* If p0 wasn't used, p1 */ X p0-> start = p1-> start; /* will be the new p0. */ X p0-> length = p1-> length; X if (p0-> length > maxlen) { /* Check p0's length. */ X assert (p0-> length - 1 == maxlen); X p0-> length = maxlen; X } X } X else { X if (*Bp_1 == *Bp && *Bp == *Bp1) { /* Bp - 1 isn't in the hash */ X p0-> start = Bp_1; /* So try it athoc. */ X p0-> length = eqlen (Bp_1, Bp, maxlen); X } X else X p0-> length = 0; X X i = hash_entry (*Bp, *Bp1); X X while (i != INDEX_END && p0-> length != maxlen) { X if ((len = eqlen (Buff + i, Bp, maxlen)) > p0-> length) { X p0-> start = Buff + i; X p0-> length = len; X } X i = next_list [i]; X } X } X X /* X ** We should adjust maxlen here, but we get faster code if we X ** just check if p1-> length is (one) to long whilst copying X ** p1 to p0 if ! p0used. X */ X X if (*Bp == *Bp1 && *Bp1 == *Bp2) { /* Bp1 - 1 isn't in the hash. */ X p1-> start = Bp; X p1-> length = eqlen (Bp, Bp1, maxlen); X } X else if (*Bp_1 == *Bp1) { /* Bp1 - 2 neighter. */ X p1-> start = Bp_1; X p1-> length = eqlen (Bp_1, Bp1, maxlen); X } X else X p1-> length = 0; X X i = hash_entry (*Bp1, *Bp2); /* Do p1. */ X while (i != INDEX_END && p1-> length != maxlen && i != itail) { X if (*Bp != Buff [Ipred (i)] X && (len = eqlen (Buff + i, Bp1, maxlen)) > p1-> length) { X p1-> start = Buff + i; X p1-> length = len; X } X i = next_list [i]; X } X assert (p0-> length <= maxlen); X assert (p1-> length <= maxlen); X} X + END-OF-FILE gettoken.c chmod 'u=rw,g=r,o=r' 'gettoken.c' set `wc -c 'gettoken.c'` count=$1 case $count in 3126) :;; *) echo 'Bad character count in ''gettoken.c' >&2 echo 'Count should be 3126' >&2 esac echo Extracting 'hash.c' sed 's/^X//' > 'hash.c' << '+ END-OF-FILE ''hash.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Hash.c: For speed sake, a (two dimensional) hash table is implemented X** on top of the existing structure. Ugly, bad, but faster. ;-( X*/ X X#include "comic.h" /* For hash.h etc. */ X#include "buffer.h" /* For Bp etc. */ X#include "hash.h" X X/* index_t hash_tbl [H1_SIZE] [H2_SIZE]; /* The hash table. */ Xindex_t *hash_tbl = (index_t *) NULL; Xindex_t next_list [BUFF_SIZE]; /* The index list. */ Xindex_t back_list [BUFF_SIZE]; /* The back list. */ X X/* X** Hash_init: Initialise the hash table. X** Pre filling the buffer might give better compression, but X** would enlarge the compress program. '-) Perhaps a pseudo X** random generator, filling the buffer with the most likely X** (lowest number of bits in their huffman code) characters. X** Note: the buffer (Buff) must be filled. X*/ Xvoid hash_init () X{ X int i; X X if (hash_tbl == (index_t *) NULL) { /* Malloc the hast table. */ X hash_tbl = (index_t *) malloc (H1_SIZE * H2_SIZE * sizeof (index_t)); X if (hash_tbl == (index_t *) NULL) { X fprintf (stderr, "\r%s: Out of memory\n", pname); X exit (-1); X } X } X X i = 0; X do /* Init the hash table. */ X hash_tbl [i++] = INDEX_END; X while (i != H1_SIZE * H2_SIZE); X X next_list [0] = BUFF_SIZE - 1; X for (i = 1; i < BUFF_SIZE; i++) /* Fill next_list. */ X next_list [i] = i - 1; X X back_list [BUFF_SIZE - 1] = 0; X for (i = 0; i < BUFF_SIZE; i++) /* Fill back_list. */ X back_list [i] = i + 1; X X hash_entry ('\0', '\0') = i = Bindex (Bsub (Bp, 2)); X X back_list [i] = INDEX_END; X next_list [Bindex (Bsub (Bp, OFFSET_MAX))] = INDEX_END; X} X X X/* X** Hash_update: Update the hash table. (Using the char at Bp) X*/ Xvoid hash_update () X{ X char p = *Bpred (Bp); /* Previous char. */ X char c = *Bp; /* Current char. */ X index_t icur = Bindex (Bp); /* Current index. */ X index_t ipre = Ipred (icur); /* Previouse index. */ X char * tail = Bsub (Bp, OFFSET_MAX); /* Tail of offset buff. */ X index_t new_tail = back_list [Bindex (tail)]; /* New tail of next list. */ X index_t ipc = hash_entry (p, c); /* Index of hash (p,c). */ X X if (next_list [Bindex (tail)] != INDEX_END) X *Bp = *Bp; X/* X** This assertion fails sometimes, but it should never fail, so X** this is a potentially dangerous sitiation. X** X** assert (next_list [Bindex (tail)] == INDEX_END); X*/ X X if ((next_list [ipre] = ipc) != INDEX_END) X back_list [ipc] = ipre; X hash_entry (p, c) = ipre; /* Update list at head of buffer. */ X back_list [ipre] = INDEX_END; X X if (new_tail == INDEX_END) { /* Idem tail. */ X hash_entry (*tail, *Bsucc (tail)) = INDEX_END; X } X else { X next_list [new_tail] = INDEX_END; X } X} X + END-OF-FILE hash.c chmod 'u=rw,g=r,o=r' 'hash.c' set `wc -c 'hash.c'` count=$1 case $count in 2708) :;; *) echo 'Bad character count in ''hash.c' >&2 echo 'Count should be 2708' >&2 esac echo Extracting 'header.c' sed 's/^X//' > 'header.c' << '+ END-OF-FILE ''header.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Header.c: header handeling routines. X** Magic routines only, but for 2.0 the header will become X** more inportante. X*/ X X#include "comic.h" X#include "header.h" X X/* X** Magic_ok: Check the first bytes on stdin. They should be ok. X** Return True if magic is ok, else False. X*/ Xint magic_ok () X{ X char c; X X if (read (0, &c, 1) != 1) { X fprintf (stderr, "\r%s: Can't read header\n", pname); X exit (-1); X } X if (c != MAGIC1) return 0; /* First byte has to be ok. */ X X if (read (0, &c, 1) != 1) { X fprintf (stderr, "\r%s: Can't read headers 2nd byte\n", pname); X exit (-1); X } X X if ((c & SUFFIX_BIT) != 0) { X fprintf (stderr, "\r%s: Version 1.0 can't handle dos suffix\n", pname); X exit (-1); X } X if ((c & DYNAMIC_BIT) != 0) { X fprintf (stderr, "\r%s: Version 1.0 can't handle dynamic bit\n", pname); X exit (-1); X } X if ((c & EXTEND_BIT) != 0) { X fprintf (stderr, "\r%s: Version 1.0 can't handle extend bit\n", pname); X exit (-1); X } X X if (c != (MAGIC2 | STATIC_BIT)) return 0; /* 1.0 static only ;-) */ X X return 1; X} X X/* X** Put_magic: Write magic header on stdout. X*/ Xvoid put_magic () X{ X char c1 = MAGIC1, c2 = (MAGIC2 | STATIC_BIT); X if (write (1, &c1, 1) != 1 || write (1, &c2, 1) != 1) { X fprintf (stderr, "\r%s: Can't write header\n", pname); X exit (-1); X } X Nout += 2; X} + END-OF-FILE header.c chmod 'u=rw,g=r,o=r' 'header.c' set `wc -c 'header.c'` count=$1 case $count in 1368) :;; *) echo 'Bad character count in ''header.c' >&2 echo 'Count should be 1368' >&2 esac echo Extracting 'huffman.c' sed 's/^X//' > 'huffman.c' << '+ END-OF-FILE ''huffman.c' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Huffman.c: huffman routines to get and put huffman codes. X** Note: If the Hencode is called for SWITCH codes with a codelength > X** HUFFMAN_BITS, the actual code is used. This is mainly an optimalisation X** for binary chunck's in the text. This could be replaced by dynamic X** huffman code. (See "Data Compression" AMC computing Surveys, X** Vol.19 No. 3 September 1987). I tryed modified BSTW, but that wasn't X** to good. X*/ X X#include "comic.h" X#include "huffman.h" X X#define SWITCH 8 /* 4 Might do very well to. */ X X/* X** Include the auto generated tables. X** There is a big redundency in tables.h, Both encode and decode X** tables are included. (But the bit length per code would be innough X** but this would mean initializing a lot.) X** Ctab tables, have code, length pairs. The low length bits of code X** are the huffman code. Tree tables, have 0, 1 pairs. They point X** to the next pair or the code. X*/ X#if OFFSET_BITS == 13 X# include "tables.h" X#else X error No tables.h for other than 13 bits. X#endif X Xstatic struct ctab_s * ctab_tab [] = { ctab_char, ctab_off, ctab_len }; Xstatic struct tree_s * tree_tab [] = { tree_char, tree_off, tree_len }; Xstatic int Ntolong [3]; /* Ntolong for each table. */ X X/* X** Decend: decend down he tree. X*/ Xstatic int decend (tree) Xstruct tree_s *tree; X{ X int i = (HUFFMAN_SIZE * 2) - 2; X X while (i >= HUFFMAN_SIZE) { X switch (getbit ()) { X case EOF: X fprintf (stderr, "\r%s: Unexpected EOF\n", pname); X exit (-1); X case 0: X i = tree[i - HUFFMAN_SIZE]._0; X break; X case 1: X i = tree[i - HUFFMAN_SIZE]._1; X break; X default: X fprintf (stderr, "\r%s: Funny bit\n", pname); X exit (-1); X } X } X return i; X} X X X/* X** Hinit: Get the propper huffman code tables. X*/ Xvoid Hinit () X{ X Ntolong [0] = 0; X Ntolong [1] = 0; X Ntolong [2] = 0; X X /* X ** Read in tables if ness. (Version to come.) X */ X} X X X/* X** Hdecode: Get a int using a huffman tree. X*/ Xint Hdecode (index) Xint index; X{ X struct tree_s *tree = tree_tab [index]; X struct ctab_s *ctab = ctab_tab [index]; X int i; X X if (Ntolong [index] > SWITCH) { X i = (int) getnbit (HUFFMAN_BITS); X if (ctab [i].length > HUFFMAN_BITS) X Ntolong [index] = SWITCH << 1; X else X Ntolong [index] -= 1; X } X else { X i = decend (tree); X if (ctab [i].length > HUFFMAN_BITS) X Ntolong [index] += 1; X else X Ntolong [index] = 0; X } X return i; X} X X X/* X** Hcodelen: Return the length of the encoded word in bits. X*/ Xint Hcodelen (index, c) Xint index; Xint c; X{ X return Ntolong [index] > SWITCH ? HUFFMAN_BITS : ctab_tab [index] [c].length; X} X X/* X** Hencode: ouput code i from code table ctab X*/ Xvoid Hencode (index, i) Xint index, i; X{ X struct ctab_s *ctab = ctab_tab [index]; X int len = ctab [i].length; X X if (Ntolong [index] > SWITCH) { X putnbit ((long)i, HUFFMAN_BITS); X if (len > HUFFMAN_BITS) X Ntolong [index] = SWITCH << 1; X else X Ntolong [index] -= 1; X } X else { X putnbit ((long)(ctab [i].code), len); X if (len > HUFFMAN_BITS) X Ntolong [index] += 1; X else X Ntolong [index] = 0; X } X} + END-OF-FILE huffman.c chmod 'u=rw,g=r,o=r' 'huffman.c' set `wc -c 'huffman.c'` count=$1 case $count in 3076) :;; *) echo 'Bad character count in ''huffman.c' >&2 echo 'Count should be 3076' >&2 esac echo Extracting 'bits.h' sed 's/^X//' > 'bits.h' << '+ END-OF-FILE ''bits.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Bits.h: Bit operations header file. X*/ X X/* Needs "comic.h" for _PROTOTYPE() */ X Xvoid _PROTOTYPE( putnbit, (long __code, int __n) ); Xint _PROTOTYPE( getnbit, (int __n) ); Xvoid _PROTOTYPE( putbit, (int __bit) ); Xint _PROTOTYPE( getbit, () ); Xvoid _PROTOTYPE( flush_bits, () ); Xvoid _PROTOTYPE( init_bits, () ); + END-OF-FILE bits.h chmod 'u=rw,g=r,o=r' 'bits.h' set `wc -c 'bits.h'` count=$1 case $count in 404) :;; *) echo 'Bad character count in ''bits.h' >&2 echo 'Count should be 404' >&2 esac echo Extracting 'buffer.h' sed 's/^X//' > 'buffer.h' << '+ END-OF-FILE ''buffer.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Buffer.h: functions for circular buffer menagement. X*/ X X/* X** Global variables. Declared in `comic.c' X*/ Xextern char Buff [BUFF_SIZE]; /* The circular Buffer. */ Xextern char *Bend; /* Pointer to the last char in Buff. */ Xextern char *Blow_sent; /* Pointer to the char befor Buff. */ Xextern char *Bp; /* Pointer to unproccessed char. */ Xextern char *Binputend; /* End of read ahead input. */ Xextern int Bsize; /* Size of the used part of the buffer. */ X#ifdef LINT Xextern char *memset(); /* To shut up lint, a bit ;-( */ X#endif X X#define Bsucc(p) /* pointer after p */\ X ((p) == Bend ? Buff : (p) + 1) X X#define Bpred(p) /* pointer before p */\ X ((p) == Buff ? Bend : (p) - 1) X X#define Badd(p, n) /* Add n to p, circular. */\ X ((p) + (n) - ((p) + (n) > Bend ? Bsize : 0)) X X#define Bsub(p, n) /* Substract n from p, circular. */\ X ((p) - (n) + ((p) < Buff + (n) ? Bsize : 0)) X X#define Bdelta(p, q) /* Return p - q circular. */\ X (int)((p) - (q) + ((p) < (q) ? Bsize : 0)) X X#define Blookupstart() /* End of the lookup pair. */\ X Bsub (Bp, NON_INPUT_SIZE) X X#define Bindex(p) /* Index of pointer. */\ X (index_t)((p) - Buff) X X#define Binit() /* Clear the buffer. */\ X (void)memset (Buff, '\0', Bsize) + END-OF-FILE buffer.h chmod 'u=rw,g=r,o=r' 'buffer.h' set `wc -c 'buffer.h'` count=$1 case $count in 1339) :;; *) echo 'Bad character count in ''buffer.h' >&2 echo 'Count should be 1339' >&2 esac echo Extracting 'comic.h' sed 's/^X//' > 'comic.h' << '+ END-OF-FILE ''comic.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Comic.h: General include file for comic source files. X*/ X X#ifndef COMIC_H X#define COMIC_H X X#ifdef DOS X# include <fcntl.h> /* Use O_BINARY by `setmode ()' in SM-DOS. */ X# include <io.h> /* For `setmode()' to. */ X#endif X#if __STDC__ && ! GCC X# include <stdlib.h> X#endif X#include <assert.h> X#include <stdio.h> X X/* X** Compress constands. X*/ X#define HUFFMAN_BITS 8 /* Huffman codes are 8 bits. */ X#define LENGTH_BITS 8 /* # of bits in length info. */ X#define OFFSET_BITS 13 /* # of bits in offset info. */ X#define PAIR_MAX 1 /* There are two pairs. */ X X/* X** If above are chainged, chainge these to! X*/ X#define HUFFMAN_SIZE 256 /* Max for 8 bits. */ X#define LENGTH_SIZE 256 /* Max for 8 bits. */ X#define OFFSET_SIZE 8192 /* Max for 13 bits. */ X#define OFFSET_MIN 1 /* Minimum offset. */ X#define LENGTH_MIN 2 /* Minimum length. */ X#define OFFSET_MAX (OFFSET_SIZE + OFFSET_MIN - 1) X#define LENGTH_MAX (LENGTH_SIZE + LENGTH_MIN - 1) X#define INPUT_SIZE (LENGTH_SIZE + PAIR_MAX + LENGTH_MIN) X#define BUFF_SIZE (INPUT_SIZE + OFFSET_SIZE + OFFSET_MIN) X#define BUFF_MAX (BUFF_SIZE - 1) X#define NON_INPUT_SIZE (BUFF_SIZE - INPUT_SIZE) X#define LOW_OFFSET_BITS (OFFSET_BITS - HUFFMAN_BITS) X X/* X** Index type is used for indexing the buffer and the hash tables. X** X** This type is added laters, so some int declarations should be index_t. X*/ Xtypedef unsigned short index_t; X#define INDEX_END ((index_t) BUFF_SIZE + 1) X X X/* X** Pairs are build of a start pointer and a length pointer. X*/ Xtypedef struct pair { /* Part descriptor type. */ X char * start; /* Pointer in the circular Buffer. */ X int length; /* Length of part. */ X} pair_t, *pair_p; X X/* X** Global variables. Declared in `comic.c' X*/ Xextern char *pname; /* Name of the program. */ Xextern pair_p p0, p1; /* Short hands. */ Xextern long Nin; /* Total # of bytes read. */ Xextern long Nout; Xextern int v_flag; /* Verbose flag == 1 if -v was given. */ X#ifdef DOS Xextern int a_flag; /* Ascii flag == 1 if -a was given. */ X#endif X X/* X** All global function prototypes. X*/ X#ifndef _PROTOTYPE X# define _PROTOTYPE(func, args) func () X#endif /* _PROTOTYPE */ X Xvoid _PROTOTYPE( putnbit, (long __code, int __n) ); Xint _PROTOTYPE( getinput, () ); Xvoid _PROTOTYPE( gettoken, (int __p0used) ); Xvoid _PROTOTYPE( encode, () ); Xvoid _PROTOTYPE( decode, () ); X X#endif /* COMIC_H */ + END-OF-FILE comic.h chmod 'u=rw,g=r,o=r' 'comic.h' set `wc -c 'comic.h'` count=$1 case $count in 2418) :;; *) echo 'Bad character count in ''comic.h' >&2 echo 'Count should be 2418' >&2 esac echo Extracting 'hash.h' sed 's/^X//' > 'hash.h' << '+ END-OF-FILE ''hash.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Hash.h: For speed sake, a (two dimensional) hash table is implemented X** on top of the existing structure. X** The hashing goes as follows. For each character pair {c1, c2} X** there exists an index (at hash_tbl [H1 (c1), H2 (c2)]) containing X** the index of the first pair {d1, d2} in the buffer so that X** H1 (c1) == H1 (d1) and H2 (c2) == H2 (d2). Both Hs are functions X** ie. if H (c) != H (d) than c != d. The same index is used as an X** index to the index list, to find the next index. Again this index X** is used in both the buffer and the index list (next_list) etc. etc. X** The final index is INDEX_END. Defined in comic.h. There is alsow a X** index list pointing back, so the index list can be quickly updated. X** This leaves us with a double linked list like construction. X*/ X X/* X** Hash.h needs comic.h for the index type (index_t) and some constands. X*/ X X#ifdef MINIX X# define H1_SIZE 64 /* Hash table size first char. */ X# define H2_SIZE 32 /* They have to be powers of 2! */ X#else X# ifdef C89 X# define H1_SIZE 64 X# define H2_SIZE 32 X# else X# ifdef DOS X# define H1_SIZE 64 X# define H2_SIZE 64 X# else X# define H1_SIZE 256 X# define H2_SIZE 256 X# endif X# endif X#endif X X#define H1(i) ((index_t)(i) & (H1_SIZE -1)) /* Hash functions. */ X#define H2(i) ((index_t)(i) & (H2_SIZE -1)) X X/* X** The buffer index macros. (Look like the buffer pointer macros. ;-) X*/ X X#define Ipred(i) /* Dec i circular. */\ X (((i) == 0 ? BUFF_SIZE : (i)) - 1) X X#define Isucc(i) /* Inc i circular. */\ X ((i) == BUFF_SIZE - 1 ? 0 : (i) + 1) X Xextern index_t *hash_tbl; /* See hash.c. */ Xextern index_t next_list [BUFF_SIZE]; Xextern index_t back_list [BUFF_SIZE]; X X#define hash_entry(i,j) hash_tbl [H1 (i) + H1_SIZE * H2 (j)] X Xvoid _PROTOTYPE( hash_init, (void) ); Xvoid _PROTOTYPE( hash_update, (void) ); + END-OF-FILE hash.h chmod 'u=rw,g=r,o=r' 'hash.h' set `wc -c 'hash.h'` count=$1 case $count in 1894) :;; *) echo 'Bad character count in ''hash.h' >&2 echo 'Count should be 1894' >&2 esac echo Extracting 'header.h' sed 's/^X//' > 'header.h' << '+ END-OF-FILE ''header.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Header.h: Defines for the comic header bytes and file suffix. X** The first byte is a normal magic byte. X** The second byte is eighter 0xAX X** The X nibble (1/2byte) contains extra info. X*/ X X/* X** First byte is plane magic. X*/ X#define MAGIC1 (char)0x69 /* Magic number. */ X X/* X** Second bytes is half magic half flag. X*/ X#define MAGIC2 (char)0x60 /* High part of 2d byte. */ X X#define STATIC_BIT (char)0x8 /* Use buildin Huffman tables. */ X#define DYNAMIC_BIT (char)0x4 /* H. tables precead data. */ X#define SUFFIX_BIT (char)0x2 /* Next three bytes are old suffix. */ X#define EXTEND_BIT (char)0x1 /* More header data. */ X X/* X** Third byte indicates extra i/o-processing. EXTEND_BIT has to be set. X*/ X#define EXTRA_EXTEND (char)0x0 /* Extra extension bytes. */ X#define TRANSLATE (char)0x1 /* Input was xlated. */ X X/* X** Note to assist dos, the first three chars after the header can be X** the original suffix. The suffix bit indicates this. X*/ X X X/* X** Prototypes. X*/ Xvoid _PROTOTYPE( put_magic, () ); Xint _PROTOTYPE( magic_ok, () ); + END-OF-FILE header.h chmod 'u=rw,g=r,o=r' 'header.h' set `wc -c 'header.h'` count=$1 case $count in 1117) :;; *) echo 'Bad character count in ''header.h' >&2 echo 'Count should be 1117' >&2 esac echo Extracting 'huffman.h' sed 's/^X//' > 'huffman.h' << '+ END-OF-FILE ''huffman.h' X/* X** Part of the comic package. (p) Jan-Mark Wams (email: jms@cs.vu.nl) X** X** Huffman.h: types and routines for the huffman tables. X*/ X X/* Needs "comic.h" for _PROTOTYPE() */ X X/* X** Tree and code types. X*/ Xtypedef long bitstr_t; X Xtypedef struct tree_s { X int _0, _1; X} tree_t []; X Xtypedef struct ctab_s { X bitstr_t code; X char length; /* Hast to hold upto sizeof (bitstr_t) * 8 bits. */ X} ctab_t []; X X#define Hchar 0 X#define Hoff 1 X#define Hlen 2 X Xint _PROTOTYPE( Hdecode, (int __treei) ); Xvoid _PROTOTYPE( Hencode, (int __ctabi, int __i) ); Xint _PROTOTYPE( Hcodelen, (int __ctabi, int __i) ); Xvoid _PROTOTYPE( Hinit, () ); + END-OF-FILE huffman.h chmod 'u=rw,g=r,o=r' 'huffman.h' set `wc -c 'huffman.h'` count=$1 case $count in 653) :;; *) echo 'Bad character count in ''huffman.h' >&2 echo 'Count should be 653' >&2 esac echo Extracting 'tables.h' sed 's/^X//' > 'tables.h' << '+ END-OF-FILE ''tables.h' X/* X** Part of the comic package. X** X** Tables.h: Auto generated by comicgen. X*/ X Xctab_t ctab_char = { /* {code, length} pairs */ X {0x000054L, 9}, {0x0003B6L, 10}, {0x00067AL, 11}, {0x000242L, 10}, X {0x0033DCL, 14}, {0x000D99L, 13}, {0x000D98L, 13}, {0x00076BL, 11}, X {0x000CF6L, 12}, {0x000017L, 5}, {0x00002CL, 6}, {0x001977L, 14}, X {0x0CF749L, 20}, {0x0001B6L, 10}, {0x0000AAL, 10}, {0x00013BL, 9}, X {0x0006DEL, 12}, {0x0CF748L, 20}, {0x0006CFL, 12}, {0x001976L, 14}, X {0x001975L, 14}, {0x000D97L, 13}, {0x00076AL, 11}, {0x000B4DL, 12}, X {0x000D96L, 13}, {0x000B4CL, 12}, {0x001974L, 14}, {0x001973L, 14}, X {0x000B4BL, 12}, {0x000B4AL, 12}, {0x000B49L, 12}, {0x001972L, 14}, X {0x000008L, 5}, {0x00004FL, 7}, {0x00001CL, 6}, {0x000120L, 9}, X {0x0003B4L, 10}, {0x000031L, 8}, {0x000075L, 7}, {0x000028L, 6}, X {0x00001AL, 5}, {0x000010L, 5}, {0x00001CL, 7}, {0x000030L, 8}, X {0x000003L, 6}, {0x000026L, 6}, {0x000031L, 6}, {0x00003AL, 7}, X {0x000015L, 6}, {0x000002L, 6}, {0x00000BL, 6}, {0x000001L, 7}, X {0x00003EL, 7}, {0x000054L, 7}, {0x000074L, 7}, {0x000061L, 7}, X {0x000055L, 7}, {0x000013L, 8}, {0x00001DL, 7}, {0x00000FL, 6}, X {0x000077L, 7}, {0x000029L, 7}, {0x000056L, 7}, {0x000038L, 9}, X {0x000012L, 8}, {0x000014L, 7}, {0x00002BL, 8}, {0x00002FL, 7}, X {0x00006EL, 7}, {0x000013L, 7}, {0x000066L, 7}, {0x000051L, 8}, X {0x0000B5L, 8}, {0x000045L, 7}, {0x00019FL, 9}, {0x0000A1L, 9}, X {0x000037L, 7}, {0x00006FL, 7}, {0x000057L, 7}, {0x00003DL, 7}, X {0x000060L, 7}, {0x000156L, 11}, {0x000044L, 7}, {0x00000FL, 7}, X {0x00002EL, 7}, {0x00005BL, 7}, {0x0000C9L, 9}, {0x00009CL, 8}, X {0x0000DAL, 9}, {0x0000C8L, 9}, {0x00013AL, 9}, {0x00003CL, 7}, X {0x000039L, 9}, {0x000019L, 7}, {0x00033CL, 10}, {0x000036L, 6}, X {0x000D95L, 13}, {0x00000DL, 6}, {0x000032L, 6}, {0x00001CL, 5}, X {0x000008L, 6}, {0x00001FL, 5}, {0x000016L, 6}, {0x000008L, 7}, X {0x000033L, 7}, {0x000006L, 6}, {0x0000CEL, 8}, {0x00003BL, 7}, X {0x000025L, 6}, {0x000023L, 6}, {0x000005L, 6}, {0x000001L, 6}, X {0x000018L, 6}, {0x000168L, 9}, {0x00001AL, 6}, {0x000009L, 5}, X {0x00001EL, 5}, {0x000029L, 6}, {0x00003FL, 7}, {0x000012L, 7}, X {0x00001DL, 8}, {0x000000L, 7}, {0x0000ECL, 8}, {0x000091L, 8}, X {0x0000A0L, 9}, {0x000049L, 7}, {0x0005A7L, 11}, {0x0CF747L, 20}, X {0x000B48L, 12}, {0x0CF746L, 20}, {0x001971L, 14}, {0x0CF745L, 20}, X {0x001970L, 14}, {0x0CF744L, 20}, {0x00196FL, 14}, {0x0CF743L, 20}, X {0x000D94L, 13}, {0x0CF742L, 20}, {0x0CF741L, 20}, {0x0CF740L, 20}, X {0x067BBFL, 19}, {0x00196EL, 14}, {0x067BBEL, 19}, {0x067BBDL, 19}, X {0x00196DL, 14}, {0x067BBCL, 19}, {0x067BBBL, 19}, {0x067BBAL, 19}, X {0x000D93L, 13}, {0x067BB9L, 19}, {0x00196CL, 14}, {0x067BB8L, 19}, X {0x067BB7L, 19}, {0x00196BL, 14}, {0x000D92L, 13}, {0x00196AL, 14}, X {0x001969L, 14}, {0x001968L, 14}, {0x001967L, 14}, {0x001966L, 14}, X {0x001965L, 14}, {0x000D91L, 13}, {0x000D90L, 13}, {0x000D8FL, 13}, X {0x0003B7L, 10}, {0x000D8EL, 13}, {0x000D8DL, 13}, {0x001964L, 14}, X {0x001963L, 14}, {0x000D8CL, 13}, {0x001962L, 14}, {0x000D8BL, 13}, X {0x001961L, 14}, {0x000D8AL, 13}, {0x001960L, 14}, {0x00195FL, 14}, X {0x00090FL, 12}, {0x000D89L, 13}, {0x00195EL, 14}, {0x000D88L, 13}, X {0x00195DL, 14}, {0x00090EL, 12}, {0x00195CL, 14}, {0x000D87L, 13}, X {0x00195BL, 14}, {0x00195AL, 14}, {0x001959L, 14}, {0x000D86L, 13}, X {0x067BB6L, 19}, {0x000D85L, 13}, {0x067BB5L, 19}, {0x001958L, 14}, X {0x001957L, 14}, {0x00036EL, 11}, {0x000D84L, 13}, {0x001956L, 14}, X {0x001955L, 14}, {0x000D83L, 13}, {0x001954L, 14}, {0x001953L, 14}, X {0x067BB4L, 19}, {0x001952L, 14}, {0x001951L, 14}, {0x001950L, 14}, X {0x00194FL, 14}, {0x00194EL, 14}, {0x067BB3L, 19}, {0x00194DL, 14}, X {0x067BB2L, 19}, {0x00194CL, 14}, {0x067BB1L, 19}, {0x000D82L, 13}, X {0x067BB0L, 19}, {0x00194BL, 14}, {0x067BAFL, 19}, {0x00194AL, 14}, X {0x067BAEL, 19}, {0x001949L, 14}, {0x067BADL, 19}, {0x001948L, 14}, X {0x067BACL, 19}, {0x001947L, 14}, {0x067BABL, 19}, {0x001946L, 14}, X {0x067BAAL, 19}, {0x001945L, 14}, {0x001944L, 14}, {0x001943L, 14}, X {0x001942L, 14}, {0x001941L, 14}, {0x067BA9L, 19}, {0x001940L, 14}, X {0x067BA8L, 19}, {0x000D81L, 13}, {0x067BA7L, 19}, {0x000D80L, 13}, X {0x067BA6L, 19}, {0x0006CEL, 12}, {0x000ABFL, 14}, {0x000ABEL, 14}, X {0x000ABDL, 14}, {0x00090DL, 12}, {0x000ABCL, 14}, {0x0006CDL, 12}, X {0x067BA5L, 19}, {0x000CBFL, 13}, {0x000ABBL, 14}, {0x000CBEL, 13}, X {0x000ABAL, 14}, {0x000CBDL, 13}, {0x000AB9L, 14}, {0x00090CL, 12}, X {0x000AB8L, 14}, {0x000CBCL, 13}, {0x0019EFL, 13}, {0x0006DFL, 12} X}; X Xtree_t tree_char = { /* {link 0, link 1} pairs. */ X {17 , 12}, {129, 127}, {133, 131}, {137, 135}, X {139, 138}, {142, 140}, {145, 143}, {147, 146}, X {151, 149}, {188, 152}, {200, 190}, {208, 206}, X {212, 210}, {216, 214}, {220, 218}, {224, 222}, X {232, 230}, {236, 234}, {256, 244}, {258, 257}, X {260, 259}, {262, 261}, {264, 263}, {266, 265}, X {268, 267}, {270, 269}, {272, 271}, {274, 273}, X {276, 275}, {278, 277}, {280, 279}, {282, 281}, X {284, 283}, {286, 285}, {288, 287}, {290, 289}, X {4 , 291}, {19 , 11}, {26 , 20}, {31 , 27}, X {132, 130}, {141, 134}, {150, 144}, {155, 153}, X {157, 156}, {159, 158}, {167, 160}, {170, 168}, X {174, 172}, {178, 175}, {182, 180}, {185, 184}, X {191, 186}, {195, 192}, {198, 196}, {201, 199}, X {203, 202}, {205, 204}, {209, 207}, {215, 213}, X {219, 217}, {223, 221}, {226, 225}, {228, 227}, X {231, 229}, {239, 238}, {242, 240}, {248, 246}, X {252, 250}, {292, 254}, {6 , 5}, {24 , 21}, X {136, 96}, {154, 148}, {162, 161}, {165, 163}, X {169, 166}, {173, 171}, {179, 177}, {187, 183}, X {194, 189}, {211, 197}, {235, 233}, {247, 245}, X {253, 249}, {294, 293}, {296, 295}, {298, 297}, X {300, 299}, {302, 301}, {304, 303}, {306, 305}, X {308, 307}, {310, 309}, {312, 311}, {314, 313}, X {316, 315}, {318, 317}, {320, 319}, {322, 321}, X {324, 323}, {8 , 325}, {25 , 23}, {29 , 28}, X {128, 30}, {181, 176}, {251, 241}, {16 , 255}, X {237, 18}, {326, 243}, {328, 327}, {330, 329}, X {332, 331}, {334, 333}, {336, 335}, {338, 337}, X {340, 339}, {342, 341}, {344, 343}, {346, 345}, X {348, 347}, {350, 349}, {352, 351}, {354, 353}, X {356, 355}, {22 , 7}, {2 , 357}, {358, 126}, X {360, 359}, {362, 361}, {193, 363}, {365, 364}, X {367, 366}, {369, 368}, {371, 370}, {373, 372}, X {375, 374}, {377, 376}, {379, 378}, {81 , 380}, X {1 , 164}, {36 , 381}, {94 , 382}, {384, 383}, X {3 , 385}, {13 , 386}, {388, 387}, {390, 389}, X {392, 391}, {394, 393}, {14 , 395}, {397, 396}, X {398, 74}, {113, 399}, {90 , 15}, {35 , 400}, X {88 , 401}, {403, 402}, {405, 404}, {89 , 86}, X {124, 75}, {0 , 406}, {63 , 92}, {122, 407}, X {106, 408}, {409, 72}, {87 , 410}, {411, 123}, X {413, 412}, {415, 414}, {416, 71}, {43 , 37}, X {417, 66}, {418, 120}, {64 , 57}, {419, 60}, X {54 , 38}, {68 , 77}, {70 , 420}, {80 , 55}, X {421, 85}, {62 , 78}, {53 , 56}, {422, 33}, X {423, 125}, {82 , 73}, {52 , 118}, {91 , 79}, X {47 , 107}, {424, 76}, {425, 104}, {84 , 67}, X {426, 61}, {42 , 58}, {427, 93}, {65 , 428}, X {119, 69}, {429, 83}, {103, 430}, {121, 51}, X {432, 431}, {95 , 433}, {98 , 434}, {435, 46}, X {10 , 436}, {438, 437}, {39 , 117}, {45 , 439}, X {440, 108}, {441, 109}, {443, 442}, {34 , 444}, X {114, 445}, {112, 446}, {102, 447}, {448, 48}, X {449, 59}, {450, 97}, {451, 50}, {100, 452}, X {105, 453}, {454, 110}, {49 , 44}, {455, 111}, X {116, 101}, {99 , 456}, {40 , 457}, {459, 458}, X {460, 9}, {462, 461}, {464, 463}, {41 , 465}, X {467, 466}, {469, 468}, {471, 470}, {32 , 115}, X {473, 472}, {475, 474}, {477, 476}, {479, 478}, X {481, 480}, {483, 482}, {485, 484}, {487, 486}, X {489, 488}, {491, 490}, {493, 492}, {495, 494}, X {497, 496}, {499, 498}, {501, 500}, {503, 502}, X {505, 504}, {507, 506}, {509, 508} X}; X Xctab_t ctab_len = { /* {code, length} pairs */ X {0x000002L, 3}, {0x000000L, 3}, {0x000003L, 3}, {0x000005L, 3}, X {0x000006L, 3}, {0x000003L, 4}, {0x000009L, 4}, {0x00000FL, 4}, X {0x000005L, 5}, {0x00001CL, 5}, {0x000008L, 6}, {0x000021L, 6}, X {0x00003AL, 6}, {0x000013L, 7}, {0x000041L, 7}, {0x000045L, 7}, X {0x000076L, 7}, {0x000024L, 8}, {0x00008CL, 8}, {0x000088L, 8}, X {0x00008EL, 8}, {0x0000EEL, 8}, {0x00004AL, 9}, {0x000100L, 9}, X {0x000102L, 9}, {0x000101L, 9}, {0x00011EL, 9}, {0x000206L, 10}, X {0x000225L, 10}, {0x000207L, 10}, {0x000235L, 10}, {0x0001DFL, 9}, X {0x000237L, 10}, {0x00047DL, 11}, {0x0003BDL, 10}, {0x000448L, 11}, X {0x000234L, 10}, {0x00044CL, 11}, {0x00012EL, 11}, {0x00047CL, 11}, X {0x00046DL, 11}, {0x000258L, 12}, {0x000779L, 11}, {0x000778L, 11}, X {0x00025EL, 12}, {0x0008D9L, 12}, {0x259D41L, 24}, {0x0004BEL, 13}, X {0x000892L, 12}, {0x0008D8L, 12}, {0x00089FL, 12}, {0x000966L, 14}, X {0x0008FCL, 12}, {0x0004B7L, 13}, {0x0004B6L, 13}, {0x0011FFL, 13}, X {0x00113DL, 13}, {0x0011FEL, 13}, {0x259D40L, 24}, {0x0011FDL, 13}, X {0x0004B5L, 13}, {0x002275L, 14}, {0x0011FCL, 13}, {0x00259CL, 16}, X {0x002274L, 14}, {0x259D3FL, 24}, {0x002273L, 14}, {0x002272L, 14}, X {0x002271L, 14}, {0x002270L, 14}, {0x00226FL, 14}, {0x0004B4L, 13}, X {0x00226EL, 14}, {0x00226DL, 14}, {0x259D3EL, 24}, {0x0044D1L, 15}, X {0x00226CL, 14}, {0x0004B2L, 13}, {0x00113CL, 13}, {0x00113BL, 13}, X {0x0044D0L, 15}, {0x00449FL, 15}, {0x00449EL, 15}, {0x0011FBL, 13}, X {0x259D3DL, 24}, {0x259D3CL, 24}, {0x259D3BL, 24}, {0x259D3AL, 24}, X {0x00226BL, 14}, {0x259D39L, 24}, {0x00449DL, 15}, {0x00449CL, 15}, X {0x00449BL, 15}, {0x00449AL, 15}, {0x259D38L, 24}, {0x00226AL, 14}, X {0x0011FAL, 13}, {0x004499L, 15}, {0x259D37L, 24}, {0x259D36L, 24}, X {0x004498L, 15}, {0x002269L, 14}, {0x259D35L, 24}, {0x259D34L, 24}, X {0x259D33L, 24}, {0x259D32L, 24}, {0x259D31L, 24}, {0x259D30L, 24}, X {0x259D2FL, 24}, {0x259D2EL, 24}, {0x259D2DL, 24}, {0x259D2CL, 24}, X {0x259D2BL, 24}, {0x259D2AL, 24}, {0x259D29L, 24}, {0x0012FFL, 15}, X {0x259D28L, 24}, {0x259D27L, 24}, {0x259D26L, 24}, {0x259D25L, 24}, X {0x259D24L, 24}, {0x259D23L, 24}, {0x259D22L, 24}, {0x259D21L, 24}, X {0x259D20L, 24}, {0x259D1FL, 24}, {0x0012FEL, 15}, {0x259D1EL, 24}, X {0x259D1DL, 24}, {0x259D1CL, 24}, {0x259D1BL, 24}, {0x259D1AL, 24}, X {0x259D19L, 24}, {0x259D18L, 24}, {0x259D17L, 24}, {0x259D16L, 24}, X {0x259D15L, 24}, {0x0012FDL, 15}, {0x259D14L, 24}, {0x259D13L, 24}, X {0x259D12L, 24}, {0x259D11L, 24}, {0x259D10L, 24}, {0x259D0FL, 24}, X {0x259D0EL, 24}, {0x259D0DL, 24}, {0x259D0CL, 24}, {0x259D0BL, 24}, X {0x259D0AL, 24}, {0x259D09L, 24}, {0x259D08L, 24}, {0x259D07L, 24}, X {0x259D06L, 24}, {0x259D05L, 24}, {0x0012FCL, 15}, {0x259D04L, 24}, X {0x259D03L, 24}, {0x259D02L, 24}, {0x259D01L, 24}, {0x259D00L, 24}, X {0x12CEFFL, 23}, {0x12CEFEL, 23}, {0x12CEFDL, 23}, {0x12CEFCL, 23}, X {0x12CEFBL, 23}, {0x12CEFAL, 23}, {0x12CEF9L, 23}, {0x12CEF8L, 23}, X {0x12CEF7L, 23}, {0x12CEF6L, 23}, {0x12CEF5L, 23}, {0x0012CFL, 15}, X {0x12CEF4L, 23}, {0x12CEF3L, 23}, {0x12CEF2L, 23}, {0x12CEF1L, 23}, X {0x12CEF0L, 23}, {0x12CEEFL, 23}, {0x12CEEEL, 23}, {0x12CEEDL, 23}, X {0x12CEECL, 23}, {0x12CEEBL, 23}, {0x12CEEAL, 23}, {0x12CEE9L, 23}, X {0x12CEE8L, 23}, {0x12CEE7L, 23}, {0x12CEE6L, 23}, {0x12CEE5L, 23}, X {0x12CEE4L, 23}, {0x12CEE3L, 23}, {0x12CEE2L, 23}, {0x12CEE1L, 23}, X {0x12CEE0L, 23}, {0x12CEDFL, 23}, {0x12CEDEL, 23}, {0x12CEDDL, 23}, X {0x12CEDCL, 23}, {0x12CEDBL, 23}, {0x12CEDAL, 23}, {0x12CED9L, 23}, X {0x12CED8L, 23}, {0x12CED7L, 23}, {0x12CED6L, 23}, {0x12CED5L, 23}, X {0x12CED4L, 23}, {0x12CED3L, 23}, {0x12CED2L, 23}, {0x12CED1L, 23}, X {0x12CED0L, 23}, {0x12CECFL, 23}, {0x12CECEL, 23}, {0x12CECDL, 23}, X {0x12CECCL, 23}, {0x12CECBL, 23}, {0x12CECAL, 23}, {0x12CEC9L, 23}, X {0x12CEC8L, 23}, {0x12CEC7L, 23}, {0x12CEC6L, 23}, {0x12CEC5L, 23}, X {0x12CEC4L, 23}, {0x12CEC3L, 23}, {0x12CEC2L, 23}, {0x12CEC1L, 23}, X {0x12CEC0L, 23}, {0x12CEBFL, 23}, {0x12CEBEL, 23}, {0x12CEBDL, 23}, X {0x12CEBCL, 23}, {0x12CEBBL, 23}, {0x12CEBAL, 23}, {0x12CEB9L, 23}, X {0x12CEB8L, 23}, {0x12CEB7L, 23}, {0x12CEB6L, 23}, {0x12CEB5L, 23}, X {0x12CEB4L, 23}, {0x12CEB3L, 23}, {0x12CEB2L, 23}, {0x12CEB1L, 23}, X {0x12CEB0L, 23}, {0x12CEAFL, 23}, {0x12CEAEL, 23}, {0x12CEADL, 23}, X {0x12CEACL, 23}, {0x12CEABL, 23}, {0x12CEAAL, 23}, {0x12CEA9L, 23}, X {0x12CEA8L, 23}, {0x12CEA7L, 23}, {0x12CEA6L, 23}, {0x12CEA5L, 23}, X {0x12CEA4L, 23}, {0x12CEA3L, 23}, {0x12CEA2L, 23}, {0x12CEA1L, 23} X}; X Xtree_t tree_len = { /* {link 0, link 1} pairs. */ X {58 , 46}, {74 , 65}, {85 , 84}, {87 , 86}, X {94 , 89}, {99 , 98}, {103, 102}, {105, 104}, X {107, 106}, {109, 108}, {111, 110}, {113, 112}, X {116, 114}, {118, 117}, {120, 119}, {122, 121}, X {124, 123}, {127, 125}, {129, 128}, {131, 130}, X {133, 132}, {135, 134}, {138, 136}, {140, 139}, X {142, 141}, {144, 143}, {146, 145}, {148, 147}, X {150, 149}, {152, 151}, {155, 153}, {157, 156}, X {159, 158}, {161, 160}, {163, 162}, {165, 164}, X {167, 166}, {169, 168}, {172, 170}, {174, 173}, X {176, 175}, {178, 177}, {180, 179}, {182, 181}, X {184, 183}, {186, 185}, {188, 187}, {190, 189}, X {192, 191}, {194, 193}, {196, 195}, {198, 197}, X {200, 199}, {202, 201}, {204, 203}, {206, 205}, X {208, 207}, {210, 209}, {212, 211}, {214, 213}, X {216, 215}, {218, 217}, {220, 219}, {222, 221}, X {224, 223}, {226, 225}, {228, 227}, {230, 229}, X {232, 231}, {234, 233}, {236, 235}, {238, 237}, X {240, 239}, {242, 241}, {244, 243}, {246, 245}, X {248, 247}, {250, 249}, {252, 251}, {254, 253}, X {256, 255}, {258, 257}, {260, 259}, {262, 261}, X {264, 263}, {266, 265}, {268, 267}, {270, 269}, X {272, 271}, {274, 273}, {276, 275}, {278, 277}, X {280, 279}, {282, 281}, {284, 283}, {286, 285}, X {288, 287}, {290, 289}, {292, 291}, {294, 293}, X {296, 295}, {298, 297}, {300, 299}, {302, 301}, X {304, 303}, {306, 305}, {308, 307}, {310, 309}, X {312, 311}, {314, 313}, {316, 315}, {318, 317}, X {320, 319}, {322, 321}, {324, 323}, {326, 325}, X {328, 327}, {330, 329}, {332, 331}, {334, 333}, X {336, 335}, {338, 337}, {340, 339}, {342, 341}, X {344, 343}, {346, 345}, {348, 347}, {350, 349}, X {352, 351}, {354, 353}, {356, 355}, {358, 357}, X {360, 359}, {362, 361}, {364, 363}, {366, 365}, X {368, 367}, {370, 369}, {372, 371}, {374, 373}, X {376, 375}, {378, 377}, {380, 379}, {382, 381}, X {384, 383}, {386, 385}, {388, 387}, {390, 389}, X {392, 391}, {394, 393}, {396, 395}, {398, 397}, X {400, 399}, {402, 401}, {404, 403}, {406, 405}, X {408, 407}, {410, 409}, {412, 411}, {414, 413}, X {63 , 415}, {80 , 75}, {82 , 81}, {91 , 90}, X {93 , 92}, {100, 97}, {126, 115}, {154, 137}, X {416, 171}, {64 , 61}, {67 , 66}, {69 , 68}, X {72 , 70}, {76 , 73}, {95 , 88}, {417, 101}, X {419, 418}, {421, 420}, {423, 422}, {51 , 424}, X {57 , 55}, {62 , 59}, {96 , 83}, {78 , 56}, X {425, 79}, {427, 426}, {429, 428}, {431, 430}, X {433, 432}, {47 , 434}, {54 , 53}, {71 , 60}, X {77 , 435}, {437, 436}, {52 , 438}, {49 , 45}, X {439, 50}, {441, 440}, {443, 442}, {48 , 444}, X {44 , 445}, {447, 446}, {41 , 448}, {43 , 42}, X {450, 449}, {39 , 33}, {451, 40}, {453, 452}, X {37 , 454}, {35 , 455}, {38 , 456}, {458, 457}, X {459, 34}, {461, 460}, {462, 32}, {36 , 30}, X {464, 463}, {465, 28}, {27 , 29}, {467, 466}, X {468, 31}, {26 , 469}, {471, 470}, {473, 472}, X {24 , 474}, {23 , 25}, {22 , 475}, {21 , 476}, X {20 , 477}, {18 , 478}, {19 , 479}, {481, 480}, X {17 , 482}, {16 , 483}, {485, 484}, {486, 15}, X {487, 14}, {488, 13}, {12 , 489}, {491, 490}, X {492, 11}, {10 , 493}, {9 , 494}, {496, 495}, X {497, 8}, {498, 7}, {499, 6}, {500, 5}, X {4 , 501}, {502, 3}, {0 , 2}, {1 , 503}, X {505, 504}, {507, 506}, {509, 508} X}; X Xctab_t ctab_off = { /* {code, length} pairs */ X {0x000007L, 3}, {0x000003L, 4}, {0x00000CL, 4}, {0x00000AL, 5}, X {0x000012L, 5}, {0x00001BL, 5}, {0x000008L, 6}, {0x000010L, 6}, X {0x00001CL, 6}, {0x00001FL, 6}, {0x000028L, 6}, {0x000008L, 7}, X {0x000035L, 6}, {0x000003L, 7}, {0x00000BL, 7}, {0x00002FL, 6}, X {0x00000EL, 7}, {0x000024L, 7}, {0x000026L, 7}, {0x00003AL, 7}, X {0x00003CL, 7}, {0x000040L, 7}, {0x00004EL, 7}, {0x000045L, 7}, X {0x000005L, 8}, {0x000057L, 7}, {0x00005AL, 7}, {0x000003L, 8}, X {0x00000CL, 8}, {0x00002AL, 8}, {0x00001FL, 8}, {0x000002L, 8}, X {0x00000AL, 8}, {0x00004CL, 7}, {0x000009L, 8}, {0x00002CL, 8}, X {0x00004FL, 8}, {0x000019L, 8}, {0x000065L, 8}, {0x000089L, 8}, X {0x000087L, 8}, {0x000029L, 8}, {0x00002FL, 8}, {0x00008DL, 8}, X {0x00006BL, 8}, {0x000063L, 8}, {0x00006DL, 8}, {0x00005AL, 8}, X {0x000085L, 8}, {0x000060L, 8}, {0x00005CL, 8}, {0x00009BL, 8}, X {0x0000A5L, 8}, {0x00006FL, 8}, {0x0000A4L, 8}, {0x000083L, 8}, X {0x0000ACL, 8}, {0x000084L, 8}, {0x00008EL, 8}, {0x00009AL, 8}, X {0x0000D2L, 8}, {0x0000BBL, 8}, {0x00002BL, 9}, {0x0000ABL, 8}, X {0x000017L, 9}, {0x0000BAL, 8}, {0x0000AAL, 8}, {0x000035L, 9}, X {0x0000A8L, 8}, {0x000016L, 9}, {0x0000B9L, 8}, {0x000008L, 9}, X {0x00003DL, 9}, {0x00008AL, 9}, {0x000026L, 9}, {0x000009L, 9}, X {0x0000B8L, 8}, {0x00001DL, 9}, {0x000000L, 9}, {0x0000B7L, 8}, X {0x00002AL, 9}, {0x00005DL, 9}, {0x000095L, 9}, {0x000050L, 9}, X {0x00004AL, 9}, {0x0000BFL, 9}, {0x00004FL, 9}, {0x0000BBL, 9}, X {0x00008DL, 9}, {0x00004EL, 9}, {0x00003CL, 9}, {0x00009CL, 9}, X {0x0000CFL, 9}, {0x0000C5L, 9}, {0x000057L, 9}, {0x000088L, 9}, X {0x0000D8L, 9}, {0x000037L, 9}, {0x00014FL, 9}, {0x000056L, 9}, X {0x000094L, 9}, {0x000051L, 9}, {0x0000B0L, 9}, {0x0000CEL, 9}, X {0x00005CL, 9}, {0x0000F7L, 9}, {0x000097L, 9}, {0x0000DDL, 9}, X {0x0000D5L, 9}, {0x0000D4L, 9}, {0x00008CL, 9}, {0x0000B6L, 9}, X {0x0000F6L, 9}, {0x0000D3L, 9}, {0x0000BEL, 9}, {0x000118L, 9}, X {0x00016CL, 9}, {0x0000D2L, 9}, {0x0000BDL, 9}, {0x000023L, 10}, X {0x0000DCL, 9}, {0x000105L, 9}, {0x000167L, 9}, {0x0000F5L, 9}, X {0x000111L, 9}, {0x00004BL, 10}, {0x0000F4L, 9}, {0x0000C4L, 9}, X {0x00013EL, 9}, {0x0000C9L, 9}, {0x0000CDL, 9}, {0x00004AL, 10}, X {0x0000C3L, 9}, {0x00011FL, 9}, {0x00014EL, 9}, {0x000167L, 10}, X {0x0001A1L, 9}, {0x000153L, 9}, {0x000119L, 9}, {0x0000EDL, 9}, X {0x000039L, 10}, {0x00009BL, 10}, {0x0000D1L, 9}, {0x000163L, 9}, X {0x0000B7L, 10}, {0x000162L, 9}, {0x000052L, 10}, {0x000152L, 9}, X {0x000051L, 10}, {0x000068L, 10}, {0x000038L, 10}, {0x0000BCL, 9}, X {0x000037L, 10}, {0x00014DL, 9}, {0x00013DL, 9}, {0x000007L, 10}, X {0x00010CL, 9}, {0x000161L, 9}, {0x000049L, 10}, {0x000006L, 10}, X {0x00011EL, 9}, {0x00006DL, 10}, {0x000160L, 9}, {0x0001A6L, 9}, X {0x000104L, 9}, {0x000166L, 9}, {0x000048L, 10}, {0x0001A3L, 9}, X {0x00014CL, 9}, {0x00015BL, 9}, {0x000165L, 9}, {0x000036L, 10}, X {0x000063L, 10}, {0x0001A0L, 9}, {0x000005L, 10}, {0x000164L, 9}, X {0x000093L, 10}, {0x000022L, 10}, {0x000110L, 9}, {0x00006CL, 10}, X {0x000004L, 10}, {0x00013CL, 9}, {0x000003L, 10}, {0x00003FL, 10}, X {0x000002L, 10}, {0x0001A2L, 9}, {0x00009AL, 10}, {0x000035L, 10}, X {0x000116L, 10}, {0x0001A7L, 9}, {0x00013FL, 9}, {0x000050L, 10}, X {0x00004FL, 10}, {0x000113L, 10}, {0x00012CL, 10}, {0x000092L, 10}, X {0x000034L, 10}, {0x000175L, 10}, {0x000166L, 10}, {0x000091L, 10}, X {0x000099L, 10}, {0x0001D8L, 10}, {0x00003EL, 10}, {0x000112L, 10}, X {0x0000B6L, 10}, {0x000190L, 10}, {0x0001A0L, 10}, {0x00004EL, 10}, X {0x00013AL, 10}, {0x00015AL, 9}, {0x0001B3L, 10}, {0x00021BL, 10}, X {0x000165L, 10}, {0x000062L, 10}, {0x000098L, 10}, {0x000097L, 10}, X {0x000021L, 10}, {0x000069L, 10}, {0x000061L, 10}, {0x000164L, 10}, X {0x00011FL, 10}, {0x000163L, 10}, {0x000174L, 10}, {0x00012DL, 10}, X {0x0001B2L, 10}, {0x000096L, 10}, {0x00011EL, 10}, {0x00011DL, 10}, X {0x0001A1L, 10}, {0x000090L, 10}, {0x000199L, 10}, {0x00003DL, 10}, X {0x0000B5L, 10}, {0x000162L, 10}, {0x0001DFL, 10}, {0x00016FL, 10}, X {0x000185L, 10}, {0x00003CL, 10}, {0x0001DEL, 10}, {0x00011CL, 10}, X {0x00013BL, 10}, {0x000184L, 10}, {0x0002DBL, 10}, {0x000198L, 10}, X {0x00021AL, 10}, {0x0000B4L, 10}, {0x0002DAL, 10}, {0x000060L, 10}, X {0x0001DDL, 10}, {0x0001DCL, 10}, {0x0001D9L, 10}, {0x000053L, 10}, X {0x000117L, 10}, {0x000020L, 10}, {0x000191L, 10}, {0x00016EL, 10} X}; X Xtree_t tree_off = { /* {link 0, link 1} pairs. */ X {246, 242}, {244, 211}, {238, 234}, {249, 248}, X {201, 250}, {224, 210}, {206, 228}, {243, 230}, X {205, 254}, {241, 236}, {222, 197}, {255, 235}, X {198, 135}, {219, 212}, {233, 221}, {208, 240}, X {194, 223}, {226, 220}, {239, 227}, {188, 252}, X {203, 193}, {204, 144}, {245, 232}, {186, 141}, X {214, 200}, {225, 215}, {195, 176}, {229, 199}, X {179, 161}, {149, 217}, {213, 172}, {247, 218}, X {146, 251}, {191, 148}, {207, 192}, {131, 125}, X {166, 158}, {202, 183}, {237, 231}, {150, 140}, X {171, 152}, {196, 187}, {177, 119}, {253, 216}, X {159, 155}, {180, 174}, {184, 182}, {163, 189}, X {185, 167}, {173, 136}, {116, 256}, {165, 122}, X {175, 170}, {145, 143}, {162, 157}, {209, 169}, X {147, 137}, {134, 98}, {168, 153}, {128, 190}, X {181, 154}, {160, 133}, {115, 138}, {178, 124}, X {156, 257}, {164, 121}, {112, 105}, {126, 123}, X {259, 258}, {260, 139}, {120, 107}, {96 , 261}, X {109, 108}, {117, 113}, {262, 142}, {103, 92}, X {263, 130}, {264, 129}, {127, 93}, {265, 132}, X {114, 85}, {151, 118}, {266, 87}, {111, 267}, X {269, 268}, {102, 270}, {91 , 271}, {272, 106}, X {100, 82}, {274, 273}, {110, 88}, {73 , 275}, X {95 , 276}, {104, 81}, {278, 277}, {99 , 94}, X {83 , 101}, {89 , 86}, {280, 279}, {84 , 281}, X {283, 282}, {90 , 72}, {284, 97}, {285, 67}, X {287, 286}, {80 , 62}, {289, 288}, {74 , 290}, X {292, 291}, {294, 293}, {295, 77}, {297, 296}, X {69 , 64}, {299, 298}, {71 , 75}, {301, 300}, X {78 , 302}, {60 , 303}, {305, 304}, {65 , 61}, X {76 , 70}, {306, 79}, {308, 307}, {310, 309}, X {56 , 311}, {66 , 63}, {68 , 312}, {314, 313}, X {54 , 52}, {316, 315}, {59 , 51}, {58 , 317}, X {318, 43}, {319, 39}, {320, 40}, {57 , 48}, X {321, 55}, {323, 322}, {325, 324}, {326, 53}, X {327, 46}, {328, 44}, {330, 329}, {332, 331}, X {333, 38}, {334, 45}, {49 , 335}, {337, 336}, X {50 , 338}, {47 , 339}, {341, 340}, {342, 36}, X {344, 343}, {346, 345}, {348, 347}, {349, 42}, X {35 , 350}, {29 , 351}, {352, 41}, {354, 353}, X {356, 355}, {357, 30}, {359, 358}, {360, 37}, X {362, 361}, {364, 363}, {366, 365}, {28 , 367}, X {32 , 368}, {369, 34}, {370, 24}, {31 , 27}, X {372, 371}, {374, 373}, {376, 375}, {26 , 377}, X {379, 378}, {380, 25}, {382, 381}, {384, 383}, X {22 , 385}, {33 , 386}, {388, 387}, {389, 23}, X {391, 390}, {21 , 392}, {20 , 393}, {19 , 394}, X {396, 395}, {398, 397}, {400, 399}, {402, 401}, X {404, 403}, {406, 405}, {18 , 407}, {17 , 408}, X {410, 409}, {412, 411}, {414, 413}, {416, 415}, X {16 , 417}, {419, 418}, {420, 14}, {11 , 421}, X {423, 422}, {425, 424}, {426, 13}, {428, 427}, X {429, 12}, {430, 15}, {432, 431}, {434, 433}, X {10 , 435}, {437, 436}, {439, 438}, {441, 440}, X {442, 9}, {8 , 443}, {445, 444}, {447, 446}, X {449, 448}, {451, 450}, {7 , 452}, {454, 453}, X {6 , 455}, {457, 456}, {459, 458}, {461, 460}, X {463, 462}, {464, 5}, {466, 465}, {468, 467}, X {4 , 469}, {471, 470}, {473, 472}, {475, 474}, X {3 , 476}, {478, 477}, {480, 479}, {482, 481}, X {484, 483}, {2 , 485}, {487, 486}, {489, 488}, X {491, 490}, {493, 492}, {494, 1}, {496, 495}, X {497, 0}, {499, 498}, {501, 500}, {503, 502}, X {505, 504}, {507, 506}, {509, 508} X}; + END-OF-FILE tables.h chmod 'u=rw,g=r,o=r' 'tables.h' set `wc -c 'tables.h'` count=$1 case $count in 23395) :;; *) echo 'Bad character count in ''tables.h' >&2 echo 'Count should be 23395' >&2 esac echo Extracting 'Makefile' sed 's/^X//' > 'Makefile' << '+ END-OF-FILE ''Makefile' X# X# Makefile for comic X# X# (p) Jan-Mark Wams (email: jms@cs.vu.nl) X# X XCFLAGS=-O Xo=s X XOBJS=bits.$o \ X comic.$o \ X decode.$o \ X encode.$o \ X getinput.$o \ X gettoken.$o \ X header.$o \ X hash.$o \ X huffman.$o X XCOMIC=comic XCOMIC.SH=comic.sh X X# For speed or mem savage, use exec below XRM=rm XMAKE=make XECHO=echo X Xcomic: minix X @$(ECHO) comic done... X Xclean: X @$(RM) -f core a.out *.o *.obj $(OBJS) $(COMIC.SH) *.?-X *.-X *-X X Xshar: X shar *.c *.h [A-Z]* comic.prj > $(COMIC.SH) X Xgcc: X @$(MAKE) _GCC CC='gcc' 'CFLAGS=-DGCC $(CFLAGS)' 'o=o' X Xminix: X @$(MAKE) _MINIX 'CFLAGS=-i -DMINIX $(CFLAGS)' 'o=s' X Xpro: # profileing under some U*ix boxes. X @$(MAKE) _UNIX 'CFLAGS=-DUNIX -p $(CFLAGS)' 'o=o' X Xunix: X @$(MAKE) _UNIX 'CFLAGS=-DUNIX $(CFLAGS)' 'o=o' X Xamoeba: X @$(MAKE) _AMOEBA CC='amcc' 'CFLAGS=-DAMOEBA $(CFLAGS)' 'o=o' X Xc89: X @$(MAKE) _C89 CC='c89' 'CFLAGS=-i -wo -DC89 $(CFLAGS)' 'o=o' X Xm68: X @$(MAKE) _M68 'CFLAGS=-DM68 $(CFLAGS)' 'o=o' X Xtcc: # Turbo make is a bit unintel, not allowing commandline defines. X TCC -G -O -Z -DDOS -L\c\lib -I\c\inc \ X comic bits decode encode getinput hash gettoken huffman header X @del *.obj X Xdos: X @$(MAKE) _DOS CC='CC' 'CFLAGS=-DDOS' 'o=OBJ' 'COMIC=comic.exe' X X X_MINIX _C89 _GCC _M68 _UNIX _AMOEBA _DOS: $(OBJS) X $(CC) $(CFLAGS) -o $(COMIC) $(OBJS) X Xbits.$o: bits.h comic.h bits.c X $(CC) $(CFLAGS) -c bits.c X Xcomic.$o: buffer.h comic.h hash.h comic.c X $(CC) $(CFLAGS) -c comic.c X Xdecode.$o: bits.h buffer.h comic.h huffman.h decode.c header.h X $(CC) $(CFLAGS) -c decode.c X Xencode.$o: hash.h bits.h buffer.h comic.h huffman.h encode.c header.h X $(CC) $(CFLAGS) -c encode.c X Xgetinput.$o: buffer.h comic.h getinput.c X $(CC) $(CFLAGS) -c getinput.c X Xgettoken.$o: hash.h buffer.h comic.h gettoken.c X $(CC) $(CFLAGS) -c gettoken.c X Xhuffman.$o: comic.h huffman.h tables.h huffman.c X $(CC) $(CFLAGS) -c huffman.c X Xhash.$o: hash.h buffer.h comic.h hash.c X $(CC) $(CFLAGS) -c hash.c X Xheader.$o: comic.h header.h header.c X $(CC) $(CFLAGS) -c header.c + END-OF-FILE Makefile chmod 'u=rw,g=r,o=r' 'Makefile' set `wc -c 'Makefile'` count=$1 case $count in 1977) :;; *) echo 'Bad character count in ''Makefile' >&2 echo 'Count should be 1977' >&2 esac echo Extracting 'READ_ME' sed 's/^X//' > 'READ_ME' << '+ END-OF-FILE ''READ_ME' X XThis dir contains the source files for COMIC 1.0 X X COMIC stands for COmpress MInix C. X XIt contains huffman tables (tables.h) that are tuned to the tippical MINIX XC-program source. X XUsage: comic [-cfvvV?] [<file>[-X]...] XUsage: decomic [-cfvV?] [<file>[-X]...] XUsage: xcat [-vV?] [<file>[-X]...] X XEg.: X comic -V # print the version number of comic. X comic -vv <file> # compress the file, and print the savings. X comic -df <file> # decomic the file overwriting <file>. X comic -c <file> # comic the file to stout. X decomic # decomic stdin. X xcat foo # decomic foo-X to stout. X XLink comic to decomic, and decomic will act like comic -d. XLink comic to xcat, and decomic will act like comic -cd. X XTo make comic type 'make unix' or 'make gcc' or 'make minix' etc. X XNote: COMIC 1.0 is slightly incompatible with COMIC 1.0B, this Xmeans you will have to decomic all files before installing the Xnew COMIC. X XThe DOS version has an additional flag, -a this will convert \r\n to X\n and is usable to gain extra compression, or to make UN*X compatible Xfiles. To be able to decomic a text file under UN*X that was comiced Xon a DOS machine, use the -a flag with comic on the DOS machine. X XEg.: X comic -fvva PIPO.DOC # creat a PIPO.D-X on a DOS machine X comic -dc PIPO.D-X > pipo.doc # decomic it on a UN*X machine. X xcat PIPO.D-X > pipo.doc # same. X XNote: binary DOS files can't be comiced using the -a flag. (An assertion Xwill fail, this might be an error message in next versions.) XNote: DOS files with 2 or 3 char suffixes will lose 1 or 2 suffix chars. XEg. PIPO.DOC will become PIPO.D-X. Next versions will remember the OC, Xand restore it. X X XQuestions: email jms@cs.vu.nl X + END-OF-FILE READ_ME chmod 'u=rw,g=r,o=r' 'READ_ME' set `wc -c 'READ_ME'` count=$1 case $count in 1669) :;; *) echo 'Bad character count in ''READ_ME' >&2 echo 'Count should be 1669' >&2 esac echo Extracting 'READ_ME2' sed 's/^X//' > 'READ_ME2' << '+ END-OF-FILE ''READ_ME2' X XWhere should COMIC go to? (And in what order.) X X 0) Faster getinput routine. X 1) Full path names. X 2) Dynamic Huffman tables. X 3) Prefill of buffer. X 4) Pointer matching (faster) searching. X 5) General speedup. X 6) MSC port. X 7) Cleanup. X X XQuestions: email jms@cs.vu.nl X + END-OF-FILE READ_ME2 chmod 'u=rw,g=r,o=r' 'READ_ME2' set `wc -c 'READ_ME2'` count=$1 case $count in 273) :;; *) echo 'Bad character count in ''READ_ME2' >&2 echo 'Count should be 273' >&2 esac echo Extracting 'comic.prj' sed 's/^X//' > 'comic.prj' << '+ END-OF-FILE ''comic.prj' Xcomic (buffer.h; comic.h) Xbits (bits.h; comic.h) Xdecode (bits.h; buffer.h; comic.h; huffman.h; header.h) Xencode (hash.h; bits.h; buffer.h; comic.h; huffman.h; header.h) Xgetinput (buffer.h; comic.h) Xgettoken (hash.h; buffer.h; comic.h) Xhuffman (comic.h; huffman.h; tables.h) Xhash (hash.h; buffer.h; comic.h) Xheader (comic.h; header.h) + END-OF-FILE comic.prj chmod 'u=rw,g=r,o=r' 'comic.prj' set `wc -c 'comic.prj'` count=$1 case $count in 352) :;; *) echo 'Bad character count in ''comic.prj' >&2 echo 'Count should be 352' >&2 esac exit 0 -- (:> jms (_) ========""======