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

enum
{
	Nhash	= 4001,
	Nbuf		= 300,
};

typedef struct Entry Entry;
typedef struct IO IO;


struct Entry
{
	int		index;
	int		prefix;
	int		exten;
	Entry	*next;
};

struct IO
{
	Biobuf	*fd;
	uchar	buf[Nbuf];
	int		i;
	int		nbits;	/* bits in right side of shift register */
	int		sreg;		/* shift register */
};

static Rectangle	mainrect;
static Entry	tbl[4096];
static uchar	*colormap[5];	/* one for each ldepth: GREY1 GREY2 GREY4 CMAP8=rgbv plus GREY8 */
#define	GREYMAP	4
static int		colormapsize[] = { 2, 4, 16, 256, 256 };	/* 2 for zero is an odd property of GIF */

static void		writeheader(Biobuf*, Rectangle, int, ulong, int);
static void		writedescriptor(Biobuf*, Rectangle);
static char*	writedata(Biobuf*, Image*, Memimage*);
static void		writecomment(Biobuf *fd, char*);
static void		writegraphiccontrol(Biobuf *fd, int, int);
static void*	gifmalloc(ulong);
static void		encode(Biobuf*, Rectangle, int, uchar*, uint);

static
char*
startgif0(Biobuf *fd, ulong chan, Rectangle r, int depth, int loopcount)
{
	int i;

	for(i=0; i<nelem(tbl); i++){
		tbl[i].index = i;
		tbl[i].prefix = -1;
		tbl[i].exten = i;
	}

	switch(chan){
	case GREY1:
	case GREY2:
	case GREY4:
	case CMAP8:
	case GREY8:
		break;
	default:
		return "WriteGIF: can't handle channel type";
	}

	mainrect = r;
	writeheader(fd, r, depth, chan, loopcount);
	return nil;
}

char*
startgif(Biobuf *fd, Image *image, int loopcount)
{
	return startgif0(fd, image->chan, image->r, image->depth, loopcount);
}

char*
memstartgif(Biobuf *fd, Memimage *memimage, int loopcount)
{
	return startgif0(fd, memimage->chan, memimage->r, memimage->depth, loopcount);
}

static
char*
writegif0(Biobuf *fd, Image *image, Memimage *memimage, ulong chan, Rectangle r, char *comment, int dt, int trans)
{
	char *err;

	switch(chan){
	case GREY1:
	case GREY2:
	case GREY4:
	case CMAP8:
	case GREY8:
		break;
	default:
		return "WriteGIF: can't handle channel type";
	}

	writecomment(fd, comment);
	writegraphiccontrol(fd, dt, trans);
	writedescriptor(fd, r);

	err = writedata(fd, image, memimage);
	if(err != nil)
		return err;

	return nil;
}

char*
writegif(Biobuf *fd, Image *image, char *comment, int dt, int trans)
{
	return writegif0(fd, image, nil, image->chan, image->r, comment, dt, trans);
}

char*
memwritegif(Biobuf *fd, Memimage *memimage, char *comment, int dt, int trans)
{
	return writegif0(fd, nil, memimage, memimage->chan, memimage->r, comment, dt, trans);
}

/*
 * Write little-endian 16-bit integer
 */
static
void
put2(Biobuf *fd, int i)
{
	Bputc(fd, i);
	Bputc(fd, i>>8);
}

/*
 * Get color map for all ldepths, in format suitable for writing out
 */
static
void
getcolormap(void)
{
	int i, col;
	ulong rgb;
	uchar *c;

	if(colormap[0] != nil)
		return;
	for(i=0; i<nelem(colormap); i++)
		colormap[i] = gifmalloc(3* colormapsize[i]);
	c = colormap[GREYMAP];	/* GREY8 */
	for(i=0; i<256; i++){
		c[3*i+0] = i;	/* red */
		c[3*i+1] = i;	/* green */
		c[3*i+2] = i;	/* blue */
	}
	c = colormap[3];	/* RGBV */
	for(i=0; i<256; i++){
		rgb = cmap2rgb(i);
		c[3*i+0] = (rgb>>16) & 0xFF;	/* red */
		c[3*i+1] = (rgb>> 8) & 0xFF;	/* green */
		c[3*i+2] = (rgb>> 0) & 0xFF;	/* blue */
	}
	c = colormap[2];	/* GREY4 */
	for(i=0; i<16; i++){
		col = (i<<4)|i;
		rgb = cmap2rgb(col);
		c[3*i+0] = (rgb>>16) & 0xFF;	/* red */
		c[3*i+1] = (rgb>> 8) & 0xFF;	/* green */
		c[3*i+2] = (rgb>> 0) & 0xFF;	/* blue */
	}
	c = colormap[1];	/* GREY2 */
	for(i=0; i<4; i++){
		col = (i<<6)|(i<<4)|(i<<2)|i;
		rgb = cmap2rgb(col);
		c[3*i+0] = (rgb>>16) & 0xFF;	/* red */
		c[3*i+1] = (rgb>> 8) & 0xFF;	/* green */
		c[3*i+2] = (rgb>> 0) & 0xFF;	/* blue */
	}
	c = colormap[0];	/* GREY1 */
	for(i=0; i<2; i++){
		if(i == 0)
			col = 0;
		else
			col = 0xFF;
		rgb = cmap2rgb(col);
		c[3*i+0] = (rgb>>16) & 0xFF;	/* red */
		c[3*i+1] = (rgb>> 8) & 0xFF;	/* green */
		c[3*i+2] = (rgb>> 0) & 0xFF;	/* blue */
	}
}

