Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » 16 bit color to ALLEGRO_COLOR

Credits go to gnolam, jmasterx, and Matthew Leverton for helping out!
This thread is locked; no one can reply to it. rss feed Print
16 bit color to ALLEGRO_COLOR
James Bunting
Member #30
April 2000
avatar

Hello All,

There are no getr16() getg16() getb16() functions in A5, yet more code to write myself!

I have 16 bit colours read from an old tileset file in "unsigned short int" format. Under A4 they decode perfectly using getr16() etc.

Any ideas on best way of decoding it under A5? I am thinking bit shifting.

<rant>I am considering devoting my life to created Allegro425 which makes A4 code run under A5. All the simplicity of 4 with the features of 5. Here's to ALLEGRO_BITMAP->w (can't be that hard now can it?)</rant>

jmasterx
Member #11,410
October 2009

The reason for opaque data types in A5 is to avoid exposing implementation to help ensure binary compatibility. If from one day to the next A5 added ALLEGRO_BITMAP->something_new then it would no longer be binary compatible. I believe one of the goals of A5 is binary compatibility.

Matthew Leverton
Supreme Loser
January 1999
avatar

You could just copy/paste the functions from Allegro 4's source.

Note that storing raw 16-bit data directly in a file and using Allegro 4 getr16 isn't even guaranteed to work if you are doing it after set_gfx_mode is called because the RGB ordering is machine dependent.

Regarding the ALLEGRO_BITMAP->w comment, Allegro 5 does not expose internal struct data when it's not necessary. That is a good design decision.

#SelectExpand
1/* lookup table for scaling 5 bit colors up to 8 bits */ 2int _rgb_scale_5[32] = 3{ 4 0, 8, 16, 24, 33, 41, 49, 57, 5 66, 74, 82, 90, 99, 107, 115, 123, 6 132, 140, 148, 156, 165, 173, 181, 189, 7 198, 206, 214, 222, 231, 239, 247, 255 8}; 9 10 11/* lookup table for scaling 6 bit colors up to 8 bits */ 12int _rgb_scale_6[64] = 13{ 14 0, 4, 8, 12, 16, 20, 24, 28, 15 32, 36, 40, 44, 48, 52, 56, 60, 16 65, 69, 73, 77, 81, 85, 89, 93, 17 97, 101, 105, 109, 113, 117, 121, 125, 18 130, 134, 138, 142, 146, 150, 154, 158, 19 162, 166, 170, 174, 178, 182, 186, 190, 20 195, 199, 203, 207, 211, 215, 219, 223, 21 227, 231, 235, 239, 243, 247, 251, 255 22}; 23 24AL_INLINE(int, getr16, (int c), 25{ 26 return _rgb_scale_5[(c >> _rgb_r_shift_16) & 0x1F]; 27}) 28 29 30AL_INLINE(int, getg16, (int c), 31{ 32 return _rgb_scale_6[(c >> _rgb_g_shift_16) & 0x3F]; 33}) 34 35 36AL_INLINE(int, getb16, (int c), 37{ 38 return _rgb_scale_5[(c >> _rgb_b_shift_16) & 0x1F]; 39})

You'll have to use the shift values that relate to whatever RGB order you are using.

gnolam
Member #2,030
March 2002
avatar

Untested and pseudocodish:

// Assuming rgb ordering
rshift = 11;
gshift = 5;
bshift = 0;

r5 = (color >> rshift) & 0x1F;
g6 = (color >> gshift) & 0x3F;
b5 = (color >> bshift) & 0x1F;

r8 = r5*255/31;
g8 = g6*255/63;
g8 = b5*255/31;

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

James Bunting
Member #30
April 2000
avatar

Thanks I will look try it out. This is for legacy import so won't be used very often (the importer will be available in the game).

Looks like it will just have to be #define gbw(lolz) al_get_bitmap_width(lolz)

After a few months of "expanding" [making more portable] my code to A5 we almost have a ported version of Mowteor which I am very happy about.

