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

/*
 MS-BMP file reader
 (c) 2003, I.P.Keller

 aims to decode *all* valid bitmap formats, although some of the
 flavours couldn't be verified due to lack of suitable test-files.
 the following flavours are supported:

	Bit/Pix	Orientation	Compression	Tested?
	  1	top->bottom	n/a		yes
	  1	bottom->top	n/a		yes
	  4	top->bottom	no		yes
	  4	bottom->top	no		yes
	  4	top->bottom	RLE4		yes, but not with displacement
	  8	top->bottom	no		yes
	  8	bottom->top	no		yes
	  8	top->bottom	RLE8		yes, but not with displacement
	 16	top->bottom	no		no
	 16	bottom->top	no		no
	 16	top->bottom	BITMASK		no
	 16	bottom->top	BITMASK		no
	 24	top->bottom	n/a		yes
	 24	bottom->top	n/a		yes
	 32	top->bottom	no		no
	 32	bottom->top	no		no
	 32	top->bottom	BITMASK		no
	 32	bottom->top	BITMASK		no

 OS/2 1.x bmp files are recognised as well, but testing was very limited.

 verifying was done with a number of test files, generated by
 different tools. nevertheless, the tests were in no way exhaustive
 enough to guarantee bug-free decoding. caveat emptor!
*/

static short
r16(Biobuf*b)
{
	short s;

	s = Bgetc(b);
	s |= ((short)Bgetc(b)) << 8;
	return s;
}


static long
r32(Biobuf*b)
{
	long l;

	l = Bgetc(b);
	l |= ((long)Bgetc(b)) << 8;
	l |= ((long)Bgetc(b)) << 16;
	l |= ((long)Bgetc(b)) << 24;
	return l;
}


/* get highest bit set */
static int
msb(ulong x)
{
	int i;
	for(i = 32; i; i--, x <<= 1)
		if(x & 0x80000000L)
			return i;
	return 0;
}

/* Load a 1-Bit encoded BMP file (uncompressed) */
static int
load_1T(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	long ix, iy, i = 0, step_up = 0, padded_width = ((width + 31) / 32) * 32;
	int val = 0, n;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	for(iy = height; iy; iy--, i += step_up)
		for(ix = 0, n = 0; ix < padded_width; ix++, n--) {
			if(!n) {
				val = Bgetc(b);
				n = 8;
			}
			if(ix < width) {
				buf[i] = clut[val & 0x80 ? 1 : 0];
				i++;
			}
			val <<= 1;
		}
	return 0;
}

/* Load a 4-Bit encoded BMP file (uncompressed) */
static int
load_4T(Biobuf* b, long width, long height, Rgb* buf, Rgb* clut)
{
	long ix, iy, i = 0, step_up = 0, skip = (4 - (((width % 8) + 1) / 2)) & 3;
	uint valH, valL;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	for(iy = height; iy; iy--, i += step_up) {
		for(ix = 0; ix < width; ) {
			valH = valL = Bgetc(b) & 0xff;
			valH >>= 4;

			buf[i] = clut[valH];
			i++; ix++;

			if(ix < width) {
				valL &= 0xf;
				buf[i] = clut[valL];
				i++; ix++;
			}
		}
		Bseek(b, skip, 1);
	}
	return 0;
}

/* Load a 4-Bit encoded BMP file (RLE4-compressed) */
static int
load_4C(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	long ix, iy = height -1;
	uint val, valS, skip;
	Rgb* p;

	while(iy >= 0) {
		ix = 0;
		while(ix < width) {
			val = Bgetc(b);

			if(0 != val) {
				valS = (uint)Bgetc(b);
				p = &buf[ix + iy * width];
				while(val--) {
					*p = clut[0xf & (valS >> 4)];
					p++;
					ix++;
					if(0 < val) {
						*p = clut[0xf & valS];
						p++;
						ix++;
						val--;
					}
				}
			} else {
				/* Special modes... */
				val = Bgetc(b);
				switch(val) {
					case 0:	/* End-Of-Line detected */
						ix = width;
						iy--;
						break;
					case 1:	/* End-Of-Picture detected -->> abort */
						ix = width;
						iy = -1;
						break;
					case 2:	/* Position change detected */
						val = Bgetc(b);
						ix += val;
						val = Bgetc(b);
						iy -= val;
						break;

					default:/* Transparent data sequence detected */
						p = &buf[ix + iy * width];
						if((1 == (val & 3)) || (2 == (val & 3)))
							skip = 1;
						else 
							skip = 0;

						while(val--) {
							valS = (uint)Bgetc(b);
							*p = clut[0xf & (valS >> 4)];
							p++;
							ix++;
							if(0 < val) {
								*p = clut[0xf & valS];
								p++;
								ix++;
								val--;
							}
						}
						if(skip)
							Bgetc(b);
						break;
				}
			}
		}
	}
	return 0;
}

