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

  1. /*
  2.  
  3. gbmscale.c - Scale bitmap to new size
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdio.h>
  9. #include <stddef.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <memory.h>
  13. #include "gbm.h"
  14.  
  15. /*...vgbm\46\h:0:*/
  16. /*...e*/
  17.  
  18. /*...sgbm_simple_scale \45\ point sampled:0:*/
  19. /*...ssimple_scale_1:0:*/
  20. static void simple_scale_1(
  21.     const byte *s,
  22.     byte *d, int dw,
  23.     int xs[]
  24.     )
  25.     {
  26.     int sx = 0;
  27.     byte bit, value;
  28.  
  29.     for ( ; dw >= 8; dw -= 8 )
  30.         {
  31.         for ( value = 0, bit = 0x80; bit > 0; bit >>= 1 )
  32.             {
  33.             if ( s[(unsigned)sx>>3]&(0x80U>>((unsigned)sx&7U)) )
  34.                 value |= bit;
  35.             sx += *xs++;
  36.             }
  37.         *d++ = value;
  38.         }
  39.  
  40.     if ( dw > 0 )
  41.         {
  42.         for ( value = 0, bit = 0x80; dw-- > 0; bit >>= 1 )
  43.             {
  44.             if ( s[(unsigned)sx>>3]&(0x80U>>((unsigned)sx&7U)) )
  45.                 value |= bit;
  46.             sx += *xs++;
  47.             }
  48.         *d = value;
  49.         }
  50.     }
  51. /*...e*/
  52. /*...ssimple_scale_4:0:*/
  53. static void simple_scale_4(
  54.     const byte *s,
  55.     byte *d, int dw,
  56.     int xs[]
  57.     )
  58.     {
  59.     int sx = 0;
  60.     for ( ;; )
  61.         {
  62.         if ( dw-- == 0 ) return;
  63.         if ( sx&1 ) *d = (s[(unsigned)sx>>1] << 4 );
  64.         else        *d = (s[(unsigned)sx>>1]&0xf0U);
  65.         sx += *xs++;
  66.  
  67.         if ( dw-- == 0 ) return;
  68.         if ( sx&1 ) *d++ |= (s[(unsigned)sx>>1]&0x0fU);
  69.         else        *d++ |= (s[(unsigned)sx>>1] >>  4);
  70.         sx += *xs++;
  71.         }
  72.     }
  73. /*...e*/
  74. /*...ssimple_scale_8:0:*/
  75. static void simple_scale_8(
  76.     const byte *s,
  77.     byte *d, int dw,
  78.     int xs[]
  79.     )
  80.     {
  81.     while ( dw-- > 0 )
  82.         {
  83.         *d++ = *s;
  84.         s += *xs++;
  85.         }
  86.     }
  87. /*...e*/
  88. /*...ssimple_scale_24:0:*/
  89. static void simple_scale_24(
  90.     const byte *s,
  91.     byte *d, int dw,
  92.     int xs[]
  93.     )
  94.     {
  95.     while ( dw-- > 0 )
  96.         {
  97.         *d++ = s[0];
  98.         *d++ = s[1];
  99.         *d++ = s[2];
  100.         s += ( 3 * *xs++ );
  101.         }
  102.     }
  103. /*...e*/
  104. /*...sfast_simple_scale_1:0:*/
  105. static void fast_simple_scale_1(
  106.     const byte *s,
  107.     byte *d, int dw,
  108.     int xs[]
  109.     )
  110.     {
  111.     xs=xs; /* Suppress warnings */
  112.     memcpy(d, s, (unsigned)(dw+7) >> 3);
  113.     }
  114. /*...e*/
  115. /*...sfast_simple_scale_4:0:*/
  116. static void fast_simple_scale_4(
  117.     const byte *s,
  118.     byte *d, int dw,
  119.     int xs[]
  120.     )
  121.     {
  122.     xs=xs; /* Suppress warnings */
  123.     memcpy(d, s, (unsigned) (dw+1)>>1);
  124.     }
  125. /*...e*/
  126. /*...sfast_simple_scale_8:0:*/
  127. static void fast_simple_scale_8(
  128.     const byte *s,
  129.     byte *d, int dw,
  130.     int xs[]
  131.     )
  132.     {
  133.     xs=xs; /* Suppress warnings */
  134.     memcpy(d, s, dw);
  135.     }
  136. /*...e*/
  137. /*...sfast_simple_scale_24:0:*/
  138. static void fast_simple_scale_24(
  139.     const byte *s,
  140.     byte *d, int dw,
  141.     int xs[]
  142.     )
  143.     {
  144.     xs=xs; /* Suppress warnings */
  145.     memcpy(d, s, dw*3);
  146.     }
  147. /*...e*/
  148.  
  149. GBM_ERR gbm_simple_scale(
  150.     const byte *s, int sw, int sh,
  151.           byte *d, int dw, int dh,
  152.     int bpp
  153.     )
  154.     {
  155.     int sst = ( (sw * bpp + 31) / 32 ) * 4;
  156.     int dst = ( (dw * bpp + 31) / 32 ) * 4;
  157.     int *xs, *ys, i;
  158.     void (*scaler)(const byte *s, byte *d, int dw, int xs[]);
  159.  
  160.     /* Allocate memory for step arrays */
  161.  
  162.     if ( (xs = malloc((size_t) ((dw+1+dh+1)*sizeof(int)))) == NULL )
  163.         return GBM_ERR_MEM;
  164.     ys = xs + (dw+1);
  165.  
  166.     /* Make mapping to 0..dx from 0..sx (and same for y) */
  167.  
  168.     for ( i = 0; i <= dw; i++ )
  169.         xs[i] = (i * sw) / dw;
  170.  
  171.     for ( i = 0; i <= dh; i++ )
  172.         ys[i] = (i * sh) / dh;
  173.  
  174.     /* Compute step coefficients */
  175.  
  176.     for ( i = 0; i < dw; i++ )
  177.         xs[i] = xs[i+1] - xs[i];
  178.     
  179.     for ( i = 0; i < dh; i++ )
  180.         ys[i] = ys[i+1] - ys[i];
  181.  
  182.     /* Pick a scaling routine. Special optimisation to prevent
  183.        excessive work scaling horizontally if widths are the same.
  184.        Effectively reduces this code to a memcpy. */
  185.  
  186.     if ( dw == sw )
  187.         switch ( bpp )
  188.             {
  189.             case 1 : scaler = fast_simple_scale_1 ; break;
  190.             case 4 : scaler = fast_simple_scale_4 ; break;
  191.             case 8 : scaler = fast_simple_scale_8 ; break;
  192.             case 24: scaler = fast_simple_scale_24; break;
  193.             }
  194.     else
  195.         switch ( bpp )
  196.             {
  197.             case 1 : scaler = simple_scale_1 ; break;
  198.             case 4 : scaler = simple_scale_4 ; break;
  199.             case 8 : scaler = simple_scale_8 ; break;
  200.             case 24: scaler = simple_scale_24; break;
  201.             }
  202.  
  203.     /* Now do guts of scaling */
  204.  
  205.     while ( dh-- > 0 )
  206.         {
  207.         (*scaler)(s, d, dw, xs);
  208.         d += dst;
  209.         s += (sst * *ys++);
  210.         }
  211.  
  212.     free(xs);
  213.     return GBM_ERR_OK;
  214.     }
  215. /*...e*/
  216.