ftp.nice.ch/pub/next/graphics/viewer/NeXTGIF.0.1.N.bs.tar.gz#/NeXTGIF/giflib.c

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

/*
Copyright Notice:
	Copyright 1990 Robert C. Hood
	This software is distributed "as is" without warranty.  Use this software at your OWN RISK.  Source may be distributed freely, at NO CHARGE, but must be accompanied by this documentation and copyright notice.
*/
#include <stdio.h>
#include "giflib.h"
	
readgifheader ()
	{
	if (getsig () < 0)
		return -1;
	if (getdesc () < 0)
		return -1;
	if (getgcmap () < 0)
		return -1;
	if (getidesc () < 0)
		return -1;
	return 0;
	}
	
readgif ()
	{
	int loop;
	
	GIF_curx = 0;
	GIF_cury = 0;
	GIF_ytemp = 8;
	GIF_ystart = 0;
	r = (unsigned char *)malloc (GIF_ysize * GIF_xsize);
	g = (unsigned char *)malloc (GIF_ysize * GIF_xsize);
	b = (unsigned char *)malloc (GIF_ysize * GIF_xsize);
	for (loop = 0; loop < (GIF_ysize * GIF_xsize); ++loop)
		{
		r [loop] = GIF_globalmap [GIF_background * 3];
		b [loop] = GIF_globalmap [GIF_background * 3 + 1];
		g [loop] = GIF_globalmap [GIF_background * 3 + 2];
		}
	if ((r == 0) || (g == 0) || (b == 0))
		return -1;
	loop = getimage ();
	free (GIF_globalmap);
	return loop;
	}
	
getsig  ()
	{
	if (((char)fgetc (GIF_file) != 'G') || ((char)fgetc (GIF_file) != 'I') || 
		((char)fgetc (GIF_file) != 'F') || ((char)fgetc (GIF_file) != '8') || 
		((char)fgetc (GIF_file) != '7') || ((char)fgetc (GIF_file) != 'a'))
		return (-1);
	return 0;
	}	

getdesc ()
	{
	unsigned char temp;

	GIF_swidth = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	GIF_sheight = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	temp = (unsigned char)fgetc (GIF_file);
	GIF_gmap = temp >> 7;
	GIF_colorres = (temp >> 4) & 7;
	GIF_gbits = temp & 7;
	GIF_background = fgetc (GIF_file);
	if (fgetc (GIF_file) != 0)
		return (-1);
	return 0;
	}
	
getgcmap ()
	{
	int size, loop;
	unsigned char *ptr;
	
	if (GIF_gmap)
		{
		size = 1 << (GIF_gbits + 1);
		if ((GIF_globalmap = (unsigned char *)malloc (sizeof (char) * size * 3)) == 0)
			return -1;
		ptr = GIF_globalmap;
		for (loop = 0; loop < size * 3; ++loop)
			{
			*ptr = fgetc (GIF_file);
			++ptr;
			}
		}
	else
		{
		GIF_globalmap = 0;
		}
	}

getidesc ()
	{
	unsigned char temp;

	if ((char)fgetc (GIF_file) != ',')
		return -1;
	GIF_xpos = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	GIF_ypos = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	GIF_xsize = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	GIF_ysize = (int)fgetc (GIF_file) + ((int)fgetc (GIF_file) << 8);
	temp = fgetc (GIF_file);
	GIF_lmap = temp >> 7;
	GIF_interlaced = (temp >> 6) & 1;
	GIF_lbits = temp & 7;
	return 0;
	}

unsigned short *table [4096];
char hex [] = "0123456789abcdef";

