/****************************************************************************/
/*                                                                          */
/*  VolVis is a volume visualization system for investigating, manipulating */
/*  and rendering geometric and volumetric data.                            */
/*                                                                          */
/*  Copyright (C) 1993 by the Research Foundation of the State University   */
/*                            of New York                                   */
/*                                                                          */
/*  This program is free software; you can redistribute it and/or modify    */
/*  it under the terms of the GNU General Public License as published by    */
/*  the Free Software Foundation; either version 1, or (at your option)     */
/*  any later version.                                                      */
/*                                                                          */
/*  This program is distributed in the hope that it will be useful,         */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of          */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
/*  GNU General Public License for more details.                            */
/*                                                                          */
/*  You should have received a copy of the GNU General Public License       */
/*  along with this program; if not, write to the Free Software             */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
/*                                                                          */
/*  For information on VolVis, contact us at:                               */
/*                                                                          */
/*                volvis@cs.sunysb.edu                         (email)      */
/*                                                                          */
/*                Lisa Sobierajski & Ricardo Avila             (US Mail)    */
/*                Department of Computer Science                            */
/*                State University of New York at Stony Brook               */
/*                Stony Brook, New York  11794-4400                         */
/*                                                                          */
/****************************************************************************/



# include <stdio.h>
# include <fcntl.h> 

# include "C_volvis.h"



C_Byte *C_encode_8bit_data( in_ptr, size, num_bytes )
C_Byte		*in_ptr;
int		size;
int		*num_bytes;
{
	register C_Byte		*curr_ptr;
	register C_Byte  	*buff_end;
	register C_Byte  	*start_ptr;
	register C_Byte		*encode_ptr;
	register C_Byte  	current_value;
	register C_Byte		processing;
	register int		remaining;
	register int		bytes_so_far;
	C_Byte			*return_ptr;

	
	curr_ptr = in_ptr;
	buff_end = curr_ptr + size;
	bytes_so_far = 0;

	return_ptr = encode_ptr = 
		( C_Byte * ) malloc( size * sizeof( C_Byte ) + 20 );	
	
	if ( !encode_ptr )
	{
		C_error_message("Not Enough Memory To Encode!!!\n");
		return NULL;
	}
	
	while ( curr_ptr < buff_end )
	{
		start_ptr = curr_ptr;
		curr_ptr  += 2;

		while ( ( curr_ptr < buff_end ) &&
			( ( *(curr_ptr - 2) != *(curr_ptr - 1)  ) ||
			  ( *(curr_ptr - 1) != *(curr_ptr) ) ) )
		    curr_ptr++;

		curr_ptr -= 2;

		remaining = curr_ptr - start_ptr;

		while (remaining)
		{
			processing = remaining > 127 ? 127 : remaining;
			remaining  -= processing;
			*(encode_ptr++) = 0x80 | processing;

			bytes_so_far += processing + 1;

			if ( bytes_so_far  >= size ) 
			{
				free( return_ptr );
				*num_bytes = 0;
				return NULL;
			}
			
			while ( processing-- )
			    *(encode_ptr++) = *(start_ptr++);
		}


		current_value = *(curr_ptr++);

		while ( (curr_ptr < buff_end) && (*curr_ptr == current_value) )
		    curr_ptr++;

		remaining = curr_ptr - start_ptr;

		while (remaining)
		{
			processing = remaining > 127 ? 127 : remaining;
			remaining  -= processing;

			bytes_so_far += 2;
		
			if ( bytes_so_far  >= size ) 
			{
				free( return_ptr );
				*num_bytes = 0;
				return NULL;
			}
			
			*(encode_ptr++) = processing;
			*(encode_ptr++) = current_value;
		}
	}

	bytes_so_far++;

	*(encode_ptr++) = 0;

	*num_bytes = bytes_so_far;

	return return_ptr;

}


C_Byte *C_decode_8bit_data( in_ptr, size )
C_Byte		*in_ptr;
int		size;
{

	register C_Byte		*curr_ptr;
	register C_Byte		*decode_ptr;
	register C_Byte		*return_ptr;
	register C_Byte		current_value;
	register C_Byte		remaining;

	curr_ptr = in_ptr;

	decode_ptr = return_ptr = (C_Byte *) malloc( size * sizeof(C_Byte) );

	while ( 1 )
	{
		current_value = *(curr_ptr++);

		if ( !(remaining = (current_value & 0x7f)) )
			break;

		if ( current_value & 0x80 )
		{
			while ( remaining-- )
				*(decode_ptr++) = *(curr_ptr++);
		}
		else
		{
			current_value = *(curr_ptr++);
			while ( remaining-- )
				*(decode_ptr++) = current_value;
		}	
		
	}

	return return_ptr;
}