The important part (for me) is that this game tests my underlying library which is essentially an in-house class-based wrapper for Allegro allowing me to develop loads of games and larger "Meteor sized" projects with ease and without duplication.

Matthew Leverton
Supreme Loser
January 1999
avatar

pack.h#SelectExpand
1#ifndef __included_pack_h__ 2#define __included_pack_h__ 3 4#include <allegro5/allegro.h> 5 6uint32_t pack_pixel(ALLEGRO_COLOR color, ALLEGRO_PIXEL_FORMAT format); 7ALLEGRO_COLOR unpack_pixel(uint32_t p, ALLEGRO_PIXEL_FORMAT format); 8 9#endif

pack.c#SelectExpand
1#include <allegro5/allegro.h> 2#include "pack.h" 3 4/* lookup table for scaling 5 bit colors up to 8 bits */ 5static int _rgb_scale_5[32] = 6{ 7 0, 8, 16, 24, 33, 41, 49, 57, 8 66, 74, 82, 90, 99, 107, 115, 123, 9 132, 140, 148, 156, 165, 173, 181, 189, 10 198, 206, 214, 222, 231, 239, 247, 255 11}; 12 13 14/* lookup table for scaling 6 bit colors up to 8 bits */ 15static int _rgb_scale_6[64] = 16{ 17 0, 4, 8, 12, 16, 20, 24, 28, 18 32, 36, 40, 44, 48, 52, 56, 60, 19 65, 69, 73, 77, 81, 85, 89, 93, 20 97, 101, 105, 109, 113, 117, 121, 125, 21 130, 134, 138, 142, 146, 150, 154, 158, 22 162, 166, 170, 174, 178, 182, 186, 190, 23 195, 199, 203, 207, 211, 215, 219, 223, 24 227, 231, 235, 239, 243, 247, 251, 255 25}; 26 27#define PACK_8888(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 28#define PACK_4444(a,b,c,d) ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | (((c) & 0xf0)) | (((d) & 0xf0) >> 4)) 29#define PACK_565(a,b,c) ((((a) * 31/255) << 11) | (((b) * 63/255) << 5) | ((c) * 31/255)) 30#define PACK_555(a,b,c) ((((a) * 31/255) << 10) | (((b) * 31/255) << 5) | ((c) * 31/255)) 31 32uint32_t pack_pixel(ALLEGRO_COLOR color, ALLEGRO_PIXEL_FORMAT format) 33{ 34 uint8_t r, g, b, a; 35 36 al_unmap_rgba(color, &r, &g, &b, &a); 37 38 switch (format) { 39 case ALLEGRO_PIXEL_FORMAT_ARGB_8888: 40 return PACK_8888(a, r, g, b); 41 42 case ALLEGRO_PIXEL_FORMAT_RGBA_8888: 43 return PACK_8888(r, g, b, a); 44 45 case ALLEGRO_PIXEL_FORMAT_ABGR_8888: 46 return PACK_8888(a, b, g, r); 47 48 case ALLEGRO_PIXEL_FORMAT_XBGR_8888: 49 case ALLEGRO_PIXEL_FORMAT_BGR_888: 50 return PACK_8888(0, b, g, r); 51 52 case ALLEGRO_PIXEL_FORMAT_RGBX_8888: 53 return PACK_8888(r, g, b, 0); 54 55 case ALLEGRO_PIXEL_FORMAT_XRGB_8888: 56 case ALLEGRO_PIXEL_FORMAT_RGB_888: 57 return PACK_8888(0, r, g, b); 58 59 case ALLEGRO_PIXEL_FORMAT_ARGB_4444: 60 return PACK_4444(a, r, g, b); 61 62 case ALLEGRO_PIXEL_FORMAT_RGB_565: 63 return PACK_565(r,g,b); 64 65 case ALLEGRO_PIXEL_FORMAT_BGR_565: 66 return PACK_565(b,g,r); 67 68 case ALLEGRO_PIXEL_FORMAT_RGBA_5551: 69 return (PACK_555(r,g,b) << 1) | (a ? 1 : 0); 70 71 case ALLEGRO_PIXEL_FORMAT_ARGB_1555: 72 return PACK_555(r,g,b) | (a ? 0x8000 : 0); 73 74 case ALLEGRO_PIXEL_FORMAT_RGB_555: 75 return PACK_555(r,g,b); 76 77 case ALLEGRO_PIXEL_FORMAT_BGR_555: 78 return PACK_555(b,g,r); 79 } 80 81 return 0; 82} 83 84#define UNPACK_8888(a,b,c,d) a = (p >> 24) & 0xff; b = (p >> 16) & 0xff; c = (p >> 8) & 0xff; d = (p & 0xff) 85#define UNPACK_4444(a,b,c,d) a = ((p >> 12) & 0x0f) * 255 / 15; b = ((p >> 8) & 0x0f) * 255 / 15; c = ((p >> 4) & 0xf) * 255 / 15; d = (p & 0xf) * 255 / 15 86#define UNPACK_565(a,b,c) a = _rgb_scale_5[(p >> 11) & 0x1f]; b = _rgb_scale_6[(p >> 5) & 0x1f]; c = _rgb_scale_5[p & 0x1f]; 87#define UNPACK_555(a,b,c) a = _rgb_scale_5[(p >> 10) & 0x1f]; b = _rgb_scale_5[(p >> 5) & 0x1f]; c = _rgb_scale_5[p & 0x1f]; 88 89ALLEGRO_COLOR unpack_pixel(uint32_t p, ALLEGRO_PIXEL_FORMAT format) 90{ 91 uint8_t r = 0, g = 0, b = 0, a = 255, x = 0; 92 93 switch (format) { 94 case ALLEGRO_PIXEL_FORMAT_ARGB_8888: 95 UNPACK_8888(a, r, g, b); 96 break; 97 98 case ALLEGRO_PIXEL_FORMAT_RGBA_8888: 99 UNPACK_8888(r, g, b, a); 100 break; 101 102 case ALLEGRO_PIXEL_FORMAT_ABGR_8888: 103 UNPACK_8888(a, b, g, r); 104 break; 105 106 case ALLEGRO_PIXEL_FORMAT_XBGR_8888: 107 case ALLEGRO_PIXEL_FORMAT_BGR_888: 108 UNPACK_8888(x, b, g, r); 109 break; 110 111 case ALLEGRO_PIXEL_FORMAT_RGBX_8888: 112 UNPACK_8888(r, g, b, x); 113 break; 114 115 case ALLEGRO_PIXEL_FORMAT_XRGB_8888: 116 case ALLEGRO_PIXEL_FORMAT_RGB_888: 117 UNPACK_8888(x, r, g, b); 118 break; 119 120 case ALLEGRO_PIXEL_FORMAT_ARGB_4444: 121 UNPACK_4444(a, r, g, b); 122 break; 123 124 case ALLEGRO_PIXEL_FORMAT_RGB_565: 125 UNPACK_565(r,g,b); 126 break; 127 128 case ALLEGRO_PIXEL_FORMAT_BGR_565: 129 UNPACK_565(b,g,r); 130 break; 131 132 case ALLEGRO_PIXEL_FORMAT_RGBA_5551: 133 a = (p & 1) ? 255 : 0; 134 p >>= 1; 135 UNPACK_555(r,g,b); 136 break; 137 138 case ALLEGRO_PIXEL_FORMAT_ARGB_1555: 139 a = (p & 0x8000) ? 255 : 0; 140 UNPACK_555(r,g,b); 141 break; 142 143 case ALLEGRO_PIXEL_FORMAT_RGB_555: 144 UNPACK_555(r,g,b); 145 break; 146 147 case ALLEGRO_PIXEL_FORMAT_BGR_555: 148 UNPACK_555(b,g,r); 149 break; 150 151 } 152 153 return al_map_rgba(r, g, b, a); 154}

Disclaimers:

  1. Not thoroughly tested

  2. Could use some more scale tables to smooth out rounding

  3. Not built for speed

Go to: