You are here: Home Software src Main unit sensors rice decoding

Main unit sensors rice decoding

by Leif Kalla last modified Oct 04, 2006 07:45 AM

ELS,NPI,NPD1,NPD2 rice coding/decoding

— C source code, 15Kb

File contents

/*
*
* $Author: sales $
* $Revision: 1.1 $
* $Log: rice.c,v $
* Revision 1.1  2002/10/23 05:59:23  sales
* Main module, version R-4.1.0
*
* Revision 1.1.2.1  2002/06/27 14:38:39  sales
* RICE + log comp included for NPI. Also secotrmask
*
*/


#include <math.h>
#include <string.h>
#include <stdio.h>       
#include "uses.h"

#define USES_16_MAX_POS_INTEGER 65535
#define USES_16_ID_SIZE 4
#define USES_16_REFERENCE_SIZE 16

static unsigned short output_bit_buffer;
static int output_bit_buffer_index;

static int zero_blocks;
static int reference_packet_frequency;
static int reference_packet_count;
static unsigned short reference;
static unsigned short next_reference;
static int insert_reference;
static unsigned short pack_index;
static unsigned short *pack_table_ptr;
static unsigned short packed_data_index;

void bit_output_done(void)
{
	if (output_bit_buffer_index) {
		pack_table_ptr[pack_index++] = 
			( output_bit_buffer << ( 16 - output_bit_buffer_index ) );
	}
	pack_table_ptr[pack_index++] = 0xAEA3;
}


void output_bit( long bit )
{
	output_bit_buffer <<= 1;
	output_bit_buffer |= bit;
	output_bit_buffer_index++;
	if (output_bit_buffer_index == 16) {
		pack_table_ptr[pack_index++] = (output_bit_buffer);
		output_bit_buffer_index = 0;
	}
}

void output_fundamental_sequence( long x, int k )
{
	int i;

	for (i=0;i<(x>>k);i++) {
		output_bit( 0 );
	}
	output_bit( 1 );
}

/*
void output_fundamental_sequence( unsigned x, int k )
{
	int temp;
	int movable;

//   fprintf(stdout, "Out: fund %i\n", x>>k); 

temp = (x>>k)+1;
movable = 0;

if ((output_bit_buffer_index + temp) <= 16) {
	output_bit_buffer <<= temp;
	output_bit_buffer |= 0x0001;
	output_bit_buffer_index += temp;
} else {
	movable = 16-output_bit_buffer_index;
	output_bit_buffer <<= movable;
	output_bit_buffer_index += movable;
}
if (output_bit_buffer_index == 16) {
	pack_table_ptr[pack_index++] = output_bit_buffer;
	output_bit_buffer_index = 0;
}
if (movable) {
	output_bit_buffer = 0x0001;
	output_bit_buffer_index += (temp-movable);
}
}
*/

void output_split_bits( unsigned short x, int k )
{
	int movable;

	movable = 0;

	if ((output_bit_buffer_index + k) <= 16) {
		output_bit_buffer <<= (k);
		output_bit_buffer |= x & ((0x1<<k)-1);
		output_bit_buffer_index += (k);
	} else {
		movable = 16-output_bit_buffer_index;
		output_bit_buffer <<= movable;
		output_bit_buffer |= (x>>(k-movable)) & ((0x1<<movable)-1);
		output_bit_buffer_index += movable;
	}
	if (output_bit_buffer_index == 16) {
		pack_table_ptr[pack_index++] = output_bit_buffer;
		output_bit_buffer_index = 0;
	}
	if (movable) {
		output_bit_buffer = x & ((0x1<<(k-movable))-1);
		output_bit_buffer_index += (k-movable);
	}
/*     fprintf(stdout, "buffer %4.4X\n", output_bit_buffer); */
}

unsigned short standard_mapper( unsigned short x, unsigned predictor )
{
	long delta;
	long difference;
	long theta;
	long abs_theta;
	long temp;

	delta = (long)x - (long)predictor;
	difference = USES_16_MAX_POS_INTEGER - (long)predictor;
	if (predictor > difference) {
		theta = difference;
	} else {
		theta = predictor;
	}
	abs_theta = labs( theta );
	if (delta >= 0) {
		if (delta <= abs_theta) {
			temp = 2 * delta;
		} else {
			temp = theta + delta;
		}
	} else {
		if (delta >= -abs_theta) {
			temp = 2 * (-delta) - 1;
		} else {
			temp = theta - delta;
		}
	}
/*   fprintf(stdout, "SM %X=%i\n", temp, temp); */

	return (unsigned short)temp;
}

