/*
 * DMLib
 * -- Simple bitstream I/O functions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2012 Tecnic Software productions (TNSP)
 */
#include "dmbstr.h"


int dmInitBitStream(DMBitStream *ctx, FILE *fp)
{
    if (ctx == NULL || fp == NULL)
        return DMERR_NULLPTR;

    ctx->fp      = fp;
    ctx->buf     = 0;
    ctx->bytecnt = 0;
    ctx->bitcnt  = 8;

    return DMERR_OK;
}


BOOL dmPutBits(DMBitStream *ctx, const int val, const int n)
{
    int i;
    unsigned int mask = 1 << (n - 1);

    for (i = 0; i < n; i++)
    {
        ctx->buf <<= 1;

        if (val & mask)
          ctx->buf |= 1;

        mask >>= 1;
        ctx->bitcnt--;

        if (ctx->bitcnt == 0)
        {
            if (fputc((ctx->buf & 0xff), ctx->fp) == EOF)
                return FALSE;

            ctx->bitcnt = 8;
            ctx->bytecnt++;
        }
    }

    return TRUE;
}


int dmFlushBitStream(DMBitStream *ctx)
{
  if (ctx == NULL)
      return DMERR_NULLPTR;

  if (ctx->bitcnt != 8)
      dmPutBits(ctx, 0, ctx->bitcnt);
  
  return 0;
}
