ftp.nice.ch/pub/next/graphics/viewer/ToyViewer.2.6a.s.tar.gz#/ToyViewer2.6a/src/giflzw.c

This is giflzw.c in view mode; [Download] [Up]

#include  <stdio.h>
#include  "gif.h"

#define	MAX_LWZ_BITS		12

static int	fresh = NO;
static int	code_size, set_code_size;
static int	max_code, max_code_size;
static int	firstcode, oldcode;
static int	clear_code, end_code;
static int	*sp;
static int	table[2][(1<< MAX_LWZ_BITS)];
#define  MAXSTACKSZ	((1<<(MAX_LWZ_BITS))*2 + 2)
static int	stack[MAXSTACKSZ];

static unsigned char	buffer[280];
static int		curbit, lastbit, done, last_byte;

static void
initGetCode(void)
{
	curbit = 0;
	lastbit = 0;
	done = NO;
}

static int
GetCode(FILE *fd, int code_size)
{
	int		i, j, ret;
	unsigned char	count;

	if ( (curbit+code_size) >= lastbit) {
		if (done)
			return -1;
		buffer[0] = buffer[last_byte-2];
		buffer[1] = buffer[last_byte-1];
		if ((count = GetDataBlock(fd, &buffer[2])) == 0)
			done = YES;
		last_byte = 2 + count;
		curbit = (curbit - lastbit) + 16;
		lastbit = (2+count)*8 ;
	}
	ret = 0;
	for (i = curbit, j = 0; j < code_size; ++i, ++j)
		ret |= ((buffer[ i / 8 ] & (1 << (i % 8))) != 0) << j;
	curbit += code_size;
	return ret;
}


static int	ZeroDataBlock = NO;

int GetDataBlock(FILE *fd, unsigned char *buf)
{
	int count;

	if ((count = getc(fd)) == EOF)
		return -1;
	ZeroDataBlock = count == 0;
	if ((count != 0) && (! ReadOK(fd, buf, count)))
		return -1;
	buf[count] = 0;
	return count;
}


int initGifLZW(FILE *fp)
{
	int i;

	if ((set_code_size = getc(fp)) == EOF)
		return EOF;
	code_size = set_code_size+1;
	clear_code = 1 << set_code_size ;
	end_code = clear_code + 1;
	max_code_size = 2*clear_code;
	max_code = clear_code+2;
	fresh = YES;
	sp = stack;
	initGetCode();
	for (i = 0; i < clear_code; ++i) {
		table[0][i] = 0;
		table[1][i] = i;
	}
	for (; i < (1<<MAX_LWZ_BITS); ++i)
		table[0][i] = table[1][0] = 0;
	return 0;
}

int LWZReadByte(FILE *fd)
{
	register int	i;
	int	code, incode;

	if (fresh) {
		fresh = NO;
		do {
			firstcode = oldcode = GetCode(fd, code_size);
		} while (firstcode == clear_code);
		return firstcode;
	}

	if (sp > stack)
		return *--sp;

	while ((code = GetCode(fd, code_size)) >= 0) {
		if (code == clear_code) {
			for (i = 0; i < clear_code; ++i) {
				table[0][i] = 0;
				table[1][i] = i;
			}
			for (; i < (1<<MAX_LWZ_BITS); ++i)
				table[0][i] = table[1][i] = 0;
			code_size = set_code_size+1;
			max_code_size = 2*clear_code;
			max_code = clear_code+2;
			sp = stack;
			firstcode = oldcode = GetCode(fd, code_size);
			return firstcode;
		}
		if (code == end_code) {
			int		count;
			unsigned char	buf[260];

			if (ZeroDataBlock)
				return -2;
			while ((count = GetDataBlock(fd, buf)) > 0)
				;
			return -2;
		}

		incode = code;
		if (code >= max_code) {
			*sp++ = firstcode;
			code = oldcode;
		}
		while (code >= clear_code) {
			if (sp >= &stack[MAXSTACKSZ-1])
				return *--sp;	/* ERROR */
			*sp++ = table[1][code];
			code = table[0][code];
		}

		*sp++ = firstcode = table[1][code];

		if ((code = max_code) < (1<<MAX_LWZ_BITS)) {
			table[0][code] = oldcode;
			table[1][code] = firstcode;
			++max_code;
			if ((max_code >= max_code_size) &&
				(max_code_size < (1<<MAX_LWZ_BITS))) {
				max_code_size *= 2;
				++code_size;
			}
		}
		oldcode = incode;
		if (sp > stack)
			return *--sp;
	}
	return code;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.