source: libcaca/branches/0.9/test/optipal.c @ 3273

Last change on this file since 3273 was 305, checked in by Sam Hocevar, 17 years ago
  • src/ examples/ test/: + Changed <const type> constructs into <type const>.
  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1/*
2 *  optipal       S-Lang optimised palette generator for libcaca
3 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: optipal.c 305 2004-01-02 16:52:10Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU Lesser General Public
10 *  License as published by the Free Software Foundation; either
11 *  version 2 of the License, or (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  Lesser General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Lesser General Public
19 *  License along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *  02111-1307  USA
22 */
23
24#include "config.h"
25
26#include <stdio.h>
27
28#include "caca.h"
29
30static void base_colors(void);
31static void emulated_colors(void);
32static void unused_colors(void);
33
34static int slang_assoc[16*16], palette[16*16];
35
36/* 6 colours in hue order */
37static enum caca_color const hue_list[] =
38{
39    CACA_COLOR_RED,
40    CACA_COLOR_BROWN,
41    CACA_COLOR_GREEN,
42    CACA_COLOR_CYAN,
43    CACA_COLOR_BLUE,
44    CACA_COLOR_MAGENTA
45};
46
47#define SETPAIR(_fg, _bg, _n) \
48    do \
49    { \
50        int fg = _fg, bg = _bg, n = _n; \
51        slang_assoc[fg + 16 * bg] = n; \
52        palette[n] = fg + 16 * bg; \
53    } \
54    while(0);
55
56int main(void)
57{
58    int i;
59
60    for(i = 0; i < 16 * 16; i++)
61    {
62        slang_assoc[i] = -1;
63        palette[i] = -1;
64    }
65
66    /* The base colour pairs (0-127) */
67    base_colors();
68
69    /* Now the less important pairs that we can afford to emulate using
70     * previously defined colour pairs. */
71    emulated_colors();
72
73    /* Fill the rest of the palette with equal colour pairs such as black
74     * on black. They will never be used, but nevermind. */
75    unused_colors();
76
77    /* Output the palette */
78    printf("static int const slang_palette[2*16*16] =\n{\n");
79    for(i = 0; i < 16 * 16; i++)
80    {
81        if((i % 8) == 0) printf("    ");
82        printf("%2i, %2i,  ", palette[i] % 16, palette[i] / 16);
83        if((i % 8) == 7) printf("\n");
84    }
85    printf("};\n\n");
86
87    /* Output the association table */
88    printf("static int const slang_assoc[16*16] =\n{\n");
89    for(i = 0; i < 16 * 16; i++)
90    {
91        if((i % 16) == 0) printf("    ");
92        printf("%i, ", slang_assoc[i]);
93        if((i % 16) == 15) printf("\n");
94    }
95    printf("};\n");
96
97    return 0;
98}
99
100/*
101 * XXX: See the NOTES file for what follows
102 */
103
104static void base_colors(void)
105{
106    int i, cur = 0;
107
108    /* black background colour pairs that are needed for the old renderer */
109    for(i = 1; i < 16; i++)
110        SETPAIR(i, CACA_COLOR_BLACK, cur++);
111
112    /* gray combinations used for grayscale dithering */
113    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_DARKGRAY, cur++);
114    SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY, cur++);
115    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY, cur++);
116    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_LIGHTGRAY, cur++);
117    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_WHITE, cur++);
118
119    /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
120     * combinations often used for saturation/value dithering (the two
121     * other possible combinations, lightgray/dark and darkgray/light, are
122     * not considered here) */
123    for(i = 1; i < 7; i++)
124    {
125        SETPAIR(CACA_COLOR_WHITE, i + 8, cur++);
126        SETPAIR(i + 8, CACA_COLOR_WHITE, cur++);
127        SETPAIR(i, i + 8, cur++);
128        SETPAIR(i + 8, i, cur++);
129        SETPAIR(CACA_COLOR_LIGHTGRAY, i + 8, cur++);
130        SETPAIR(i + 8, CACA_COLOR_LIGHTGRAY, cur++);
131        SETPAIR(CACA_COLOR_DARKGRAY, i, cur++);
132        SETPAIR(i, CACA_COLOR_DARKGRAY, cur++);
133        SETPAIR(CACA_COLOR_BLACK, i, cur++);
134    }
135
136    /* next colour combinations for hue dithering (magenta/blue, blue/green
137     * and so on) */
138    for(i = 0; i < 6; i++)
139    {
140        SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
141        SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
142        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
143        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
144    }
145
146    /* next colour combinations for hue/value dithering (blue/lightgreen,
147     * green/lightblue and so on) */
148    for(i = 0; i < 6; i++)
149    {
150        SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
151        SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
152        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
153        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
154    }
155
156    /* black on light gray, black on white, white on dark gray, dark gray
157     * on white, white on blue, light gray on blue (chosen arbitrarily) */
158    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_LIGHTGRAY, cur++);
159    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_WHITE, cur++);
160    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_DARKGRAY, cur++);
161    SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_WHITE, cur++);
162    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_BLUE, cur++);
163    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLUE, cur++);
164}
165
166static void emulated_colors(void)
167{
168    int i;
169
170    /* light gray on dark colour: emulate with light colour on dark colour
171     * white on dark colour: emulate with light gray on light colour
172     * black on light colour: emulate with dark gray on dark colour
173     * dark gray on light colour: emulate with dark colour on light colour
174     * light colour on dark gray: emulate with dark colour on dark gray
175     * dark colour on light gray: emulate with light colour on light gray
176     * dark colour on white: emulate with light colour on white */
177    for(i = 1; i < 7; i++)
178    {
179        if(i != CACA_COLOR_BLUE)
180        {
181            SETPAIR(CACA_COLOR_LIGHTGRAY, i, 128 +
182                    slang_assoc[i + 8 + 16 * i]);
183            SETPAIR(CACA_COLOR_WHITE, i, 128 +
184                    slang_assoc[CACA_COLOR_LIGHTGRAY + 16 * (i + 8)]);
185        }
186        SETPAIR(CACA_COLOR_BLACK, i + 8,
187                128 + slang_assoc[CACA_COLOR_DARKGRAY + 16 * i]);
188        SETPAIR(CACA_COLOR_DARKGRAY, i + 8,
189                128 + slang_assoc[i + 16 * (i + 8)]);
190        SETPAIR(i + 8, CACA_COLOR_DARKGRAY,
191                128 + slang_assoc[i + 16 * CACA_COLOR_DARKGRAY]);
192        SETPAIR(i, CACA_COLOR_LIGHTGRAY,
193                128 + slang_assoc[i + 8 + 16 * CACA_COLOR_LIGHTGRAY]);
194        SETPAIR(i, CACA_COLOR_WHITE,
195                128 + slang_assoc[i + 8 + 16 * CACA_COLOR_WHITE]);
196    }
197
198    /* 120 degree hue pairs can be emulated as well; for instance blue on
199     * red can be emulated using magenta on red, and blue on green using
200     * cyan on green */
201    for(i = 0; i < 6; i++)
202    {
203        SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
204            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
205        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
206            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
207        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
208            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
209        SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
210            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
211
212        SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
213            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
214        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
215            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
216        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
217            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
218        SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
219            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
220    }
221
222    /* dark opposite on dark: emulate with dark opposite on black
223     * light opposite on dark: emulate with light opposite on black
224     * dark opposite on light: emulate with black on dark
225     * light opposite on light: emulate with white on light */
226    for(i = 0; i < 6; i++)
227    {
228        SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
229                128 + slang_assoc[hue_list[i] + 16 * CACA_COLOR_BLACK]);
230        SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
231                128 + slang_assoc[hue_list[i] + 8 + 16 * CACA_COLOR_BLACK]);
232        SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
233                128 + slang_assoc[CACA_COLOR_BLACK + 16 * hue_list[i]]);
234        SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
235                128 + slang_assoc[CACA_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
236    }
237}
238
239static void unused_colors(void)
240{
241    int i, j;
242
243    for(i = 0, j = 0; i < 16 * 16; i++)
244    {
245        if(palette[i] == -1)
246        {
247            SETPAIR(j, j, i);
248            j++;
249        }
250    }
251}
252
Note: See TracBrowser for help on using the repository browser.