|
|
1.1 ! root 1: /* bits.c -- output variable-length bit strings ! 2: * Copyright (C) 1992-1993 Jean-loup Gailly ! 3: * This is free software; you can redistribute it and/or modify it under the ! 4: * terms of the GNU General Public License, see the file COPYING. ! 5: */ ! 6: ! 7: ! 8: /* ! 9: * PURPOSE ! 10: * ! 11: * Output variable-length bit strings. Compression can be done ! 12: * to a file or to memory. (The latter is not supported in this version.) ! 13: * ! 14: * DISCUSSION ! 15: * ! 16: * The PKZIP "deflate" file format interprets compressed file data ! 17: * as a sequence of bits. Multi-bit strings in the file may cross ! 18: * byte boundaries without restriction. ! 19: * ! 20: * The first bit of each byte is the low-order bit. ! 21: * ! 22: * The routines in this file allow a variable-length bit value to ! 23: * be output right-to-left (useful for literal values). For ! 24: * left-to-right output (useful for code strings from the tree routines), ! 25: * the bits must have been reversed first with bi_reverse(). ! 26: * ! 27: * For in-memory compression, the compressed bit stream goes directly ! 28: * into the requested output buffer. The input data is read in blocks ! 29: * by the mem_read() function. The buffer is limited to 64K on 16 bit ! 30: * machines. ! 31: * ! 32: * INTERFACE ! 33: * ! 34: * void bi_init (FILE *zipfile) ! 35: * Initialize the bit string routines. ! 36: * ! 37: * void send_bits (int value, int length) ! 38: * Write out a bit string, taking the source bits right to ! 39: * left. ! 40: * ! 41: * int bi_reverse (int value, int length) ! 42: * Reverse the bits of a bit string, taking the source bits left to ! 43: * right and emitting them right to left. ! 44: * ! 45: * void bi_windup (void) ! 46: * Write out any remaining bits in an incomplete byte. ! 47: * ! 48: * void copy_block(char *buf, unsigned len, int header) ! 49: * Copy a stored block to the zip file, storing first the length and ! 50: * its one's complement if requested. ! 51: * ! 52: */ ! 53: ! 54: #include "tailor.h" ! 55: #include "gzip.h" ! 56: #include "crypt.h" ! 57: ! 58: #ifdef DEBUG ! 59: # include <stdio.h> ! 60: #endif ! 61: ! 62: #ifndef lint ! 63: static char rcsid[] = "$Id: bits.c,v 0.8 1993/02/04 13:21:06 jloup Exp $"; ! 64: #endif ! 65: ! 66: /* =========================================================================== ! 67: * Local data used by the "bit string" routines. ! 68: */ ! 69: ! 70: local file_t zfile; /* output gzip file */ ! 71: ! 72: local unsigned short bi_buf; ! 73: /* Output buffer. bits are inserted starting at the bottom (least significant ! 74: * bits). ! 75: */ ! 76: ! 77: #define Buf_size (8 * 2*sizeof(char)) ! 78: /* Number of bits used within bi_buf. (bi_buf might be implemented on ! 79: * more than 16 bits on some systems.) ! 80: */ ! 81: ! 82: local int bi_valid; ! 83: /* Number of valid bits in bi_buf. All bits above the last valid bit ! 84: * are always zero. ! 85: */ ! 86: ! 87: int (*read_buf) OF((char *buf, unsigned size)) = file_read; ! 88: /* Current input function. Set to mem_read for in-memory compression */ ! 89: ! 90: #ifdef DEBUG ! 91: ulg bits_sent; /* bit length of the compressed data */ ! 92: #endif ! 93: ! 94: /* =========================================================================== ! 95: * Initialize the bit string routines. ! 96: */ ! 97: void bi_init (zipfile) ! 98: file_t zipfile; /* output zip file, NO_FILE for in-memory compression */ ! 99: { ! 100: zfile = zipfile; ! 101: bi_buf = 0; ! 102: bi_valid = 0; ! 103: #ifdef DEBUG ! 104: bits_sent = 0L; ! 105: #endif ! 106: ! 107: /* Set the defaults for file compression. They are set by memcompress ! 108: * for in-memory compression. ! 109: */ ! 110: if (zfile != NO_FILE) { ! 111: read_buf = file_read; ! 112: } ! 113: } ! 114: ! 115: /* =========================================================================== ! 116: * Send a value on a given number of bits. ! 117: * IN assertion: length <= 16 and value fits in length bits. ! 118: */ ! 119: void send_bits(value, length) ! 120: int value; /* value to send */ ! 121: int length; /* number of bits */ ! 122: { ! 123: #ifdef DEBUG ! 124: Tracev((stderr," l %2d v %4x ", length, value)); ! 125: Assert(length > 0 && length <= 15, "invalid length"); ! 126: bits_sent += (ulg)length; ! 127: #endif ! 128: /* If not enough room in bi_buf, use (valid) bits from bi_buf and ! 129: * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) ! 130: * unused bits in value. ! 131: */ ! 132: if (bi_valid > (int)Buf_size - length) { ! 133: bi_buf |= (value << bi_valid); ! 134: put_short(bi_buf); ! 135: bi_buf = (ush)value >> (Buf_size - bi_valid); ! 136: bi_valid += length - Buf_size; ! 137: } else { ! 138: bi_buf |= value << bi_valid; ! 139: bi_valid += length; ! 140: } ! 141: } ! 142: ! 143: /* =========================================================================== ! 144: * Reverse the first len bits of a code, using straightforward code (a faster ! 145: * method would use a table) ! 146: * IN assertion: 1 <= len <= 15 ! 147: */ ! 148: unsigned bi_reverse(code, len) ! 149: unsigned code; /* the value to invert */ ! 150: int len; /* its bit length */ ! 151: { ! 152: register unsigned res = 0; ! 153: do { ! 154: res |= code & 1; ! 155: code >>= 1, res <<= 1; ! 156: } while (--len > 0); ! 157: return res >> 1; ! 158: } ! 159: ! 160: /* =========================================================================== ! 161: * Write out any remaining bits in an incomplete byte. ! 162: */ ! 163: void bi_windup() ! 164: { ! 165: if (bi_valid > 8) { ! 166: put_short(bi_buf); ! 167: } else if (bi_valid > 0) { ! 168: put_byte(bi_buf); ! 169: } ! 170: bi_buf = 0; ! 171: bi_valid = 0; ! 172: #ifdef DEBUG ! 173: bits_sent = (bits_sent+7) & ~7; ! 174: #endif ! 175: } ! 176: ! 177: /* =========================================================================== ! 178: * Copy a stored block to the zip file, storing first the length and its ! 179: * one's complement if requested. ! 180: */ ! 181: void copy_block(buf, len, header) ! 182: char *buf; /* the input data */ ! 183: unsigned len; /* its length */ ! 184: int header; /* true if block header must be written */ ! 185: { ! 186: bi_windup(); /* align on byte boundary */ ! 187: ! 188: if (header) { ! 189: put_short((ush)len); ! 190: put_short((ush)~len); ! 191: #ifdef DEBUG ! 192: bits_sent += 2*16; ! 193: #endif ! 194: } ! 195: #ifdef DEBUG ! 196: bits_sent += (ulg)len<<3; ! 197: #endif ! 198: while (len--) { ! 199: #ifdef CRYPT ! 200: int t; ! 201: if (key) zencode(*buf, t); ! 202: #endif ! 203: put_byte(*buf++); ! 204: } ! 205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.