#include #include "modern.h" #include "stdinc.h" #include "zalloc.h" #include "zipdefs.h" #include "zipguts.h" #include "zippipe.h" void (*ziputbyte)__ARGS__((int)) = NULL; static unsigned bitbuff; static int boffset; #ifdef DEBUG ulg bits_sent; /* bit length of the compressed data */ #endif void bi_init() /* Initialize the bit string routines. */ { bitbuff = 0; boffset = 0; #ifdef DEBUG bits_sent = 0L; #endif } void send_bits(value, length) /* Send a value on a given number of bits. */ unsigned value; /* value to send */ int length; /* number of bits: length =< 16 */ { #ifdef DEBUG Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); Assert(boffset < 8, "bad offset"); bits_sent += (ulg)length; #endif bitbuff |= value << boffset; if ((boffset += length) >= 8) { putbyte(bitbuff); value >>= length - (boffset -= 8); if (boffset >= 8) { boffset -= 8; putbyte(value); value >>= 8; } bitbuff = value; } } /* Write out any remaining bits in an incomplete byte. */ void bi_windup() { Assert(boffset < 8, "bad offset"); if (boffset) { putbyte(bitbuff); boffset = 0; bitbuff = 0; #ifdef DEBUG bits_sent = (bits_sent+7) & ~7; #endif } } void bi_putsh(x) ush x; { putbyte(x & 255); putbyte((x>>8) & 255); } /* Copy a stored block to the zip file, storing first the length and its one's complement if requested. */ void copy_block(buf, len, header) char far *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { /* align on byte boundary */ bi_windup(); if (header) { bi_putsh(len); bi_putsh(~len); #ifdef DEBUG bits_sent += 2*16; #endif } while (len--) putbyte(*buf++); #ifdef DEBUG bits_sent += (ulg)len<<3; #endif }