unsigned short encoder( unsigned short d1, unsigned short d2 )
{
	unsigned short temp;

	temp = d1 + d2;
	temp = ( temp * ( temp + 1 ) ) / 2;
	return temp + d2;
}

void low_entropy( unsigned short data[16] )
{
	int i;

	output_split_bits( 1, USES_16_ID_SIZE+1 );
	if (insert_reference) {
		output_split_bits( reference, USES_16_REFERENCE_SIZE );
		insert_reference = 0;
	}

	for (i=0;i<16;i+=2) {
		output_fundamental_sequence( encoder( data[i], data[i+1] ), 0 );
	}
}

void encode_ushort_data( unsigned short orig_data[16] )
{
	unsigned short temp_data[16];
	int psi;
	int i;
	int k;
	long summ;
	int loop;

	if (insert_reference) {
		reference = orig_data[0];
		temp_data[0] = standard_mapper( orig_data[0], reference );
	} else {
		temp_data[0] = standard_mapper( orig_data[0], next_reference );
	}
	for (i=1;i<16;i++) {
		temp_data[i] = standard_mapper( orig_data[i], orig_data[i-1] );
	}
	next_reference = orig_data[15];

/*   for (i=0;i<16;i++) { */
/*     fprintf(stdout, "%i: %4.4X=%5i\n", i, temp_data[i], temp_data[i]); */
/*   } */
	summ = 16;
	for (i=0;i<16;i++) {
		summ += temp_data[i];
	}
	if (summ==16L) {
		psi = 0;
	} else if (summ<=(3L*8)) {
		psi = -1;
	} else if (summ<=(5L*8)) {
		psi = 1;
	} else if (summ<=(9L*8)) {
		psi = 2;
	} else if (summ<=(17L*8)) {
		psi = 3;
	} else if (summ<=(33L*8)) {
		psi = 4;
	} else if (summ<=(65L*8)) {
		psi = 5;
	} else if (summ<=(129L*8)) {
		psi = 6;
	} else if (summ<=(257L*8)) {
		psi = 7;
	} else if (summ<=(513L*8)) {
		psi = 8;
	} else if (summ<=(1025L*8)) {
		psi = 9;
	} else if (summ<=(2049L*8)) {
		psi = 10;
	} else if (summ<=(4097L*8)) {
		psi = 11;
	} else if (summ<=(8193L*8)) {
		psi = 12;
	} else if (summ<=(16385L*8)) {
		psi = 13;
	} else if (summ<=(32769L*8)) {
		psi = 14;
	} else {
		psi = 15;
	}

/*   fprintf(stdout, "Sum is %i, psi %i\n", summ, psi); */

	if ( ( (zero_blocks > 0) && (psi != 0) ) || ( zero_blocks == 64 ) ) {
		if (zero_blocks<5) {
			output_fundamental_sequence( zero_blocks, 0 );
		} else if (zero_blocks == 64) {
			output_fundamental_sequence( 5, 0 );
		} else {
			output_fundamental_sequence( zero_blocks + 1, 0 );
		}
		zero_blocks = 0;
	}

	loop = 0;
	if (psi == -1) {
		if (insert_reference) {
			bit_output_done();
		}
		low_entropy( temp_data );
		reference_packet_count++;
	} else if (psi==0) {
		if ( zero_blocks == 0 ) {
			if (insert_reference) {
				bit_output_done();
			}
			output_split_bits( 0, USES_16_ID_SIZE+1 );
			if (insert_reference) {
				output_split_bits( reference, USES_16_REFERENCE_SIZE );
				insert_reference = 0;
				loop = 1;
			}
			reference_packet_count++;
		}
		zero_blocks++;
	} else if (psi==1) {
		if (insert_reference) {
			bit_output_done();
		}
		output_split_bits( 1, USES_16_ID_SIZE );
		if (insert_reference) {
			output_split_bits( reference, USES_16_REFERENCE_SIZE );
			insert_reference = 0;
			loop = 1;
		}
		for (i=loop;i<16;i++) {
			output_fundamental_sequence( temp_data[i], 0 );
		}
		reference_packet_count++;
	} else if (psi<15) {
		if (insert_reference) {
			bit_output_done();
		}
		k = psi - 1;
		output_split_bits( k+1, USES_16_ID_SIZE );
/*     fprintf(stdout, "id %i, size %i\n", k+1, USES_16_ID_SIZE); */
		if (insert_reference) {
			output_split_bits( reference, USES_16_REFERENCE_SIZE );
			insert_reference = 0;
			loop = 1;
		}
		for (i=loop;i<16;i++) {
			output_fundamental_sequence( temp_data[i], k );
			output_split_bits( temp_data[i], k );
		}
		reference_packet_count++;
	} else {
		if (insert_reference) {
			bit_output_done();
		}
		output_split_bits( 15, USES_16_ID_SIZE );
		if (insert_reference) {
			output_split_bits( reference, USES_16_REFERENCE_SIZE );
			insert_reference = 0;
			loop = 1;
		}
		for (i=loop;i<16;i++) {
			output_split_bits( temp_data[i], USES_16_REFERENCE_SIZE );
		}
		reference_packet_count++;
	}
	if (reference_packet_count == reference_packet_frequency) {
		reference_packet_count = 0;
		insert_reference = 1;
	}
}


