#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include "imagefile.h"

typedef struct Entry Entry;
typedef struct Header Header;

struct Entry{
	int		prefix;
	int		exten;
};


struct Header{
	Biobuf	*fd;
	char		err[256];
	jmp_buf	errlab;
	uchar 	buf[3*256];
	char 		vers[8];
	uchar 	*globalcmap;
	int		screenw;
	int		screenh;
	int		fields;
	int		bgrnd;
	int		aspect;
	int		flags;
	int		delay;
	int		trindex;
	int		loopcount;
	Entry	tbl[4096];
	Rawimage	**array;
	Rawimage	*new;

	uchar	*pic;
};

static char		readerr[] = "ReadGIF: read error: %r";
static char		extreaderr[] = "ReadGIF: can't read extension: %r";
static char		memerr[] = "ReadGIF: malloc failed: %r";

static Rawimage**	readarray(Header*);
static Rawimage*	readone(Header*);
static void			readheader(Header*);
static void			skipextension(Header*);
static uchar*		readcmap(Header*, int);
static uchar*		decode(Header*, Rawimage*, Entry*);
static void			interlace(Header*, Rawimage*);

static
void
clear(void *pp)
{
	void **p = (void**)pp;

	if(*p){
		free(*p);
		*p = nil;
	}
}

static
void
giffreeall(Header *h, int freeimage)
{
	int i;

	if(h->fd){
		Bterm(h->fd);
		h->fd = nil;
	}
	clear(&h->pic);
	if(h->new){
		clear(&h->new->cmap);
		clear(&h->new->chans[0]);
		clear(&h->new);
	}
	clear(&h->globalcmap);
	if(freeimage && h->array!=nil){
		for(i=0; h->array[i]; i++){
			clear(&h->array[i]->cmap);
			clear(&h->array[i]->chans[0]);
		}
		clear(&h->array);
	}
}

static
void
giferror(Header *h, char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	vseprint(h->err, h->err+sizeof h->err, fmt, arg);
	va_end(arg);

	werrstr(h->err);
	giffreeall(h, 1);
	longjmp(h->errlab, 1);
}


Rawimage**
readgif(int fd, int colorspace)
{
	Rawimage **a;
	Biobuf b;
	Header *h;
	char buf[ERRMAX];

	buf[0] = '\0';
	USED(colorspace);
	if(Binit(&b, fd, OREAD) < 0)
		return nil;
	h = malloc(sizeof(Header));
	if(h == nil){
		Bterm(&b);
		return nil;
	}
	memset(h, 0, sizeof(Header));
	h->fd = &b;
	errstr(buf, sizeof buf);	/* throw it away */
	if(setjmp(h->errlab))
		a = nil;
	else
		a = readarray(h);
	giffreeall(h, 0);
	free(h);
	return a;
}

static
void
inittbl(Header *h)
{
	int i;
	Entry *tbl;

	tbl = h->tbl;
	for(i=0; i<258; i++) {
		tbl[i].prefix = -1;
		tbl[i].exten = i;
	}
}

static
Rawimage**
readarray(Header *h)
{
	Entry *tbl;
	Rawimage *new, **array;
	int c, nimages;

	tbl = h->tbl;

	readheader(h);

	if(h->fields & 0x80)
		h->globalcmap = readcmap(h, (h->fields&7)+1);

	array = malloc(sizeof(Rawimage**));
	if(array == nil)
		giferror(h, memerr);
	nimages = 0;
	array[0] = nil;
	h->array = array;
		
	for(;;){
		switch(c = Bgetc(h->fd)){
		case Beof:
			goto Return;

		case 0x21:	/* Extension (ignored) */
			skipextension(h);
			break;

		case 0x2C:	/* Image Descriptor */
			inittbl(h);
			new = readone(h);
			if(new->fields & 0x80){
				new->cmaplen = 3*(1<<((new->fields&7)+1));
				new->cmap = readcmap(h, (new->fields&7)+1);
			}else{
				new->cmaplen = 3*(1<<((h->fields&7)+1));
				new->cmap = malloc(new->cmaplen);
				memmove(new->cmap, h->globalcmap, new->cmaplen);
			}
			h->new = new;
			new->chans[0] = decode(h, new, tbl);
			if(new->fields & 0x40)
				interlace(h, new);
			new->gifflags = h->flags;
			new->gifdelay = h->delay;
			new->giftrindex = h->trindex;
			new->gifloopcount = h->loopcount;
			array = realloc(h->array, (nimages+2)*sizeof(Rawimage*));
			if(array == nil)
				giferror(h, memerr);
			array[nimages++] = new;
			array[nimages] = nil;
			h->array = array;
			h->new = nil;
			break;

		case 0x3B:	/* Trailer */
			goto Return;

		default:
			fprint(2, "ReadGIF: unknown block type: 0x%.2x\n", c);
			goto Return;
		}
	}

   Return:
	if(array[0]==nil || array[0]->chans[0] == nil)
		giferror(h, "ReadGIF: no picture in file");

	return array;
}

