找回密码
 注册
搜索
查看: 2981|回复: 1

[DER] 技术帖:SFC 调色板数据格式

[复制链接]
发表于 2016-9-26 23:10 | 显示全部楼层 |阅读模式
本文由 痕 原创

出处:http://langrisser.xyz/sfc-palette

网上找到的资料。(http://wiki.superfamicom.org/snes/show/Palettes

这个跟PS版的应该是一样的。

15-Bit BGR Format

The Super Nintendo / Super Famicom stores it’s palette in 512 bytes in a 15-bit BGR format. Each BGR word is 2 bytes, thus it is 512 bytes for 256 colors (256 x 2). The format for each BGR word looks like this:
  1. 0BBBBBGG GGGRRRRR
复制代码
Bit 15 is unused and should be set to 0. Each color value can range from 0 – 31. So a R, G, B value of 31, 31, 31 represents white. As you can see this is quite different from the usual 24-bit RGB where the colors range from 0 – 255.

Converting a 24-Bit RGB Color to a 15-Bit BGR Color

In order to convert a 24-bit RGB value into the 15-Bit BGR format, the 8-bit color value of the 24-Bit RGB color must be scaled down to 5-bits. Then the 3 color values must be packed into 2 bytes. This can be achieved by the following formula:
  1. R = R / 8 (ie: 17 / 8 = 2)
  2. G = G / 8 (ie: 16 / 8 = 2)
  3. B = B / 8 (ie: 14 / 8 = 1)
  4. =========
  5. Color = B x 1024 + G x 32 + R
复制代码
The following example show how to convert white (255,255,255) to the 15-bit format:
  1. R = 255 / 8 = 31
  2. G = 255 / 8 = 31
  3. B = 255 / 8 = 31
  4. ================
  5. Color = 31 x 1024 + 31 x 32 + 31 = 32767
复制代码
So white as a 15-bit BGR color is 32767 or
  1. 0x7FFF
复制代码
in hex. And to clear up any confusion, YES, this value will be stored in LSB order (otherwise known as ‘bits reversed’). So you will see this as
  1. FF 7F
复制代码
in the hex editor.
  1. c = color;
  2. int r = (c & 0xF80000) >> 19;
  3. int g = (c & 0x00F800) >>  6;
  4. int b = (c & 0x0000F8) <<  7;
  5. return b | g | r;
复制代码
Converting a 15-Bit BGR Color to a 24-Bit ColorTo convert a 15-BGR value into 24-RGB values, is simply the reverse operation. The formula is:
  1. R = ((color       ) % 32) * 8
  2. G = ((color /   32) % 32) * 8
  3. B = ((color / 1024) % 32) * 8
复制代码
The following example shows how to convert white (32767) to it’s respective RGB values:
  1. Color = 32767
  2. R = (Color          % 32) x 8
  3. R = (32767          % 32) x 8 = 31 x 8 = 248
  4. G = ((color /   32) % 32) x 8
  5. G = ((32767 /   32) % 32) x 8 = (1023 % 32) x 8 = 32 x 8 = 248
  6. B = ((color / 1024) % 32) x 8
  7. B = ((32767 / 1024) % 32) x 8 = (31 % 32) x 8 = 32 x 8 = 248
复制代码
Since we are using powers of 2 we can use a bitmask of (color & 0x1F) instead of (color mod 32) incase you are using a older compiler that doesn’t optimize mod division by a constant. Also, it may be easier to think in hex instead of decimal:
  1. Color = 32767
  2. R = (Color & 31) * 8
  3. = (32767 & 31) * 8
  4. = (0x7FFF & 0x1F) << 3
  5. = 0x1F << 3
  6. = 0xF8
  7. = 248

  8. Similarly for green and blue ...
复制代码
So the final output is (248, 248, 248). Uh-oh, 24-bit RGB white is (255, 255, 255) not (248, 248, 248). Apparently, what happened is there was a precision loss during the conversion. Think about it, if you convert a 24-bit value into a 15-bit you would have loss some precision. The three least significant bits are lost in each component. Thus, the extra precision that 24-bit color provides is lost and is unrecoverable.
So you won’t get precision but you can stretch the range rather easily after the conversion (_ensure_ that you use unsigned integer math for this):
A na&#239;ve approach would be to do a multiplication and division scaling:
  1. R = (255*R)/31;
  2. G = (255*G)/31;
  3. B = (255*B)/31;
复制代码
A faster approach is:
  1. R = R + R / 32
  2. G = G + G / 32
  3. B = B + B / 32
复制代码
This seems strange at first glance, but what happens is that you replicate the top three bits of each component into the bottom three bits (which, as stated above, are empty after conversion). This, if you think long enough about it, has the effect of stretching the color values into the full (0,0,0) -> (255,255,255) range.
E.g. If red is close to 0, those three bits will also tend to be be 0 so you won’t lose the blackest black. If red is close to 248 (the maximum after conversion) those bits will all be 1’s, so you get full red. Between the extremes, it works out so you gradually get the required boost up to the real maximum (255).



发表于 2016-9-26 23:55 | 显示全部楼层
SFC归到DER
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|虎纹猫家园

GMT+8, 2024-4-29 11:00 , Processed in 0.016523 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表