void uses_coder(unsigned short *data, unsigned short data_size,
	int reference_frequency,
	unsigned short *packed_table, unsigned short *packed_size,
	short sync)
{
	unsigned short i;
	unsigned short temp_data[16];

	pack_index = 0;
	output_bit_buffer = 0;
	output_bit_buffer_index = 0;
	zero_blocks = 0;
	reference_packet_frequency = reference_frequency;
	reference_packet_count = 0;
	insert_reference = 1;
	pack_table_ptr = packed_table;

/*   pack_table_ptr[pack_index++] = sync; */

	for (i=0;i<data_size/16;i++) {
		encode_ushort_data( &data[i*16] );
	}
	if (data_size % 16) {
		for (i=0;i<(data_size % 16); i++) {
			temp_data[i] = data[((data_size/16)*16+i)];
		}
		for (i=data_size % 16;i<16; i++) {
			temp_data[i] = temp_data[i-1];
		}
		encode_ushort_data( temp_data );
	}
	if (zero_blocks) {
		if (zero_blocks<5) {
			output_fundamental_sequence( zero_blocks, 0 );
		} else if (zero_blocks == 64) {
			output_fundamental_sequence( 5, 0 );
		} else {
			output_fundamental_sequence( zero_blocks + 1, 0 );
		}
	}
	bit_output_done();
	*packed_size = pack_index;
}
/*
unsigned short pack[1000];
short pack_size;

long next(void) {
//   fprintf(stdout, "current %4.4X at %i\n", pack[pack_size], pack_size); 
	return pack[pack_size++];
}

int main(int argc, char **argv)
{
	unsigned short data[128];
	int i;
	int words;
	unsigned short temp;

	data[0] = 0;
	data[1] = 0x00ff;
	data[2] = 0;
	data[3] = 0;
	data[4] = 0;
	data[5] = 0;
	data[6] = 0;
	data[7] = 0;
	data[8] = 0;
	data[9] = 0;
	data[10] = 0;
	data[11] = 0;
	data[12] = 0x0;
	data[13] = 0x00f0;
	data[14] = 0;
	data[15] = 0xffff;
	data[16] = 0xffff;
	data[17] = 0xffff;
	data[18] = 0xffff;
	data[19] = 0xffff;
	data[20] = 0xffff;
	data[21] = 0xffff;
	data[22] = 0xffff;
	data[23] = 0xffff;
	data[24] = 0xffff;
	data[25] = 0xffff;
	data[26] = 0xffff;
	data[27] = 0xffff;
	data[28] = 0xffff;
	data[29] = 0xfff0;
	data[30] = 0xffff;
	data[31] = 0xffff;
	for (i=32;i<48;i++) {
		data[i] = i;
	}
	for (i=48;i<64;i++) {
		data[i] = i;
	}
	for (i=64;i<80;i++) {
		data[i] = 0;
	}
	data[74] = 1;
	data[75] = 2;
	for (i=80;i<96;i++) {
		data[i] = 0;
	}
	for (i=96;i<112;i++) {
		data[i] = 0;
	}
	for (i=112;i<128;i++) {
		data[i] = 0;
	}

	words = 128;

	uses_coder(data, words, 64, pack, &pack_size, 0xAEA3);

	for (i=0;i<pack_size;i++) {
		fprintf(stdout, "%4.4X ", pack[i]);
		if ((i % 8) == 7) {
			fprintf(stdout, "\n");
		}
	}
	fprintf(stdout, "\n");

	pack_size = 0;

	uses_init_unpack(16, 64, next, 0);

	fprintf(stdout, "words %i\n", words);
	for (i=0;i<words;i++) {
		temp = uses_read_data();
//     fprintf(stdout, "ORIG %i: %4.4X =? %4.4X\n", i, data[i], temp); 
		if (temp != data[i]) {
			fprintf(stdout, "ERROR at %i !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", i);
		}
	}
	fprintf(stdout, "done\n");
	return 0;
}
*/

