作者: comcat 发表日期: 2006-10-17 21:04 http://comcat.blog.openrays.org/blog.php?do=showone&tid=130
注: 本文仅讨论常见的小端机器
1. 声明
对于RGB模式下, 8 bit 颜色可以用一个字节描述:
7 5 4 2 1 0
|-------|--------|-----|
R G B
|---------------------|
则可以定义数据结构为:
struct color8
{
unsigned char blue : 2; // 2 bit for B
unsigned char green : 3; // 3 bit for G
unsigned char red : 3; // 3 bit for R
};
容易得到 sizeof(struct color8) 的值为 1 Byte
注意 struct color8 中成员的声明顺序, 先声明的成员,在内存中的位置在低位
使用上面的 struct color8, 可以很容易的转为1字节,用于显示:
struct color8 c8;
c8.red = 4; // 值不能超过7
c8.green = 0;
c8.blue = 2;
unsigned char * tran = (unsigned char *)&c8
printf("8 bit color value is: 0x%x\n", *tran);
//100 000 10
则输出为: 8 bit color value is: 0x82
2. 赋值
低位赋予原则,直至目的变量之所有位填满.
如:
struct color8 c8;
unsigned char i = 0x82; // 1000 0010
c8.blue = i; // 将 i 之低2位(1~0)赋给成员blue(长2位), 其值为 0x2
c8.green = i >> 2; // 将 i 之 4~2 位赋予成员green(长3位), 其值为 0x0
c8.red = i >> 5; // 将 i 之 7~5 位赋给成员red(长3位), 其值为 0x4
3. 16bit 值的合并
在RGB模式下, 16 bit 颜色可以用二个字节描述:
15 14 10 9 5 4 0
|---|-------|-------|-------|
| x | R | G | B |
|--------------------------|
struct color16
{
unsigned char b:5;
unsigned char g:5;
unsigned char r:5;
unsigned char ge:1;
};
注意到 sizeof(struct color16) 的值为 3 Byte
因为要便于机器访问以字节为单位的存储单元,上述结构在内存中的布局为:
7 5 4 0
|------|---------| 低地址
| 0 | b |
|------|---------|
| 0 | g |
|------|---------|
| 0 |ge| r |
|------|---------| 高地址
故而:
struct color16 cx;
cx.r = 4;
cx.g = 1;
cx.b = 3;
cx.ge = 1;
printf(" 0x%x \n", *((unsigned short*)&cx));
输出为 0x103,
分析:
经赋值后内存映象为:
000 00011 -----> 1st byte
000 00001 -----> 2nd byte
001 00100 -----> 3rd byte
强制地址转换后访问前二个字节,输出时则为: 0000 0001 0000 0011
又:
printf(" 0x%x \n", *((unsigned char*)&cx + 2));
输出为 0x24, 即为第三个字节 0010 0100 的值
经以上分析,在非对齐的数据结构中使用指针强制转换的方式合并数据位是不可行的,
可用以下方法实现:
unsigned short tt = 0, t = 0;
t = cx.ge;
t <<= 15;
tt = t;
t = cx.r;
t <<= 10;
tt |= t;
t = cx.g;
t <<= 5;
tt |= t;
tt |= cx.b;