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