OpenCores
URL https://opencores.org/ocsvn/jtag_stapl_player/jtag_stapl_player/trunk

Subversion Repositories jtag_stapl_player

[/] [jtag_stapl_player/] [trunk/] [jamcomp.c] - Rev 2

Compare with Previous | Blame | View Log

/****************************************************************************/
/*																			*/
/*	Module:			jamcomp.c												*/
/*																			*/
/*					Copyright (C) Altera Corporation 1997					*/
/*																			*/
/*	Description:	Contains the code for compressing and uncompressing		*/
/*					Boolean array data.										*/
/*																			*/
/*					This algorithm works by searching previous bytes in the */
/*					data that match the current data. If a match is found,	*/
/*					then the offset and length of the matching data can		*/
/*					replace the actual data in the output.					*/
/*																			*/
/****************************************************************************/
 
/****************************************************************************/
/*																			*/
/*	Actel version 1.1             May 2003									*/
/*																			*/
/****************************************************************************/
 
#include "jamexprt.h"
#include "jamdefs.h"
#include "jamcomp.h"
 
#define	SHORT_BITS			16
#define	CHAR_BITS			8
#define	DATA_BLOB_LENGTH	3
#define	MATCH_DATA_LENGTH	8192
 
/****************************************************************************/
/*																			*/
 
short jam_bits_required(short n)
 
/*																			*/
/*	Description:	Calculate the minimum number of bits required to		*/
/*					represent n.											*/
/*																			*/
/*	Returns:		Number of bits.											*/
/*																			*/
/****************************************************************************/
{
	short	result = SHORT_BITS;
 
	if (n == 0) result = 1;
	else
	{
		/* Look for the highest non-zero bit position */
		while ((n & (1 << (SHORT_BITS - 1))) == 0)
		{
			n = (short) (n << 1);
			--result;
		}
	}
 
	return (result);
}
 
/****************************************************************************/
/*																			*/
 
short jam_read_packed(char *buffer, long length, short bits)
 
/*																			*/
/*	Description:	Read the next value from the input array "buffer".		*/
/*					Read only "bits" bits from the array. The amount of		*/
/*					bits that have already been read from "buffer" is		*/
/*					stored internally to this function.					 	*/
/*																			*/
/*	Returns:		Up to 16 bit value. -1 if buffer overrun.				*/
/*																			*/
/****************************************************************************/
{
	short			result = -1;
	static long		index = 0L;
	static short	bits_avail = 0;
	short			shift = 0;
 
	/* If buffer is NULL then initialize. */
	if (buffer == NULL)
	{
		index = 0;
		bits_avail = CHAR_BITS;
	}
	else
	{
		result = 0;
		while (result != -1 && bits > 0)
		{
			result = (short) (result | (((buffer[index] >> (CHAR_BITS - bits_avail)) & (0xFF >> (CHAR_BITS - bits_avail))) << shift));
 
			if (bits <= bits_avail)
			{
				result = (short) (result & (0xFFFF >> (SHORT_BITS - (bits + shift))));
				bits_avail = (short) (bits_avail - bits);
				bits = 0;
			}
			else
			{
				/* Check for buffer overflow. */
				if (++index >= length) result = -1;
				else
				{
					shift = (short) (shift + bits_avail);
					bits = (short) (bits - bits_avail);
					bits_avail = CHAR_BITS;
				}
			}
		}
	}
 
	return (result);
}
 
/****************************************************************************/
/*																			*/
 
long jam_uncompress
(
	char *in, 
	long in_length, 
	char *out, 
	long out_length,
	int version
)
 
/*																			*/
/*	Description:	Uncompress data in "in" and write result to	"out".		*/
/*																			*/
/*	Returns:		Length of uncompressed data. -1 if:						*/
/*						1) out_length is too small							*/
/*						2) Internal error in the code						*/
/*						3) in doesn't contain ACA compressed data.			*/
/*																			*/
/****************************************************************************/
{
	long	i, j, data_length = 0L;
	short	offset, length;
	long	match_data_length = MATCH_DATA_LENGTH;
 
	if (version == 2) --match_data_length;
 
	jam_read_packed(NULL, 0, 0);
	for (i = 0; i < out_length; ++i) out[i] = 0;
 
	/* Read number of bytes in data. */
	for (i = 0; i < sizeof (in_length); ++i) 
	{
		data_length = data_length | ((long) jam_read_packed(in, in_length, CHAR_BITS) << (long) (i * CHAR_BITS));
	}
 
	if (data_length > out_length) data_length = -1L;
	else
	{
		i = 0;
		while (i < data_length)
		{
			/* A 0 bit indicates literal data. */
			if (jam_read_packed(in, in_length, 1) == 0)
			{
				for (j = 0; j < DATA_BLOB_LENGTH; ++j)
				{
					if (i < data_length)
					{
						out[i] = (char) jam_read_packed(in, in_length, CHAR_BITS);
						i++;
					}
				}
			}
			else
			{
				/* A 1 bit indicates offset/length to follow. */
				offset = jam_read_packed(in, in_length, jam_bits_required((short) (i > match_data_length ? match_data_length : i)));
				length = jam_read_packed(in, in_length, CHAR_BITS);
 
				for (j = 0; j < length; ++j)
				{
					if (i < data_length)
					{
						out[i] = out[i - offset];
						i++;
					}
				}
			}
		}
	}
 
	return (data_length);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.