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; }