/*
int input_bit_counter;
unsigned long input_buffer;
int reference_counter;
int read_reference;
unsigned long zero_counter;
int uses_counter16;
unsigned long temp_read_data[16];
int uses_reference_frequency;
char packet_header[3];
int packet_read;
long maxint;
long (*next_data) (void);
int reference_order;
int debug_uses;

unsigned long uses_input_bit(void)
{
	long temp;

	if (input_bit_counter == 0) {
		input_buffer = next_data();
//     fprintf(stdout, "input_buffer %8.8X\n", input_buffer);/
		packed_data_index++;
		input_bit_counter = 16;
	}

	temp = (input_buffer & 0x8000U) >> 15;
	input_buffer = input_buffer << 1;
	input_bit_counter--;

	return temp;
}


unsigned long read_fundamental_sequence(void)
{
	unsigned long i = 0;

	while (uses_input_bit() == 0) {
		i++;
	}
	if (debug_uses > 4) {
		printf(" Fundamental read %lX\n", i);
	}
	return i;
}

unsigned long read_split_bits( int k )
{
	int i;
	unsigned long temp = 0l;

	if (reference_order) {
		for ( i=0; i<k; i++ ) {
			temp = temp + ( uses_input_bit() << i );
		}
	} else {
		for ( i=0; i<k; i++ ) {
			temp = ( temp << 1 ) | uses_input_bit();
		}
	}
	if (debug_uses > 4) {
		printf(" Split [%i] read %lX\n", k, temp);
	}

	return temp;
}


void read_sample_splitting( int k, unsigned long data[16] )
{
	int i;
	for ( i=read_reference; i<16; i++ ) {
		data[ i ] = read_fundamental_sequence() << k;    
		data[ i ] += read_split_bits( k );
		if (debug_uses) {
			fprintf(stdout, "Df %2i %li %i\n", i, data[i], k);
		}
	}
//   for ( i=0; i<16; i++ ) { 
//     printf("Ds %2i %i %i\n", i, data[i], k); 
//   } 
//   fprintf(stdout, "read sample\n");
}

void read_default( unsigned long data[16] )
{
	int i;
	for ( i=read_reference; i<16; i++ ) {
		data[ i ] = read_split_bits( USES_16_REFERENCE_SIZE );
//     printf("Df %2i %i\n", i, data[i]); 
	}
}

void read_low_entropy( unsigned long data[16] )
{
	int i;
	long c;
	long d;
	unsigned long temp;

	for ( i=0; i<8; i++ ) {
		temp = read_fundamental_sequence();
		c = ( sqrt( 1 + 8*temp ) - 1 ) / 2;
		d = temp*2 - c*c;
		data[(i*2+1)] = (d-c)/2l;
		data[(i*2)] = c - data[(i*2+1)];
	}
}

long number_of_zero_blocks(void)
{
	long temp;

	temp = read_fundamental_sequence();
	if (debug_uses) {
		if (temp < 5) {
			printf("zero blocks %li\n", temp);
		} else if (temp == 5) {
			printf("zero blocks %i\n", 64);
		} else {
			printf("zero blocks %li\n", temp+1);
		}
	}
	if (temp < 5) {
		return temp;
	} else if (temp == 5) {
		return 64;
	} else {
		return temp - 1;
	}
}


unsigned short reverse_mapper( unsigned long delta, unsigned long reference )
{
	long int theta;
	long int difference;
	long int temp;
	long int long_delta;

	difference = maxint - reference;
	long_delta = delta;

	if (reference > difference) {
		theta = difference;
	} else {
		theta = reference;
	}

	if (long_delta > (2*theta)) {
		temp = long_delta - theta;
		if ( (temp + (unsigned long int)reference) > maxint ) {
			temp = -temp;
		}
	} else if ( (long_delta & 0x0001) == 0x0001 ) {
		temp = -( long_delta + 1 ) / 2;
	} else {
		temp = long_delta / 2;
	}

	return reference + temp;
}

void uses_init_unpack(int bits,
	int reference_frequency,
	long (*next_data_input)(void),
	int debug_state)
{
	debug_uses = debug_state;
	next_data = next_data_input;
	input_bit_counter = 0;
	reference_counter = 0;
	zero_counter = 0;
	uses_counter16 = 0;
	uses_reference_frequency = reference_frequency;
	reference_packet_count = 0;
	packet_read = 0;
	packed_data_index = 0;
	maxint = ( 1L << bits ) - 1;
	if (debug_uses) {
		printf("USES init, id %i, reference size %i, max. integer %li\n", 
			4, USES_16_REFERENCE_SIZE, maxint);
	}
}

void uses_unpack_data( unsigned long data[16] )
{
	int k;
	long low_option;
	long id;
	int sync;

	if ( (reference_counter == 0) &&
		(zero_counter == 0) ) {
		input_bit_counter = 0;
		reference_order = 0;

		sync = read_split_bits( 16 );
		fprintf(stdout, "sync %X\n", sync);
	}

	if (zero_counter == 0) {
		id = read_split_bits( USES_16_ID_SIZE );
		if (debug_uses) {
			printf("id %li\n", id);
		}
		if (id == 0) {
			low_option = uses_input_bit();
			if (debug_uses) {
				printf("option %li\n", low_option);
			}
		}
		if (reference_counter == 0) {
			reference_packet_count++;
			reference = read_split_bits( USES_16_REFERENCE_SIZE );
			if (debug_uses) {
				printf("reference %X\n", reference);
			}
			read_reference = 1;
		} else {
			read_reference = 0;
		}
		reference_counter++;
		if (reference_counter == (uses_reference_frequency)) {
			reference_counter = 0;
		}
		if (id == 0) {
			if (low_option == 0) {
				zero_counter = number_of_zero_blocks() - 1;
				for (k=0; k<16; k++) {
					data[ k ] = 0;
				}
			} else {
				read_low_entropy( data );
			}
		} else if ( id < (USES_16_REFERENCE_SIZE-1) ) {
			read_sample_splitting( (int)id-1, data );
		} else {
			if (debug_uses) {
				printf("Default data\n");
			}
			read_default( data );
		}
	} else {
		for (k=0; k<16; k++) {
			data[ k ] = 0;
		}
		zero_counter--;
	}

	if (read_reference) {
		data[ 0 ] = reference;
	} else {
		data[ 0 ] = reverse_mapper( data[ 0 ], reference );
	}
	//   fprintf(stdout, "Data  0 %i\n", data[0]); 
	for (k=1; k<16; k++) {
		data[ k ] = reverse_mapper( data[ k ], data[ k - 1 ] );
		//     printf("Data %2i %i\n", k, data[k]); 
	}
	reference = data[ 15 ];

}

/*

unsigned long uses_read_data(void)
{
	unsigned long temp;

	if (uses_counter16 == 0) {
		uses_unpack_data( temp_read_data );
	}
	temp = temp_read_data[ uses_counter16++ ];
	if (uses_counter16 > 15) {
		uses_counter16 = 0;
	}
	return temp;
}

*/
Document Actions