/* Load a 8-Bit encoded BMP file (uncompressed) */
static int
load_8T(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	long ix, iy, i = 0, step_up = 0, skip = (4 - (width % 4)) & 3;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	for(iy = height; iy; iy--, i += step_up) {
		for(ix = 0; ix < width; ix++, i++)
			buf[i] = clut[Bgetc(b) & 0xff];
		Bseek(b, skip, 1);
	}
	return 0;
}

/* Load a 8-Bit encoded BMP file (RLE8-compressed) */
static int
load_8C(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	long ix, iy = height -1;
	int val, valS, skip;
	Rgb* p;

	while(iy >= 0) {
		ix = 0;
		while(ix < width) {
			val = Bgetc(b);

			if(0 != val) {
				valS = Bgetc(b);
				p = &buf[ix + iy * width];
				while(val--) {
					*p = clut[valS];
					p++;
					ix++;
				}
			} else {
				/* Special modes... */
				val = Bgetc(b);
				switch(val) {
					case 0: /* End-Of-Line detected */
						ix = width;
						iy--;
						break;
					case 1: /* End-Of-Picture detected */
						ix = width;
						iy = -1;
						break;
					case 2: /* Position change detected */
						val = Bgetc(b);
						ix += val;
						val = Bgetc(b);
						iy -= val;
						break;
					default: /* Transparent (not compressed) sequence detected */
						p = &buf[ix + iy * width];
						if(val & 1)
							skip = 1;
						else 
							skip = 0;

						while(val--) {
							valS = Bgetc(b);
							*p = clut[valS];
							p++;
							ix++;
						}
						if(skip)
							/* Align data stream */
							Bgetc(b);
						break;
				}
			}
		}
	}
	return 0;
}

/* Load a 16-Bit encoded BMP file (uncompressed) */
static int
load_16(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	uchar c[2];
	long ix, iy, i = 0, step_up = 0;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	if(clut) {
		unsigned mask_blue =  (unsigned)clut[0].blue +
		                     ((unsigned)clut[0].green << 8);
		unsigned mask_green =  (unsigned)clut[1].blue +
		                      ((unsigned)clut[1].green << 8);
		unsigned mask_red =  (unsigned)clut[2].blue +
		                    ((unsigned)clut[2].green << 8);
		int shft_blue = msb((ulong)mask_blue) - 8;
		int shft_green = msb((ulong)mask_green) - 8;
		int shft_red = msb((ulong)mask_red) - 8;

		for(iy = height; iy; iy--, i += step_up)
			for(ix = 0; ix < width; ix++, i++) {
				unsigned val;
				Bread(b, c, sizeof(c));
				val = (unsigned)c[0] + ((unsigned)c[1] << 8);

				buf[i].alpha = 0;
				if(shft_blue >= 0)
					buf[i].blue = (uchar)((val & mask_blue) >> shft_blue);
				else
					buf[i].blue = (uchar)((val & mask_blue) << -shft_blue);
				if(shft_green >= 0)
					buf[i].green = (uchar)((val & mask_green) >> shft_green);
				else
					buf[i].green = (uchar)((val & mask_green) << -shft_green);
				if(shft_red >= 0)
					buf[i].red = (uchar)((val & mask_red) >> shft_red);
				else
					buf[i].red = (uchar)((val & mask_red) << -shft_red);
			}
	} else
		for(iy = height; iy; iy--, i += step_up)
			for(ix = 0; ix < width; ix++, i++) {
				Bread(b, c, sizeof(c));
				buf[i].blue = (uchar)((c[0] << 3) & 0xf8);
				buf[i].green = (uchar)(((((unsigned)c[1] << 6) +
				                        (((unsigned)c[0]) >> 2))) & 0xf8);
				buf[i].red = (uchar)((c[1] << 1) & 0xf8);
			}
	return 0;
}

