home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / ZIP10X.ZIP / ZIP10EX.ZOO / im_bits.c < prev    next >
C/C++ Source or Header  |  1991-10-03  |  5KB  |  185 lines

  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.  *  im_bits.c by Richard B. Wales & Jean-loup Gailly.
  13.  *
  14.  *  PURPOSE
  15.  *
  16.  *      Output variable-length bit strings.
  17.  *
  18.  *  DISCUSSION
  19.  *
  20.  *      The PKZIP "imploded" file format interprets compressed file data
  21.  *      as a sequence of bits.  Multi-bit strings in the file may cross
  22.  *      byte boundaries without restriction.
  23.  *
  24.  *      The first bit of each byte is the low-order bit.
  25.  *
  26.  *      The routines in this file allow a variable-length bit value to
  27.  *      be output right-to-left (useful for literal values). For
  28.  *      left-to-right output (useful for code strings from the tree routines),
  29.  *      the bits must have been reversed first with bi_reverse().
  30.  *
  31.  *  INTERFACE
  32.  *
  33.  *      ImpErr bi_init (FILE *fp)
  34.  *          Initialize the bit string routines and specify the output
  35.  *          file to be written to in subsequent calls.
  36.  *
  37.  *      ImpErr bi_rlout (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.  *      ImpErr bi_windup (void)
  46.  *          Write out any remaining bits in an incomplete byte.
  47.  */
  48.  
  49.  
  50. #include "implode.h"
  51.  
  52.  
  53. /***********************************************************************
  54.  *
  55.  * Local data used by the "bit string" routines.
  56.  */
  57.  
  58.  
  59. /* Current file stream pointer. */
  60. local   FILE *  bi_fp;
  61.  
  62. local unsigned short bi_buf;
  63. /* Output buffer. bits are inserted starting at the bottom (least significant
  64.  * bits).
  65.  */
  66.  
  67. #define Buf_size (8 * 2*sizeof(char))
  68. /* Number of bits used within bi_buf. (bi_buf might be implemented on
  69.  * more than 16 bits on some systems.)
  70.  */
  71.  
  72. local int bi_valid;                  /* number of valid bits in bi_buf */
  73. /* All bits above the last valid bit are always zero.
  74.  */
  75.  
  76. /* Output a 16 bit value to the bit stream, lower (oldest) byte first */
  77. #define PUTSHORT(w) \
  78. {  (void) zputc ((char)((w) & 0xff), bi_fp); \
  79.    (void) zputc ((char)((US_INT)(w) >> 8), bi_fp); \
  80.    if (ferror (bi_fp)) return IM_IOERR; \
  81. }
  82.  
  83. /* Output an 8 bit value to the bit stream, bits right to left */
  84. #define PUTBYTE(w) \
  85. {  (void) zputc ((char)((w) & 0xff), bi_fp); \
  86.    if (ferror (bi_fp)) return IM_IOERR; \
  87. }
  88.  
  89. /***********************************************************************
  90.  *
  91.  * Initialize the bit string routines.
  92.  */
  93.  
  94. ImpErr
  95. bi_init (fp)
  96.     FILE *fp;
  97. {   if (fp == NULL)
  98.     {   fprintf (stderr, "\nError in bi_init: null file pointer");
  99.         return IM_LOGICERR;
  100.     }
  101.     bi_fp   = fp;
  102.     bi_buf = 0;
  103.     bi_valid = 0;
  104.     return IM_OK;
  105. }
  106.  
  107.  
  108. /***********************************************************************
  109.  *
  110.  * Output bits from right to left.
  111.  */
  112.  
  113. ImpErr
  114. bi_rlout (value, length)
  115.     int value;
  116.     int length; /* must be <= 16 */
  117. {
  118.     /* Send value on length bits. If not enough room in bi_buf, use
  119.      * (valid) bits from bi_buf and (16 - bi_valid) bits from value, leaving
  120.      * (width - (16-bi_valid)) unused bits in value.
  121.      */
  122.     if (bi_valid > Buf_size - length) {
  123.         bi_buf |= (value << bi_valid);
  124.         PUTSHORT(bi_buf);
  125.         bi_buf = (unsigned short)value >> (Buf_size - bi_valid);
  126.         bi_valid += length - Buf_size;
  127.     } else {
  128.         bi_buf |= value << bi_valid;
  129.         bi_valid += length;
  130.     }
  131. #ifdef  IMPDEBUG
  132.     fprintf (stderr, " / ");
  133.     while (length-- > 0)
  134.     {
  135.         putc ((value & 1) ? '1' : '0', stderr);
  136.         value >>= 1;
  137.     }
  138. #endif  /* IMPDEBUG */
  139.     return IM_OK;
  140. }
  141.  
  142.  
  143. /***********************************************************************
  144.  *
  145.  * Reverse the bits of a bit string, taking the source bits left to
  146.  * right (starting at 2^15) and emitting them right to left.
  147.  */
  148.  
  149. int
  150. bi_reverse (value, length)
  151.     int value;
  152.     int length;
  153. {
  154.     int result = 0;
  155.     unsigned short lbit = 0x8000;
  156.     unsigned short rbit = 1;
  157.     while (length-- > 0) {
  158.        if (value & lbit) result |= rbit;
  159.        lbit >>= 1, rbit <<= 1;
  160.     }
  161.     return result;
  162. }
  163.  
  164.  
  165. /***********************************************************************
  166.  *
  167.  * Flush any remaining bits.
  168.  */
  169.  
  170. ImpErr
  171. bi_windup ()
  172. {
  173.     if (bi_valid > 8) {
  174.         PUTSHORT(bi_buf);
  175.     } else if (bi_valid > 0) {
  176.         PUTBYTE(bi_buf);
  177.     }
  178.     bi_buf = 0;
  179.     bi_valid = 0;
  180.     return IM_OK;
  181. }
  182.  
  183.  
  184. /**********************************************************************/
  185.