aboutsummaryrefslogtreecommitdiffstats
path: root/todo.html
Commit message (Expand)AuthorAgeFilesLines
* Fix patch for Sunil Shetye's POP3 tweaks.Eric S. Raymond2004-01-131-2/+25
* Close a Debian bug.Eric S. Raymond2003-10-101-2/+13
* First round ofmlong-delayed bug fixes.Eric S. Raymond2003-07-171-2/+4
* Documentation updates.Eric S. Raymond2003-02-281-2/+11
* IDLE implementation.Eric S. Raymond2003-02-281-10/+2
* Fix a minor bug reported by Matthias Andree.Eric S. Raymond2002-09-171-31/+2
* XML headers everywhere.Eric S. Raymond2002-07-301-2/+3
* XML conversionEric S. Raymond2002-07-281-93/+108
* Cleanup.Eric S. Raymond2002-07-281-6/+6
* Cleanup.Eric S. Raymond2002-07-281-7/+8
* Added a bug note.Eric S. Raymond2002-03-091-2/+27
* Initial version of ESMTP AUTH.Eric S. Raymond2002-03-091-7/+2
* Note a new bug.Eric S. Raymond2001-12-141-2/+8
* License cleanup.Eric S. Raymond2001-09-301-10/+2
* Eliminate a bug.Eric S. Raymond2001-09-241-5/+2
* Added TODO about license com[patibility.Eric S. Raymond2001-09-221-2/+10
* Ready to ship.Eric S. Raymond2001-08-101-2/+6
* Updated buglist.Eric S. Raymond2001-07-311-38/+21
* Note Paul Howarth's error.Eric S. Raymond2001-07-061-2/+19
* Resady to ship.Eric S. Raymond2001-05-301-2/+5
* SSL certification handling.Eric S. Raymond2001-05-141-5/+3
* Version bump.Eric S. Raymond2001-02-191-3/+3
* Initial revisionEric S. Raymond2001-02-111-0/+74
: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#include <stdio.h>
#include <stdlib.h>

#include "meh.h"

unsigned short getshort(FILE *f){
	unsigned short ret;
	ret = getc(f);
	ret = ret | (getc(f) << 8);
	return ret;
}

unsigned long getlong(FILE *f){
	unsigned short ret;
	ret = getc(f);
	ret = ret | (getc(f) << 8);
	ret = ret | (getc(f) << 16);
	ret = ret | (getc(f) << 24);
	return ret;
}

struct rgb_t{
	unsigned char r, g, b;
};

struct bmp_t{
	struct image img;
	unsigned long bitmapoffset;
	int compression;
	int bpp;
	int ncolors;
	struct rgb_t *colours;
	unsigned int rowwidth;
};

struct image *bmp_open(FILE *f){
	struct bmp_t *b;
	unsigned long headersize;
	
	rewind(f);
	if(getc(f) != 'B' || getc(f) != 'M')
		return NULL;

	b = malloc(sizeof(struct bmp_t));
	b->img.f = f;

	fseek(f, 10, SEEK_SET);
	b->bitmapoffset = getlong(f);

	fseek(f, 14, SEEK_SET);
	headersize = getlong(f);

	if(headersize == 12){ /* OS/2 v1 */
		b->ncolors = 0;
		fseek(f, 18, SEEK_SET);
		b->img.width = getshort(f);
		b->img.height = getshort(f);
		b->compression = 0;
	}else{
		fseek(f, 18, SEEK_SET);
		b->img.width = getlong(f);
		b->img.height = getlong(f);

		fseek(f, 28, SEEK_SET);
		b->bpp = getshort(f);

		fseek(f, 30, SEEK_SET);
		b->compression = getlong(f);

		fseek(f, 46, SEEK_SET);
		b->ncolors = getlong(f);
	}

	if(!b->ncolors){
		b->ncolors = 1 << b->bpp;
	}

	if(b->compression){
		fprintf(stderr, "unsupported compression method %i\n", b->compression);
		return NULL;
	}

	if(b->bpp >= 16){
		b->rowwidth = b->img.width * b->bpp / 8;
	}else{
		int i;
		b->colours = malloc(b->ncolors * sizeof(struct rgb_t));
		fseek(f, 14+headersize, SEEK_SET);
		for(i = 0; i < b->ncolors; i++){
			b->colours[i].b = getc(f);
			b->colours[i].g = getc(f);
			b->colours[i].r = getc(f);
			if(headersize != 12)
				getc(f);
		}
		b->rowwidth = (b->img.width * b->bpp + 7) / 8;
	}
	if(b->rowwidth & 3){
		b->rowwidth += 4 - (b->rowwidth & 3);
	}

	return (struct image *)b;
}

void rgb16(unsigned char *buf, unsigned short c){
	int i;
	for(i = 0; i < 3; i++){
		*buf++ = ((c >> (i * 5)) & 0x1f) << 3;
	}
}

static int readrow(struct image *img, unsigned char *row, unsigned char *buf){
	struct bmp_t *b = (struct bmp_t *)img;
	unsigned int x, i = 0;
	if(b->bpp == 24 || b->bpp == 32){
		for(x = 0; x < img->width * 3; x+=3){
			buf[x + 2] = row[i++];
			buf[x + 1] = row[i++];
			buf[x + 0] = row[i++];
			if(b->bpp == 32)
				i++;
		}
	}else if(b->bpp == 16){
		for(x = 0; x < img->width * 3; x+=3){
			unsigned short c;
			c = row[i++];
			c |= row[i++] << 8;
			rgb16(&buf[x], c);
		}
	}else if(b->bpp <= 8){
		int mask;
		int pixelsperbit = 8 / b->bpp;
		mask = ~((~0) << b->bpp);
		for(x = 0; x < img->width; x++){
			unsigned char c = ((row[i / pixelsperbit]) >> ((8 - ((i+1) % pixelsperbit) * b->bpp)) % 8) & mask;
			*buf++ = b->colours[c].r;
			*buf++ = b->colours[c].g;
			*buf++ = b->colours[c].b;
			i++;
		}
	}else{
		fprintf(stderr, "bad bpp %i\n", b->bpp);
		return 1;
	}
	return 0;
}

int bmp_read(struct image *img){
	struct bmp_t *b = (struct bmp_t *)img;
	unsigned int i, y;
	unsigned int dy;
	unsigned char *row;
	FILE *f = img->f;

	row = malloc(b->rowwidth);
	dy = img->width * 3;
	i = img->height * dy;

	fseek(f, b->bitmapoffset, SEEK_SET);
	for(y = img->height; y; y--){
		i -= dy;
		if(fread(row, 1, b->rowwidth, f) != b->rowwidth || readrow(img, row, &img->buf[i])){
			free(row);
			return 1;
		}
	}

	free(row);
	return 0;
}

struct imageformat gif = {
	bmp_open,
	bmp_read
};