home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gbmsrc.zip / gbmtrunc.c < prev    next >
C/C++ Source or Header  |  1996-12-15  |  22KB  |  761 lines

  1. /*
  2.  
  3. gbmtrunc.c - Truncate to lower bits per pixel
  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. /*...svars:0:*/
  18. static BOOLEAN inited = FALSE;
  19.  
  20. /*
  21. For 6Rx6Gx6B, 7Rx8Gx4B palettes etc.
  22. */
  23.  
  24. static byte index4[0x100];
  25. static byte index6[0x100];
  26. static byte index7[0x100];
  27. static byte index8[0x100];
  28. static byte index16[0x100];
  29. static byte scale4[] = { 0, 85, 170, 255 };
  30. static byte scale6[] = { 0, 51, 102, 153, 204, 255 };
  31. static byte scale7[] = { 0, 43, 85, 128, 170, 213, 255 };
  32. static byte scale8[] = { 0, 36, 73, 109, 146, 182, 219, 255 };
  33. static byte scale16[] = { 0, 17, 34, 51, 68, 85, 102, 119, 136,
  34.                153, 170, 187, 204, 221, 238, 255 };
  35. /*...e*/
  36. /*...sinit:0:*/
  37. /*
  38. This function initialises this module.
  39. */
  40.  
  41. /*...snearest_inx:0:*/
  42. #ifndef abs
  43. #define    abs(x)    (((x)>=0)?(x):-(x))
  44. #endif
  45.  
  46. static byte nearest_inx(byte value, const byte ab[], unsigned short cb)
  47.     {
  48.     byte b, inx, inx_min;
  49.     short diff, diff_min;
  50.  
  51.     b = ab[0];
  52.     diff_min = abs((short) value - (short) b);
  53.     inx_min = 0;
  54.     for ( inx = 1; (unsigned short) inx < cb; inx++ )
  55.         {
  56.         b = ab[inx];
  57.         diff = abs((short) value - (short) b);
  58.         if ( diff < diff_min )
  59.             {
  60.             diff_min = diff;
  61.             inx_min = inx;
  62.             }
  63.         }
  64.     return inx_min;
  65.     }
  66. /*...e*/
  67.  
  68. static void init(void)
  69.     {
  70.     int i;
  71.  
  72.     if ( inited )
  73.         return;
  74.  
  75.     /* For 7 Red x 8 Green x 4 Blue palettes etc. */
  76.  
  77.     for ( i = 0; i < 0x100; i++ )
  78.         {
  79.         index4 [i] = nearest_inx((byte) i, scale4 , sizeof(scale4 ));
  80.         index6 [i] = nearest_inx((byte) i, scale6 , sizeof(scale6 ));
  81.         index7 [i] = nearest_inx((byte) i, scale7 , sizeof(scale7 ));
  82.         index8 [i] = nearest_inx((byte) i, scale8 , sizeof(scale8 ));
  83.         index16[i] = nearest_inx((byte) i, scale16, sizeof(scale16));
  84.         }
  85.  
  86.     inited = TRUE;
  87.     }
  88. /*...e*/
  89. /*...strunc:0:*/
  90. static void trunc(
  91.     const GBM *gbm, const byte *src, byte *dest,
  92.     int dest_bpp,
  93.     void (*trunc_line)(const byte *src, byte *dest, int cx)
  94.     )
  95.     {
  96.     int    stride_src = ((gbm->w * 3 + 3) & ~3);
  97.     int    stride_dest = ((gbm->w * dest_bpp + 31) / 32) * 4;
  98.     int    y;
  99.  
  100.     for ( y = 0; y < gbm->h; y++ )
  101.         (*trunc_line)(src + y * stride_src, dest + y * stride_dest, gbm->w);
  102.     }
  103. /*...e*/
  104.  
  105. /*...sgbm_trunc_line_24     \45\ truncate to fewer bits per pixel one line:0:*/
  106. void gbm_trunc_line_24(const byte *src, byte *dest, int cx, byte rm, byte gm, byte bm)
  107.     {
  108.     int x;
  109.  
  110.     for ( x = 0; x < cx; x++ )
  111.         {
  112.         *dest++ = (*src++ & bm);
  113.         *dest++ = (*src++ & gm);
  114.         *dest++ = (*src++ & rm);
  115.         }
  116.     }
  117. /*...e*/
  118. /*...sgbm_trunc_24          \45\ truncate to fewer bits per pixel:0:*/
  119. void gbm_trunc_24(const GBM *gbm, const byte *data24, byte *data8, byte rm, byte gm, byte bm)
  120.     {
  121.     int    stride = ((gbm->w * 3 + 3) & ~3);
  122.     int    y;
  123.  
  124.     for ( y = 0; y < gbm->h; y++ )
  125.         gbm_trunc_line_24(data24 + y * stride, data8 + y * stride, gbm->w, rm, gm, bm);
  126.     }
  127. /*...e*/
  128.  
  129. /*...sgbm_trunc_pal_6R6G6B  \45\ return 6Rx6Gx6B palette:0:*/
  130. /*
  131. This function makes the palette for the 6 red x 6 green x 6 blue palette.
  132. 216 palette entrys used. Remaining 40 left blank.
  133. */
  134.  
  135. void gbm_trunc_pal_6R6G6B(GBMRGB *gbmrgb)
  136.     {
  137.     byte r, g, b;
  138.  
  139.     init();
  140.     memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
  141.     for ( r = 0; r < 6; r++ )
  142.         for ( g = 0; g < 6; g++ )
  143.             for ( b = 0; b < 6; b++ )
  144.                 {
  145.                 gbmrgb->r = scale6[r];
  146.                 gbmrgb->g = scale6[g];
  147.                 gbmrgb->b = scale6[b];
  148.                 gbmrgb++;
  149.                 }
  150.     }
  151. /*...e*/
  152. /*...sgbm_trunc_line_6R6G6B \45\ truncate to 6Rx6Gx6B one line:0:*/
  153. void gbm_trunc_line_6R6G6B(const byte *src, byte *dest, int cx)
  154.     {
  155.     int x;
  156.  
  157.     init();
  158.  
  159.     for ( x = 0; x < cx; x++ )
  160.         {
  161.         byte bi = index6[*src++];
  162.         byte gi = index6[*src++];
  163.         byte ri = index6[*src++];
  164.  
  165.         *dest++ = (byte) (6 * (6 * ri + gi) + bi);
  166.         }
  167.     }
  168. /*...e*/
  169. /*...sgbm_trunc_6R6G6B      \45\ truncate to 6Rx6Gx6B:0:*/
  170. void gbm_trunc_6R6G6B(const GBM *gbm, const byte *data24, byte *data8)
  171.     {
  172.     trunc(gbm, data24, data8, 8, gbm_trunc_line_6R6G6B);
  173.     }
  174. /*...e*/
  175.  
  176. /*...sgbm_trunc_pal_7R8G4B  \45\ return 7Rx8Gx4B palette:0:*/
  177. /*
  178. This function makes the palette for the 7 red x 8 green x 4 blue palette.
  179. 224 palette entrys used. Remaining 32 left blank.
  180. Colours calculated to match those used by 8514/A PM driver.
  181. */
  182.  
  183. void gbm_trunc_pal_7R8G4B(GBMRGB *gbmrgb)
  184.     {
  185.     byte r, g, b;
  186.  
  187.     init();
  188.  
  189.     memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
  190.     for ( r = 0; r < 7; r++ )
  191.         for ( g = 0; g < 8; g++ )
  192.             for ( b = 0; b < 4; b++ )
  193.                 {
  194.                 gbmrgb->r = scale7[r];
  195.                 gbmrgb->g = scale8[g];
  196.                 gbmrgb->b = scale4[b];
  197.                 gbmrgb++;
  198.                 }
  199.     }
  200. /*...e*/
  201. /*...sgbm_trunc_line_7R8G4B \45\ truncate to 7Rx8Gx4B one line:0:*/
  202. void gbm_trunc_line_7R8G4B(const byte *src, byte *dest, int cx)
  203.     {
  204.     int x;
  205.  
  206.     init();
  207.  
  208.     for ( x = 0; x < cx; x++ )
  209.         {
  210.         byte bi = index4[*src++];
  211.         byte gi = index8[*src++];
  212.         byte ri = index7[*src++];
  213.  
  214.         *dest++ = (byte) (4 * (8 * ri + gi) + bi);
  215.         }
  216.     }
  217. /*...e*/
  218. /*...sgbm_trunc_7R8G4B      \45\ truncate to 7Rx8Gx4B:0:*/
  219. void gbm_trunc_7R8G4B(const GBM *gbm, const byte *data24, byte *data8)
  220.     {
  221.     trunc(gbm, data24, data8, 8, gbm_trunc_line_7R8G4B);
  222.     }
  223. /*...e*/
  224.  
  225. /*...sgbm_trunc_pal_VGA     \45\ return default VGA palette:0:*/
  226. /*
  227. This function makes the palette for the 16 colour VGA palette.
  228. */
  229.  
  230. static GBMRGB gbmrgb_vga[] =
  231.     {
  232.       0,  0,  0,
  233.     128,  0,  0,
  234.       0,128,  0,
  235.     128,128,  0,
  236.       0,  0,128,
  237.     128,  0,128,
  238.       0,128,128,
  239.     128,128,128,
  240.     204,204,204,
  241.     255,  0,  0,
  242.       0,255,  0,
  243.     255,255,  0,
  244.       0,  0,255,
  245.     255,  0,255,
  246.       0,255,255,
  247.     255,255,255,
  248.     };
  249.  
  250. void gbm_trunc_pal_VGA(GBMRGB *gbmrgb)
  251.     {
  252.     init();
  253.     memcpy((char *) gbmrgb, (char *) gbmrgb_vga, sizeof(gbmrgb_vga));
  254.     }
  255. /*...e*/
  256. /*...sgbm_trunc_line_VGA    \45\ truncate to default VGA palette:0:*/
  257. /*...scalc_nearest:0:*/
  258. /*
  259. This function, when given am RGB colour, finds the VGA palette entry closest
  260. to it. We deliberately bias away from the two grey palette entries.
  261. */
  262.  
  263. static byte calc_nearest(byte r, byte g, byte b)
  264.     {
  265.     long min_dist = 3L * 256L * 256L * 10L;
  266.     byte bi, bi_min;
  267.  
  268.     for ( bi = 0; bi < 0x10; bi++ )
  269.         {
  270.         long b_dist = ((long) b - (long) gbmrgb_vga[bi].b);
  271.         long g_dist = ((long) g - (long) gbmrgb_vga[bi].g);
  272.         long r_dist = ((long) r - (long) gbmrgb_vga[bi].r);
  273.         long dist = r_dist * r_dist + g_dist * g_dist + b_dist * b_dist;
  274.  
  275.         if ( dist < min_dist )
  276.             {
  277.             min_dist = dist;
  278.             bi_min = bi;
  279.             }
  280.         }
  281.     return bi_min;
  282.     }
  283. /*...e*/
  284. /*...snearest_colour:0:*/
  285. /*
  286. This function finds the closest VGA palette colour to a given RGB value.
  287. It uses a lookup table to avoid performing distance calculations to the
  288. 16 palette entrys. The table is pre-calculated.
  289. */
  290.  
  291. /*...squick lookup table:0:*/
  292. /*...v_gbmtrun\46\c \45\ used to make quick_tab:0:*/
  293.  
  294. static byte quick_tab[16][16][16] =
  295.     {
  296.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  297.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  298.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  299.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  300.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  301.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
  302.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
  303.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  304.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  305.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
  306.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
  307.     2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
  308.     10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
  309.     10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
  310.     10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
  311.     10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
  312.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  313.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  314.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  315.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  316.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  317.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
  318.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
  319.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  320.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  321.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
  322.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
  323.     2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
  324.     10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
  325.     10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
  326.     10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
  327.     10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
  328.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  329.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  330.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  331.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  332.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  333.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
  334.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
  335.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  336.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  337.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
  338.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
  339.     2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
  340.     10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
  341.     10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
  342.     10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
  343.     10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
  344.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  345.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  346.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  347.     0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
  348.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  349.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
  350.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
  351.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  352.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
  353.     2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
  354.     2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
  355.     2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
  356.     10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
  357.     10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
  358.     10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
  359.     10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
  360.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  361.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  362.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  363.     255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
  364.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,
  365.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,
  366.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  367.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  368.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  369.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  370.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,14,
  371.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,14,14,
  372.     255,255,255,255,255,255,255,255,255,255,255,255,255,14,14,14,
  373.     10,10,10,10,255,255,255,255,255,255,255,255,14,14,14,14,
  374.     10,10,10,10,10,255,255,255,255,255,255,14,14,14,14,14,
  375.     10,10,10,10,10,10,255,255,255,255,14,14,14,14,14,14,
  376.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
  377.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
  378.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
  379.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
  380.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,
  381.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  382.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  383.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  384.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  385.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  386.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  387.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  388.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,14,
  389.     255,255,255,255,255,7,7,7,7,7,7,255,255,255,14,14,
  390.     10,10,10,10,255,255,7,7,7,7,255,255,255,14,14,14,
  391.     10,10,10,10,10,255,255,7,7,255,255,255,14,14,14,14,
  392.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
  393.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
  394.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
  395.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
  396.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  397.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  398.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  399.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  400.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  401.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  402.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  403.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,255,
  404.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,255,255,
  405.     3,3,3,3,255,7,7,7,7,7,255,255,255,255,255,255,
  406.     255,255,255,255,255,7,7,7,7,255,255,255,255,255,255,255,
  407.     10,10,10,10,255,255,7,7,255,255,255,255,255,255,255,255,
  408.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  409.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  410.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  411.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  412.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  413.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  414.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  415.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  416.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  417.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  418.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
  419.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
  420.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  421.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  422.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  423.     255,255,255,255,255,7,7,255,255,255,8,8,8,8,8,255,
  424.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  425.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  426.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  427.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
  428.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  429.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
  430.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  431.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  432.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  433.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
  434.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
  435.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  436.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  437.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  438.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  439.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  440.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
  441.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
  442.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
  443.     1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
  444.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  445.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
  446.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  447.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  448.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
  449.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
  450.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  451.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  452.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  453.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  454.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  455.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  456.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
  457.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
  458.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
  459.     1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
  460.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,13,
  461.     3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
  462.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  463.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
  464.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
  465.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  466.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  467.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  468.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  469.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  470.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  471.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  472.     1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
  473.     1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
  474.     1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
  475.     1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
  476.     255,255,255,255,255,255,255,255,255,255,255,255,255,255,13,13,
  477.     3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
  478.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,255,
  479.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
  480.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  481.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  482.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  483.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  484.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  485.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  486.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  487.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
  488.     9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
  489.     9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
  490.     9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
  491.     9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
  492.     255,255,255,255,255,255,255,255,255,255,255,255,255,13,13,13,
  493.     3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,13,
  494.     3,3,3,3,255,7,7,7,7,7,7,255,255,255,255,255,
  495.     3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
  496.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  497.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  498.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  499.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  500.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  501.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  502.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
  503.     11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
  504.     9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
  505.     9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
  506.     9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
  507.     9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
  508.     9,9,9,9,255,255,255,255,255,255,255,255,13,13,13,13,
  509.     255,255,255,255,255,7,7,7,7,7,7,255,255,255,13,13,
  510.     3,3,3,3,255,7,7,7,7,7,255,255,255,255,255,255,
  511.     3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
  512.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  513.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  514.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  515.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  516.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  517.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
  518.     11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
  519.     11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
  520.     9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
  521.     9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
  522.     9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
  523.     9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
  524.     9,9,9,9,9,255,255,255,255,255,255,13,13,13,13,13,
  525.     9,9,9,9,255,255,7,7,7,7,255,255,255,13,13,13,
  526.     255,255,255,255,255,7,7,7,7,255,255,255,255,255,255,255,
  527.     3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
  528.     3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
  529.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  530.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  531.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  532.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
  533.     11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
  534.     11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
  535.     11,11,11,11,11,11,255,8,8,8,8,8,255,255,255,15,
  536.     9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
  537.     9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
  538.     9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
  539.     9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
  540.     9,9,9,9,9,9,255,255,255,255,13,13,13,13,13,13,
  541.     9,9,9,9,9,255,255,7,7,255,255,255,13,13,13,13,
  542.     9,9,9,9,255,255,7,7,255,255,255,255,255,255,255,255,
  543.     255,255,255,255,255,7,7,255,255,255,8,8,8,8,8,255,
  544.     255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
  545.     11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
  546.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
  547.     11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
  548.     11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
  549.     11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
  550.     11,11,11,11,11,11,255,8,8,8,8,8,255,255,255,15,
  551.     11,11,11,11,11,11,255,255,8,8,8,255,255,255,15,15,
  552.     };
  553. /*...e*/
  554.  
  555. static byte nearest_colour(byte r, byte g, byte b)
  556.     {
  557.     byte i;
  558.  
  559.     if ( (i = quick_tab[r >> 4][g >> 4][b >> 4]) != (byte) 0xff )
  560.         return i;
  561.  
  562.     return calc_nearest(r, g, b);
  563.     }
  564. /*...e*/
  565.  
  566. void gbm_trunc_line_VGA(const byte *src, byte *dest, int cx)
  567.     {
  568.     BOOLEAN left = TRUE;
  569.     int x;
  570.  
  571.     init();
  572.  
  573.     for ( x = 0; x < cx; x++ )
  574.         {
  575.         byte b   = *src++;
  576.         byte g   = *src++;
  577.         byte r   = *src++;
  578.         byte inx = nearest_colour(r, g, b); 
  579.  
  580.         if ( left )
  581.             *dest = (byte) (inx << 4);
  582.         else
  583.             *dest++ |= inx;
  584.  
  585.         left = !left;
  586.         }
  587.     }
  588. /*...e*/
  589. /*...sgbm_trunc_VGA         \45\ truncate to default VGA palette:0:*/
  590. void gbm_trunc_VGA(const GBM *gbm, const byte *data24, byte *data4)
  591.     {
  592.     trunc(gbm, data24, data4, 4, gbm_trunc_line_VGA);
  593.     }
  594. /*...e*/
  595.  
  596. /*...sgbm_trunc_pal_8       \45\ return default 8 colour palette:0:*/
  597. /*
  598. This function makes the palette for the 16 colour VGA palette.
  599. */
  600.  
  601. static GBMRGB gbmrgb_8[] =
  602.     {
  603.       0,  0,  0,
  604.       0,  0,255,
  605.       0,255,  0,
  606.       0,255,255,
  607.     255,  0,  0,
  608.     255,  0,255,
  609.     255,255,  0,
  610.     255,255,255,
  611.       0,  0,  0,
  612.       0,  0,  0,
  613.       0,  0,  0,
  614.       0,  0,  0,
  615.       0,  0,  0,
  616.       0,  0,  0,
  617.       0,  0,  0,
  618.       0,  0,  0,
  619.     };
  620.  
  621. void gbm_trunc_pal_8(GBMRGB *gbmrgb)
  622.     {
  623.     init();
  624.     memcpy((char *) gbmrgb, (char *) gbmrgb_8, sizeof(gbmrgb_8));
  625.     }
  626. /*...e*/
  627. /*...sgbm_trunc_line_8      \45\ truncate to default 8 colour palette:0:*/
  628. void gbm_trunc_line_8(const byte *src, byte *dest, int cx)
  629.     {
  630.     BOOLEAN left = TRUE;
  631.     int x;
  632.  
  633.     init();
  634.  
  635.     for ( x = 0; x < cx; x++ )
  636.         {
  637.         byte b   = ((*src++ & 0x80U) >> 7);
  638.         byte g   = ((*src++ & 0x80U) >> 6);
  639.         byte r   = ((*src++ & 0x80U) >> 5);
  640.         byte inx = r|g|b;
  641.  
  642.         if ( left )
  643.             *dest = (byte) (inx << 4);
  644.         else
  645.             *dest++ |= inx;
  646.  
  647.         left = !left;
  648.         }
  649.     }
  650. /*...e*/
  651. /*...sgbm_trunc_8           \45\ truncate to default 8 colour palette:0:*/
  652. void gbm_trunc_8(const GBM *gbm, const byte *data24, byte *data4)
  653.     {
  654.     trunc(gbm, data24, data4, 4, gbm_trunc_line_8);
  655.     }
  656. /*...e*/
  657.  
  658. /*...sgbm_trunc_pal_4G      \45\ return 4 bit greyscale palette:0:*/
  659. /*
  660. This function makes the palette for the 16 colour VGA palette.
  661. */
  662.  
  663. void gbm_trunc_pal_4G(GBMRGB *gbmrgb)
  664.     {
  665.     int i;
  666.  
  667.     init();
  668.     for ( i = 0; i < 0x10; i++ )
  669.         {
  670.         gbmrgb[i].r = scale16[i];
  671.         gbmrgb[i].g = scale16[i];
  672.         gbmrgb[i].b = scale16[i];
  673.         }
  674.     }
  675. /*...e*/
  676. /*...sgbm_trunc_line_4G     \45\ truncate to 4 bit greyscale palette:0:*/
  677. void gbm_trunc_line_4G(const byte *src, byte *dest, int cx)
  678.     {
  679.     BOOLEAN left = TRUE;
  680.     int x;
  681.  
  682.     init();
  683.  
  684.     for ( x = 0; x < cx; x++ )
  685.         {
  686.         byte b   = *src++;
  687.         byte g   = *src++;
  688.         byte r   = *src++;
  689.         byte k   = (byte) (((word) r * 77U + (word) g * 150U + (word) b * 29U) >> 8);
  690.         byte inx = index16[k];
  691.  
  692.         if ( left )
  693.             *dest = (byte) (inx << 4);
  694.         else
  695.             *dest++ |= inx;
  696.  
  697.         left = !left;
  698.         }
  699.     }
  700. /*...e*/
  701. /*...sgbm_trunc_4G          \45\ truncate to 4 bit greyscale palette:0:*/
  702. void gbm_trunc_4G(const GBM *gbm, const byte *data24, byte *data4)
  703.     {
  704.     trunc(gbm, data24, data4, 4, gbm_trunc_line_4G);
  705.     }
  706. /*...e*/
  707.  
  708. /*...sgbm_trunc_pal_BW      \45\ return black and white palette:0:*/
  709. /*
  710. This function makes the black and white palette.
  711. (We consider the image to be black on white, hence the ordering).
  712. */
  713.  
  714. static GBMRGB gbmrgb_bw[] =
  715.     {
  716.     255,255,255,
  717.     0,0,0,
  718.     };
  719.  
  720. void gbm_trunc_pal_BW(GBMRGB *gbmrgb)
  721.     {
  722.     init();
  723.     memcpy((char *) gbmrgb, (char *) gbmrgb_bw, sizeof(gbmrgb_bw));
  724.     }
  725. /*...e*/
  726. /*...sgbm_trunc_line_BW     \45\ truncate to black and white:0:*/
  727. void gbm_trunc_line_BW(const byte *src, byte *dest, int cx)
  728.     {
  729.     int x, bit = 0;
  730.     byte v = 0xff;
  731.  
  732.     init();
  733.  
  734.     for ( x = 0; x < cx; x++ )
  735.         {
  736.         byte b = *src++;
  737.         byte g = *src++;
  738.         byte r = *src++;
  739.         word k = (word) ((word) r * 77 + (word) g * 150 + (word) b * 29);
  740.  
  741.         if ( k >= 0x8000U )
  742.             v &= ~(0x80U >> bit);
  743.  
  744.         if ( ++bit == 8 )
  745.             {
  746.             bit = 0;
  747.             *dest++ = v;
  748.             v = 0xff;
  749.             }
  750.         }
  751.     if ( bit )
  752.         *dest  = v;
  753.     }
  754. /*...e*/
  755. /*...sgbm_trunc_BW          \45\ truncate to black and white:0:*/
  756. void gbm_trunc_BW(const GBM *gbm, const byte *data24, byte *data1)
  757.     {
  758.     trunc(gbm, data24, data1, 1, gbm_trunc_line_BW);
  759.     }
  760. /*...e*/
  761.