home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gbmsrc.zip / gbmrect.c < prev    next >
C/C++ Source or Header  |  1996-04-14  |  6KB  |  267 lines

  1. /*
  2.  
  3. gbmrect.c - Subrectangle Transfer
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <memory.h>
  14. #include <malloc.h>
  15. #include "gbm.h"
  16.  
  17. /*...vgbm\46\h:0:*/
  18. /*...e*/
  19.  
  20. /*...sgbm_subrectangle:0:*/
  21. /*...smiddle_4:0:*/
  22. static void middle_4(byte *dst, const byte *src, int x, int w)
  23.     {
  24.     if ( x & 1 )
  25.         {
  26.         src += (x / 2);
  27.         for ( ; w >= 2; w -= 2 )
  28.             {
  29.             *dst    = (byte) (*src++ << 4);
  30.             *dst++ |= (byte) (*src   >> 4);
  31.             }
  32.         if ( w )
  33.             *dst = (byte) (*src << 4);
  34.         }
  35.     else
  36.         memcpy(dst, src + x / 2, (w + 1) / 2);
  37.     }
  38. /*...e*/
  39. /*...smiddle_1:0:*/
  40. static void middle_1(byte *dst, const byte *src, int x, int w)
  41.     {
  42.     int    last = (x & 7);
  43.  
  44.     src += (x/8);
  45.     if ( last )
  46.         {
  47.         for ( ; w >= 8; w -= 8 )
  48.             {
  49.             *dst    = (byte) (*src++ << last);
  50.             *dst++ |= (byte) (*src   >> (8U - last));
  51.             }
  52.         if ( w )
  53.             {
  54.             *dst = (byte) (*src++ << last);
  55.             w -= (8U-last);
  56.             if ( w )
  57.                 *dst |= (byte) (*src >> (8U - last));
  58.             }
  59.         }
  60.     else
  61.         memcpy(dst, src, (w + 7) / 8);
  62.     }
  63. /*...e*/
  64.  
  65. void gbm_subrectangle(
  66.     const GBM *gbm,
  67.     int x, int y, int w, int h,
  68.     const byte *data_src, byte *data_dst
  69.     )
  70.     {
  71.     int i;
  72.     int stride_src = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
  73.     int stride_dst = ( ((     w * gbm->bpp + 31)/32) * 4 );
  74.  
  75.     data_src += stride_src * y;
  76.  
  77.     switch ( gbm->bpp )
  78.         {
  79.         case 24:
  80.             for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
  81.                 memcpy(data_dst, data_src + x * 3, w * 3);
  82.             break;
  83.         case 8:
  84.             for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
  85.                 memcpy(data_dst, data_src + x, w);
  86.             break;
  87.         case 4:
  88.             for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
  89.                 middle_4(data_dst, data_src, x, w);
  90.             break;
  91.         case 1:
  92.             for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
  93.                 middle_1(data_dst, data_src, x, w);
  94.             break;
  95.         }
  96.     }
  97. /*...e*/
  98. /*...sgbm_blit:0:*/
  99. /*...sblit_1:0:*/
  100. static void blit_1(
  101.     const byte *s, int sts, int sx,
  102.           byte *d, int dts, int dx,
  103.     int w, int h
  104.     )
  105.     {
  106.     s += (sx>>3); sx &= 7;
  107.     d += (dx>>3); dx &= 7;
  108.  
  109.     if ( sx == dx )
  110. /*...saligned transfer:16:*/
  111. {
  112. int left, right, middle = w;
  113. byte left_mask, right_mask;
  114.  
  115. /* If starting mid-byte, then remember this */
  116. if ( (sx&7)!=0 && middle > 0 )
  117.     { left = 8-(sx&7); middle -= left; }
  118. else
  119.     left = 0;
  120. /* If ending mid-byte, then remember this */
  121. if ( ((sx+w)&7)!=0 && middle > 0 )
  122.     { right = ((sx+w)&7); middle -= right; }
  123. else
  124.     right = 0;
  125. /* Remainder will be a multiple of 8, divide by 8 to give bytes */
  126. middle >>= 3;
  127.  
  128. left_mask  = (byte) (0xffU<<left );
  129. right_mask = (byte) (0xffU>>right);
  130.  
  131. for ( ; h-- > 0; s += sts, d += dts )
  132.     {
  133.     const byte *sp = s;
  134.           byte *dp = d;
  135.     if ( left > 0 )
  136.         { *dp = ( (*dp&left_mask) | (*sp&~left_mask) ); dp++; sp++; }
  137.     memcpy(dp, sp, middle); dp += middle; sp += middle;
  138.     if ( right )
  139.         *dp = ( (*dp&right_mask) | (*sp&~right_mask) );
  140.     }
  141. }
  142. /*...e*/
  143.     else
  144. /*...smisaligned transfer:16:*/
  145. /* This will be very inefficient, but will work */
  146.  
  147. for ( ; h-- > 0; s += sts, d += dts )
  148.     {
  149.     int x, sxl, dxl;
  150.     for ( x = 0, sxl = sx, dxl = dx; x < w; x++, sxl++, dxl++ )
  151.         if ( s[(unsigned)sxl>>3] & (0x80U>>((unsigned)sxl&7U)) )
  152.             d[(unsigned)dxl>>3] |=  (0x80U>>((unsigned)dxl&7U));
  153.         else
  154.             d[(unsigned)dxl>>3] &= ~(0x80U>>((unsigned)dxl&7U));
  155.     }
  156. /*...e*/
  157.     }
  158. /*...e*/
  159. /*...sblit_4:0:*/
  160. static void blit_4(
  161.     const byte *s, int sts, int sx,
  162.           byte *d, int dts, int dx,
  163.     int w, int h
  164.     )
  165.     {
  166.     s += ((unsigned)sx>>1); sx &= 1;
  167.     d += ((unsigned)dx>>1); dx &= 1;
  168.  
  169.     if ( sx == dx )
  170. /*...saligned transfer:16:*/
  171. {
  172. BOOLEAN lnibble, rnibble;
  173. int middle = w;
  174.  
  175. /* If starting mid-byte, then remember this */
  176. if ( (sx&1)!=0 && middle > 0 )
  177.     { lnibble = TRUE; middle--; }
  178. else
  179.     lnibble = FALSE;
  180. /* If ending mid-byte, then remember this */
  181. if ( ((sx+w)&1)!=0 && middle > 0 )
  182.     { rnibble = TRUE; middle--; }
  183. else
  184.     rnibble = FALSE;
  185. /* Remainder will be a multiple of 2, divide by 2 to give bytes */
  186. middle >>= 1;
  187.  
  188. for ( ; h-- > 0; s += sts, d += dts )
  189.     {
  190.     const byte *sp = s;
  191.           byte *dp = d;
  192.     if ( lnibble )
  193.         { *dp = ( (*dp&0xf0) | (*sp&0x0f) ); dp++; sp++; }
  194.     memcpy(dp, sp, middle); dp += middle; sp += middle;
  195.     if ( rnibble )
  196.         *dp = ( (*dp&0x0f) | (*sp&0xf0) );
  197.     }
  198. }
  199. /*...e*/
  200.     else
  201. /*...smisaligned transfer:16:*/
  202. /* This will be quite inefficient, but will work */
  203.  
  204. for ( ; h-- > 0; s += sts, d += dts )
  205.     {
  206.     int x, sxl, dxl;
  207.     for ( x = 0, sxl = sx, dxl = dx; x < w; x++, sxl++, dxl++ )
  208.         if ( x&1 )
  209.             d[(unsigned)dxl>>1] = ( (d[(unsigned)dxl>>1]&0xf0U) | s[(unsigned)sxl>>1]>>4 );
  210.         else
  211.             d[(unsigned)dxl>>1] = ( (d[(unsigned)dxl>>1]&0x0fU) | s[(unsigned)sxl>>1]<<4 );
  212.     }
  213. /*...e*/
  214.     }
  215. /*...e*/
  216. /*...sblit_8:0:*/
  217. static void blit_8(
  218.     const byte *s, int sts, int sx,
  219.           byte *d, int dts, int dx,
  220.     int w, int h
  221.     )
  222.     {
  223.     s += sx;
  224.     d += dx;
  225.     for ( ; h-- > 0; s += sts, d += dts )
  226.         memcpy(d, s, w);
  227.     }
  228. /*...e*/
  229. /*...sblit_24:0:*/
  230. static void blit_24(
  231.     const byte *s, int sts, int sx,
  232.           byte *d, int dts, int dx,
  233.     int w, int h
  234.     )
  235.     {
  236.     s += (sx*3);
  237.     d += (dx*3);
  238.     for ( ; h-- > 0; s += sts, d += dts )
  239.         memcpy(d, s, w*3);
  240.     }
  241. /*...e*/
  242.  
  243. void gbm_blit(
  244.     const byte *s, int sw, int sx, int sy,
  245.           byte *d, int dw, int dx, int dy,
  246.     int w, int h,
  247.     int bpp
  248.     )
  249.     {
  250.     int sts = ((sw * bpp + 31) / 32) * 4;
  251.     int dts = ((dw * bpp + 31) / 32) * 4;
  252.  
  253.     if ( w == 0 || h == 0 )
  254.         return;
  255.  
  256.     s += sts * sy;
  257.     d += dts * dy;
  258.     switch ( bpp )
  259.         {
  260.         case 1:        blit_1 (s,sts,sx, d,dts,dx, w,h);    break;
  261.         case 4:        blit_4 (s,sts,sx, d,dts,dx, w,h);    break;
  262.         case 8:        blit_8 (s,sts,sx, d,dts,dx, w,h);    break;
  263.         case 24:    blit_24(s,sts,sx, d,dts,dx, w,h);    break;
  264.         }
  265.     }
  266. /*...e*/
  267.