Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!sharkey!mcf!elsie!ado From: ado@elsie.UUCP (Arthur David Olson) Newsgroups: comp.lang.c Subject: Re: Looking for routine to expand bitmap Keywords: bitmap routine Message-ID: <9129@elsie.UUCP> Date: 19 Aug 89 00:08:58 GMT References: <8917@attctc.Dallas.TX.US> <10683@smoke.BRL.MIL> Organization: NIH-LEC, Bethesda, MD Lines: 129 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@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; }