1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Asm routines for software color conversion.
12 * Suggestions to make it faster are welcome :)
13 *
14 * By Isaac Cruz.
15 *
16 * 24-bit color support and non MMX routines by Eric Botcazou.
17 *
18 * Support for rectangles of any width, 8-bit destination color
19 * and cross-conversion between 15-bit and 16-bit colors,
20 * additional MMX and color copy routines by Robert J. Ohannessian.
21 *
22 * See readme.txt for copyright information.
23 */
24
25
26 #include "allegro.h"
27 #include "allegro/internal/aintern.h"
28
29
30 int *_colorconv_indexed_palette = NULL; /* for conversion from 8-bit */
31 int *_colorconv_rgb_scale_5x35 = NULL; /* for conversion from 15/16-bit */
32 unsigned char *_colorconv_rgb_map = NULL; /* for conversion from 8/12-bit to 8-bit */
33
34 static int indexed_palette_depth; /* target depth of the indexed palette */
35 static int indexed_palette_size; /* size of the indexed palette */
36
37
38
39 /* build_rgb_scale_5235_table:
40 * Builds pre-calculated tables for 15-bit to truecolor conversion.
41 */
build_rgb_scale_5235_table(int to_depth)42 static void build_rgb_scale_5235_table(int to_depth)
43 {
44 int i, color, red, green, blue;
45
46 if (to_depth == 24)
47 /* 6 contiguous 256-entry tables (6k) */
48 _colorconv_rgb_scale_5x35 = _AL_MALLOC_ATOMIC(sizeof(int)*1536);
49 else if (to_depth == 32)
50 /* 2 contiguous 256-entry tables (2k) */
51 _colorconv_rgb_scale_5x35 = _AL_MALLOC_ATOMIC(sizeof(int)*512);
52
53 /* 1st table: r5g2 to r8g8b0 */
54 for (i=0; i<128; i++) {
55 red = _rgb_scale_5[i>>2];
56 green=((i&3)<<6)+((i&3)<<1);
57
58 color = (red<<16) | (green<<8);
59 _colorconv_rgb_scale_5x35[i] = color;
60
61 if (to_depth == 24) {
62 _colorconv_rgb_scale_5x35[ 512+i] = (color>>8)+((color&0xff)<<24);
63 _colorconv_rgb_scale_5x35[1024+i] = (color>>16)+((color&0xffff)<<16);
64 }
65 }
66
67 /* 2nd table: g3b5 to r0g8b8 */
68 for (i=0; i<256; i++) {
69 blue = _rgb_scale_5[i&0x1f];
70 green=(i>>5)<<3;
71
72 if (green == 0x38)
73 green++;
74
75 color = (green<<8) | blue;
76 _colorconv_rgb_scale_5x35[256+i] = color;
77
78 if (to_depth == 24) {
79 _colorconv_rgb_scale_5x35[ 512+256+i] = (color>>8)+((color&0xff)<<24);
80 _colorconv_rgb_scale_5x35[1024+256+i] = (color>>16)+((color&0xffff)<<16);
81 }
82 }
83 }
84
85
86
87 /* build_rgb_scale_5335_table:
88 * Builds pre-calculated tables for 16-bit to truecolor conversion.
89 */
build_rgb_scale_5335_table(int to_depth)90 static void build_rgb_scale_5335_table(int to_depth)
91 {
92 int i, color, red, green, blue;
93
94 if (to_depth == 24)
95 /* 6 contiguous 256-entry tables (6k) */
96 _colorconv_rgb_scale_5x35 = _AL_MALLOC_ATOMIC(sizeof(int)*1536);
97 else if (to_depth == 32)
98 /* 2 contiguous 256-entry tables (2k) */
99 _colorconv_rgb_scale_5x35 = _AL_MALLOC_ATOMIC(sizeof(int)*512);
100
101 /* 1st table: r5g3 to r8g8b0 */
102 for (i=0; i<256; i++) {
103 red = _rgb_scale_5[i>>3];
104 green=(i&7)<<5;
105
106 if (green >= 68)
107 green++;
108
109 if (green >= 160)
110 green++;
111
112 color = (red<<16) | (green<<8);
113 _colorconv_rgb_scale_5x35[i] = color;
114
115 if (to_depth == 24) {
116 _colorconv_rgb_scale_5x35[ 512+i] = (color>>8)+((color&0xff)<<24);
117 _colorconv_rgb_scale_5x35[1024+i] = (color>>16)+((color&0xffff)<<16);
118 }
119 }
120
121 /* 2nd table: g3b5 to r0g8b8 */
122 for (i=0; i<256; i++) {
123 blue = _rgb_scale_5[i&0x1f];
124 green=(i>>5)<<2;
125
126 if (green == 0x1c)
127 green++;
128
129 color = (green<<8) | blue;
130 _colorconv_rgb_scale_5x35[256+i] = color;
131
132 if (to_depth == 24) {
133 _colorconv_rgb_scale_5x35[ 512+256+i] = (color>>8)+((color&0xff)<<24);
134 _colorconv_rgb_scale_5x35[1024+256+i] = (color>>16)+((color&0xffff)<<16);
135 }
136 }
137 }
138
139
140
141 /* create_indexed_palette:
142 * Reserves storage for the 8-bit palette.
143 */
create_indexed_palette(int to_depth)144 static void create_indexed_palette(int to_depth)
145 {
146 switch (to_depth) {
147
148 case 15:
149 case 16:
150 indexed_palette_size = PAL_SIZE*2;
151 break;
152
153 case 24:
154 indexed_palette_size = PAL_SIZE*4;
155 break;
156
157 case 32:
158 indexed_palette_size = PAL_SIZE;
159 break;
160 }
161
162 indexed_palette_depth = to_depth;
163 _colorconv_indexed_palette = _AL_MALLOC_ATOMIC(sizeof(int) * indexed_palette_size);
164 }
165
166
167
168 /* _set_colorconv_palette:
169 * Updates 8-bit palette entries.
170 */
_set_colorconv_palette(AL_CONST struct RGB * p,int from,int to)171 void _set_colorconv_palette(AL_CONST struct RGB *p, int from, int to)
172 {
173 int n, color;
174
175 if (!indexed_palette_size)
176 return;
177
178 for (n = from; n <= to; n++) {
179 color = makecol_depth(indexed_palette_depth,
180 (p[n].r << 2) | ((p[n].r & 0x30) >> 4),
181 (p[n].g << 2) | ((p[n].g & 0x30) >> 4),
182 (p[n].b << 2) | ((p[n].b & 0x30) >> 4));
183
184 _colorconv_indexed_palette[n] = color;
185
186 if ((indexed_palette_depth == 15) || (indexed_palette_depth == 16)) {
187 /* 2 pre-calculated shift tables (2k) */
188 _colorconv_indexed_palette[PAL_SIZE+n] = color<<16;
189 }
190 else if (indexed_palette_depth == 24) {
191 /* 4 pre-calculated shift tables (4k) */
192 _colorconv_indexed_palette[PAL_SIZE+n] = (color>>8)+((color&0xff)<<24);
193 _colorconv_indexed_palette[PAL_SIZE*2+n] = (color>>16)+((color&0xffff)<<16);
194 _colorconv_indexed_palette[PAL_SIZE*3+n] = color<<8;
195 }
196 }
197 }
198
199
200
201 /* create_rgb_map:
202 * Reserves storage for the rgb map to 8-bit.
203 */
create_rgb_map(int from_depth)204 static void create_rgb_map(int from_depth)
205 {
206 int rgb_map_size = 0;
207
208 switch (from_depth) {
209 case 8:
210 rgb_map_size = 256; /* 8-bit */
211 break;
212
213 case 15:
214 case 16:
215 case 24:
216 case 32:
217 rgb_map_size = 4096; /* 12-bit */
218 break;
219 }
220
221 _colorconv_rgb_map = _AL_MALLOC_ATOMIC(sizeof(int) * rgb_map_size);
222 }
223
224
225
226 /* _get_colorconv_map:
227 * Retrieves a handle to the rgb map.
228 */
_get_colorconv_map(void)229 unsigned char *_get_colorconv_map(void)
230 {
231 return _colorconv_rgb_map;
232 }
233
234
235
236 /* _get_colorconv_blitter:
237 * Returns the blitter function matching the specified depths.
238 */
_get_colorconv_blitter(int from_depth,int to_depth)239 COLORCONV_BLITTER_FUNC *_get_colorconv_blitter(int from_depth, int to_depth)
240 {
241 switch (from_depth) {
242
243 #ifdef ALLEGRO_COLOR8
244 case 8:
245 switch (to_depth) {
246
247 case 8:
248 create_rgb_map(8);
249 return &_colorconv_blit_8_to_8;
250
251 case 15:
252 create_indexed_palette(15);
253 return &_colorconv_blit_8_to_15;
254
255 case 16:
256 create_indexed_palette(16);
257 return &_colorconv_blit_8_to_16;
258
259 case 24:
260 create_indexed_palette(24);
261 return &_colorconv_blit_8_to_24;
262
263 case 32:
264 create_indexed_palette(32);
265 return &_colorconv_blit_8_to_32;
266 }
267 break;
268 #endif
269
270 #ifdef ALLEGRO_COLOR16
271 case 15:
272 switch (to_depth) {
273
274 case 8:
275 create_rgb_map(15);
276 return &_colorconv_blit_15_to_8;
277
278 case 15:
279 #ifndef ALLEGRO_NO_COLORCOPY
280 return &_colorcopy_blit_15_to_15;
281 #else
282 return NULL;
283 #endif
284
285 case 16:
286 return &_colorconv_blit_15_to_16;
287
288 case 24:
289 build_rgb_scale_5235_table(24);
290 return &_colorconv_blit_15_to_24;
291
292 case 32:
293 build_rgb_scale_5235_table(32);
294 return &_colorconv_blit_15_to_32;
295 }
296 break;
297
298 case 16:
299 switch (to_depth) {
300
301 case 8:
302 create_rgb_map(16);
303 return &_colorconv_blit_16_to_8;
304
305 case 15:
306 return &_colorconv_blit_16_to_15;
307
308 case 16:
309 #ifndef ALLEGRO_NO_COLORCOPY
310 return &_colorcopy_blit_16_to_16;
311 #else
312 return NULL;
313 #endif
314
315 case 24:
316 build_rgb_scale_5335_table(24);
317 return &_colorconv_blit_16_to_24;
318
319 case 32:
320 build_rgb_scale_5335_table(32);
321 return &_colorconv_blit_16_to_32;
322 }
323 break;
324 #endif
325
326 #ifdef ALLEGRO_COLOR24
327 case 24:
328 switch (to_depth) {
329
330 case 8:
331 create_rgb_map(24);
332 return &_colorconv_blit_24_to_8;
333
334 case 15:
335 return &_colorconv_blit_24_to_15;
336
337 case 16:
338 return &_colorconv_blit_24_to_16;
339
340 case 24:
341 #ifndef ALLEGRO_NO_COLORCOPY
342 return &_colorcopy_blit_24_to_24;
343 #else
344 return NULL;
345 #endif
346
347 case 32:
348 return &_colorconv_blit_24_to_32;
349 }
350 break;
351 #endif
352
353 #ifdef ALLEGRO_COLOR32
354 case 32:
355 switch (to_depth) {
356
357 case 8:
358 create_rgb_map(32);
359 return &_colorconv_blit_32_to_8;
360
361 case 15:
362 return &_colorconv_blit_32_to_15;
363
364 case 16:
365 return &_colorconv_blit_32_to_16;
366
367 case 24:
368 return &_colorconv_blit_32_to_24;
369
370 case 32:
371 #ifndef ALLEGRO_NO_COLORCOPY
372 return &_colorcopy_blit_32_to_32;
373 #else
374 return NULL;
375 #endif
376 }
377 break;
378 #endif
379 }
380
381 return NULL;
382 }
383
384
385
386 /* _release_colorconv_blitter:
387 * Frees previously allocated resources.
388 */
_release_colorconv_blitter(COLORCONV_BLITTER_FUNC * blitter)389 void _release_colorconv_blitter(COLORCONV_BLITTER_FUNC *blitter)
390 {
391 /* destroy the 8-bit palette */
392 if (_colorconv_indexed_palette) {
393 _AL_FREE(_colorconv_indexed_palette);
394 _colorconv_indexed_palette = NULL;
395 indexed_palette_size = 0;
396 }
397
398 /* destroy the shift table */
399 if (_colorconv_rgb_scale_5x35) {
400 _AL_FREE(_colorconv_rgb_scale_5x35);
401 _colorconv_rgb_scale_5x35 = NULL;
402 }
403
404 /* destroy the rgb map to 8-bit */
405 if (_colorconv_rgb_map) {
406 _AL_FREE(_colorconv_rgb_map);
407 _colorconv_rgb_map = NULL;
408 }
409 }
410
411