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

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

#include  <stdio.h>
#include  <libc.h>
#include  <objc/objc.h>
#include  "common.h"

int optimalBits(unsigned char *pattern, int num)
/* How many bits are needed to represent given patterns */
{
	int i, x;

	if (num > 16) return 8;
	if (num == 1) { /* 1 bit; only one color */
		if (pattern[0] || pattern[0xff]) return 1;
	}else if (num == 2) { /* 1 bit */
		if (pattern[0] && pattern[0xff]) return 1;
	}
	if (num <= 4) { /* 2 bits */
		for (i = 1; i <= 0xfe; i++)
			if (pattern[i] && (i != 0x55 && i != 0xaa))
				goto BIT4;
		return 2;
	}
BIT4:	/* num <= 16 -- 4 bits */
	for (i = 1; i <= 0xfe; i++)
		if (pattern[i]
			&& ((x = i & 0x0f) != 0 && x != 0x0f && x != i >> 4))
				return 8;
	return 4;
}

int howManyBits(paltype *pal, int n)
/* How many bits are needed to display colors of the palette ? */
{
	int i, c, num;
	unsigned char *p, buf[256];

	for (i = 0; i < 256; i++) buf[i] = 0;
	num = 0;
	for (i = 0; i < n; i++) {
	    p = pal[i];
	    for (c = 0; c < 3; c++)
		if (buf[p[c]] == 0) {
			buf[p[c]] = 1;
			if (++num > 16) return 8;
		}
	}
	return optimalBits(buf, num);
}

BOOL isGray(paltype *pal, int n)
/* Is Gray-scaled all colors of the palette ? */
{
	int i;
	unsigned char *p;

	if (pal == NULL)
		return NO;
	for (i = 0; i < n; i++) {
		p = pal[i];
		if (p[0] != p[1] || p[1] != p[2])
			return NO;
	}
	return YES;
}


int allocImage(unsigned char **planes,
	int width, int height, int repbits, int pnum)
{
	int i, xbyte, wd;
	unsigned char *p;

	xbyte = byte_length(repbits, width);
	wd = xbyte * height;
	if ((p = (unsigned char *)malloc(wd * pnum)) == NULL)
		return Err_MEMORY;
	for (i = 0; i < pnum; i++) {
		planes[i] = p;
		p += wd;
	}
	if (pnum < 5) planes[pnum] = NULL;
	return 0;
}


