ftp.nice.ch/pub/next/graphics/viewer/RLEViewer.2.3.N.bs.tar.gz#/RLEViewer-2.3/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 <libc.h>
#include "giflib.h"
#include "io.h"
	
int readgifheader(char *filename, int *xsize, int *ysize)
{
    if ( (GIF_file = fopen(filename,"rb")) == NULL){
	return(-1);
    }
    if (getsig () < 0)
	return -1;
    if (getdesc () < 0)
	return -1;
    if (getgcmap () < 0)
	return -1;
    if (getidesc () < 0)
	return -1;

    *xsize = GIF_xsize;
    *ysize = GIF_ysize;
    return 0;
}
	
int readgif(unsigned char *rmap, unsigned char *gmap, unsigned char *bmap)
{
    int loop;
    
    GIF_curx = 0;
    GIF_cury = 0;
    GIF_ytemp = 8;
    GIF_ystart = 0;
    r = rmap;
    g = gmap;
    b = bmap;
    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);
    fclose(GIF_file);
    return loop;
}
	
int getsig(void)
{
    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;
}	

int getdesc (void)
{
    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;
}
	
int getgcmap (void)
{
    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;
	}
    return(0);
}

int getidesc (void)
{
    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";

void output (int code, int bits)
{
    register int loop;
    unsigned char *ptr;
    unsigned short *p;
    
    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;
		    }
		}
	    }
	}
    }
}
	
int getimage (void)
{
    unsigned int first, data, bits, dsize, csize, clear, eod, maxcode, nextcode, oldcode=0;
    register unsigned int totalbits, maxbits, loop, done;
    
    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.