Looking for routine to expand bitmap

Arthur David Olson ado at elsie.UUCP
Sat Aug 19 10:08:58 AEST 1989


Here's the X-Window-System code used to do such a job at elsie.
Doug Gwyn's code uses fewer bitblt operations;
this code applies operations to fewer bits.
--
X Window System is a trademark of the Massachusetts Institute of Technology.
-- 
	Arthur David Olson    ado at alw.nih.gov    ADO is a trademark of Ampex.

static int
is_power_of_two(i)
int	i;
{
	if (i > 0)
		while ((i % 2) == 0)
			i /= 2;
	return i == 1;
}

typedef enum {
	FORWARD,
	BACKWARD
} direction_t;

typedef enum {
	DONTSWAPXY,
	SWAPXY
} swapxy_t;

#define ROTCOPY(disp, src, dest, gc, sx, sy, w, h, dx, dy, swapxy) \
		(((swapxy) == DONTSWAPXY) ? \
			XCopyArea((disp), (src), (dest), (gc), \
				(sx), (sy), \
				(unsigned int) (w), (unsigned int) (h), \
				(dx), (dy)) : \
			XCopyArea((disp), (src), (dest), (gc), \
				(sy), (sx), \
				(unsigned int) (h), (unsigned int) (w), \
				(dy), (dx)))

static void
smear(disp, drawable, gc, x, y, w, h, direction, swapxy)
Display * const		disp;
const Drawable		drawable;
const GC		gc;
const int		x, y, w, h;
const direction_t	direction;
const swapxy_t		swapxy;
{
	register int	src_x, dest_x;
	register int	done, copy_w;

	if (h <= 0)
		return;
	for (done = 1; done < w; done += copy_w) {
		copy_w = w - done;
		if (copy_w > done)
			copy_w = done;
		if (direction == FORWARD) {
			dest_x = x + done;
			src_x = dest_x - copy_w;
		} else {
			src_x = x - done + 1;
			dest_x = src_x - copy_w;
		}
		ROTCOPY(disp, drawable, drawable, gc,
			src_x, y, copy_w, h, dest_x, y, swapxy);
	}
}

static void
enlsub(disp, drawable, gc, x, y, z, w, h, swapxy)
Display * const		disp;
const Drawable		drawable;
const int		x, y, z, w, h;
const GC		gc;
const swapxy_t		swapxy;
{
	register int	src_x, dest_x, copy_w;
	register int	special, final_z;

	if (w <= z) {
		smear(disp, drawable, gc, x, y, w, h, FORWARD, swapxy);
		return;
	}
	copy_w = (w - 1) % z + 1;
	src_x = x + (w - 1) / z - 1;
	dest_x = x + w - copy_w - 1;
	special = is_power_of_two(z - 1);
	for ( ; ; ) {
		ROTCOPY(disp, drawable, drawable, gc,
			src_x, y, 2, h, dest_x, y, swapxy);
		smear(disp, drawable, gc,
			dest_x + 1, y, copy_w, h, FORWARD, swapxy);
		if (src_x-- == x) {
			final_z = z - 1;
			break;
		}
		if (special && src_x > x) {
			copy_w = z - 1;
			dest_x -= z;
			continue;
		}
		smear(disp, drawable, gc, dest_x, y, z, h, BACKWARD, swapxy);
		if (src_x-- == x) {
			final_z = z;
			break;
		}
		copy_w = z;
		dest_x -= 2 * z;
	}
	smear(disp, drawable, gc, x, y, final_z, h, FORWARD, swapxy);
}

int
enlarge(disp, drawable, gc, x, y, z, w, h)
Display *	disp;
Drawable	drawable;
GC		gc;
int		x, y, z, w, h;
{
	register int	myh;

	if (z <= 1 || w <= 0 || h <= 0)
		return 0;
	myh = (h + z - 1) / z;
	enlsub(disp, drawable, gc, x, y, z, w, myh, DONTSWAPXY);
	enlsub(disp, drawable, gc, y, x, z, h, w, SWAPXY);
	return 0;
}



More information about the Comp.lang.c mailing list