static
void
readheader(Header *h)
{
	if(Bread(h->fd, h->buf, 13) != 13)
		giferror(h, "ReadGIF: can't read header: %r");
	memmove(h->vers, h->buf, 6);
	if(strcmp(h->vers, "GIF87a")!=0 &&  strcmp(h->vers, "GIF89a")!=0)
		giferror(h, "ReadGIF: can't recognize format %s", h->vers);
	h->screenw = h->buf[6]+(h->buf[7]<<8);
	h->screenh = h->buf[8]+(h->buf[9]<<8);
	h->fields = h->buf[10];
	h->bgrnd = h->buf[11];
	h->aspect = h->buf[12];
	h->flags = 0;
	h->delay = 0;
	h->trindex = 0;
	h->loopcount = -1;
}

static
uchar*
readcmap(Header *h, int size)
{
	uchar *map;

	if(size > 8)
		giferror(h, "ReadGIF: can't handles %d bits per pixel", size);
	size = 3*(1<<size);
	if(Bread(h->fd, h->buf, size) != size)
		giferror(h, "ReadGIF: short read on color map");
	map = malloc(size);
	if(map == nil)
		giferror(h, memerr);
	memmove(map, h->buf, size);
	return map;
}

static
Rawimage*
readone(Header *h)
{
	Rawimage *i;
	int left, top, width, height;

	if(Bread(h->fd, h->buf, 9) != 9)
		giferror(h, "ReadGIF: can't read image descriptor: %r");
	i = malloc(sizeof(Rawimage));
	if(i == nil)
		giferror(h, memerr);
	left = h->buf[0]+(h->buf[1]<<8);
	top = h->buf[2]+(h->buf[3]<<8);
	width = h->buf[4]+(h->buf[5]<<8);
	height = h->buf[6]+(h->buf[7]<<8);
	i->fields = h->buf[8];
	i->r.min.x = left;
	i->r.min.y = top;
	i->r.max.x = left+width;
	i->r.max.y = top+height;
	i->nchans = 1;
	i->chandesc = CRGB1;
	return i;
}


static
int
readdata(Header *h, uchar *data)
{
	int nbytes, n;

	nbytes = Bgetc(h->fd);
	if(nbytes < 0)
		giferror(h, "ReadGIF: can't read data: %r");
	if(nbytes == 0)
		return 0;
	n = Bread(h->fd, data, nbytes);
	if(n < 0)
		giferror(h, "ReadGIF: can't read data: %r");
	if(n != nbytes)
		fprint(2, "ReadGIF: short data subblock\n");
	return n;
}

static
void
graphiccontrol(Header *h)
{
	if(Bread(h->fd, h->buf, 5+1) != 5+1)
		giferror(h, readerr);
	h->flags = h->buf[1];
	h->delay = h->buf[2]+(h->buf[3]<<8);
	h->trindex = h->buf[4];
}

static
void
skipextension(Header *h)
{
	int type, hsize, hasdata, n;
	uchar data[256];

	hsize = 0;
	hasdata = 0;

	type = Bgetc(h->fd);
	switch(type){
	case Beof:
		giferror(h, extreaderr);
		break;
	case 0x01:	/* Plain Text Extension */
		hsize = 13;
		hasdata = 1;
		break;
	case 0xF9:	/* Graphic Control Extension */
		graphiccontrol(h);
		return;
	case 0xFE:	/* Comment Extension */
		hasdata = 1;
		break;
	case 0xFF:	/* Application Extension */
		hsize = Bgetc(h->fd);
		/* standard says this must be 11, but Adobe likes to put out 10-byte ones,
		 * so we pay attention to the field. */
		hasdata = 1;
		break;
	default:
		giferror(h, "ReadGIF: unknown extension");
	}
	if(hsize>0 && Bread(h->fd, h->buf, hsize) != hsize)
		giferror(h, extreaderr);
	if(!hasdata)
		return;

	/* loop counter: Application Extension with NETSCAPE2.0 as string and 1 <loop.count> in data */
	if(type == 0xFF && hsize==11 && memcmp(h->buf, "NETSCAPE2.0", 11)==0){
		n = readdata(h, data);
		if(n == 0)
			return;
		if(n==3 && data[0]==1)
			h->loopcount = data[1] | (data[2]<<8);
	}
	while(readdata(h, data) != 0)
		;
}

