home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
RISC DISC 3
/
RISC_DISC_3.iso
/
resources
/
etexts
/
gems
/
gemsiii
/
fastbitmap.c
< prev
next >
Wrap
Text File
|
1992-12-14
|
5KB
|
180 lines
/*
Fast Bitmap Stretching
Tomas MŒller
*/
/* user provided routines */
short ReadPixel(long x,long y);/* returns color of (x,y) in source bitmap*/
void SetColor(short Col); /* set the current writing color to Col */
void WritePixel(long x,long y); /* write a pixel at (x,y) in destination bitmap with the current writing color */
#define sign(x) ((x)>0 ? 1:-1)
void RectStretch(long xs1,long ys1,long xs2,long ys2,long xd1,long yd1,long xd2,long yd2) ;
void Stretch(long x1,long x2,long y1,long y2,long yr,long yw) ;
void CircleStretch(long SBMINX,long SBMAXX,long xc,long yc,long r) ;
void Stretch2Lines(long x1,long x2,long y1,long y2,long yr1,long yw1,long yr2,long yw2) ;
/**********************************************************
RectStretch enlarges or diminishes a source rectangle of
a bitmap to a destination rectangle. The source
rectangle is selected by the two points (xs1,ys1) and
(xs2,ys2), and the destination rectangle by (xd1,yd1) and
(xd2,yd2). Since readability of source-code is wanted,
some optimizations have been left out for the reader:
It«s possible to read one line at a time, by first
stretching in x-direction and then stretching that bitmap
in y-direction.
Entry:
xs1,ys1 - first point of source rectangle
xs2,ys2 - second point of source rectangle
xd1,yd1 - first point of destination rectangle
xd2,yd2 - second point of destination rectangle
**********************************************************/
void RectStretch(long xs1,long ys1,long xs2,long ys2,long xd1,long yd1,long xd2,long yd2)
{
long dx,dy,e,d,dx2;
short sx,sy;
dx=abs((int)(yd2-yd1));
dy=abs((int)(ys2-ys1));
sx=sign(yd2-yd1);
sy=sign(ys2-ys1);
e=(dy<<1)-dx;
dx2=dx<<1;
dy<<=1;
for(d=0;d<=dx;d++)
{
Stretch(xd1,xd2,xs1,xs2,ys1,yd1);
while(e>=0)
{
ys1+=sy;
e-=dx2;
}
yd1+=sx;
e+=dy;
}
}
/**********************************************************
Stretches a horizontal source line onto a horizontal
destination line. Used by RectStretch.
Entry:
x1,x2 - x-coordinates of the destination line
y1,y2 - x-coordinates of the source line
yr - y-coordinate of source line
yw - y-coordinate of destination line
**********************************************************/
void Stretch(long x1,long x2,long y1,long y2,long yr,long yw)
{
long dx,dy,e,d,dx2;
short sx,sy,color;
dx=abs((int)(x2-x1));
dy=abs((int)(y2-y1));
sx=sign(x2-x1);
sy=sign(y2-y1);
e=(dy<<1)-dx;
dx2=dx<<1;
dy<<=1;
for(d=0;d<=dx;d++)
{
color=ReadPixel(y1,yr);
SetColor(color);
WritePixel(x1,yw);
while(e>=0)
{
y1+=sy;
e-=dx2;
}
x1+=sx;
e+=dy;
}
}
/**********************************************************
CircleStretch stretches a source rectangle, selected by
the two points (SBMINX,0) and (SBMAXX,2*r-1), onto a
Bresenham circle at (xc,yc) with radius=r.
Instead of writing pixels on the circle, horizontal lines
of the source rectangle are being stretched onto all
horizontal lines of the circle.
Entry:
SBMINX - min x of source rectangle
SBMAXX - max x of source rectangle
xc,yc - center of the circle
r - radius of circle
**********************************************************/
void CircleStretch(long SBMINX,long SBMAXX,long xc,long yc,long r)
{
long p=3-(r<<1),x=0,y=r;
while(x<y)
{
/* stretch lines in first octant */
Stretch2Lines(xc-y,xc+y,SBMINX,SBMAXX,r-x,yc-x,r+x,yc+x);
if(p<0) p=p+(x<<2)+6;
else
{
/* stretch lines in second octant */
Stretch2Lines(xc-x,xc+x,SBMINX,SBMAXX,r-y,yc-y,r+y,yc+y);
p=p+((x-y)<<2)+10;
y--;
}
x++;
}
if(x==y) Stretch2Lines(xc-x,xc+x,SBMINX,SBMAXX,r-y,yc-y,r+y,yc+y);
}
/**********************************************************
Stretch2Lines stretches two source lines with same length
and different y-coordinates onto two destination lines
with same length and different y-coordinates. Used by
CircleStretch.
Entry:
x1,x2 - x-coordinates of the destination line
y1,y2 - x-coordinates of the source line
yr1 - y-coordinate of source line # 1
yw1 - y-coordinate of destination line # 1
yr2 - y-coordinate of source line # 2
yw2 - y-coordinate of destination line # 2
**********************************************************/
void Stretch2Lines(long x1,long x2,long y1,long y2,long yr1,long yw1,long yr2,long yw2)
{
long dx,dy,e,d,dx2;
short sx,sy,color;
dx=abs((int)(x2-x1));
dy=abs((int)(y2-y1));
sx=sign(x2-x1);
sy=sign(y2-y1);
e=(dy<<1)-dx;
dx2=dx<<1;
dy<<=1;
for(d=0;d<=dx;d++)
{
color=ReadPixel(y1,yr1);
SetColor(color);
WritePixel(x1,yw1);
color=ReadPixel(y1,yr2);
SetColor(color);
WritePixel(x1,yw2);
while(e>=0)
{
y1+=sy;
e-=dx2;
}
x1+=sx;
e+=dy;
}
}