ftp.nice.ch/pub/next/graphics/viewer/ToyViewer.2.6a.s.tar.gz#/ToyViewer2.6a/src/bmpimage.c

This is bmpimage.c in view mode; [Download] [Up]

#include <stdio.h>
#include <libc.h>

#include "bmp.h"

static xdelta, ydelta, compmode;

static int bmpGetPalette(FILE *fp, bmpHeader *bh)
     /* ¥Ñ¥ì¥Ã¥È¤òÆɤ߹þ¤ó¤Ç¤½¤ÎÎΰè¤ÎÀèƬ¥¢¥É¥ì¥¹¤ò bh->palette¤ËÂåÆþ¡£
	¥¨¥é¡¼¤Î»þ¡¢¤ª¤è¤Ó24¥Ó¥Ã¥È¥«¥é¡¼¤Î»þ¤Ë¤Ï NULL ¤¬Æþ¤ë¡£
	ÊÖ¤êÃͤϡ¢À®¸ù¤Î¾ì¹ç 0, ¥¨¥é¡¼¤Î¾ì¹ç¤Ï¸¶°ø(!=0)¡£ */
{
	int	i, color;
	paltype	*pal = NULL;
	unsigned char *p;

	bh->palette = NULL;
	if (bh->bits == 24)	/* 24¥Ó¥Ã¥È¥«¥é¡¼¤Ï¥Ñ¥ì¥Ã¥ÈÉÔÍ× */
		return 0;
	color = 1 << bh->bits;
	pal = (paltype *)malloc(sizeof(paltype) * color);
	if (bh->type == OS2) {
		for (i = 0; i < color; i++) {
			p = pal[i];
			p[BLUE] = getc(fp);
			p[GREEN] = getc(fp);
			p[RED] = getc(fp);
		}
	}else { /* WIN3 */
		for (i = 0; i < color; i++) {
			p = pal[i];
			p[BLUE] = getc(fp);
			p[GREEN] = getc(fp);
			p[RED] = getc(fp);
			(void) getc(fp);
		}
	}
	bh->palette = pal;
	if (feof(fp) || fseek(fp, bh->bitoffset, SEEK_SET) < 0)
		return Err_SHORT;
	return 0;
}

static int get1dot(FILE *fp, int wid, unsigned char *ln)
{
	int x, cnt, cc, mask;

	if (feof(fp))
		return -1;
	for (x = 0, cnt = 0; x < wid; cnt++) {
		cc = getc(fp);
		for (mask = 0x80; mask; mask >>= 1)
			ln[x++] = (cc & mask) ? 1 : 0;
	}
	for ( ; cnt & 0x03; cnt++)
		(void) getc(fp);
	return 0;
}

static int get4dots(FILE *fp, int wid, unsigned char *ln)
{
	int x, cnt, cc;

	if (feof(fp))
		return -1;
	for (x = 0, cnt = 0; x < wid; cnt++) {
		cc = getc(fp);
		ln[x++] = cc >> 4;
		ln[x++] = (cc & 0x0f);
	}
	for ( ; cnt & 0x03; cnt++)
		(void) getc(fp);
	return 0;
}

static int get8dots(FILE *fp, int wid, unsigned char *ln)
{
	int cnt;

	if (feof(fp))
		return -1;
	for (cnt = 0; cnt < wid; cnt++)
		ln[cnt] = getc(fp);
	for ( ; cnt & 0x03; cnt++)
		(void) getc(fp);
	return 0;
}