output (code, bits)
int code, bits;
	{
	register int loop;
	unsigned char *ptr;
	unsigned short *p;
	register unsigned char temp;
	static char lastcode = 0;
	char output [7], *i;
	
	p = table [code];
	for (loop = 1; loop < ((int)*p + 1); ++loop)
	    {
		ptr = GIF_globalmap + *(p + loop) * 3;
		*(r + (GIF_cury * GIF_xsize) + GIF_curx) = *ptr;
		*(g + (GIF_cury * GIF_xsize) + GIF_curx) = *(ptr + 1);
		*(b + (GIF_cury * GIF_xsize) + GIF_curx) = *(ptr + 2);
		if ((++(GIF_curx)) == GIF_xsize)
	    	{
			GIF_curx = 0;
			if (GIF_interlaced == 0)
				++GIF_cury;
			else
				{
				GIF_cury += GIF_ytemp;
				if (GIF_cury >= GIF_ysize)
					{
					++GIF_ystart;
					switch (GIF_ystart)
						{
						case 1:
							GIF_ytemp = 8;
							GIF_cury = 4;
							break;
						case 2:
							GIF_ytemp = 4;
							GIF_cury = 2;
							break;
						case 3:
							GIF_ytemp = 2;
							GIF_cury = 1;
							break;
						}
					}
				}
			}
		}
	}
	
getimage ()
	{
	unsigned int first, data, bits, dsize, csize, clear, eod, maxcode, nextcode, oldcode;
	register unsigned int totalbits, maxbits, loop, done;
	unsigned int buffer [4097];
	
	
	csize = fgetc (GIF_file);
	bits = csize + 1;
	for (loop = 0; loop < (1 << csize); ++ loop)
		{
		table [loop] = (unsigned short *)malloc (sizeof (unsigned short) * 2);
		*table [loop] = 1;
		*(table [loop] + 1) = (unsigned char)loop;
		}
		
	dsize = fgetc (GIF_file);
	startbuffer (dsize);
	totalbits = 0;
	maxbits = dsize * 8;
	clear = 1 << csize;
	eod = clear + 1;
	nextcode = eod + 1;
	maxcode = (1 << bits) - 1;
	done = 0;
	first = 1;
	while (!done)
		{
		if ((totalbits + bits) >= maxbits)
			{
//			data = getbits (maxbits - totalbits) << (bits - (maxbits - totalbits));
			data = getbits (maxbits - totalbits); 
			dsize = fgetc (GIF_file);
			startbuffer (dsize);
			data += (getbits (bits - (maxbits - totalbits)) << (maxbits - totalbits));
			totalbits = (bits - (maxbits - totalbits));
			maxbits = dsize * 8;
			}
		else
			{
			data = getbits (bits);
			totalbits += bits;
			}
		if (data == clear)
			{
			bits = csize + 1;
			for (loop = clear + 2; loop < nextcode; ++loop)
				free (table [loop]);
			nextcode = clear + 2;
			maxcode = (1 << bits) - 1;
			first = 1;
			}
		else if (data == eod)
			{
			done = 1;
			}
		else if (first == 1)
			{
			first = 0;
			output (data, clear);
			oldcode = data;
			}
		else if (data < nextcode)
			{
			output (data, clear);
			table [nextcode] = (unsigned short *)malloc (sizeof (unsigned short) * (*table [oldcode] + 2));
			for (loop = 1; loop < ((int)*table [oldcode] + 1); ++loop)
				*(table [nextcode] + loop) = *(table [oldcode] + loop);
			*table [nextcode] = *table [oldcode] + 1;
			*(table [nextcode] + *table [nextcode]) = *(table [data] + 1);
			++nextcode;
			if (nextcode > maxcode)
				{
				if (nextcode != 4096)
					{
					++bits;
					maxcode = (1 << bits) - 1;
					}
				}
			oldcode = data;
			}
		else if (data == nextcode)
			{
			table [nextcode] = (unsigned short *)malloc (sizeof (unsigned short) * 
				(*table [oldcode] + 2));
			for (loop = 1; loop < ((int)*table [oldcode] + 1); ++loop)
				*(table [nextcode] + loop) = *(table [oldcode] + loop);
			*table [nextcode] = *table [oldcode] + 1;
			*(table [nextcode] + *table [nextcode]) = *(table [oldcode]+1);
			output (nextcode, clear);
			++nextcode;
			if (nextcode > maxcode)
				{
				if (nextcode != 4096)
					{
					++bits;
					maxcode = (1 << bits) - 1;
					}
				}
			oldcode = data;
			}
		else /* BAD */
			{
			return (-1);
			}
		}
	for (loop = clear + 2; loop < nextcode; ++loop)
		free (table [loop]);
	return 0;
	}
	

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