/*
 *                            N E X T C O D E . C
 *
 *  Module to read codes from input file in EXPAND.  EXPAND is a file
 *  maintenance utility to decompress files.  It is compatible with the
 *  public domain COMPRESS v4.0 by Spencer W. Thomas, et al.
 *
 *-----------------------------------------------------------------------
 *  Author: Lyle V. Rains
 *      Based on the sources of COMPRESS.C v4.0 by Spencer Thomas, et al.
 *-----------------------------------------------------------------------
 *  Revision History:
 */

#define NEXTCODE
#include "nextcode.h" 


int nextcode(in, codeptr, bits, highcode)
  FILE *in;
  CODE * CONST codeptr;
  CONST int bits;
  CONST CODE highcode;
/* Get the next code from input and put it in *codeptr.
 * Return (YES) on success, or return (NO) on end-of-file.
 */
{
  static int prevbits = 0;
  register CODE code;
  static int offset, size;
  static UCHAR inbuf[MAXMAXBITS];
  register int shift;
  UCHAR *bp;

  /* If the next entry is a different bit-size than the preceeding one
   * then we must adjust the size and scrap the old buffer.
   */
  if (prevbits != bits) {
    prevbits = bits;
    size = 0;
  }
  /* If we can't read another code from the buffer, then refill it.
   */
  if (size - (shift = offset) < bits) {
    /* Read more input and convert size from # of bytes to # of bits */
    if ((size = fread(inbuf, 1, bits, in) << 3) <= 0 || ferror(in))
      return (NO);
    offset = shift = 0;
  }
  /* Get to the first byte. */
  bp = inbuf + (shift >> 3);
  /* Get first part (low order bits) */
  code = (*bp++ >> (shift &= 7));
  /* high order bits. */
  code |= *bp++ << (shift = 8 - shift);
  if ((shift += 8) < bits) code |= *bp << shift;
  *codeptr = code & highcode;
  offset += bits;
  return (YES);
}