/* Load a 24-Bit encoded BMP file (uncompressed) */
static int
load_24T(Biobuf* b, long width, long height, Rgb* buf)
{
	long ix, iy, i = 0, step_up = 0, skip = (4 - ((width * 3) % 4)) & 3;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	for(iy = height; iy; iy--, i += step_up) {
		for(ix = 0; ix < width; ix++, i++) {
			buf[i].alpha = 0;
			buf[i].blue = Bgetc(b);
			buf[i].green = Bgetc(b);
			buf[i].red = Bgetc(b);
		}
		Bseek(b, skip, 1);
	}
	return 0;
}

/* Load a 32-Bit encoded BMP file (uncompressed) */
static int
load_32(Biobuf *b, long width, long height, Rgb* buf, Rgb* clut)
{
	uchar c[4];
	long ix, iy, i = 0, step_up = 0;

	if(height > 0) {	/* bottom-up */
		i = (height - 1) * width;
		step_up = -2 * width;
	} else
		height = -height;

	if(clut) {
		ulong mask_blue =  (ulong)clut[0].blue +
		                          ((ulong)clut[0].green << 8) +
		                          ((ulong)clut[0].red << 16) +
		                          ((ulong)clut[0].alpha << 24);
		ulong mask_green =  (ulong)clut[1].blue +
		                           ((ulong)clut[1].green << 8) +
		                           ((ulong)clut[1].red << 16) +
		                           ((ulong)clut[1].alpha << 24);
		ulong mask_red =  (ulong)clut[2].blue +
		                         ((ulong)clut[2].green << 8) +
		                         ((ulong)clut[2].red << 16) +
		                         ((ulong)clut[2].alpha << 24);
		int shft_blue = msb(mask_blue) - 8;
		int shft_green = msb(mask_green) - 8;
		int shft_red = msb(mask_red) - 8;

		for(iy = height; iy; iy--, i += step_up)
			for(ix = 0; ix < width; ix++, i++) {
				ulong val;
				Bread(b, c, sizeof(c));
				val =  (ulong)c[0] + ((ulong)c[1] << 8) +
				      ((ulong)c[2] << 16) + ((ulong)c[1] << 24);

				buf[i].alpha = 0;
				if(shft_blue >= 0)
					buf[i].blue = (uchar)((val & mask_blue) >> shft_blue);
				else
					buf[i].blue = (uchar)((val & mask_blue) << -shft_blue);
				if(shft_green >= 0)
					buf[i].green = (uchar)((val & mask_green) >> shft_green);
				else
					buf[i].green = (uchar)((val & mask_green) << -shft_green);
				if(shft_red >= 0)
					buf[i].red = (uchar)((val & mask_red) >> shft_red);
				else
					buf[i].red = (uchar)((val & mask_red) << -shft_red);
			}
	} else
		for(iy = height; iy; iy--, i += step_up)
			for(ix = 0; ix < width; ix++, i++) {
				Bread(b, c, nelem(c));
				buf[i].blue = c[0];
				buf[i].green = c[1];
				buf[i].red = c[2];
			}
	return 0;
}


