bobc@attctc.Dallas.TX.US (Bob Calbridge) (08/08/89)
Novice that I am I have two unrelated problems to solve. The first involves expanding a bitmap. For example, I have an N x M bitmap that I need to expand by A to get a resulting AN x AM bitmap. The vertical I can handle once I get the horizontal expansion. By way of example if I have an 8 X 14 bit matrix and the first byte is 01101011 and I need to have it expanded 3 times so that the resulting three bytes are 00011111,10001110,00111111, where each zero is replaced by three zeros and ditto for the ones. Is there a general algorithm for handling this type of expansion? The second problem is probably simpler. I have pretty much determined that Turbo C stores integers with the least significant byte first. One file structure that I'm accessing does it most significant byte first. I've used a macro to get around the problem of printing out the value of this integer but was wondering for the sake of manipulating the value if there is a standard structure or "typedef" that can be used instead. Thanks beaucoup, Bob -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- = I know it's petty.......... = - But I have to justify my salary! - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/09/89)
In article <8917@attctc.Dallas.TX.US> bobc@attctc.Dallas.TX.US (Bob Calbridge) writes: >Is there a general algorithm for handling this type of expansion? static void Magnify( b, r, tb, p, fac ) /* adapted from "lens" */ register Bitmap *b, *tb; Rectangle r; Point p, fac; { register Bitmap *stage; register int i, shift; Point d; Rectangle s; #if 0 if ( fac.x < 1 || fac.y < 1 ) /* "can't happen" */ return; #endif d = sub( r.corner, r.origin ); s.origin = p; s.corner = add( p, Pt( fac.x * d.x, fac.y * d.y ) ); /* Copy source into origin of dest */ bitblt( b, r, tb, p, F_STORE ); /* Clear rest of dest */ rectf( tb, Rect( s.origin.x + d.x, s.origin.y, s.corner.x, s.corner.y ), F_CLR ); rectf( tb, Rect( s.origin.x, s.origin.y + d.y, s.origin.x + d.x, s.corner.y ), F_CLR ); /* Now we expand in place */ /* 1: expand horizontally */ if ( fac.x > 1 ) for( i = d.x - 1; i > 0; --i ) { bitblt( tb, Rect( p.x + i, p.y, p.x + i + 1, p.y + d.y), tb, Pt( p.x + i * fac.x, p.y ), F_OR ); rectf( tb, Rect( p.x + i, p.y, p.x + i + 1, p.y + d.y ), F_CLR ); } /* 2: smear horizontally */ for( i = 1; i < fac.x; i *= 2 ) { shift = min( i, fac.x - i ); bitblt( tb, Rect( p.x, p.y, s.corner.x - shift, p.y + d.y ), tb, Pt( p.x + shift, p.y ), F_OR ); } /* 3: expand vertically */ if ( fac.y > 1 ) for ( i = d.y - 1; i > 0; --i ) { bitblt( tb, Rect( p.x, p.y + i, s.corner.x, p.y + i + 1 ), tb, Pt( p.x, p.y + i * fac.y ), F_OR ); rectf( tb, Rect( p.x, p.y + i, s.corner.x, p.y + i + 1 ), F_CLR ); } /* 4: smear vertically */ for ( i = 1; i < fac.y; i *= 2 ) { shift = min( i, fac.y - i ); bitblt( tb, Rect( p.x, p.y, s.corner.x, s.corner.y - shift ), tb, Pt( p.x, p.y + shift ), F_OR ); } }
ado@elsie.UUCP (Arthur David Olson) (08/19/89)
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;
}