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

  1. /*
  2.  
  3. gbmmir.c - Produce Mirror Image of General Bitmap
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stddef.h>
  11. #include <stdlib.h>
  12. #include <memory.h>
  13. #include <malloc.h>
  14. #include "gbm.h"
  15.  
  16. /*...vgbm\46\h:0:*/
  17. /*...e*/
  18.  
  19. /*...sgbm_ref_vert:0:*/
  20. BOOLEAN gbm_ref_vert(const GBM *gbm, byte *data)
  21.     {
  22.     int stride = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
  23.     byte *p1 = data;
  24.     byte *p2 = data + (gbm->h - 1) * stride;
  25.     byte *p3;
  26.  
  27.     if ( (p3 = malloc((size_t) stride)) == NULL )
  28.         return FALSE;
  29.  
  30.     for ( ; p1 < p2; p1 += stride, p2 -= stride )
  31.         {
  32.         memcpy(p3, p1, stride);
  33.         memcpy(p1, p2, stride);
  34.         memcpy(p2, p3, stride);
  35.         }
  36.  
  37.     free(p3);
  38.  
  39.     return TRUE;
  40.     }
  41. /*...e*/
  42. /*...sgbm_ref_horz:0:*/
  43. /*...sref_horz_24:0:*/
  44. static void ref_horz_24(byte *dst, byte *src, int n)
  45.     {
  46.     dst += n * 3;
  47.     while ( n-- )
  48.         {
  49.         dst -= 3;
  50.         dst[0] = *src++;
  51.         dst[1] = *src++;
  52.         dst[2] = *src++;
  53.         }
  54.     }
  55. /*...e*/
  56. /*...sref_horz_8:0:*/
  57. static void ref_horz_8(byte *dst, byte *src, int n)
  58.     {
  59.     dst += n;
  60.     while ( n-- )
  61.         *(--dst) = *src++;
  62.     }
  63. /*...e*/
  64. /*...sref_horz_4:0:*/
  65. static byte rev4[0x100];
  66.  
  67. static void table_4(void)
  68.     {
  69.     unsigned int i;
  70.  
  71.     for ( i = 0; i < 0x100; i++ )
  72.         rev4[i] = (byte) ( ((i & 0x0fU) << 4) | ((i & 0xf0U) >> 4) );
  73.     }
  74.  
  75. static void ref_horz_4(byte *dst, byte *src, int n)
  76.     {
  77.     if ( (n & 1) == 0 )
  78.         {
  79.         n /= 2;
  80.         dst += n;
  81.         while ( n-- )
  82.             *(--dst) = rev4[*src++];
  83.         }
  84.     else
  85.         {
  86.         n /= 2;
  87.         src += n;
  88.         while ( n-- )
  89.             {
  90.             *dst    = (byte) (*(src--) & 0xf0);
  91.             *dst++ |= (byte) (* src    & 0x0f);
  92.             }
  93.         *dst = (byte) (*src & 0xf0);
  94.         }
  95.     }
  96. /*...e*/
  97. /*...sref_horz_1:0:*/
  98. static byte rev[0x100]; /* Reverses all bits in a byte */
  99. static byte rev_top[7][0x100]; /* Reverses top N bits of a byte */
  100. static byte rev_bot[7][0x100]; /* Reverses bottom N bits of a byte */
  101. static byte lmask[8] = { 0, 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe };
  102.  
  103. static void table_1(void)
  104.     {
  105.     unsigned int i;
  106.  
  107.     for ( i = 0; i < 0x100; i++ )
  108.         {
  109.         unsigned int j, p, q, b = 0;
  110.  
  111.         for ( p = 0x01U, q = 0x80U; p < 0x100U; p <<= 1, q >>= 1 )
  112.             if ( i & p )
  113.                 b |= q;
  114.         rev[i] = b;
  115.  
  116.         for ( j = 1; j < 8U; j++ )
  117.             {
  118.             byte l = 0, r = 0;
  119.             byte lm = 0x80U, lmr = (byte) (0x80U >> (j - 1));
  120.             byte rm = 0x01U, rmr = (byte) (0x01U << (j - 1));
  121.             unsigned int k;
  122.  
  123.             for ( k = 0; k < j; k++ )
  124.                 {
  125.                 if ( i & (lm >> k) ) l |= (lmr << k);
  126.                 if ( i & (rm << k) ) r |= (rmr >> k);
  127.                 }
  128.             rev_top[j-1][i] = l;
  129.             rev_bot[j-1][i] = r;
  130.             }
  131.         }
  132.     }
  133.  
  134. static void ref_horz_1(byte *dst, byte *src, int n)
  135.     {
  136.     int last = ( n & 7 );
  137.  
  138.     n >>= 3;
  139.     if ( last == 0 )
  140.         {
  141.         dst += n;
  142.         while ( n-- )
  143.             *(--dst) = rev[*src++];
  144.         }
  145.     else
  146.         {
  147.         byte    *lrev = rev_top[   last -1];
  148.         byte    *rrev = rev_bot[(8-last)-1];
  149.         byte    lm = lmask[last], rm = 0xff - lm;
  150.  
  151.         src += n;
  152.         while ( n-- )
  153.             {
  154.             *dst    = lrev[*(src--) & lm];
  155.             *dst++ |= rrev[* src    & rm];
  156.             }
  157.         *dst = lrev[*src & lm];
  158.         }
  159.     }
  160. /*...e*/
  161.  
  162. BOOLEAN gbm_ref_horz(const GBM *gbm, byte *data)
  163.     {
  164.     int stride = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
  165.     int y;
  166.     byte *p = data;
  167.     byte *tmp;
  168.  
  169.     if ( (tmp = malloc((size_t) stride)) == NULL )
  170.         return FALSE;
  171.  
  172.     switch ( gbm->bpp )
  173.         {
  174.         case 24:
  175.             for ( y = 0; y < gbm->h; y++, p += stride )
  176.                 {
  177.                 ref_horz_24(tmp, p, gbm->w);
  178.                 memcpy(p, tmp, stride);
  179.                 }
  180.             break;
  181.         case 8:
  182.             for ( y = 0; y < gbm->h; y++, p += stride )
  183.                 {
  184.                 ref_horz_8(tmp, p, gbm->w);
  185.                 memcpy(p, tmp, stride);
  186.                 }
  187.             break;
  188.         case 4:
  189.             table_4();
  190.             for ( y = 0; y < gbm->h; y++, p += stride )
  191.                 {
  192.                 ref_horz_4(tmp, p, gbm->w);
  193.                 memcpy(p, tmp, stride);
  194.                 }
  195.             break;
  196.         case 1:
  197.             table_1();
  198.             for ( y = 0; y < gbm->h; y++, p += stride )
  199.                 {
  200.                 ref_horz_1(tmp, p, gbm->w);
  201.                 memcpy(p, tmp, stride);
  202.                 }
  203.             break;
  204.         }
  205.  
  206.     free(tmp);
  207.  
  208.     return TRUE;
  209.     }
  210. /*...e*/
  211. /*...sgbm_transpose:0:*/
  212. void gbm_transpose(const GBM *gbm, const byte *data, byte *data_t)
  213.     {
  214.     int stride   = ((gbm->w * gbm->bpp + 31) / 32) * 4;
  215.     int stride_t = ((gbm->h * gbm->bpp + 31) / 32) * 4;
  216.  
  217.     switch ( gbm->bpp )
  218.         {
  219. /*...s24:16:*/
  220. case 24:
  221.     {
  222.     int data_step = stride - gbm->w * 3;
  223.     int p_step = stride_t - 2;
  224.     int x, y;
  225.  
  226.     for ( y = 0; y < gbm->h; y++ )
  227.         {
  228.         byte *p = data_t; data_t += 3;
  229.  
  230.         for ( x = 0; x < gbm->w; x++ )
  231.             {
  232.             *p++ = *data++;
  233.             *p++ = *data++;
  234.             *p   = *data++;
  235.             p += p_step;
  236.             }
  237.         data += data_step;
  238.         }
  239.     }
  240.     break;
  241. /*...e*/
  242. /*...s8:16:*/
  243. case 8:
  244.     {
  245.     int data_step = stride - gbm->w;
  246.     int x, y;
  247.  
  248.     for ( y = 0; y < gbm->h; y++ )
  249.         {
  250.         byte *p = data_t++;
  251.  
  252.         for ( x = 0; x < gbm->w; x++ )
  253.             {
  254.             *p = *data++;
  255.             p += stride_t;
  256.             }
  257.         data += data_step;
  258.         }
  259.     }
  260.     break;
  261. /*...e*/
  262. /*...s4:16:*/
  263. case 4:
  264.     {
  265.     int x, y;
  266.  
  267.     for ( y = 0; y < gbm->h; y += 2 )
  268.         {
  269.         for ( x = 0; x < gbm->w; x += 2 )
  270. /*...s2x2 transpose to 2x2:40:*/
  271. {
  272. const byte *src = data + y * stride + ((unsigned)x >> 1);
  273. byte ab        = src[0     ];
  274. byte cd        = src[stride];
  275. byte *dst      = data_t + x * stride_t + ((unsigned)y >> 1);
  276. dst[0       ] = (byte) ((ab & 0xf0) | (cd >> 4));
  277. dst[stride_t] = (byte) ((ab << 4) | (cd & 0x0f));
  278. }
  279. /*...e*/
  280.         if ( x < gbm->w )
  281. /*...s1x2 transpose to 2x1:40:*/
  282. {
  283. const byte *src = data + y * stride + ((unsigned)x >> 1);
  284. byte a0      = src[0     ];
  285. byte b0      = src[stride];
  286. byte *dst    = data_t + x * stride_t + ((unsigned)y >> 1);
  287. dst[0     ] = (byte) ((a0 & 0xf0) | (b0 >> 4));
  288. }
  289. /*...e*/
  290.         }
  291.     if ( y < gbm->h )
  292.         {
  293.         for ( x = 0; x < gbm->w; x += 2 )
  294. /*...s2x1 transpose to 1x2:40:*/
  295. {
  296. const byte *src = data + y * stride + ((unsigned)x >> 1);
  297. byte ab        = src[0     ];
  298. byte *dst      = data_t + x * stride_t + ((unsigned)y >> 1);
  299. dst[0       ] = (byte) (ab & 0xf0);
  300. dst[stride_t] = (byte) (ab << 4);
  301. }
  302. /*...e*/
  303.         if ( x < gbm->w )
  304. /*...s1x1 transpose to 1x1:40:*/
  305. {
  306. const byte *src = data + y * stride + ((unsigned)x >> 1);
  307. byte a0      = src[0     ];
  308. byte *dst    = data_t + x * stride_t + ((unsigned)y >> 1);
  309. dst[0     ] = (byte) (a0 & 0xf0);
  310. }
  311. /*...e*/
  312.         }
  313.     }
  314.     break;
  315. /*...e*/
  316. /*...s1:16:*/
  317. case 1:
  318.     {
  319.     int x, y;
  320.     byte xbit, ybit;
  321.  
  322.     memset(data_t, 0, gbm->w * stride_t);
  323.  
  324.     ybit = 0x80;
  325.     for ( y = 0; y < gbm->h; y++ )
  326.         {
  327.         xbit = 0x80;
  328.         for ( x = 0; x < gbm->w; x++ )
  329.             {
  330.             const byte *src = data   + y * stride   + ((unsigned)x >> 3);
  331.                   byte *dst = data_t + x * stride_t + ((unsigned)y >> 3); 
  332.  
  333.             if ( *src & xbit )
  334.                 *dst |= ybit;
  335.  
  336.             if ( (xbit >>= 1) == 0 )
  337.                 xbit = 0x80;
  338.             }
  339.         if ( (ybit >>= 1) == 0 )
  340.             ybit = 0x80;
  341.         }
  342.     }
  343.     break;
  344. /*...e*/
  345.         }
  346.     }
  347. /*...e*/
  348.