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

enum
{
	FileHdrLen=	6,
	IconDescrLen=	16,
	IconHdrLen=	40,
};

typedef struct Icon Icon;
struct Icon
{
	Icon	*next;
	char	*file;

	uchar	w;		/* icon width */
	uchar	h;		/* icon height */
	ushort	ncolor;		/* number of colors */
	ushort	nplane;		/* number of bit planes */
	ushort	bits;		/* bits per pixel */
	ulong	len;		/* length of data */
	ulong	offset;		/* file offset to data */
	uchar	map[4*256];	/* color map */

	Image	*img;

	uchar	*xor;
	int	xorlen;
	uchar	*and;
	int	andlen;
};

typedef struct Header Header;
struct Header
{
	uint	n;
	Icon	*first;
	Icon	*last;
};

void
Bputs(Biobuf *b, ushort x)
{
	Bputc(b, x&0xff);
	Bputc(b, x>>8);
}

void
Bputl(Biobuf *b, ulong x)
{
	Bputs(b, x&0xffff);
	Bputs(b, x>>16);
}

Header h;

void*	emalloc(int);
void	mk8bit(Icon*, int);
void	mkxorand(Icon*, int);
void	readicon(char*);

void
main(int argc, char **argv)
{
	int i;
	Biobuf *b, out;
	Icon *icon;
	ulong offset;
	ulong len;

	ARGBEGIN{
	}ARGEND;

	/* read in all the images */
	initdraw(nil, nil, nil);
	if(argc < 1){
		readicon("/fd/0");
	} else {
		for(i = 0; i < argc; i++)
			readicon(argv[i]);
	}

	/* create the .ico file */
	b = &out;
	Binit(b, 1, OWRITE);

	/* offset to first icon */
	offset = FileHdrLen + h.n*IconDescrLen;

	/* file header is */
	Bputs(b, 0);
	Bputs(b, 1);
	Bputs(b, h.n);

	/* icon description */
	for(icon = h.first; icon != nil; icon = icon->next){
		Bputc(b, icon->w);
		Bputc(b, icon->h);
		Bputc(b, icon->ncolor);
		Bputc(b, 0);
		Bputs(b, icon->nplane);
		Bputs(b, icon->bits);
		len = IconHdrLen + icon->ncolor*4 + icon->xorlen + icon->andlen;
		Bputl(b, len);
		Bputl(b, offset);
		offset += len;
	}

	/* icons */
	for(icon = h.first; icon != nil; icon = icon->next){
		/* icon header (BMP like) */
		Bputl(b, IconHdrLen);
		Bputl(b, icon->w);
		Bputl(b, 2*icon->h);
		Bputs(b, icon->nplane);
		Bputs(b, icon->bits);
		Bputl(b, 0);	/* compression info */
		Bputl(b, 0);
		Bputl(b, 0);
		Bputl(b, 0);
		Bputl(b, 0);
		Bputl(b, 0);

		/* color map */
		if(Bwrite(b, icon->map, 4*icon->ncolor) < 0)
			sysfatal("writing color map: %r");

		/* xor bits */
		if(Bwrite(b, icon->xor, icon->xorlen) < 0)
			sysfatal("writing xor bits: %r");

		/* and bits */
		if(Bwrite(b, icon->and, icon->andlen) < 0)
			sysfatal("writing and bits: %r");
	}

	Bterm(b);
	exits(0);
}

void
readicon(char *file)
{
	int fd;
	Icon *icon;

	fd = open(file, OREAD);
	if(fd < 0)
		sysfatal("opening %s: %r", file);
	icon = emalloc(sizeof(Icon));
	icon->img = readimage(display, fd, 0);
	if(icon->img == nil)
		sysfatal("reading image %s: %r", file);
	close(fd);

	if(h.first)
		h.last->next = icon;
	else
		h.first = icon;
	h.last = icon;
	h.n++;

	icon->h = Dy(icon->img->r);
	icon->w = Dx(icon->img->r);
	icon->bits = 1<<icon->img->depth;
	icon->nplane = 1;

	/* convert to 8 bits per pixel */
	switch(icon->img->chan){
	case GREY8:
	case CMAP8:
		break;
	case GREY1:
	case GREY2:
	case GREY4:
		mk8bit(icon, 1);
		break;
	default:
		mk8bit(icon, 0);
		break;
	}
	icon->bits = 8;
	icon->file = file;

	/* create xor/and masks, minimizing bits per pixel */
	mkxorand(icon, icon->img->chan == GREY8);
}

