1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Pixel formats.
12 *
13 * By Trent Gamblin.
14 *
15 * See LICENSE.txt for copyright information.
16 */
17
18 #include "allegro5/allegro.h"
19 #include "allegro5/internal/aintern_pixels.h"
20
21 ALLEGRO_DEBUG_CHANNEL("pixels")
22
23
24 /* lookup table for scaling 8 bit integers up to floats [0.0, 1.0] */
25 #include "pixel_tables.inc"
26
27 static int pixel_sizes[] = {
28 0, /* ALLEGRO_PIXEL_FORMAT_ANY */
29 0,
30 0,
31 2,
32 2,
33 2,
34 3,
35 4,
36 4,
37 4, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
38 4,
39 2,
40 3,
41 2,
42 2,
43 2,
44 2,
45 4,
46 4,
47 3,
48 2,
49 2,
50 4,
51 4,
52 16, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
53 4, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
54 2, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
55 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
56 0,
57 0,
58 0,
59 };
60
61 static int pixel_bits[] = {
62 0, /* ALLEGRO_PIXEL_FORMAT_ANY */
63 0,
64 0,
65 15,
66 16,
67 16,
68 24,
69 32,
70 32,
71 32, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
72 32,
73 16,
74 24,
75 16,
76 15,
77 16,
78 16,
79 32,
80 32,
81 24,
82 16,
83 15,
84 32,
85 32,
86 128, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
87 32, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
88 16, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
89 8, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
90 0,
91 0,
92 0,
93 };
94
95 static int pixel_block_widths[] = {
96 0, /* ALLEGRO_PIXEL_FORMAT_ANY */
97 0,
98 0,
99 1,
100 1,
101 1,
102 1,
103 1,
104 1,
105 1, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
106 1,
107 1,
108 1,
109 1,
110 1,
111 1,
112 1,
113 1,
114 1,
115 1,
116 1,
117 1,
118 1,
119 1,
120 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
121 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
122 1, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
123 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
124 4,
125 4,
126 4,
127 };
128
129 static int pixel_block_heights[] = {
130 0, /* ALLEGRO_PIXEL_FORMAT_ANY */
131 0,
132 0,
133 1,
134 1,
135 1,
136 1,
137 1,
138 1,
139 1, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
140 1,
141 1,
142 1,
143 1,
144 1,
145 1,
146 1,
147 1,
148 1,
149 1,
150 1,
151 1,
152 1,
153 1,
154 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
155 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
156 1, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
157 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
158 4,
159 4,
160 4,
161 };
162
163 static int pixel_block_sizes[] = {
164 0, /* ALLEGRO_PIXEL_FORMAT_ANY */
165 0,
166 0,
167 2,
168 2,
169 2,
170 3,
171 4,
172 4,
173 4, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
174 4,
175 2,
176 3,
177 2,
178 2,
179 2,
180 2,
181 4,
182 4,
183 3,
184 2,
185 2,
186 4,
187 4,
188 16, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
189 4, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
190 2, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
191 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
192 8,
193 16,
194 16,
195 };
196
197 static bool format_alpha_table[ALLEGRO_NUM_PIXEL_FORMATS] = {
198 false, /* neutral (ALLEGRO_PIXEL_FORMAT_ANY) */
199 false,
200 true,
201 false,
202 false,
203 true,
204 false,
205 false,
206 true,
207 true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
208 true,
209 true,
210 false,
211 false,
212 false,
213 true,
214 true,
215 true,
216 false,
217 false,
218 false,
219 false,
220 false,
221 false,
222 true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
223 true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
224 true, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
225 false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
226 true,
227 true,
228 true,
229 };
230
231 static char const *pixel_format_names[ALLEGRO_NUM_PIXEL_FORMATS + 1] = {
232 "ANY",
233 "ANY_NO_ALPHA",
234 "ANY_WITH_ALPHA",
235 "ANY_15_NO_ALPHA",
236 "ANY_16_NO_ALPHA",
237 "ANY_16_WITH_ALPHA",
238 "ANY_24_NO_ALPHA",
239 "ANY_32_NO_ALPHA",
240 "ANY_32_WITH_ALPHA",
241 "ARGB_8888",
242 "RGBA_8888",
243 "ARGB_4444",
244 "RGB_888",
245 "RGB_565",
246 "RGB_555",
247 "RGBA_5551",
248 "ARGB_1555",
249 "ABGR_8888",
250 "XBGR_8888",
251 "BGR_888",
252 "BGR_565",
253 "BGR_555",
254 "RGBX_8888",
255 "XRGB_8888",
256 "ABGR_F32",
257 "ABGR_8888_LE",
258 "RGBA_4444",
259 "SINGLE_CHANNEL_8",
260 "RGBA_DXT1",
261 "RGBA_DXT3",
262 "RGBA_DXT5",
263 "INVALID"
264 };
265
266 static bool format_is_real[ALLEGRO_NUM_PIXEL_FORMATS] =
267 {
268 false, /* ALLEGRO_PIXEL_FORMAT_ANY */
269 false,
270 false,
271 false,
272 false,
273 false,
274 false,
275 false,
276 false,
277 true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
278 true,
279 true,
280 true,
281 true,
282 true,
283 true,
284 true,
285 true,
286 true,
287 true,
288 true,
289 true,
290 true,
291 true,
292 true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
293 true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
294 true, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
295 true, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
296 true,
297 true,
298 true,
299 };
300
301 static bool format_is_video_only[ALLEGRO_NUM_PIXEL_FORMATS] =
302 {
303 false, /* ALLEGRO_PIXEL_FORMAT_ANY */
304 false,
305 false,
306 false,
307 false,
308 false,
309 false,
310 false,
311 false,
312 false, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
313 false,
314 false,
315 false,
316 false,
317 false,
318 false,
319 false,
320 false,
321 false,
322 false,
323 false,
324 false,
325 false,
326 false,
327 false, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
328 false, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
329 false, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
330 false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
331 true,
332 true,
333 true,
334 };
335
336 static bool format_is_compressed[ALLEGRO_NUM_PIXEL_FORMATS] =
337 {
338 false, /* ALLEGRO_PIXEL_FORMAT_ANY */
339 false,
340 false,
341 false,
342 false,
343 false,
344 false,
345 false,
346 false,
347 false, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */
348 false,
349 false,
350 false,
351 false,
352 false,
353 false,
354 false,
355 false,
356 false,
357 false,
358 false,
359 false,
360 false,
361 false,
362 false, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */
363 false, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */
364 false, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */
365 false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */
366 true,
367 true,
368 true,
369 };
370
371
372 /* Function: al_get_pixel_block_size
373 */
al_get_pixel_block_size(int format)374 int al_get_pixel_block_size(int format)
375 {
376 return pixel_block_sizes[format];
377 }
378
379
380 /* Function: al_get_pixel_block_width
381 */
al_get_pixel_block_width(int format)382 int al_get_pixel_block_width(int format)
383 {
384 return pixel_block_widths[format];
385 }
386
387
388 /* Function: al_get_pixel_block_height
389 */
al_get_pixel_block_height(int format)390 int al_get_pixel_block_height(int format)
391 {
392 return pixel_block_heights[format];
393 }
394
395
396 /* Function: al_get_pixel_size
397 */
al_get_pixel_size(int format)398 int al_get_pixel_size(int format)
399 {
400 return pixel_sizes[format];
401 }
402
403
404 /* Function: al_get_pixel_format_bits
405 */
al_get_pixel_format_bits(int format)406 int al_get_pixel_format_bits(int format)
407 {
408 return pixel_bits[format];
409 }
410
411
_al_pixel_format_has_alpha(int format)412 bool _al_pixel_format_has_alpha(int format)
413 {
414 return format_alpha_table[format];
415 }
416
417
_al_pixel_format_is_real(int format)418 bool _al_pixel_format_is_real(int format)
419 {
420 ASSERT(format >= 0);
421 ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS);
422
423 return format_is_real[format];
424 }
425
_al_pixel_format_is_video_only(int format)426 bool _al_pixel_format_is_video_only(int format)
427 {
428 ASSERT(format >= 0);
429 ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS);
430
431 return format_is_video_only[format];
432 }
433
_al_pixel_format_is_compressed(int format)434 bool _al_pixel_format_is_compressed(int format)
435 {
436 ASSERT(format >= 0);
437 ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS);
438
439 return format_is_compressed[format];
440 }
441
442
443 /* We use al_get_display_format() as a hint for the preferred RGB ordering when
444 * nothing else is specified.
445 */
try_display_format(ALLEGRO_DISPLAY * display,int * format)446 static bool try_display_format(ALLEGRO_DISPLAY *display, int *format)
447 {
448 int best_format;
449 int bytes;
450
451 if (!display) {
452 return false;
453 }
454
455 best_format = al_get_display_format(display);
456 if (!_al_pixel_format_is_real(best_format))
457 return false;
458
459 bytes = al_get_pixel_size(*format);
460 if (bytes && bytes != al_get_pixel_size(best_format))
461 return false;
462
463 if (_al_pixel_format_has_alpha(*format) &&
464 !_al_pixel_format_has_alpha(best_format)) {
465 switch (best_format) {
466 case ALLEGRO_PIXEL_FORMAT_RGBX_8888:
467 *format = ALLEGRO_PIXEL_FORMAT_RGBA_8888;
468 return true;
469 case ALLEGRO_PIXEL_FORMAT_XRGB_8888:
470 *format = ALLEGRO_PIXEL_FORMAT_ARGB_8888;
471 return true;
472 case ALLEGRO_PIXEL_FORMAT_XBGR_8888:
473 *format = ALLEGRO_PIXEL_FORMAT_ABGR_8888;
474 return true;
475 default:
476 return false;
477 }
478 }
479 if (!_al_pixel_format_has_alpha(*format) &&
480 _al_pixel_format_has_alpha(best_format)) {
481 switch (best_format) {
482 case ALLEGRO_PIXEL_FORMAT_RGBA_8888:
483 *format = ALLEGRO_PIXEL_FORMAT_RGBX_8888;
484 return true;
485 case ALLEGRO_PIXEL_FORMAT_ARGB_8888:
486 *format = ALLEGRO_PIXEL_FORMAT_XRGB_8888;
487 return true;
488 case ALLEGRO_PIXEL_FORMAT_ABGR_8888:
489 *format = ALLEGRO_PIXEL_FORMAT_XBGR_8888;
490 return true;
491 default:
492 return false;
493 }
494 }
495 *format = best_format;
496 return true;
497 }
498
499
_al_get_real_pixel_format(ALLEGRO_DISPLAY * display,int format)500 int _al_get_real_pixel_format(ALLEGRO_DISPLAY *display, int format)
501 {
502 /* Pick an appropriate format if the user is vague */
503 switch (format) {
504 case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA:
505 case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA:
506 if (!try_display_format(display, &format))
507 format = ALLEGRO_PIXEL_FORMAT_XRGB_8888;
508 break;
509 case ALLEGRO_PIXEL_FORMAT_ANY:
510 case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA:
511 case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA:
512 if (!try_display_format(display, &format))
513 #if defined ALLEGRO_CFG_OPENGLES // OPENGLES doesn't have ARGB_8888
514 format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE;
515 #else
516 format = ALLEGRO_PIXEL_FORMAT_ARGB_8888;
517 #endif
518 break;
519 case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA:
520 format = ALLEGRO_PIXEL_FORMAT_RGB_555;
521 break;
522 case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA:
523 if (!try_display_format(display, &format))
524 format = ALLEGRO_PIXEL_FORMAT_RGB_565;
525 break;
526 case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA:
527 format = ALLEGRO_PIXEL_FORMAT_RGBA_4444;
528 break;
529 case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA:
530 format = ALLEGRO_PIXEL_FORMAT_RGB_888;
531 break;
532 default:
533 /* Already a real format - don't change it. */
534 break;
535 }
536
537 ASSERT(_al_pixel_format_is_real(format));
538 return format;
539 }
540
541
_al_pixel_format_name(ALLEGRO_PIXEL_FORMAT format)542 char const *_al_pixel_format_name(ALLEGRO_PIXEL_FORMAT format)
543 {
544 if (format >= ALLEGRO_NUM_PIXEL_FORMATS) format = ALLEGRO_NUM_PIXEL_FORMATS;
545 return pixel_format_names[format];
546 }
547
548
549 /* Color mapping functions */
550
551 /* Function: al_map_rgba
552 */
al_map_rgba(unsigned char r,unsigned char g,unsigned char b,unsigned char a)553 ALLEGRO_COLOR al_map_rgba(
554 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
555 {
556 ALLEGRO_COLOR color;
557 _AL_MAP_RGBA(color, r, g, b, a);
558 return color;
559 }
560
561
562 /* Function: al_premul_rgba
563 */
al_premul_rgba(unsigned char r,unsigned char g,unsigned char b,unsigned char a)564 ALLEGRO_COLOR al_premul_rgba(
565 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
566 {
567 ALLEGRO_COLOR color;
568 _AL_MAP_RGBA(color, r * a / 255, g * a / 255, b * a / 255, a);
569 return color;
570 }
571
572
573 /* Function: al_map_rgb
574 */
al_map_rgb(unsigned char r,unsigned char g,unsigned char b)575 ALLEGRO_COLOR al_map_rgb(
576 unsigned char r, unsigned char g, unsigned char b)
577 {
578 return al_map_rgba(r, g, b, 255);
579 }
580
581
582 /* Function: al_map_rgba_f
583 */
al_map_rgba_f(float r,float g,float b,float a)584 ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a)
585 {
586 ALLEGRO_COLOR color;
587 color.r = r;
588 color.g = g;
589 color.b = b;
590 color.a = a;
591 return color;
592 }
593
594
595 /* Function: al_premul_rgba_f
596 */
al_premul_rgba_f(float r,float g,float b,float a)597 ALLEGRO_COLOR al_premul_rgba_f(float r, float g, float b, float a)
598 {
599 ALLEGRO_COLOR color;
600 color.r = r * a;
601 color.g = g * a;
602 color.b = b * a;
603 color.a = a;
604 return color;
605 }
606
607
608 /* Function: al_map_rgb_f
609 */
al_map_rgb_f(float r,float g,float b)610 ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b)
611 {
612 return al_map_rgba_f(r, g, b, 1.0f);
613 }
614
615
616 /* unmapping functions */
617
618
619 /* Function: al_unmap_rgba
620 */
al_unmap_rgba(ALLEGRO_COLOR color,unsigned char * r,unsigned char * g,unsigned char * b,unsigned char * a)621 void al_unmap_rgba(ALLEGRO_COLOR color,
622 unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
623 {
624 *r = color.r * 255.0f;
625 *g = color.g * 255.0f;
626 *b = color.b * 255.0f;
627 *a = color.a * 255.0f;
628 }
629
630
631 /* Function: al_unmap_rgb
632 */
al_unmap_rgb(ALLEGRO_COLOR color,unsigned char * r,unsigned char * g,unsigned char * b)633 void al_unmap_rgb(ALLEGRO_COLOR color,
634 unsigned char *r, unsigned char *g, unsigned char *b)
635 {
636 unsigned char tmp;
637
638 al_unmap_rgba(color, r, g, b, &tmp);
639 }
640
641
642 /* Function: al_unmap_rgba_f
643 */
al_unmap_rgba_f(ALLEGRO_COLOR color,float * r,float * g,float * b,float * a)644 void al_unmap_rgba_f(ALLEGRO_COLOR color,
645 float *r, float *g, float *b, float *a)
646 {
647 *r = color.r;
648 *g = color.g;
649 *b = color.b;
650 *a = color.a;
651 }
652
653
654 /* Function: al_unmap_rgb_f
655 */
al_unmap_rgb_f(ALLEGRO_COLOR color,float * r,float * g,float * b)656 void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b)
657 {
658 float tmp;
659
660 al_unmap_rgba_f(color, r, g, b, &tmp);
661 }
662
663
664 /* vim: set sts=3 sw=3 et: */
665