#include <stdio.h>
#include <malloc.h>
 
#include "CMP_CPA.h"
#include "ErmCmp.h"
#include "CMP_File.h"
 
/**************************************************************************/
 
/*#define PACIFIER*/
#define PACIFIER_COUNT 2047
 
/**************************************************************************/
tdstBitFile *CMP_fn_p_stOpenOutputBitFile( char *name )
{
 tdstBitFile *bit_file=NULL;
 FILE *file=NULL;
 
 if ((file = fopen( name, "wb" ))!=NULL)
 {
  bit_file = (tdstBitFile *) calloc( 1, sizeof( tdstBitFile ) );
  if ( bit_file == NULL ) 
   return( bit_file );
  bit_file->file = file;
  bit_file->rack = 0;
  bit_file->mask = 0x80;
  bit_file->pacifier_counter = 0;
 }
 return( bit_file );
}
/**************************************************************************/
tdstBitFile *CMP_fn_p_stOpenInputBitFile( char *name )
{
 tdstBitFile *bit_file=NULL;
 FILE *file=NULL;
 
 if ((file = fopen( name, "rb" ))!=NULL)
 {
  bit_file = (tdstBitFile *) calloc( 1, sizeof( tdstBitFile ) );
  if ( bit_file == NULL ) 
   return( bit_file );
  bit_file->file = file;
  bit_file->rack = 0;
  bit_file->mask = 0x80;
  bit_file->pacifier_counter = 0;
 }
 return( bit_file );
}
/**************************************************************************/
void CMP_fn_vCloseOutputBitFile( tdstBitFile *bit_file )
{
 if ( bit_file->mask != 0x80 )
	 if ( putc( bit_file->rack, bit_file->file ) != bit_file->rack )
   M_CMPFatalError(E_uwCMPCloseFileError);
 fclose( bit_file->file );
 free( (char *) bit_file );
}
/**************************************************************************/
void CMP_fn_vCloseInputBitFile( tdstBitFile *bit_file )
{
 fclose( bit_file->file );
 free( (char *) bit_file );
}
/**************************************************************************/
void CMP_fn_vOutputBit( tdstBitFile *bit_file , int bit )
{
 if ( bit )
  bit_file->rack |= bit_file->mask;
 bit_file->mask >>= 1;
 if ( bit_file->mask == 0 )
 {
  if ( putc( bit_file->rack, bit_file->file ) != bit_file->rack ) 
   M_CMPFatalError(E_uwCMPOutputBitError);
  #ifdef PACIFIER
  else if ( ( bit_file->pacifier_counter++ & PACIFIER_COUNT ) == 0 ) 
   putc( '.', stdout );
  #endif /* PACIFIER */
  bit_file->rack = 0;
  bit_file->mask = 0x80;
 }
}
/**************************************************************************/
void CMP_fn_vOutputBits( tdstBitFile *bit_file , unsigned long code , int count )
{
 unsigned long mask;
 
 mask = 1L << ( count - 1 );
 while ( mask != 0)
 {
  if ( mask & code ) 
   bit_file->rack |= bit_file->mask;
  bit_file->mask >>= 1;
  if ( bit_file->mask == 0 )
  {
  	if ( putc( bit_file->rack, bit_file->file ) != bit_file->rack ) 
    M_CMPFatalError(E_uwCMPOutputBitsError);
   #ifdef PACIFIER
	  else if ( ( bit_file->pacifier_counter++ & PACIFIER_COUNT ) == 0 ) 
    putc( '.', stdout );
   #endif
	  bit_file->rack = 0;
	  bit_file->mask = 0x80;
  }
  mask >>= 1;
 }
}
/**************************************************************************/
long CMP_fn_lInputBit( tdstBitFile *bit_file )
{
 long value;
 
 if ( bit_file->mask == 0x80 )
 {
  bit_file->rack = getc( bit_file->file );
  if ( bit_file->rack == EOF )
   M_CMPFatalError(E_uwCMPInputBitError);
  #ifdef PACIFIER
  if ( ( bit_file->pacifier_counter++ & PACIFIER_COUNT ) == 0 ) 
   putc( '.', stdout );
  #endif
 }
 value = bit_file->rack & bit_file->mask;
 bit_file->mask >>= 1;
 if ( bit_file->mask == 0 )
  bit_file->mask = 0x80;
 return( value ? 1 : 0 );
}
/**************************************************************************/
unsigned long CMP_fn_ulInputBits( tdstBitFile *bit_file , int bit_count )
{
 unsigned long mask;
 unsigned long return_value;
 
 mask = 1L << ( bit_count - 1 );
 return_value = 0;
 while ( mask != 0)
 {
  if ( bit_file->mask == 0x80 )
  {
  	bit_file->rack = getc( bit_file->file );
  	if ( bit_file->rack == EOF ) 
    M_CMPFatalError(E_uwCMPInputBitsError);
   #ifdef PACIFIER
	  if ( ( bit_file->pacifier_counter++ & PACIFIER_COUNT ) == 0 ) 
    putc( '.', stdout );
   #endif
  }
  if ( bit_file->rack & bit_file->mask ) 
   return_value |= mask;
  mask >>= 1;
  bit_file->mask >>= 1;
  if ( bit_file->mask == 0 ) bit_file->mask = 0x80;
 }
 return( return_value );
}
/**************************************************************************/
