home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gems / gemsiii / fastbtmp.c < prev    next >
Text File  |  1992-03-16  |  4KB  |  173 lines

  1. /*
  2. Fast Bitmap Stretching
  3. Tomas MÜller
  4. */
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19. short ReadPixel(long x,long y);/* returns color of (x,y) in source bitmap*/
  20. void SetColor(short Col); /* set the current writing color to Col */
  21. void WritePixel(long x,long y); /* write a pixel at (x,y) in destination bitmap with the current writing color */
  22. #define sign(x) ((x)>0 ? 1:-1)
  23.  
  24. /**********************************************************
  25.  RectStretch enlarges or diminishes a source rectangle of
  26.  a bitmap to a destination rectangle. The source
  27.  rectangle is selected by the two points (xs1,ys1) and
  28.  (xs2,ys2), and the destination rectangle by (xd1,yd1) and
  29.  (xd2,yd2). Since readability of source-code is wanted,
  30.  some optimizations have been left out for the reader:
  31.  It½s possible to read one line at a time, by first
  32.  stretching in x-direction and then stretching that bitmap
  33.  in y-direction.
  34.  Entry:
  35.     xs1,ys1 - first point of source rectangle
  36.     xs2,ys2 - second point of source rectangle
  37.     xd1,yd1 - first point of destination rectangle
  38.     xd2,yd2 - second point of destination rectangle
  39. **********************************************************/
  40. void RectStretch(long xs1,long ys1,long xs2,long ys2,long xd1,long yd1,long xd2,long yd2)
  41. {
  42.     long dx,dy,e,d,dx2;
  43.     short sx,sy;
  44.     dx=abs(yd2-yd1);
  45.     dy=abs(ys2-ys1);
  46.     sx=sign(yd2-yd1);
  47.     sy=sign(ys2-ys1);
  48.     e=(dy<<1)-dx;
  49.     dx2=dx<<1;
  50.     dy<<=1;
  51.     for(d=0;d<=dx;d++)
  52.     {
  53.         Stretch(xd1,xd2,xs1,xs2,ys1,yd1);
  54.         while(e>=0)
  55.         {
  56.             ys1+=sy;
  57.             e-=dx2;
  58.         }
  59.         yd1+=sx;
  60.         e+=dy;
  61.     }
  62. }
  63.  
  64. /**********************************************************
  65.  Stretches a horizontal source line onto a horizontal
  66.  destination line. Used by RectStretch.
  67.  Entry:
  68.     x1,x2 - x-coordinates of the destination line
  69.     y1,y2 - x-coordinates of the source line
  70.     yr    - y-coordinate of source line
  71.     yw    - y-coordinate of destination line
  72. **********************************************************/
  73. void Stretch(long x1,long x2,long y1,long y2,long yr,long yw)
  74. {
  75.     long dx,dy,e,d,dx2;
  76.     short sx,sy,color;
  77.     dx=abs(x2-x1);
  78.     dy=abs(y2-y1);
  79.     sx=sign(x2-x1);
  80.     sy=sign(y2-y1);
  81.     e=(dy<<1)-dx;
  82.     dx2=dx<<1;
  83.     dy<<=1;
  84.     for(d=0;d<=dx;d++)
  85.     {
  86.         color=ReadPixel(y1,yr); 
  87.         SetColor(color);
  88.         WritePixel(x1,yw);
  89.         while(e>=0)
  90.         {
  91.             y1+=sy;
  92.             e-=dx2;
  93.         }
  94.         x1+=sx;
  95.         e+=dy;
  96.     }
  97. }
  98.  
  99. /**********************************************************
  100.  CircleStretch stretches a source rectangle, selected by
  101.  the two points (SBMINX,0) and (SBMAXX,2*r-1), onto a
  102.  Bresenham circle at (xc,yc) with radius=r.
  103.  Instead of writing pixels on the circle, horizontal lines
  104.  of the source rectangle are being stretched onto all
  105.  horizontal lines of the circle. 
  106.  Entry:
  107.     SBMINX - min x of source rectangle
  108.     SBMAXX - max x of source rectangle 
  109.     xc,yc  - center of the circle
  110.     r      - radius of circle
  111. **********************************************************/
  112. void CircleStretch(long SBMINX,long SBMAXX,long xc,long yc,long r)
  113. {
  114.     long p=3-(r<<1),x=0,y=r;
  115.     while(x<y)
  116.     {
  117.         /* stretch lines in first octant */
  118.         Stretch2Lines(xc-y,xc+y,SBMINX,SBMAXX,r-x,yc-x,r+x,yc+x);
  119.         if(p<0) p=p+(x<<2)+6;
  120.         else
  121.         {
  122.             /* stretch lines in second octant */
  123.             Stretch2Lines(xc-x,xc+x,SBMINX,SBMAXX,r-y,yc-y,r+y,yc+y);
  124.             p=p+((x-y)<<2)+10;
  125.             y--;
  126.         }
  127.         x++;
  128.     }
  129.     if(x==y) Stretch2Lines(xc-x,xc+x,SBMINX,SBMAXX,r-y,yc-y,r+y,yc+y);
  130. }
  131.  
  132. /**********************************************************
  133.  Stretch2Lines stretches two source lines with same length
  134.  and different y-coordinates onto two destination lines
  135.  with same length and different y-coordinates. Used by
  136.  CircleStretch.
  137.  Entry:
  138.     x1,x2 - x-coordinates of the destination line
  139.     y1,y2 - x-coordinates of the source line
  140.     yr1   - y-coordinate of source line # 1
  141.     yw1   - y-coordinate of destination line # 1
  142.     yr2   - y-coordinate of source line # 2
  143.     yw2   - y-coordinate of destination line # 2
  144. **********************************************************/
  145. void Stretch2Lines(long x1,long x2,long y1,long y2,long yr1,long yw1,long yr2,long yw2)
  146. {
  147.     long dx,dy,e,d,dx2;
  148.     short sx,sy,color;
  149.     dx=abs(x2-x1);
  150.     dy=abs(y2-y1);
  151.     sx=sign(x2-x1);
  152.     sy=sign(y2-y1);
  153.     e=(dy<<1)-dx;
  154.     dx2=dx<<1;
  155.     dy<<=1;
  156.     for(d=0;d<=dx;d++)
  157.     {
  158.         color=ReadPixel(y1,yr1);
  159.         SetColor(color);
  160.         WritePixel(x1,yw1);
  161.         color=ReadPixel(y1,yr2);
  162.         SetColor(color);
  163.         WritePixel(x1,yw2);
  164.         while(e>=0)
  165.         {
  166.             y1+=sy;
  167.             e-=dx2;
  168.         }
  169.         x1+=sx;
  170.         e+=dy;
  171.     }
  172. }
  173.