/*
 * Write header, logical screen descriptor, and color map
 */
static
void
writeheader(Biobuf *fd, Rectangle r, int depth, ulong chan, int loopcount)
{
	/* Header */
	Bprint(fd, "%s", "GIF89a");

	/*  Logical Screen Descriptor */
	put2(fd, Dx(r));
	put2(fd, Dy(r));

	/* Color table present, 4 bits per color (for RGBV best case), size of color map */
	Bputc(fd, (1<<7)|(3<<4)|(depth-1));	/* not right for GREY8, but GIF doesn't let us specify enough bits */
	Bputc(fd, 0xFF);	/* white background (doesn't matter anyway) */
	Bputc(fd, 0);	/* pixel aspect ratio - unused */

	/* Global Color Table */
	getcolormap();
	if(chan == GREY8)
		depth = GREYMAP;
	else
		depth = drawlog2[depth];
	Bwrite(fd, colormap[depth], 3*colormapsize[depth]);

	if(loopcount >= 0){	/* hard-to-discover way to force cycled animation */
		/* Application Extension with (1 loopcountlo loopcounthi) as data */
		Bputc(fd, 0x21);
		Bputc(fd, 0xFF);
		Bputc(fd, 11);
		Bwrite(fd, "NETSCAPE2.0", 11);
		Bputc(fd, 3);
		Bputc(fd, 1);
		put2(fd, loopcount);
		Bputc(fd, 0);
	}
}

/*
 * Write optional comment block
 */
static
void
writecomment(Biobuf *fd, char *comment)
{
	int n;

	if(comment==nil || comment[0]=='\0')
		return;

	/* Comment extension and label */
	Bputc(fd, 0x21);
	Bputc(fd, 0xFE);

	/* Comment data */
	n = strlen(comment);
	if(n > 255)
		n = 255;
	Bputc(fd, n);
	Bwrite(fd, comment, n);

	/* Block terminator */
	Bputc(fd, 0x00);
}

/*
 * Write optional control block (sets Delay Time)
 */
static
void
writegraphiccontrol(Biobuf *fd, int dt, int trans)
{
	if(dt < 0 && trans < 0)
		return;

	/* Comment extension and label and block size*/
	Bputc(fd, 0x21);
	Bputc(fd, 0xF9);
	Bputc(fd, 0x04);

	/* Disposal method and other flags (none) */
	if(trans >= 0)
		Bputc(fd, 0x01);
	else
		Bputc(fd, 0x00);
	
	/* Delay time, in centisec (argument is millisec for sanity) */
	if(dt < 0)
		dt = 0;
	else if(dt < 10)
		dt = 1;
	else
		dt = (dt+5)/10;
	put2(fd, dt);

	/* Transparency index */
	if(trans < 0)
		trans = 0;
	Bputc(fd, trans);

	/* Block terminator */
	Bputc(fd, 0x00);
}

/*
 * Write image descriptor
 */
static
void
writedescriptor(Biobuf *fd, Rectangle r)
{
	/* Image Separator */
	Bputc(fd, 0x2C);

	/* Left, top, width, height */
	put2(fd, r.min.x-mainrect.min.x);
	put2(fd, r.min.y-mainrect.min.y);
	put2(fd, Dx(r));
	put2(fd, Dy(r));
	/* no special processing */
	Bputc(fd, 0);
}

/*
 * Write data
 */
static
char*
writedata(Biobuf *fd, Image *image, Memimage *memimage)
{
	char *err;
	uchar *data;
	int ndata, depth;
	Rectangle r;

	if(memimage != nil){
		r = memimage->r;
		depth = memimage->depth;
	}else{
		r = image->r;
		depth = image->depth;
	}

	/* LZW Minimum code size */
	if(depth == 1)
		Bputc(fd, 2);
	else
		Bputc(fd, depth);

	/* 
	 * Read image data into memory
	 * potentially one extra byte on each end of each scan line
	 */
	ndata = Dy(r)*(2+(Dx(r)>>(3-drawlog2[depth])));
	data = gifmalloc(ndata);
	if(memimage != nil)
		ndata = unloadmemimage(memimage, r, data, ndata);
	else
		ndata = unloadimage(image, r, data, ndata);
	if(ndata < 0){
		err = gifmalloc(ERRMAX);
		snprint(err, ERRMAX, "WriteGIF: %r");
		free(data);
		return err;
	}

	/* Encode and emit the data */
	encode(fd, r, depth, data, ndata);
	free(data);

	/*  Block Terminator */
	Bputc(fd, 0);
	return nil;
}

