|
|
1.1.1.4 ! root 1: /* ! 2: ! 3: Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly. ! 4: Permission is granted to any individual or institution to use, copy, or ! 5: redistribute this software so long as all of the original files are included ! 6: unmodified, that it is not sold for profit, and that this copyright notice ! 7: is retained. ! 8: ! 9: */ ! 10: ! 11: /* ! 12: * bits.c by Jean-loup Gailly. ! 13: * ! 14: * This is a new version of im_bits.c originally written by Richard B. Wales ! 15: * ! 16: * PURPOSE ! 17: * ! 18: * Output variable-length bit strings. ! 19: * ! 20: * DISCUSSION ! 21: * ! 22: * The PKZIP "deflate" file format interprets compressed file data ! 23: * as a sequence of bits. Multi-bit strings in the file may cross ! 24: * byte boundaries without restriction. ! 25: * ! 26: * The first bit of each byte is the low-order bit. ! 27: * ! 28: * The routines in this file allow a variable-length bit value to ! 29: * be output right-to-left (useful for literal values). For ! 30: * left-to-right output (useful for code strings from the tree routines), ! 31: * the bits must have been reversed first with bi_reverse(). ! 32: * ! 33: * INTERFACE ! 34: * ! 35: * void bi_init (FILE *zipfile) ! 36: * Initialize the bit string routines. ! 37: * ! 38: * void send_bits (int value, int length) ! 39: * Write out a bit string, taking the source bits right to ! 40: * left. ! 41: * ! 42: * int bi_reverse (int value, int length) ! 43: * Reverse the bits of a bit string, taking the source bits left to ! 44: * right and emitting them right to left. ! 45: * ! 46: * void bi_windup (void) ! 47: * Write out any remaining bits in an incomplete byte. ! 48: * ! 49: * void copy_block(char far *buf, unsigned len, int header) ! 50: * Copy a stored block to the zip file, storing first the length and ! 51: * its one's complement if requested. ! 52: * ! 53: */ ! 54: ! 55: #include "zip.h" ! 56: ! 57: /* =========================================================================== ! 58: * Local data used by the "bit string" routines. ! 59: */ ! 60: ! 61: local FILE *zfile; /* output zip file */ ! 62: ! 63: local unsigned short bi_buf; ! 64: /* Output buffer. bits are inserted starting at the bottom (least significant ! 65: * bits). ! 66: */ ! 67: ! 68: #define Buf_size (8 * 2*sizeof(char)) ! 69: /* Number of bits used within bi_buf. (bi_buf might be implemented on ! 70: * more than 16 bits on some systems.) ! 71: */ ! 72: ! 73: local int bi_valid; /* number of valid bits in bi_buf */ ! 74: /* All bits above the last valid bit are always zero. ! 75: */ ! 76: ! 77: #ifdef DEBUG ! 78: ulg bits_sent; /* bit length of the compressed data */ ! 79: #endif ! 80: ! 81: /* Output a 16 bit value to the bit stream, lower (oldest) byte first */ ! 82: #define PUTSHORT(w) \ ! 83: { (void) zputc ((char)((w) & 0xff), zfile); \ ! 84: (void) zputc ((char)((ush)(w) >> 8), zfile); \ ! 85: } ! 86: ! 87: /* Output an 8 bit value to the bit stream, bits right to left */ ! 88: #define PUTBYTE(w) \ ! 89: { (void) zputc ((char)((w) & 0xff), zfile); \ ! 90: } ! 91: ! 92: /* =========================================================================== ! 93: * Initialize the bit string routines. ! 94: */ ! 95: void bi_init (zipfile) ! 96: ! 97: FILE *zipfile; /* output zip file */ ! 98: { ! 99: zfile = zipfile; ! 100: bi_buf = 0; ! 101: bi_valid = 0; ! 102: #ifdef DEBUG ! 103: bits_sent = 0L; ! 104: #endif ! 105: } ! 106: ! 107: /* =========================================================================== ! 108: * Send a value on a given number of bits. ! 109: * IN assertion: length <= 16 and value fits in length bits. ! 110: */ ! 111: void send_bits(value, length) ! 112: int value; /* value to send */ ! 113: int length; /* number of bits */ ! 114: { ! 115: #ifdef DEBUG ! 116: Tracevv((stderr," l %2d v %4x ", length, value)); ! 117: Assert(length > 0 && length <= 15, "invalid length"); ! 118: bits_sent += (ulg)length; ! 119: #endif ! 120: /* If not enough room in bi_buf, use (valid) bits from bi_buf and ! 121: * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) ! 122: * unused bits in value. ! 123: */ ! 124: if (bi_valid > (int)Buf_size - length) { ! 125: bi_buf |= (value << bi_valid); ! 126: PUTSHORT(bi_buf); ! 127: bi_buf = (ush)value >> (Buf_size - bi_valid); ! 128: bi_valid += length - Buf_size; ! 129: } else { ! 130: bi_buf |= value << bi_valid; ! 131: bi_valid += length; ! 132: } ! 133: } ! 134: ! 135: /* =========================================================================== ! 136: * Reverse the first len bits of a code, using straightforward code (a faster ! 137: * method would use a table) ! 138: * IN assertion: 1 <= len <= 15 ! 139: */ ! 140: unsigned bi_reverse(code, len) ! 141: unsigned code; /* the value to invert */ ! 142: int len; /* its bit length */ ! 143: { ! 144: register unsigned res = 0; ! 145: do { ! 146: res |= code & 1; ! 147: code >>= 1, res <<= 1; ! 148: } while (--len > 0); ! 149: return res >> 1; ! 150: } ! 151: ! 152: /* =========================================================================== ! 153: * Write out any remaining bits in an incomplete byte. ! 154: */ ! 155: void bi_windup() ! 156: { ! 157: if (bi_valid > 8) { ! 158: PUTSHORT(bi_buf); ! 159: } else if (bi_valid > 0) { ! 160: PUTBYTE(bi_buf); ! 161: } ! 162: bi_buf = 0; ! 163: bi_valid = 0; ! 164: if (ferror (zfile)) error ("write error on zip file"); ! 165: #ifdef DEBUG ! 166: bits_sent = (bits_sent+7) & ~7; ! 167: #endif ! 168: } ! 169: ! 170: /* =========================================================================== ! 171: * Copy a stored block to the zip file, storing first the length and its ! 172: * one's complement if requested. ! 173: */ ! 174: void copy_block(buf, len, header) ! 175: char far *buf; /* the input data */ ! 176: unsigned len; /* its length */ ! 177: int header; /* true if block header must be written */ ! 178: { ! 179: bi_windup(); /* align on byte boundary */ ! 180: ! 181: if (header) { ! 182: PUTSHORT((ush)len); ! 183: PUTSHORT((ush)~len); ! 184: #ifdef DEBUG ! 185: bits_sent += 2*16; ! 186: #endif ! 187: } ! 188: zfwrite(buf, 1, len, zfile); /* ??? far */ ! 189: #ifdef DEBUG ! 190: bits_sent += (ulg)len<<3; ! 191: #endif ! 192: fflush(zfile); ! 193: if (ferror(zfile)) error ("write error on zip file"); ! 194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.