void*
emalloc(int len)
{
	void *x;

	x = mallocz(len, 1);
	if(x == nil)
		sysfatal("memory: %r");
	return x;
}

/* convert to 8 bit */
void
mk8bit(Icon *icon, int grey)
{
	Image *img;

	img = allocimage(display, icon->img->r, grey ? GREY8 : CMAP8, 0, DNofill);
	if(img == nil)
		sysfatal("can't allocimage: %r");
	draw(img, img->r, icon->img, nil, ZP);
	freeimage(icon->img);
	icon->img = img;
}

/* make xor and and mask */
void
mkxorand(Icon *icon, int grey)
{
	int i, x, y, s, sa;
	uchar xx[256];
	uchar *data, *p, *e;
	int ndata;
	uchar *mp;
	int ncolor;
	ulong color;
	int bits;
	uchar andbyte, xorbyte;
	uchar *ato, *xto;
	int xorrl, andrl;

	ndata = icon->h * icon->w;
	data = emalloc(ndata);
	if(unloadimage(icon->img, icon->img->r, data, ndata) < 0)
		sysfatal("can't unload %s: %r", icon->file);
	e = data + ndata;

	/* find colors used */
	memset(xx, 0, sizeof xx);
	for(p = data; p < e; p++)
		xx[*p]++;

	/* count the colors and create a mapping from plan 9 */
	mp = icon->map;
	ncolor = 0;
	for(i = 0; i < 256; i++){
		if(xx[i] == 0)
			continue;
		if(grey){
			*mp++ = i;
			*mp++ = i;
			*mp++ = i;
			*mp++ = 0;
		} else {
			color = cmap2rgb(i);
			*mp++ = color;
			*mp++ = color>>8;
			*mp++ = color>>16;
			*mp++ = 0;
		}
		xx[i] = ncolor;
		ncolor++;
	}

	/* get minimum number of pixels per bit (with a color map) */
	if(ncolor <= 2){
		ncolor = 2;
		bits = 1;
	} else if(ncolor <= 4){
		ncolor = 4;
		bits = 2;
	} else if(ncolor <= 16){
		ncolor = 16;
		bits = 4;
	} else {
		ncolor = 256;
		bits = 8;
	}
	icon->bits = bits;
	icon->ncolor = ncolor;

	/* the xor mask rows are justified to a 32 bit boundary */
	/* the and mask is 1 bit grey */
	xorrl = 4*((bits*icon->w + 31)/32);
	andrl = 4*((icon->w + 31)/32);
	icon->xor = emalloc(xorrl * icon->h);
	icon->and = emalloc(andrl * icon->h);
	icon->xorlen = xorrl*icon->h;
	icon->andlen = andrl*icon->h;

	/* make both masks.  they're upside down relative to plan9 ones */
	p = data;
	for(y = 0; y < icon->h; y++){
		andbyte = 0;
		xorbyte = 0;
		sa = s = 0;
		xto = icon->xor + (icon->h-1-y)*xorrl;
		ato = icon->and + (icon->h-1-y)*andrl;
		for(x = 0; x < icon->w; x++){
			xorbyte <<= bits;
			xorbyte |= xx[*p];
			s += bits;
			if(s == 8){
				*xto++ = xorbyte;
				xorbyte = 0;
				s = 0;
			}
			andbyte <<= 1;
			if(*p == 0xff)
				andbyte |= 1;
			sa++;
			if(sa == 0){
				*ato++ = andbyte;
				sa = 0;
				andbyte = 0;
			}
			p++;
		}
	}
	free(data);
}