void expandImage(unsigned char **planes, unsigned char *buf,
	const paltype *pal, int repbits, int width, BOOL isgray, int transp)
{
	int x, n;
	unsigned char	*rr, *gg, *bb;
	const unsigned char	*p;

	if (isgray) {
		rr = planes[0];
	
		if (repbits == 1) {
			for (x = 0; x < width; x++) {
				*rr = pal[buf[x]][RED] & 0x80;
				for (n = 1; n < 8; n++) {
					if (++x >= width) break;
					*rr |= (pal[buf[x]][RED] & 0x80) >> n;
				}
				rr++;
			}
		}else if (repbits == 2) {
			for (x = 0; x < width; x++) {
				*rr = pal[buf[x]][RED] & 0xc0;
				for (n = 2; n < 8; n += 2) {
					if (++x >= width) break;
					*rr |= (pal[buf[x]][RED] & 0xc0) >> n;
				}
				rr++;
			}
		}else if (repbits == 4) {
			for (x = 0; x < width; x++) {
				*rr = pal[buf[x]][RED] & 0xf0;
				if (++x >= width) break;
				*rr++ |= pal[buf[x]][RED] >> 4;
			}
		}else /* 8 */ {
			for (x = 0; x < width; x++)
				*rr++ = pal[buf[x]][RED];
		}
	}else { /* Color */

		rr = planes[0];
		gg = planes[1];
		bb = planes[2];
	
		if (repbits == 1) {
			for (x = 0; x < width; x++) {
				p = pal[buf[x]];
				*rr = p[RED] & 0x80;
				*gg = p[GREEN] & 0x80;
				*bb = p[BLUE] & 0x80;
				for (n = 1; n < 8; n++) {
					if (++x >= width) break;
					p = pal[buf[x]];
					*rr |= (p[RED] & 0x80) >> n;
					*gg |= (p[GREEN] & 0x80) >> n;
					*bb |= (p[BLUE] & 0x80) >> n;
				}
				rr++, gg++, bb++;
			}
		}else if (repbits == 2) {
			for (x = 0; x < width; x++) {
				p = pal[buf[x]];
				*rr = p[RED] & 0xc0;
				*gg = p[GREEN] & 0xc0;
				*bb = p[BLUE] & 0xc0;
				for (n = 2; n < 8; n += 2) {
					if (++x >= width) break;
					p = pal[buf[x]];
					*rr |= (p[RED] & 0xc0) >> n;
					*gg |= (p[GREEN] & 0xc0) >> n;
					*bb |= (p[BLUE] & 0xc0) >> n;
				}
				rr++, gg++, bb++;
			}
		}else if (repbits == 4) {
			for (x = 0; x < width; x++) {
				p = pal[buf[x]];
				*rr = p[RED] & 0xf0;
				*gg = p[GREEN] & 0xf0;
				*bb = p[BLUE] & 0xf0;
				if (++x >= width) break;
				p = pal[buf[x]];
				*rr++ |= p[RED] >> 4;
				*gg++ |= p[GREEN] >> 4;
				*bb++ |= p[BLUE] >> 4;
			}
		}else /* 8 */ {
			for (x = 0; x < width; x++) {
				p = pal[buf[x]];
				*rr++ = p[RED];
				*gg++ = p[GREEN];
				*bb++ = p[BLUE];
			}
		}
	}

	if (transp >= 0) {
		rr = planes[isgray ? 1 : 3];
	
		if (repbits == 1) {
			for (x = 0; x < width; x++) {
				*rr = (buf[x] == transp) ? 0 : 0x80;
				for (n = 1; n < 8; n++) {
					if (++x >= width) break;
					if (buf[x] != transp)
						*rr |= 0x80 >> n;
				}
				rr++;
			}
		}else if (repbits == 2) {
			for (x = 0; x < width; x++) {
				*rr = (buf[x] == transp) ? 0 : 0xc0;
				for (n = 2; n < 8; n += 2) {
					if (++x >= width) break;
					if (buf[x] != transp)
						*rr |= 0xc0 >> n;
				}
				rr++;
			}
		}else if (repbits == 4) {
			for (x = 0; x < width; x++) {
				*rr = (buf[x] == transp) ? 0 : 0xf0;
				if (++x >= width) break;
				if (buf[x] != transp)
					*rr |= 0x0f;
				rr++;
			}
		}else /* 8 */ {
			for (x = 0; x < width; x++)
				*rr++ = (buf[x] == transp) ? 0 : 0xff;
		}
	}
}

void packImage(unsigned char *dst, unsigned char *src, int width, int bits)
{
	int x, n;

	if (bits == 1) {
		for (x = 0; x < width; x++) {
			*dst = *src++ & 0x80;
			for (n = 1; n < 8; n++) {
				if (++x >= width) break;
				*dst |= (*src++ & 0x80) >> n;
			}
			dst++;
		}
	}else if (bits == 2) {
		for (x = 0; x < width; x++) {
			*dst = *src++ & 0xc0;
			for (n = 2; n < 8; n += 2) {
				if (++x >= width) break;
				*dst |= (*src++ & 0xc0) >> n;
			}
			dst++;
		}
	}else if (bits == 4) {
		for (x = 0; x < width; x++) {
			*dst = *src++ & 0xf0;
			if (++x >= width) break;
			*dst++ |= *src++ >> 4;
		}
	}else /* bits == 8 */ {
		for (x = 0; x < width; x++)
			*dst++ = *src++;
	}
}

void packWorkingImage(const commonInfo *newinf, int pl,
	unsigned char **working, unsigned char **planes)
{
	int	pn, y;
	unsigned char *pp, *ww;

	for (pn = 0; pn < pl; pn++) {
	    for (y = 0; y < newinf->height; y++) {
		ww = working[pn] + y * newinf->width;
		pp = planes[pn] + y * newinf->xbytes;
		packImage(pp, ww, newinf->width, newinf->bits);
	    }
	}
}

paltype *copyPalette(paltype *pal, int pnum)
{
	paltype *np;

	if ((np = (paltype *)malloc(sizeof(paltype) * pnum)) == NULL)
		return NULL;
	memcpy(np, pal, sizeof(paltype) * pnum);
	return np;
}

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