#pragma prototyped12/*3* compress encoder/decoder4*5* compress/zcat discipline snarfed from BSD zopen by6* Glenn Fowler7* AT&T Research8* 1999-06-239*/1011/*-12* Copyright (c) 1985, 1986, 1992, 199313* The Regents of the University of California. All rights reserved.14*15* This code is derived from software contributed to Berkeley by16* Diomidis Spinellis and James A. Woods, derived from original17* work by Spencer Thomas and Joseph Orost.18*19* Redistribution and use in source and binary forms, with or without20* modification, are permitted provided that the following conditions21* are met:22* 1. Redistributions of source code must retain the above copyright23* notice, this list of conditions and the following disclaimer.24* 2. Redistributions in binary form must reproduce the above copyright25* notice, this list of conditions and the following disclaimer in the26* documentation and/or other materials provided with the distribution.27* 3. Neither the name of the University nor the names of its contributors28* may be used to endorse or promote products derived from this software29* without specific prior written permission.30*31* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND32* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE33* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE34* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE35* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL36* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS37* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)38* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT39* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY40* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF41* SUCH DAMAGE.42*/4344/*-45* fcompress.c - File compression ala IEEE Computer, June 1984.46*47* Compress authors:48* Spencer W. Thomas (decvax!utah-cs!thomas)49* Jim McKie (decvax!mcvax!jim)50* Steve Davies (decvax!vax135!petsd!peora!srd)51* Ken Turkowski (decvax!decwrl!turtlevax!ken)52* James A. Woods (decvax!ihnp4!ames!jaw)53* Joe Orost (decvax!vax135!petsd!joe)54*55* Cleaned up and converted to library returning I/O streams by56* Diomidis Spinellis <[email protected]>.57*/5859#include <codex.h>6061#define MAGIC1 0x1f62#define MAGIC2 0x9d63#define HEADER 36465#define MINBITS 966#define MAXBITS 166768#define BITS MAXBITS /* Default bits. */69#define HSIZE 69001 /* 95% occupancy */7071/* A code_int must be able to hold 2**BITS values of type int, and also -1. */72typedef int32_t code_int;73typedef int32_t count_int;7475typedef u_char char_type;7677#define BIT_MASK 0x1f /* Defines for third byte of header. */78#define BLOCK_MASK 0x807980/*81* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is82* a fourth header byte (for expansion).83*/84#define INIT_BITS 9 /* Initial number of bits/code. */8586#define MAXCODE(n_bits) ((1 << (n_bits)) - 1)8788typedef struct s_zstate {89Codex_t* codex;90enum {91S_START, S_MIDDLE, S_EOF92} zs_state; /* State of computation */93int zs_n_bits; /* Number of bits/code. */94int zs_maxbits; /* User settable max # bits/code. */95code_int zs_maxcode; /* Maximum code, given n_bits. */96code_int zs_maxmaxcode; /* Should NEVER generate this code. */97count_int zs_htab [HSIZE];98u_short zs_codetab [HSIZE];99code_int zs_hsize; /* For dynamic table sizing. */100code_int zs_free_ent; /* First unused entry. */101/*102* Block compression parameters -- after all codes are used up,103* and compression rate changes, start over.104*/105int zs_block_compress;106int zs_clear_flg;107long zs_ratio;108count_int zs_checkpoint;109int zs_offset;110long zs_in_count; /* Length of input. */111long zs_bytes_out; /* Length of compressed output. */112long zs_sync_out; /* bytes_out at last sync */113long zs_out_count; /* # of codes output (for debugging). */114char_type zs_buf[BITS];115union {116struct {117long zs_fcode;118code_int zs_ent;119code_int zs_hsize_reg;120int zs_hshift;121} w; /* Write paramenters */122struct {123char_type *zs_stackp;124int zs_finchar;125code_int zs_code, zs_oldcode, zs_incode;126int zs_roffset, zs_size;127char_type zs_gbuf[BITS];128} r; /* Read parameters */129} u;130} State_t;131132/* Definitions to retain old variable names */133#define state zs->zs_state134#define n_bits zs->zs_n_bits135#define maxbits zs->zs_maxbits136#define maxcode zs->zs_maxcode137#define maxmaxcode zs->zs_maxmaxcode138#define htab zs->zs_htab139#define codetab zs->zs_codetab140#define hsize zs->zs_hsize141#define free_ent zs->zs_free_ent142#define block_compress zs->zs_block_compress143#define clear_flg zs->zs_clear_flg144#define ratio zs->zs_ratio145#define checkpoint zs->zs_checkpoint146#define offset zs->zs_offset147#define in_count zs->zs_in_count148#define bytes_out zs->zs_bytes_out149#define sync_out zs->zs_sync_out150#define out_count zs->zs_out_count151#define buf zs->zs_buf152#define fcode zs->u.w.zs_fcode153#define hsize_reg zs->u.w.zs_hsize_reg154#define ent zs->u.w.zs_ent155#define hshift zs->u.w.zs_hshift156#define stackp zs->u.r.zs_stackp157#define finchar zs->u.r.zs_finchar158#define code zs->u.r.zs_code159#define oldcode zs->u.r.zs_oldcode160#define incode zs->u.r.zs_incode161#define roffset zs->u.r.zs_roffset162#define size zs->u.r.zs_size163#define gbuf zs->u.r.zs_gbuf164165/*166* To save much memory, we overlay the table used by compress() with those167* used by decompress(). The tab_prefix table is the same size and type as168* the codetab. The tab_suffix table needs 2**BITS characters. We get this169* from the beginning of htab. The output stack uses the rest of htab, and170* contains characters. There is plenty of room for any possible stack171* (stack used to be 8000 characters).172*/173174#define htabof(i) htab[i]175#define codetabof(i) codetab[i]176177#define tab_prefixof(i) codetabof(i)178#define tab_suffixof(i) ((char_type *)(htab))[i]179#define de_stack ((char_type *)&tab_suffixof(1 << BITS))180181#define CHECK_GAP 10000 /* Ratio check interval. */182183/*184* the next two codes should not be changed lightly, as they must not185* lie within the contiguous general code space.186*/187#define FIRST 257 /* First free entry. */188#define CLEAR 256 /* Table clear output code. */189190/*-191* Algorithm from "A Technique for High Performance Data Compression",192* Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.193*194* Algorithm:195* Modified Lempel-Ziv method (LZW). Basically finds common196* substrings and replaces them with a variable size code. This is197* deterministic, and can be done on the fly. Thus, the decompression198* procedure needs no input table, but tracks the way the table was built.199*/200201/*-202* Output the given code.203* Inputs:204* code: A n_bits-bit integer. If == -1, then EOF. This assumes205* that n_bits =< (long)wordsize - 1.206* Outputs:207* Outputs code to the file.208* Assumptions:209* Chars are 8 bits long.210* Algorithm:211* Maintain a BITS character long buffer (so that 8 codes will212* fit in it exactly). Use the VAX insv instruction to insert each213* code in turn. When the buffer fills up empty it and start over.214*/215216static char_type lmask[9] =217{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};218static char_type rmask[9] =219{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};220221static int222output(State_t* zs, Sfio_t* f, code_int ocode, Sfdisc_t* dp)223{224register int bits, r_off;225register char_type *bp;226227r_off = offset;228bits = n_bits;229bp = buf;230if (ocode >= 0) {231/* Get to the first byte. */232bp += (r_off >> 3);233r_off &= 7;234/*235* Since ocode is always >= 8 bits, only need to mask the first236* hunk on the left.237*/238*bp = (*bp & rmask[r_off]) | ((ocode << r_off) & lmask[r_off]);239bp++;240bits -= (8 - r_off);241ocode >>= 8 - r_off;242/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */243if (bits >= 8) {244*bp++ = ocode;245ocode >>= 8;246bits -= 8;247}248/* Last bits. */249if (bits)250*bp = ocode;251offset += n_bits;252if (offset == (n_bits << 3)) {253bp = buf;254bits = n_bits;255bytes_out += bits;256if (sfwr(f, bp, bits, dp) != bits)257return (-1);258bp += bits;259bits = 0;260offset = 0;261}262/*263* If the next entry is going to be too big for the ocode size,264* then increase it, if possible.265*/266if (free_ent > maxcode || (clear_flg > 0)) {267/*268* Write the whole buffer, because the input side won't269* discover the size increase until after it has read it.270*/271if (offset > 0) {272if (sfwr(f, buf, n_bits, dp) != n_bits)273return (-1);274bytes_out += n_bits;275}276offset = 0;277278if (clear_flg) {279maxcode = MAXCODE(n_bits = INIT_BITS);280clear_flg = 0;281} else {282n_bits++;283if (n_bits == maxbits)284maxcode = maxmaxcode;285else286maxcode = MAXCODE(n_bits);287}288}289} else {290/* At EOF, write the rest of the buffer. */291if (offset > 0) {292offset = (offset + 7) / 8;293if (sfwr(f, buf, offset, dp) != offset)294return (-1);295bytes_out += offset;296}297offset = 0;298}299return (0);300}301302/*-303* Read one code from the standard input. If EOF, return -1.304* Inputs:305* stdin306* Outputs:307* code or -1 is returned.308*/309static code_int310getcode(State_t* zs, Sfio_t* f, Sfdisc_t* dp)311{312register code_int gcode;313register int r_off, bits;314register char_type *bp;315316bp = gbuf;317if (clear_flg > 0 || roffset >= size || free_ent > maxcode) {318/*319* If the next entry will be too big for the current gcode320* size, then we must increase the size. This implies reading321* a new buffer full, too.322*/323if (free_ent > maxcode) {324n_bits++;325if (n_bits == maxbits) /* Won't get any bigger now. */326maxcode = maxmaxcode;327else328maxcode = MAXCODE(n_bits);329}330if (clear_flg > 0) {331maxcode = MAXCODE(n_bits = INIT_BITS);332clear_flg = 0;333}334size = sfrd(f, gbuf, n_bits, dp);335if (size <= 0) /* End of file. */336return (-1);337roffset = 0;338/* Round size down to integral number of codes. */339size = (size << 3) - (n_bits - 1);340}341r_off = roffset;342bits = n_bits;343344/* Get to the first byte. */345bp += (r_off >> 3);346r_off &= 7;347348/* Get first part (low order bits). */349gcode = (*bp++ >> r_off);350bits -= (8 - r_off);351r_off = 8 - r_off; /* Now, roffset into gcode word. */352353/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */354if (bits >= 8) {355gcode |= *bp++ << r_off;356r_off += 8;357bits -= 8;358}359360/* High order bits. */361gcode |= (*bp & rmask[bits]) << r_off;362roffset += n_bits;363364return (gcode);365}366367static void368cl_hash(State_t* zs, register count_int cl_hsize) /* Reset code table. */369{370register count_int *htab_p;371register long i, m1;372373m1 = -1;374htab_p = htab + cl_hsize;375i = cl_hsize - 16;376do { /* Might use Sys V memset(3) here. */377*(htab_p - 16) = m1;378*(htab_p - 15) = m1;379*(htab_p - 14) = m1;380*(htab_p - 13) = m1;381*(htab_p - 12) = m1;382*(htab_p - 11) = m1;383*(htab_p - 10) = m1;384*(htab_p - 9) = m1;385*(htab_p - 8) = m1;386*(htab_p - 7) = m1;387*(htab_p - 6) = m1;388*(htab_p - 5) = m1;389*(htab_p - 4) = m1;390*(htab_p - 3) = m1;391*(htab_p - 2) = m1;392*(htab_p - 1) = m1;393htab_p -= 16;394} while ((i -= 16) >= 0);395for (i += 16; i > 0; i--)396*--htab_p = m1;397}398399static int400cl_block(State_t* zs, Sfio_t* f, Sfdisc_t* dp)/* Table clear for block compress. */401{402register long rat;403404checkpoint = in_count + CHECK_GAP;405406if (sync_out == bytes_out)407return(0);408if (in_count > 0x007fffff) { /* Shift will overflow. */409rat = bytes_out >> 8;410if (rat == 0) /* Don't divide by zero. */411rat = 0x7fffffff;412else413rat = in_count / rat;414} else415rat = (in_count << 8) / bytes_out; /* 8 fractional bits. */416if (rat > ratio)417ratio = rat;418else {419ratio = 0;420cl_hash(zs, (count_int) hsize);421free_ent = FIRST;422clear_flg = 1;423if (output(zs, f, (code_int) CLEAR, dp) == -1)424return (-1);425}426sync_out = bytes_out;427return (0);428}429430static int431lzw_ident(Codexmeth_t* meth, const void* head, size_t headsize, char* name, size_t namesize)432{433unsigned char* h = (unsigned char*)head;434435if (headsize >= 3 && h[0] == MAGIC1 && h[1] == MAGIC2)436{437strncopy(name, meth->name, namesize);438return 1;439}440return 0;441}442443static int444lzw_open(Codex_t* p, char* const args[], Codexnum_t flags)445{446register State_t* zs;447const char* s;448char* e;449450if (!(zs = newof(0, State_t, 1, 0)))451{452if (p->disc->errorf)453(*p->disc->errorf)(NiL, p->disc, 2, "out of space");454return -1;455}456if (!(s = args[2]))457maxbits = BITS;458else if ((maxbits = strton(s, &e, NiL, 0)) < MINBITS || maxbits > MAXBITS || *e)459{460if (p->disc->errorf)461(*p->disc->errorf)(NiL, p->disc, 2, "%s: maximum bits per code must be in [%d..%d]", s, MINBITS, MAXBITS);462return -1;463}464zs->codex = p;465p->data = zs;466return 0;467}468469static int470lzw_init(Codex_t* p)471{472register State_t* zs = (State_t*)p->data;473u_char header[HEADER];474475hsize = HSIZE; /* For dynamic table sizing. */476block_compress = BLOCK_MASK;477clear_flg = 0;478ratio = 0;479checkpoint = CHECK_GAP;480in_count = 1; /* Length of input. */481roffset = 0;482state = S_START;483size = 0;484if (p->flags & CODEX_ENCODE)485{486header[0] = MAGIC1;487header[1] = MAGIC2;488header[2] = ((maxbits) | block_compress) & 0xff;489if (sfwr(p->sp, header, sizeof(header), &p->sfdisc) != sizeof(header))490return -1;491offset = 0;492sync_out = 0;493bytes_out = sizeof(header);494out_count = 0; /* # of codes output (for debugging). */495hshift = 0;496for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L)497hshift++;498hshift = 8 - hshift; /* Set hash code range bound. */499hsize_reg = hsize;500cl_hash(zs, (count_int)hsize_reg); /* Clear hash table. */501}502else503{504/* Check the magic number */505if (sfrd(p->sp, header, sizeof(header), &p->sfdisc) != sizeof(header) ||506header[0] != MAGIC1 || header[1] != MAGIC2)507return (-1);508maxbits = header[2]; /* Set -b from file. */509block_compress = maxbits & BLOCK_MASK;510maxbits &= BIT_MASK;511if (maxbits > BITS)512return (-1);513/* As above, initialize the first 256 entries in the table. */514for (code = 255; code >= 0; code--) {515tab_prefixof(code) = 0;516tab_suffixof(code) = (char_type) code;517}518}519maxcode = MAXCODE(n_bits = INIT_BITS);520maxmaxcode = 1L << maxbits;521free_ent = block_compress ? FIRST : 256;522return 0;523}524525/*526* lzw sync (table flush)527*/528529int530lzw_sync(Codex_t* p)531{532register State_t* zs = (State_t*)p->data;533534if ((zs->codex->flags & CODEX_ENCODE) && cl_block(zs, p->sp, &p->sfdisc))535return -1;536return 0;537}538539/*540* lzw done541*/542543int544lzw_done(Codex_t* p)545{546register State_t* zs = (State_t*)p->data;547548if (zs->codex->flags & CODEX_ENCODE)549{550if (output(zs, p->sp, (code_int)ent, &p->sfdisc))551return -1;552out_count++;553if (output(zs, p->sp, (code_int)-1, &p->sfdisc))554return -1;555}556return 0;557}558559/*560* Decompress read. This routine adapts to the codes in the file building561* the "string" table on-the-fly; requiring no table to be stored in the562* compressed file. The tables used herein are shared with those of the563* compress() routine. See the definitions above.564*/565static ssize_t566lzw_read(Sfio_t* f, Void_t* rbp, size_t num, Sfdisc_t* dp)567{568State_t *zs = (State_t*)CODEX(dp)->data;569register u_int count;570u_char *bp;571572if (num == 0)573return (0);574575count = num;576bp = (u_char *)rbp;577switch (state) {578case S_START:579state = S_MIDDLE;580break;581case S_MIDDLE:582goto middle;583case S_EOF:584goto eof;585}586587588finchar = oldcode = getcode(zs, f, dp);589if (oldcode == -1) /* EOF already? */590return (0); /* Get out of here */591592/* First code must be 8 bits = char. */593*bp++ = (u_char)finchar;594count--;595stackp = de_stack;596597while ((code = getcode(zs, f, dp)) > -1) {598599if ((code == CLEAR) && block_compress) {600for (code = 255; code >= 0; code--)601tab_prefixof(code) = 0;602clear_flg = 1;603free_ent = FIRST - 1;604if ((code = getcode(zs, f, dp)) == -1) /* O, untimely death! */605break;606}607incode = code;608609/* Special case for KwKwK string. */610if (code >= free_ent) {611*stackp++ = finchar;612code = oldcode;613}614615/* Generate output characters in reverse order. */616while (code >= 256) {617*stackp++ = tab_suffixof(code);618code = tab_prefixof(code);619}620*stackp++ = finchar = tab_suffixof(code);621622/* And put them out in forward order. */623middle: do {624if (count-- == 0)625return (num);626*bp++ = *--stackp;627} while (stackp > de_stack);628629/* Generate the new entry. */630if ((code = free_ent) < maxmaxcode) {631tab_prefixof(code) = (u_short) oldcode;632tab_suffixof(code) = finchar;633free_ent = code + 1;634}635636/* Remember previous code. */637oldcode = incode;638}639state = S_EOF;640eof: return (num - count);641}642643/*-644* compress write645*646* Algorithm: use open addressing double hashing (no chaining) on the647* prefix code / next character combination. We do a variant of Knuth's648* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime649* secondary probe. Here, the modular division first probe is gives way650* to a faster exclusive-or manipulation. Also do block compression with651* an adaptive reset, whereby the code table is cleared when the compression652* ratio decreases, but after the table fills. The variable-length output653* codes are re-sized at this point, and a special CLEAR code is generated654* for the decompressor. Late addition: construct the table according to655* file size for noticeable speed improvement on small files. Please direct656* questions about this implementation to ames!jaw.657*/658659static ssize_t660lzw_write(Sfio_t* f, const Void_t* wbp, size_t num, Sfdisc_t* dp)661{662State_t *zs = (State_t*)CODEX(dp)->data;663register code_int i;664register int c, disp;665const u_char *bp;666int count;667668if (num == 0)669return (0);670671count = num;672bp = (u_char *)wbp;673if (state == S_START)674{675state = S_MIDDLE;676ent = *bp++;677count--;678}679for (i = 0; count--;) {680c = *bp++;681in_count++;682fcode = (long)(((long)c << maxbits) + ent);683i = ((c << hshift) ^ ent); /* Xor hashing. */684685if (htabof(i) == fcode) {686ent = codetabof(i);687continue;688} else if ((long)htabof(i) < 0) /* Empty slot. */689goto nomatch;690disp = hsize_reg - i; /* Secondary hash (after G. Knott). */691if (i == 0)692disp = 1;693probe: if ((i -= disp) < 0)694i += hsize_reg;695696if (htabof(i) == fcode) {697ent = codetabof(i);698continue;699}700if ((long)htabof(i) >= 0)701goto probe;702nomatch: if (output(zs, f, (code_int) ent, dp) == -1)703return (-1);704out_count++;705ent = c;706if (free_ent < maxmaxcode) {707codetabof(i) = free_ent++; /* code -> hashtable */708htabof(i) = fcode;709} else if ((count_int)in_count >=710checkpoint && block_compress) {711if (cl_block(zs, f, dp) == -1)712return (-1);713}714}715return (num);716}717718Codexmeth_t codex_compress =719{720"compress",721"compress LZW compression. The first parameter is the maximum number"722" of bits per code { 9 - 16 }. The default is 16.",7230,724CODEX_DECODE|CODEX_ENCODE|CODEX_COMPRESS,7250,726lzw_ident,727lzw_open,7280,729lzw_init,730lzw_done,731lzw_read,732lzw_write,733lzw_sync,7340,7350,7360,7370,738CODEXNEXT(compress)739};740741CODEXLIB(compress)742743744