home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1787 / newsmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  2.2 KB  |  99 lines

  1. /*
  2.  * newsmap.c -- convert an RGB triplet into a nearby value from the
  3.  * NeWS 8 plane colourmap.
  4.  *
  5.  * Note:  I could hard code the inverse tables, but this is not so
  6.  * inscrutable in case it should be changed.  Besides, the true
  7.  * colour mode could use this information in fitting the colour
  8.  * collisions to a next-best choice.
  9.  */
  10.  
  11. #include "newsmap.h"
  12.  
  13. #define gray_base    (32)
  14. short gray_level[] = {
  15.     0, 10, 20, 30, 40, 51, 61, 71, 81, 91, 102, 112, 122, 132,
  16.     142, 153, 163, 173, 183, 193, 204, 214, 224, 234, 244, 255
  17. };
  18. #define gray_run    (sizeof(gray_level) / sizeof(short))
  19. #define gray_black    (56)
  20. #define gray_white    (255)
  21.  
  22. #define colourbase    (56)
  23. short red_level[] = { 0, 63, 127, 191, 255 };
  24. short green_level[] = { 0, 36, 72, 109, 145, 182, 218, 255 };
  25. short blue_level[] = { 0, 63, 127, 191, 255 };
  26.  
  27. #define nreds    (sizeof(red_level) / sizeof(short))
  28. #define ngreens    (sizeof(green_level) / sizeof(short))
  29. #define nblues    (sizeof(blue_level) / sizeof(short))
  30.  
  31. short gray_inverse[256];
  32. short red_inverse[256];
  33. short green_inverse[256];
  34. short blue_inverse[256];
  35.  
  36. static void run_ramp();
  37.  
  38. void init_newsmap()
  39. {
  40.     int    i;
  41.  
  42.     run_ramp(gray_run, gray_level, gray_inverse);
  43.     for (i = 0; i < 256; i++) {
  44.         if (gray_inverse[i] == 0)
  45.             gray_inverse[i] = gray_black;
  46.         else if (gray_inverse[i] == gray_run - 1)
  47.             gray_inverse[i] = gray_white;
  48.         else
  49.             gray_inverse[i] += gray_base - 1;
  50.     }
  51.  
  52.     run_ramp(ngreens, green_level, green_inverse);
  53.     run_ramp(nreds, red_level, red_inverse);
  54.     for (i = 0; i < 256; i++)
  55.         red_inverse[i] *= ngreens;
  56.  
  57.     run_ramp(nblues, blue_level, blue_inverse);
  58.     for (i = 0; i < 256; i++)
  59.         blue_inverse[i] *= ngreens * nreds;
  60. }
  61.  
  62. static void run_ramp(n, level, inverse)
  63. int        n;
  64. short    level[];
  65. short    inverse[];
  66. {
  67.     int    i;
  68.     int    closest = 0;
  69.  
  70.     for (i = 0; i < 256; i++) {
  71.         if (abs(i - level[closest]) > abs(i - level[closest + 1]))
  72.             closest++;
  73.         inverse[i] = closest;
  74.         if (closest == n - 1)
  75.             break;
  76.     }
  77.     for (; i < 256; i++)
  78.         inverse[i] = closest;
  79. }
  80.  
  81. static int abs(n)
  82. int    n;
  83. {
  84.     if (n < 0)
  85.         return(-n);
  86.     return(n);
  87. }
  88.  
  89. int rgb2newsmap(r, g, b)
  90. int    r;
  91. int    g;
  92. int    b;
  93. {
  94.     if (r == g && g == b)
  95.         return(gray_inverse[r]);
  96.     
  97.     return(red_inverse[r] + green_inverse[g] + blue_inverse[b] + colourbase);
  98. }
  99.