/************************************************/
/*                                              */
/* Like GCC/Decrunch_MIT.s - SAS_C/Decrunch30.s */
/* but all work is in C                         */
/* See Docs/Decrunch30.doc for complete docs    */
/* about this function                          */
/* See Docs/SAS_C/SAS_C_interface for an        */
/* example program using this function          */
/*                                              */
/* Copyright © 1992-1995 by Stefano Reksten     */
/*                                              */
/************************************************/

#include <exec/types.h>

#define BTOC_MSG	( (ULONG)'B'<<24L | (ULONG)'T'<<16L | 'O'<<8 | 'C' )

BOOL Decrunch30( register UBYTE *dest_ptr, register UBYTE *source_ptr )
{
register ULONG  data_size, decrunched = 0;
register UBYTE  most_used, byte_counter, current_byte,
		max_counter, skip_counter, skip_byte;

if ( *(ULONG *)source_ptr++ != BTOC_MSG )
	return( FALSE );

data_size = *(ULONG *)source_ptr++;
most_used = *source_ptr++;
max_counter = *source_ptr++;

while ( decrunched < data_size )
	{
	if ( *source_ptr != most_used )
		{
		*dest_ptr++ = *source_ptr++;
		decrunched++;
		}
	else
		{
		source_ptr++;
		byte_counter = *source_ptr++;
		if ( byte_counter == max_counter )
			{
			*dest_ptr++ = most_used;

			skip_byte = *source_ptr++;
			skip_counter=7;
			do	{
				if ( skip_byte & 1<<skip_counter )
					*dest_ptr++ = *source_ptr++;
				else	*dest_ptr++ = most_used;
				skip_counter--;
				} while ( skip_counter >= 0 );
			decrunched += 9;
			}
		else
			{
			if ( byte_counter > max_counter )
				{
				byte_counter -= max_counter;
				current_byte = *source_ptr++;
				}
			else	current_byte = most_used;

			decrunched += byte_counter;
			while ( byte_counter-- )
				*dest_ptr++ = current_byte;
			}
		}
	}
return( TRUE );
}
