/* BIT_IO.C - BIT INPUT/OUTPUT ROUTINES. */

#include <stdio.h>
#include "code.h"


/* THE BIT BUFFERS. */

static int outbuf;		/* Bits waiting to be output                */
static int outbits_left;	/* Number of bits that can still be put in  */

static int inbuf;		/* Bits waiting to be input                 */
static int inbits_left;		/* Number of bits still in input buffer     */
static int garbage;		/* Number of garbage bytes after EOF        */


/* INITIALIZE FOR BIT OUTPUT. */

void start_outputing_bits (void)
{
    outbuf = 0;					/* Buffer is empty to start */
    outbits_left = 8;				/* with.                    */
}


/* INITIALIZE FOR BIT INPUT. */

void start_inputing_bits (void)
{
    inbits_left = 0;				/* Buffer starts out with   */
    garbage = 0;				/* no bits in it.           */
}


/* OUTPUT A BIT. */

void output_bit 
(   int bit
)
{
    if (outbits_left==0) {			/* Output buffer if it is   */
        putc(outbuf,stdout);			/* full.                    */
        outbits_left = 8;
    }
    outbuf >>= 1;		 		/* Put bit in top of buffer.*/
    if (bit) outbuf |= 0x80;
    outbits_left -= 1;
}


/* INPUT A BIT. */

int input_bit (void)
{
    int t;

    if (inbits_left==0) {			/* Read next byte if no     */
        inbuf = getc(stdin);			/* bits left in the buffer. */
        inbits_left = 8;
        if (inbuf==EOF) {  			/* Return anything after    */
            if (garbage*8>=Code_bits) {		/* end-of-file, but not too */
                fprintf(stderr,"Bad input file (2)\n"); /* much of anything.*/
                exit(1);
            }
            garbage += 1;
        }
    }

    t = inbuf&1;				/* Return the next bit from */
    inbuf >>= 1;				/* the bottom of the byte.  */
    inbits_left -= 1;
    return t;	
}


/* FLUSH OUT THE LAST BITS. */

void done_outputing_bits (void)
{
    putc(outbuf>>outbits_left,stdout);
}