static int rledots(FILE *fp, int wid, unsigned char *ln)
{
	int	i, j, k, cc, count;
	int	half[2];

	if (feof(fp))
		return -1;
	for (i = 0; i < wid; i++)
		ln[i] = 0;
	if (ydelta > 0) {
		ydelta--;
		return 0;
	}
	count = wid;
	if (xdelta > 0) {
		if (xdelta > count) {
			xdelta = 0;
			return 0;
		}
		count -= xdelta;
		ln += xdelta;
	}
	xdelta = 0;
	for ( ; ; ) {
		i = getc(fp);
		if (i) { /* Codec Mode */
			if (i > count) i = count;
			count -= i;
			cc = getc(fp);
			if (compmode == RLE8) {
				while (i-- > 0)
					*ln++ = cc;
			}else {
				half[0] = cc >> 4;
				half[1] = cc & 0x0f;
				for (k = 0; i-- > 0; k ^= 1)
					*ln++ = half[k];
			}
			continue;
		}
		/* Absolute Mode */
		j = getc(fp);
		if (j == 0 || j == 1) /* EOL / EOF */
			break; /* return */
		if (j == 2) {  /* Delta Mode */
			xdelta = getc(fp);  /* X-offset */
			ydelta = getc(fp);  /* Y-offset */
			if (ydelta == 0) {
				count -= xdelta;
				ln += xdelta;
				xdelta = 0;
			}else {
				xdelta += wid - count;
				ydelta--;
				break; /* return */
			}
		}else {
			if (j > count) j = count;
			count -= j;
			if (compmode == RLE8) {
				k = j & 1;	/* 16-bit packing */
				while (j-- > 0)
					*ln++ = getc(fp);
			}else {
				k = (j + 1) & 2; /* 16-bit packing */
				while (j-- > 0) {
					cc = getc(fp);
					*ln++ = cc >> 4;
					if (j-- <= 0)
						break;
					*ln++ = cc & 0x0f;
				}
			}
			if (k)
				(void) getc(fp);
		}
	}
	return 0;
}


int bmpGetImage(FILE *fp, bmpHeader *bh, int *bits, unsigned char **planes)
     /*	¥Õ¥¡¥¤¥ë¤«¤é¥¤¥á¡¼¥¸¥Ç¡¼¥¿¤òÆɤ߽Ф·¡¢R,G,B ¤Î£³¤Ä¤Î¥×¥ì¡¼¥ó¤ÎÀèƬ
	¥¢¥É¥ì¥¹¤ò planes[0]~[2] ¤Ë¥»¥Ã¥È¤¹¤ë¡£³Æ¿§¤ËɬÍפʥԥ¯¥»¥ë¿ô¤Ï
	bits ¤ËÆþ¤ì¤é¤ì¤ë¡£mh¤Ë¤Ï¥Ø¥Ã¥À¾öÊó¤ò»ØÄꤹ¤ë¡£ */	
{
	int	x, wid, y, w;
	int	colbit = 8, colnum = 0;
	int	err = 0;
	BOOL	isgray = NO;
	int 	(*getNdots)(FILE *, int, unsigned char *) = get8dots;

	if (bh->comp) {
		if (bh->comp == RLE8)
			colnum = 256;
		else if (bh->comp == RLE4)
			colnum = 16;
		else
			return Err_IMPLEMENT;
		compmode = bh->comp;
		getNdots = rledots;
	}else {
		compmode = NoComp;
		if (bh->bits == 1)
			getNdots = get1dot;
		else if (bh->bits == 4)
			getNdots = get4dots;
		else if (bh->bits == 8)
			getNdots = get8dots;
		colnum = 1 << bh->bits;
	} /* else bits == 24 */

	if ((err = bmpGetPalette(fp, bh)) != 0)
		return err;
	if (colnum && bh->bits < 24) {
		colbit = howManyBits(bh->palette, colnum);
		isgray = isGray(bh->palette, colnum);
	}
	wid = byte_length(colbit, bh->x);
	err = allocImage(planes, bh->x, bh->y, colbit, (isgray ? 1 : 3));
	if (err)
		return err;
	if (bh->bits <= 8) {
		unsigned char	line[MAXWidth];
		unsigned char	*map[MAXPLANE];
		*bits = colbit;
		for (y = bh->y - 1; y >= 0; y--) {
			if (getNdots(fp, bh->x, line) < 0)
				return Err_SHORT;
			map[0] = planes[0] + (w = wid * y);
			map[1] = planes[1] + w;
			map[2] = planes[2] + w;
			expandImage(map, line, (const paltype *)bh->palette, 
					colbit, bh->x, isgray, -1);
		}
	}else {
		unsigned char	*rr, *gg, *bb;
		*bits = 8;
		for (y = bh->y - 1; y >= 0; y--) {
			if (feof(fp))
				return Err_SHORT;
			rr = planes[0] + (w = wid * y);
			gg = planes[1] + w;
			bb = planes[2] + w;
			for (x = 0; x < wid; x++) {
				*bb++ = getc(fp);
				*gg++ = getc(fp);
				*rr++ = getc(fp);
			}
			for (x *= 3 ; x & 0x03; x++)
				(void) getc(fp);
		}
	}
	return 0;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.