/*
 * Write trailer
 */
void
endgif(Biobuf *fd)
{
	Bputc(fd, 0x3B);
	Bflush(fd);
}

void
memendgif(Biobuf *fd)
{
	endgif(fd);
}

/*
 * Put n bits of c into output at io.buf[i];
 */
static
void
output(IO *io, int c, int n)
{
	if(c < 0){
		if(io->nbits != 0)
			io->buf[io->i++] = io->sreg;
		Bputc(io->fd, io->i);
		Bwrite(io->fd, io->buf, io->i);
		io->nbits = 0;
		return;
	}

	if(io->nbits+n >= 31){
		fprint(2, "panic: WriteGIF sr overflow\n");
		exits("WriteGIF panic");
	}
	io->sreg |= c<<io->nbits;
	io->nbits += n;

	while(io->nbits >= 8){
		io->buf[io->i++] = io->sreg;
		io->sreg >>= 8;
		io->nbits -= 8;
	}

	if(io->i >= 255){
		Bputc(io->fd, 255);
		Bwrite(io->fd, io->buf, 255);
		memmove(io->buf, io->buf+255, io->i-255);
		io->i -= 255;
	}
}

/*
 * LZW encoder
 */
static
void
encode(Biobuf *fd, Rectangle r, int depth, uchar *data, uint ndata)
{
	int i, c, h, csize, prefix, first, sreg, nbits, bitsperpixel;
	int CTM, EOD, codesize, ld0, datai, x, ld, pm;
	int nentry, maxentry, early;
	Entry *e, *oe;
	IO *io;
	Entry **hash;

	first = 1;
	ld = drawlog2[depth];
	/* ldepth 0 must generate codesize 2 with values 0 and 1 (see the spec.) */
	ld0 = ld;
	if(ld0 == 0)
		ld0 = 1;
	codesize = (1<<ld0);
	CTM = 1<<codesize;
	EOD = CTM+1;

	io = gifmalloc(sizeof(IO));
	io->fd = fd;
	sreg = 0;
	nbits = 0;
	bitsperpixel = 1<<ld;
	pm = (1<<bitsperpixel)-1;

	datai = 0;
	x = r.min.x;
	hash = gifmalloc(Nhash*sizeof(Entry*));

Init:
	memset(hash, 0, Nhash*sizeof(Entry*));
	csize = codesize+1;
	nentry = EOD+1;
	maxentry = (1<<csize);
	for(i = 0; i<nentry; i++){
		e = &tbl[i];
		h = (e->prefix<<24) | (e->exten<<8);
		h %= Nhash;
		if(h < 0)
			h += Nhash;
		e->next = hash[h];
		hash[h] = e;
	}
	prefix = -1;
	if(first)
		output(io, CTM, csize);
	first = 0;

	/*
	 * Scan over pixels.  Because of partially filled bytes on ends of scan lines,
	 * which must be ignored in the data stream passed to GIF, this is more
	 * complex than we'd like.
	 */
Next:
	for(;;){
		if(ld != 3){
			/* beginning of scan line is difficult; prime the shift register */
			if(x == r.min.x){
				if(datai == ndata)
					break;
				sreg = data[datai++];
				nbits = 8-((x&(7>>ld))<<ld);
			}
			x++;
			if(x == r.max.x)
				x = r.min.x;
		}
		if(nbits == 0){
			if(datai == ndata)
				break;
			sreg = data[datai++];
			nbits = 8;
		}
		nbits -= bitsperpixel;
		c = sreg>>nbits & pm;
		h = prefix<<24 | c<<8;
		h %= Nhash;
		if(h < 0)
			h += Nhash;
		oe = nil;
		for(e = hash[h]; e!=nil; e=e->next){
			if(e->prefix == prefix && e->exten == c){
				if(oe != nil){
					oe->next = e->next;
					e->next = hash[h];
					hash[h] = e;
				}
				prefix = e->index;
				goto Next;
			}
			oe = e;
		}

		output(io, prefix, csize);
		early = 0; /* peculiar tiff feature here for reference */
		if(nentry == maxentry-early){
			if(csize == 12){
				nbits += bitsperpixel;	/* unget pixel */
				x--;
				if(ld != 3 && x == r.min.x)
					datai--;
				output(io, CTM, csize);
				goto Init;
			}
			csize++;
			maxentry = (1<<csize);
		}

		e = &tbl[nentry];
		e->prefix = prefix;
		e->exten = c;
		e->next = hash[h];
		hash[h] = e;

		prefix = c;
		nentry++;
	}

	output(io, prefix, csize);
	output(io, EOD, csize);
	output(io, -1, csize);
	free(io);
	free(hash);
}

static
void*
gifmalloc(ulong sz)
{
	void *v;
	v = malloc(sz);
	if(v == nil) {
		fprint(2, "WriteGIF: out of memory allocating %ld\n", sz);
abort();
		exits("mem");
	}
	memset(v, 0, sz);
	return v;
}