static
uchar*
decode(Header *h, Rawimage *i, Entry *tbl)
{
	int c, incode, codesize, CTM, EOD, pici, datai, stacki, nbits, sreg, fc, code, piclen;
	int csize, nentry, maxentry, first, ocode, ndata, nb;
	uchar *pic;
	uchar stack[4096], data[256];

	if(Bread(h->fd, h->buf, 1) != 1)
		giferror(h, "ReadGIF: can't read data: %r");
	codesize = h->buf[0];
	if(codesize>8 || 0>codesize)
		giferror(h, "ReadGIF: can't handle codesize %d", codesize);
	if(i->cmap!=nil && i->cmaplen!=3*(1<<codesize)
	  && (codesize!=2 || i->cmaplen!=3*2)) /* peculiar GIF bitmap files... */
		giferror(h, "ReadGIF: codesize %d doesn't match color map 3*%d", codesize, i->cmaplen/3);

	CTM =1<<codesize;
	EOD = CTM+1;

	piclen = (i->r.max.x-i->r.min.x)*(i->r.max.y-i->r.min.y);
	i->chanlen = piclen;
	pic = malloc(piclen);
	if(pic == nil)
		giferror(h, memerr);
	h->pic = pic;
	pici = 0;
	ndata = 0;
	datai = 0;
	nbits = 0;
	sreg = 0;
	fc = 0;

    Loop:
	for(;;){
		csize = codesize+1;
		nentry = EOD+1;
		maxentry = (1<<csize)-1;
		first = 1;
		ocode = -1;

		for(;; ocode = incode) {
			while(nbits < csize) {
				if(datai == ndata){
					ndata = readdata(h, data);
					if(ndata == 0)
						goto Return;
					datai = 0;
				}
				c = data[datai++];
				sreg |= c<<nbits;
				nbits += 8;
			}
			code = sreg & ((1<<csize) - 1);
			sreg >>= csize;
			nbits -= csize;

			if(code == EOD){
				ndata = readdata(h, data);
				if(ndata != 0)
					fprint(2, "ReadGIF: unexpected data past EOD");
				goto Return;
			}

			if(code == CTM)
				goto Loop;

			stacki = (sizeof stack)-1;

			incode = code;

			/* special case for KwKwK */
			if(code == nentry) {
				stack[stacki--] = fc;
				code = ocode;
			}

			if(code > nentry)
				giferror(h, "ReadGIF: bad code %x %x", code, nentry);

			for(c=code; c>=0; c=tbl[c].prefix)
				stack[stacki--] = tbl[c].exten;

			nb = (sizeof stack)-(stacki+1);
			if(pici+nb > piclen){
				/* this common error is harmless
				 * we have to keep reading to keep the blocks in sync */
				;
			}else{
				memmove(pic+pici, stack+stacki+1, sizeof stack - (stacki+1));
				pici += nb;
			}

			fc = stack[stacki+1];

			if(first){
				first = 0;
				continue;
			}
			#define early 0 /* peculiar tiff feature here for reference */
			if(nentry == maxentry-early) {
				if(csize >= 12)
					continue;
				csize++;
				maxentry = (1<<csize);
				if(csize < 12)
					maxentry--;
			}
			tbl[nentry].prefix = ocode;
			tbl[nentry].exten = fc;
			nentry++;
		}
	}

Return:
	h->pic = nil;
	return pic;
}

static
void
interlace(Header *h, Rawimage *image)
{
	uchar *pic;
	Rectangle r;
	int dx, yy, y;
	uchar *ipic;

	pic = image->chans[0];
	r = image->r;
	dx = r.max.x-r.min.x;
	ipic = malloc(dx*(r.max.y-r.min.y));
	if(ipic == nil)
		giferror(h, nil);

	/* Group 1: every 8th row, starting with row 0 */
	yy = 0;
	for(y=r.min.y; y<r.max.y; y+=8){
		memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
		yy++;
	}

	/* Group 2: every 8th row, starting with row 4 */
	for(y=r.min.y+4; y<r.max.y; y+=8){
		memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
		yy++;
	}

	/* Group 3: every 4th row, starting with row 2 */
	for(y=r.min.y+2; y<r.max.y; y+=4){
		memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
		yy++;
	}

	/* Group 4: every 2nd row, starting with row 1 */
	for(y=r.min.y+1; y<r.max.y; y+=2){
		memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
		yy++;
	}

	free(image->chans[0]);
	image->chans[0] = ipic;
}