static Rgb*
ReadBMP(Biobuf *b, int *width, int *height)
{
	int colours, num_coltab = 0;
	Filehdr bmfh;
	Infohdr bmih;
	Rgb clut[256];
	Rgb* buf;

	bmfh.type = r16(b);
	if(bmfh.type != 0x4d42) 	/* signature must be 'BM' */
		sysfatal("bad magic number, not a BMP file");

	bmfh.size = r32(b);
	bmfh.reserved1 = r16(b);
	bmfh.reserved2 = r16(b);
	bmfh.offbits = r32(b);

	memset(&bmih, 0, sizeof(bmih));
	bmih.size = r32(b);

	if(bmih.size == 0x0c) {			/* OS/2 1.x version */
		bmih.width = r16(b);
		bmih.height = r16(b);
		bmih.planes = r16(b);
		bmih.bpp = r16(b);
		bmih.compression = BMP_RGB;
	} else {				/* Windows */
		bmih.width = r32(b);
		bmih.height = r32(b);
		bmih.planes = r16(b);
		bmih.bpp = r16(b);
		bmih.compression = r32(b);
		bmih.imagesize = r32(b);
		bmih.hres = r32(b);
		bmih.vres = r32(b);
		bmih.colours = r32(b);
		bmih.impcolours = r32(b);
	}

	if(bmih.bpp < 16) {
		/* load colour table */
		if(bmih.impcolours)
			num_coltab = (int)bmih.impcolours;
		else
			num_coltab = 1 << bmih.bpp;
	} else if(bmih.compression == BMP_BITFIELDS &&
	          (bmih.bpp == 16 || bmih.bpp == 32))
		/* load bitmasks */
		num_coltab = 3;

	if(num_coltab) {
		int i; 
		Bseek(b, bmih.size + sizeof(Infohdr), 0);

		for(i = 0; i < num_coltab; i++) {
			clut[i].blue  = (uchar)Bgetc(b);
			clut[i].green = (uchar)Bgetc(b);
			clut[i].red   = (uchar)Bgetc(b);
			clut[i].alpha = (uchar)Bgetc(b);
		}
	}

	*width = bmih.width;
	*height = bmih.height;
	colours = bmih.bpp;

	Bseek(b, bmfh.offbits, 0);

	if ((buf = calloc(sizeof(Rgb), *width * abs(*height))) == nil)
		sysfatal("no memory");

	switch(colours) {
		case 1:
			load_1T(b, *width, *height, buf, clut);
			break;
		case 4:
			if(bmih.compression == BMP_RLE4)
				load_4C(b, *width, *height, buf, clut);
			else
				load_4T(b, *width, *height, buf, clut);
			break;
		case 8:
			if(bmih.compression == BMP_RLE8)
				load_8C(b, *width, *height, buf, clut);
			else
				load_8T(b, *width, *height, buf, clut);
			break;
		case 16:
			load_16(b, *width, *height, buf,
			        bmih.compression == BMP_BITFIELDS ? clut : nil);
			break;
		case 24:
			load_24T(b, *width, *height, buf);
			break;
		case 32:
			load_32(b, *width, *height, buf,
			        bmih.compression == BMP_BITFIELDS ? clut : nil);
			break;
	}
	return buf;
}

Rawimage**
Breadbmp(Biobuf *bp, int colourspace)
{
	Rawimage *a, **array;
	int c, width, height;
	uchar *r, *g, *b;
	Rgb *s, *e;
	Rgb *bmp;
	char ebuf[128];

	a = nil;
	bmp = nil;
	array = nil;
	USED(a);
	USED(bmp);
	if (colourspace != CRGB) {
		errstr(ebuf, sizeof ebuf);	/* throw it away */
		werrstr("ReadRGB: unknown colour space %d", colourspace);
		return nil;
	}

	if ((bmp = ReadBMP(bp, &width, &height)) == nil)
		return nil;

	if ((a = calloc(sizeof(Rawimage), 1)) == nil)
		goto Error;

	for (c = 0; c  < 3; c++)
		if ((a->chans[c] = calloc(width, height)) == nil)
			goto Error;

	if ((array = calloc(sizeof(Rawimage *), 2)) == nil)
		goto Error;
	array[0] = a;
	array[1] = nil;

	a->nchans = 3;
	a->chandesc = CRGB;
	a->chanlen = width * height;
	a->r = Rect(0, 0, width, height);

	s = bmp;
	e = s + width * height;
	r = a->chans[0];
	g = a->chans[1];
	b = a->chans[2];

	do {
		*r++ = s->red;
		*g++ = s->green;
		*b++ = s->blue;
	}while(++s < e);

	free(bmp);
	return array;

Error:
	if (a)
		for (c = 0; c < 3; c++)
			if (a->chans[c])
				free(a->chans[c]);
	if (a)
		free(a);
	if (array)
		free(array);
	if (bmp)
		free(bmp);
	return nil;

}

Rawimage**
readbmp(int fd, int colorspace)
{
	Rawimage * *a;
	Biobuf b;

	if (Binit(&b, fd, OREAD) < 0)
		return nil;
	a = Breadbmp(&b, colorspace);
	Bterm(&b);
	return a;
}


