/*****
* ImBuffer.c : imageBuffer routines.
*
* This file Version	$Revision: 1.2 $
*
* Creation date:		Thu May  8 05:52:16 GMT+0100 1997
* Last modification: 	$Date: 1997/10/23 00:30:35 $
* By:					$Author: newt $
* Current State:		$State: Exp $
*
* Author:				Koen D'Hondt <ripley@xs4all.nl>
*
* Copyright (C) 1994-1997 by Ripley Software Development 
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation.  This software is provided "as is" without express or
* implied warranty.
*
*****/
/*****
* ChangeLog 
* $Log: ImBuffer.c,v $
* Revision 1.2  1997/10/23 00:30:35  newt
* XmHTML Beta 1.1.0 release
*
* Revision 1.1  1997/05/28 13:14:08  newt
* Initial Revision
*
*****/ 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>

#include "ImBuffer.h"

/*** External Function Prototype Declarations ***/

/*** Public Variable Declarations ***/

/*** Private Datatype Declarations ****/

/*** Private Function Prototype Declarations ****/

/*** Private Variable Declarations ***/

/*****
* Name: 		ImageFileToBuffer
* Return Type: 	ImageBuffer*
* Description: 	loads a file into a memory buffer
* In: 
*	file:		file to load
* Returns:
*	filled ImageBuffer.
*****/
ImageBuffer*
ImageFileToBuffer(char *file)
{
	FILE *fp;
	static ImageBuffer *ib;
	int size;

	ib = NULL;

	if((fp = fopen(file, "r")) == NULL)
	{
		perror(file);
		return(NULL);
	}

	fseek(fp, 0L, SEEK_END);
	size = ftell(fp);

	/* sanity check */
	if(size == 0)
		return(NULL);

	rewind(fp);

	ib = (ImageBuffer*)malloc(sizeof(ImageBuffer));

	ib->buffer = (Byte*)malloc(size*sizeof(Byte));
	ib->size = size;

	if((fread(ib->buffer, ib->size, 1, fp)) != 1)
	{
		perror(file);
		fclose(fp);
		free(ib->buffer);
		free(ib);
		return(NULL);
	}
	fclose(fp);

	ib->file = strdup(file);
	ib->next = 0;
	ib->may_free = 1;

	return(ib);
}

/*****
* Name: 		ReadOK
* Return Type: 	size_t
* Description: 	copy len bytes to buf from an ImageBuffer
* In: 
*	*bp:		data source
*	buf:		data destination
*	len:		no of bytes to copy
* Returns:
*	actual no of bytes read or 0 on failure or end of buffer.
*****/
size_t 
ReadOK(ImageBuffer *ib, Byte *buf, int len)
{
	if(ib->size > ib->next)
	{
		if(ib->next + len > ib->size)
			len = ib->size - ib->next;
		memcpy(buf, ib->buffer + ib->next, len);
		ib->next += len;
		return(len);
	}
	return(0);
}

/*****
* Name: 		GifGetDataBlock
* Return Type: 	int
* Description: 	gets the next amount of data from the input buffer
* In: 
*	ib:			current ImageBuffer
*	buf:		storage buffer, filled upon return.
* Returns:
*	no of bytes copied into buf or 0 when no more data.
*****/
size_t
GifGetDataBlock(ImageBuffer *ib, Byte *buf)
{
	Byte count = 0;

	if(!ReadOK(ib, &count, 1))
		return(0);

	if(((int)count != 0) && (!ReadOK(ib, buf, (int)count)))
		return(0);

	return((size_t)count);
}
