home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip201.zip / bits.c < prev    next >
C/C++ Source or Header  |  1993-09-18  |  12KB  |  375 lines

  1. /*
  2.  
  3.  Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  4.  Kai Uwe Rommel and Igor Mandrichenko.
  5.  Permission is granted to any individual or institution to use, copy, or
  6.  redistribute this software so long as all of the original files are included,
  7.  that it is not sold for profit, and that this copyright notice is retained.
  8.  
  9. */
  10.  
  11. /*
  12.  *  bits.c by Jean-loup Gailly and Kai Uwe Rommel.
  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. Compression can be done
  19.  *      to a file or to memory.
  20.  *
  21.  *  DISCUSSION
  22.  *
  23.  *      The PKZIP "deflate" file format interprets compressed file data
  24.  *      as a sequence of bits.  Multi-bit strings in the file may cross
  25.  *      byte boundaries without restriction.
  26.  *
  27.  *      The first bit of each byte is the low-order bit.
  28.  *
  29.  *      The routines in this file allow a variable-length bit value to
  30.  *      be output right-to-left (useful for literal values). For
  31.  *      left-to-right output (useful for code strings from the tree routines),
  32.  *      the bits must have been reversed first with bi_reverse().
  33.  *
  34.  *      For in-memory compression, the compressed bit stream goes directly
  35.  *      into the requested output buffer. The input data is read in blocks
  36.  *      by the mem_read() function. The buffer is limited to 64K on 16 bit
  37.  *      machines.
  38.  *
  39.  *  INTERFACE
  40.  *
  41.  *      void bi_init (FILE *zipfile)
  42.  *          Initialize the bit string routines.
  43.  *
  44.  *      void send_bits (int value, int length)
  45.  *          Write out a bit string, taking the source bits right to
  46.  *          left.
  47.  *
  48.  *      int bi_reverse (int value, int length)
  49.  *          Reverse the bits of a bit string, taking the source bits left to
  50.  *          right and emitting them right to left.
  51.  *
  52.  *      void bi_windup (void)
  53.  *          Write out any remaining bits in an incomplete byte.
  54.  *
  55.  *      void copy_block(char far *buf, unsigned len, int header)
  56.  *          Copy a stored block to the zip file, storing first the length and
  57.  *          its one's complement if requested.
  58.  *
  59.  *      int seekable(void)
  60.  *          Return true if the zip file can be seeked.
  61.  *
  62.  *      ulg memcompress (char *tgt, ulg tgtsize, char *src, ulg srcsize);
  63.  *          Compress the source buffer src into the target buffer tgt.
  64.  */
  65.  
  66. #include "zip.h"
  67. #include "crypt.h"
  68.  
  69. extern ulg window_size; /* size of sliding window */
  70.  
  71. /* ===========================================================================
  72.  * Local data used by the "bit string" routines.
  73.  */
  74.  
  75. local FILE *zfile; /* output zip file */
  76.  
  77. local unsigned short bi_buf;
  78. /* Output buffer. bits are inserted starting at the bottom (least significant
  79.  * bits).
  80.  */
  81.  
  82. #define Buf_size (8 * 2*sizeof(char))
  83. /* Number of bits used within bi_buf. (bi_buf might be implemented on
  84.  * more than 16 bits on some systems.)
  85.  */
  86.  
  87. local int bi_valid;
  88. /* Number of valid bits in bi_buf.  All bits above the last valid bit
  89.  * are always zero.
  90.  */
  91.  
  92. char file_outbuf[1024];
  93. /* Output buffer for compression to file */
  94.  
  95. local char *in_buf, *out_buf;
  96. /* Current input and output buffers. in_buf is used only for in-memory
  97.  * compression.
  98.  */
  99.  
  100. local unsigned in_offset, out_offset;
  101. /* Current offset in input and output buffers. in_offset is used only for
  102.  * in-memory compression. On 16 bit machiens, the buffer is limited to 64K.
  103.  */
  104.  
  105. local unsigned in_size, out_size;
  106. /* Size of current input and output buffers */
  107.  
  108. int (*read_buf) OF((char *buf, unsigned size)) = file_read;
  109. /* Current input function. Set to mem_read for in-memory compression */
  110.  
  111. #ifdef DEBUG
  112. ulg bits_sent;   /* bit length of the compressed data */
  113. #endif
  114.  
  115. /* Output a 16 bit value to the bit stream, lower (oldest) byte first */
  116. #define PUTSHORT(w) \
  117. { if (out_offset < out_size-1) { \
  118.     out_buf[out_offset++] = (char) ((w) & 0xff); \
  119.     out_buf[out_offset++] = (char) ((ush)(w) >> 8); \
  120.   } else { \
  121.     flush_outbuf((w),2); \
  122.   } \
  123. }
  124.  
  125. #define PUTBYTE(b) \
  126. { if (out_offset < out_size) { \
  127.     out_buf[out_offset++] = (char) (b); \
  128.   } else { \
  129.     flush_outbuf((b),1); \
  130.   } \
  131. }
  132.  
  133.  
  134. /* ===========================================================================
  135.  *  Prototypes for local functions
  136.  */
  137. local int  mem_read     OF((char *b,    unsigned bsize));
  138. local void flush_outbuf OF((unsigned w, unsigned bytes));
  139.  
  140. /* ===========================================================================
  141.  * Initialize the bit string routines.
  142.  */
  143. void bi_init (zipfile)
  144.     FILE *zipfile;  /* output zip file, NULL for in-memory compression */
  145. {
  146.     zfile  = zipfile;
  147.     bi_buf = 0;
  148.     bi_valid = 0;
  149. #ifdef DEBUG
  150.     bits_sent = 0L;
  151. #endif
  152.  
  153.     /* Set the defaults for file compression. They are set by memcompress
  154.      * for in-memory compression.
  155.      */
  156.     if (zfile != NULL) {
  157.         out_buf = file_outbuf;
  158.         out_size = sizeof(file_outbuf);
  159.         out_offset = 0;
  160.         read_buf  = file_read;
  161.     }
  162. }
  163.  
  164. /* ===========================================================================
  165.  * Send a value on a given number of bits.
  166.  * IN assertion: length <= 16 and value fits in length bits.
  167.  */
  168. void send_bits(value, length)
  169.     int value;  /* value to send */
  170.     int length; /* number of bits */
  171. {
  172. #ifdef DEBUG
  173.     Tracevv((stderr," l %2d v %4x ", length, value));
  174.     Assert(length > 0 && length <= 15, "invalid length");
  175.     bits_sent += (ulg)length;
  176. #endif
  177.     /* If not enough room in bi_buf, use (valid) bits from bi_buf and
  178.      * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
  179.      * unused bits in value.
  180.      */
  181.     if (bi_valid > (int)Buf_size - length) {
  182.         bi_buf |= (value << bi_valid);
  183.         PUTSHORT(bi_buf);
  184.         bi_buf = (ush)value >> (Buf_size - bi_valid);
  185.         bi_valid += length - Buf_size;
  186.     } else {
  187.         bi_buf |= value << bi_valid;
  188.         bi_valid += length;
  189.     }
  190. }
  191.  
  192. /* ===========================================================================
  193.  * Reverse the first len bits of a code, using straightforward code (a faster
  194.  * method would use a table)
  195.  * IN assertion: 1 <= len <= 15
  196.  */
  197. unsigned bi_reverse(code, len)
  198.     unsigned code; /* the value to invert */
  199.     int len;       /* its bit length */
  200. {
  201.     register unsigned res = 0;
  202.     do {
  203.         res |= code & 1;
  204.         code >>= 1, res <<= 1;
  205.     } while (--len > 0);
  206.     return res >> 1;
  207. }
  208.  
  209. /* ===========================================================================
  210.  * Flush the current output buffer.
  211.  */
  212. local void flush_outbuf(w, bytes)
  213.     unsigned w;     /* value to flush */
  214.     unsigned bytes; /* number of bytes to flush (0, 1 or 2) */
  215. {
  216.     if (zfile == NULL) {
  217.         error("output buffer too small for in-memory compression");
  218.     }
  219.     /* Encrypt and write the output buffer: */
  220.     if (out_offset != 0) {
  221.         zfwrite(out_buf, 1, (extent)out_offset, zfile);
  222.         if (ferror(zfile)) error ("write error on zip file");
  223.     }
  224.     out_offset = 0;
  225.     if (bytes == 2) {
  226.         PUTSHORT(w);
  227.     } else if (bytes == 1) {
  228.         out_buf[out_offset++] = (char) (w & 0xff);
  229.     }
  230. }
  231.  
  232. /* ===========================================================================
  233.  * Write out any remaining bits in an incomplete byte.
  234.  */
  235. void bi_windup()
  236. {
  237.     if (bi_valid > 8) {
  238.         PUTSHORT(bi_buf);
  239.     } else if (bi_valid > 0) {
  240.         PUTBYTE(bi_buf);
  241.     }
  242.     if (zfile != NULL) {
  243.         flush_outbuf(0, 0);
  244.     }
  245.     bi_buf = 0;
  246.     bi_valid = 0;
  247. #ifdef DEBUG
  248.     bits_sent = (bits_sent+7) & ~7;
  249. #endif
  250. }
  251.  
  252. /* ===========================================================================
  253.  * Copy a stored block to the zip file, storing first the length and its
  254.  * one's complement if requested.
  255.  */
  256. void copy_block(buf, len, header)
  257.     char far *buf; /* the input data */
  258.     unsigned len;  /* its length */
  259.     int header;    /* true if block header must be written */
  260. {
  261.     bi_windup();              /* align on byte boundary */
  262.  
  263.     if (header) {
  264.         PUTSHORT((ush)len);   
  265.         PUTSHORT((ush)~len);
  266. #ifdef DEBUG
  267.         bits_sent += 2*16;
  268. #endif
  269.     }
  270.     if (zfile) {
  271.         flush_outbuf(0, 0);
  272.         zfwrite(buf, 1, len, zfile);
  273.         if (ferror(zfile)) error ("write error on zip file");
  274.     } else if (out_offset + len > out_size) {
  275.         error("output buffer too small for in-memory compression");
  276.     } else {
  277.         memcpy(out_buf + out_offset, buf, len);
  278.         out_offset += len;
  279.     }
  280. #ifdef DEBUG
  281.     bits_sent += (ulg)len<<3;
  282. #endif
  283. }
  284.  
  285.  
  286. /* ===========================================================================
  287.  * Return true if the zip file can be seeked. This is used to check if
  288.  * the local header can be re-rewritten. This function always returns
  289.  * true for in-memory compression.
  290.  * IN assertion: the local header has already been written (ftell() > 0).
  291.  */
  292. int seekable()
  293. {
  294.     return (zfile == NULL ||
  295.             (fseek(zfile, -1L, SEEK_CUR) == 0 &&
  296.              fseek(zfile,  1L, SEEK_CUR) == 0));
  297. }    
  298.  
  299. /* ===========================================================================
  300.  * In-memory compression. This version can be used only if the entire input
  301.  * fits in one memory buffer. The compression is then done in a single
  302.  * call of memcompress(). (An extension to allow repeated calls would be
  303.  * possible but is not needed here.)
  304.  * The first two bytes of the compressed output are set to a short with the
  305.  * method used (DEFLATE or STORE). The following four bytes contain the CRC.
  306.  * The values are stored in little-endian order on all machines.
  307.  * This function returns the byte size of the compressed output, including
  308.  * the first six bytes (method and crc).
  309.  */
  310.  
  311. ulg memcompress(tgt, tgtsize, src, srcsize)
  312.     char *tgt, *src;       /* target and source buffers */
  313.     ulg tgtsize, srcsize;  /* target and source sizes */
  314. {
  315.     ush att      = (ush)UNKNOWN;
  316.     ush flags    = 0;
  317.     ulg crc      = 0;
  318.     int method   = DEFLATE;
  319.  
  320.     if (tgtsize <= 6L) error("target buffer too small");
  321.  
  322.     crc = updcrc((char *)NULL, 0);
  323.     crc = updcrc(src, (extent) srcsize);
  324.  
  325.     read_buf  = mem_read;
  326.     in_buf    = src;
  327.     in_size   = (unsigned)srcsize;
  328.     in_offset = 0;
  329.  
  330.     out_buf    = tgt;
  331.     out_size   = (unsigned)tgtsize;
  332.     out_offset = 2 + 4;
  333.     window_size = 0L;
  334.  
  335.     bi_init((FILE *)NULL);
  336.     ct_init(&att, &method);
  337.     lm_init((level != 0 ? level : 1), &flags);
  338.     deflate();
  339.     window_size = 0L; /* was updated by lm_init() */
  340.  
  341.     /* For portability, force little-endian order on all machines: */
  342.     tgt[0] = (char)(method & 0xff);
  343.     tgt[1] = (char)((method >> 8) & 0xff);
  344.     tgt[2] = (char)(crc & 0xff);
  345.     tgt[3] = (char)((crc >> 8) & 0xff);
  346.     tgt[4] = (char)((crc >> 16) & 0xff);
  347.     tgt[5] = (char)((crc >> 24) & 0xff);
  348.  
  349.     return (ulg)out_offset;
  350. }
  351.  
  352. /* ===========================================================================
  353.  * In-memory read function. As opposed to file_read(), this function
  354.  * does not perform end-of-line translation, and does not update the
  355.  * crc and input size.
  356.  *    Note that the size of the entire input buffer is an unsigned long,
  357.  * but the size used in mem_read() is only an unsigned int. This makes a
  358.  * difference on 16 bit machines. mem_read() may be called several
  359.  * times for an in-memory compression.
  360.  */
  361. local int mem_read(b, bsize)
  362.      char *b;
  363.      unsigned bsize; 
  364. {
  365.     if (in_offset < in_size) {
  366.         ulg block_size = in_size - in_offset;
  367.         if (block_size > (ulg)bsize) block_size = (ulg)bsize;
  368.         memcpy(b, in_buf + in_offset, (unsigned)block_size);
  369.         in_offset += (unsigned)block_size;
  370.         return (int)block_size;
  371.     } else {
  372.         return 0; /* end of input */
  373.     }
  374. }
  375.