#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;
}
