source: libcaca/trunk/test/optipal.c @ 733

Last change on this file since 733 was 733, checked in by Sam Hocevar, 14 years ago
  • Replaced enum cucul_color with unsigned int. The size of an enum is not really portable, and Visual Studio complains when they are not explicitely cast.
  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1/*
2 *  optipal       S-Lang optimised palette generator for libcucul
3 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: optipal.c 733 2006-04-10 09:17:51Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14#include "config.h"
15
16#include <stdio.h>
17
18#include "cucul.h"
19
20static void base_colors(void);
21static void emulated_colors(void);
22static void unused_colors(void);
23
24static int slang_assoc[16*16], palette[16*16];
25
26/* 6 colours in hue order */
27static unsigned int const hue_list[] =
28{
29    CUCUL_COLOR_RED,
30    CUCUL_COLOR_BROWN,
31    CUCUL_COLOR_GREEN,
32    CUCUL_COLOR_CYAN,
33    CUCUL_COLOR_BLUE,
34    CUCUL_COLOR_MAGENTA
35};
36
37#define SETPAIR(_fg, _bg, _n) \
38    do \
39    { \
40        int fg = _fg, bg = _bg, n = _n; \
41        slang_assoc[fg + 16 * bg] = n; \
42        palette[n] = fg + 16 * bg; \
43    } \
44    while(0);
45
46int main(void)
47{
48    int i;
49
50    for(i = 0; i < 16 * 16; i++)
51    {
52        slang_assoc[i] = -1;
53        palette[i] = -1;
54    }
55
56    /* The base colour pairs (0-127) */
57    base_colors();
58
59    /* Now the less important pairs that we can afford to emulate using
60     * previously defined colour pairs. */
61    emulated_colors();
62
63    /* Fill the rest of the palette with equal colour pairs such as black
64     * on black. They will never be used, but nevermind. */
65    unused_colors();
66
67    /* Output the palette */
68    printf("static int const slang_palette[2*16*16] =\n{\n");
69    for(i = 0; i < 16 * 16; i++)
70    {
71        if((i % 8) == 0) printf("    ");
72        printf("%2i, %2i,  ", palette[i] % 16, palette[i] / 16);
73        if((i % 8) == 7) printf("\n");
74    }
75    printf("};\n\n");
76
77    /* Output the association table */
78    printf("static int const slang_assoc[16*16] =\n{\n");
79    for(i = 0; i < 16 * 16; i++)
80    {
81        if((i % 16) == 0) printf("    ");
82        printf("%i, ", slang_assoc[i]);
83        if((i % 16) == 15) printf("\n");
84    }
85    printf("};\n");
86
87    return 0;
88}
89
90/*
91 * XXX: See the NOTES file for what follows
92 */
93
94static void base_colors(void)
95{
96    int i, cur = 0;
97
98    /* black background colour pairs that are needed for the old renderer */
99    for(i = 1; i < 16; i++)
100        SETPAIR(i, CUCUL_COLOR_BLACK, cur++);
101
102    /* gray combinations used for grayscale dithering */
103    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_DARKGRAY, cur++);
104    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_LIGHTGRAY, cur++);
105    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_DARKGRAY, cur++);
106    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_LIGHTGRAY, cur++);
107    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_WHITE, cur++);
108
109    /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
110     * combinations often used for saturation/value dithering (the two
111     * other possible combinations, lightgray/dark and darkgray/light, are
112     * not considered here) */
113    for(i = 1; i < 7; i++)
114    {
115        SETPAIR(CUCUL_COLOR_WHITE, i + 8, cur++);
116        SETPAIR(i + 8, CUCUL_COLOR_WHITE, cur++);
117        SETPAIR(i, i + 8, cur++);
118        SETPAIR(i + 8, i, cur++);
119        SETPAIR(CUCUL_COLOR_LIGHTGRAY, i + 8, cur++);
120        SETPAIR(i + 8, CUCUL_COLOR_LIGHTGRAY, cur++);
121        SETPAIR(CUCUL_COLOR_DARKGRAY, i, cur++);
122        SETPAIR(i, CUCUL_COLOR_DARKGRAY, cur++);
123        SETPAIR(CUCUL_COLOR_BLACK, i, cur++);
124    }
125
126    /* next colour combinations for hue dithering (magenta/blue, blue/green
127     * and so on) */
128    for(i = 0; i < 6; i++)
129    {
130        SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
131        SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
132        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
133        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
134    }
135
136    /* next colour combinations for hue/value dithering (blue/lightgreen,
137     * green/lightblue and so on) */
138    for(i = 0; i < 6; i++)
139    {
140        SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
141        SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
142        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
143        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
144    }
145
146    /* black on light gray, black on white, white on dark gray, dark gray
147     * on white, white on blue, light gray on blue (chosen arbitrarily) */
148    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_LIGHTGRAY, cur++);
149    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_WHITE, cur++);
150    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_DARKGRAY, cur++);
151    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_WHITE, cur++);
152    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE, cur++);
153    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLUE, cur++);
154}
155
156static void emulated_colors(void)
157{
158    int i;
159
160    /* light gray on dark colour: emulate with light colour on dark colour
161     * white on dark colour: emulate with light gray on light colour
162     * black on light colour: emulate with dark gray on dark colour
163     * dark gray on light colour: emulate with dark colour on light colour
164     * light colour on dark gray: emulate with dark colour on dark gray
165     * dark colour on light gray: emulate with light colour on light gray
166     * dark colour on white: emulate with light colour on white */
167    for(i = 1; i < 7; i++)
168    {
169        if(i != CUCUL_COLOR_BLUE)
170        {
171            SETPAIR(CUCUL_COLOR_LIGHTGRAY, i, 128 +
172                    slang_assoc[i + 8 + 16 * i]);
173            SETPAIR(CUCUL_COLOR_WHITE, i, 128 +
174                    slang_assoc[CUCUL_COLOR_LIGHTGRAY + 16 * (i + 8)]);
175        }
176        SETPAIR(CUCUL_COLOR_BLACK, i + 8,
177                128 + slang_assoc[CUCUL_COLOR_DARKGRAY + 16 * i]);
178        SETPAIR(CUCUL_COLOR_DARKGRAY, i + 8,
179                128 + slang_assoc[i + 16 * (i + 8)]);
180        SETPAIR(i + 8, CUCUL_COLOR_DARKGRAY,
181                128 + slang_assoc[i + 16 * CUCUL_COLOR_DARKGRAY]);
182        SETPAIR(i, CUCUL_COLOR_LIGHTGRAY,
183                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_LIGHTGRAY]);
184        SETPAIR(i, CUCUL_COLOR_WHITE,
185                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_WHITE]);
186    }
187
188    /* 120 degree hue pairs can be emulated as well; for instance blue on
189     * red can be emulated using magenta on red, and blue on green using
190     * cyan on green */
191    for(i = 0; i < 6; i++)
192    {
193        SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
194            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
195        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
196            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
197        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
198            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
199        SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
200            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
201
202        SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
203            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
204        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
205            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
206        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
207            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
208        SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
209            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
210    }
211
212    /* dark opposite on dark: emulate with dark opposite on black
213     * light opposite on dark: emulate with light opposite on black
214     * dark opposite on light: emulate with black on dark
215     * light opposite on light: emulate with white on light */
216    for(i = 0; i < 6; i++)
217    {
218        SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
219                128 + slang_assoc[hue_list[i] + 16 * CUCUL_COLOR_BLACK]);
220        SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
221                128 + slang_assoc[hue_list[i] + 8 + 16 * CUCUL_COLOR_BLACK]);
222        SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
223                128 + slang_assoc[CUCUL_COLOR_BLACK + 16 * hue_list[i]]);
224        SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
225                128 + slang_assoc[CUCUL_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
226    }
227}
228
229static void unused_colors(void)
230{
231    int i, j;
232
233    for(i = 0, j = 0; i < 16 * 16; i++)
234    {
235        if(palette[i] == -1)
236        {
237            SETPAIR(j, j, i);
238            j++;
239        }
240    }
241}
242
Note: See TracBrowser for help on using the repository browser.