home *** CD-ROM | disk | FTP | other *** search
- /*
- * newsmap.c -- convert an RGB triplet into a nearby value from the
- * NeWS 8 plane colourmap.
- *
- * Note: I could hard code the inverse tables, but this is not so
- * inscrutable in case it should be changed. Besides, the true
- * colour mode could use this information in fitting the colour
- * collisions to a next-best choice.
- */
-
- #include "newsmap.h"
-
- #define gray_base (32)
- short gray_level[] = {
- 0, 10, 20, 30, 40, 51, 61, 71, 81, 91, 102, 112, 122, 132,
- 142, 153, 163, 173, 183, 193, 204, 214, 224, 234, 244, 255
- };
- #define gray_run (sizeof(gray_level) / sizeof(short))
- #define gray_black (56)
- #define gray_white (255)
-
- #define colourbase (56)
- short red_level[] = { 0, 63, 127, 191, 255 };
- short green_level[] = { 0, 36, 72, 109, 145, 182, 218, 255 };
- short blue_level[] = { 0, 63, 127, 191, 255 };
-
- #define nreds (sizeof(red_level) / sizeof(short))
- #define ngreens (sizeof(green_level) / sizeof(short))
- #define nblues (sizeof(blue_level) / sizeof(short))
-
- short gray_inverse[256];
- short red_inverse[256];
- short green_inverse[256];
- short blue_inverse[256];
-
- static void run_ramp();
-
- void init_newsmap()
- {
- int i;
-
- run_ramp(gray_run, gray_level, gray_inverse);
- for (i = 0; i < 256; i++) {
- if (gray_inverse[i] == 0)
- gray_inverse[i] = gray_black;
- else if (gray_inverse[i] == gray_run - 1)
- gray_inverse[i] = gray_white;
- else
- gray_inverse[i] += gray_base - 1;
- }
-
- run_ramp(ngreens, green_level, green_inverse);
- run_ramp(nreds, red_level, red_inverse);
- for (i = 0; i < 256; i++)
- red_inverse[i] *= ngreens;
-
- run_ramp(nblues, blue_level, blue_inverse);
- for (i = 0; i < 256; i++)
- blue_inverse[i] *= ngreens * nreds;
- }
-
- static void run_ramp(n, level, inverse)
- int n;
- short level[];
- short inverse[];
- {
- int i;
- int closest = 0;
-
- for (i = 0; i < 256; i++) {
- if (abs(i - level[closest]) > abs(i - level[closest + 1]))
- closest++;
- inverse[i] = closest;
- if (closest == n - 1)
- break;
- }
- for (; i < 256; i++)
- inverse[i] = closest;
- }
-
- static int abs(n)
- int n;
- {
- if (n < 0)
- return(-n);
- return(n);
- }
-
- int rgb2newsmap(r, g, b)
- int r;
- int g;
- int b;
- {
- if (r == g && g == b)
- return(gray_inverse[r]);
-
- return(red_inverse[r] + green_inverse[g] + blue_inverse[b] + colourbase);
- }
-