ETC 图像压缩原理
说明: 我下面所讲的内容准确说应该是ETC图像解压缩的过程,即怎样从压缩后的etc数据解码出我们熟知的RGB图像数据。
以compressed_ETC1_RGB8为例(相对简单些)
ETC texture可以用N 个4x4 pixel block 来描述,如下图所示,一个8x8的texture可用4个4x4 pixel block 来表示。
如果下图中的4个pixel block作为输入,调用glCompressedTexImage2D,将产生一个8x8的texture,这个和调用glTexImage2D(输入的图像数据是以下面的顺序存储)是等效的(因为压缩是有损的,所以每个像素值可能是不同)。
a 1 e 1 i 1 m 1 a 2 e 2 i 2 m 2 b 1 f1 j 1 n 1 b 2 f2 j 2 n 2 c 1 g 1 k 1 o 1 c 2 g 2 k 2 o 2 d 1 h 1 l 1 p 1 d 2 h 2 l 2 p 2 a 3 e 3 i 3 m 3 a 4 e 4 i 4 m 4 b 3 f3 j 3 n 3 b 4 f4 j 4 n 4 c 3 g 3 k 3 o 3 c 4 g 4 k 4 o 4 d 3 h 3 l 3 p 3 d 4 h 4 l 4 p 4.
*如果这里看着有点糊涂,那么没关系,你只需要知道ETC压缩的图像是用4x4 pixel block表示就可以了,继续往下看*。对于compressed_ETC1_RGB8 format,压缩对象是RGB8的图像数据,一个4x4 pixel block 用8个bytes 数据表示,如: {q0, q1, q2, q3, q4, q5, q6, q7}, q0 表示最低位,q7表示最高位,则一个64bits整型:
int64bit = 256*(256*(256*(256*(256*(256*(256*q0+q1)+q2)+q3)+q4)+q5)+q6)+q7
每个64bits 字包含的一个4x4 pixel block的信息如下:
1) ETC1 有两种模式,”individual” 和 “differential”, 地33 位diffbit用来表示选用哪一种模式,diffbit = 0表示选用”individual”模式,如表a); diffbit = 1表示选用” differential”模式, 这里以”individual”模式为例
a) bit layout in bits 63 through 32 if diffbit = 0
63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
-----------------------------------------------
| base col1 | base col2 | base col1 | base col2 |
| R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)|
-----------------------------------------------
47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
---------------------------------------------------
| base col1 | base col2 | table | table |diff|flip|
| B1 (4bits) | B2 (4bits) | cw 1 | cw 2 |bit |bit |
---------------------------------------------------
b) bit layout in bits 31 through 0 (in both cases)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
-----------------------------------------------
| most significant pixel index bits |
| p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a|
-----------------------------------------------
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
--------------------------------------------------
| least significant pixel index bits |
| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
--------------------------------------------------
2) 第32位flipbit, 表示一个4x4的pixel block被分割成两个2x4(flipbit = 0)或4x2(flipbit = 1)的subblocks
一个4x4 pixel block 如下图:
一个4x4 pixel block 两个2x4 pixel subblocks 两个4x2 pixel subblocks
3) 获得subblock1和subblock2的base color
以”individual”模式为例,subblock1的base color由表a)中的R1(bit 63-60), G1(bit 55-52), B1(bit 47-44)获得,subblock2的base color由表a)中的R2, G2, B2获得, 下面以subblock1为例,subblock2同理。
假设R1 = 14 = 1110b, G1 = 3 = 0011b, B1 = 8 = 1000b,将其有4bit扩展成8bit后,base_R1 = 11101110b = 238, base_G1 = 00110011b =51, base_B1 = 10001000b = 136,因此subblock1的base color = (238, 51, 136), 可以用如下公式表达:
Base color of subclock1 = extend_4to8bits(R1, G1, B1);
Base color of subclock2 = extend_4to8bits(R2, G2, B2);
4) 获得subblock1和subblock2的modifier table
一个重要的表格
subblock1的table coderword对应tablecw1(bit 39-37), subblock2的table coderword对应tablecw2(bit 36-34),假设tablecw1 = 010b = 2, 则modifier table中的[-29, -9, 9, 29]被选中,同理可以subblock2的modifier table。
5) 获得像素的modifier value
另一个重要的表格
以4x4 pixel block中的d pixel为例,它的pixel index value(msb and lsb)可以从bit 19 和bit 3 获得,加入他是msb = 0, lsb = 1, modifier talbe = [-29, -9, 9, 29], 则它的modifier value = 29。
6) 获得最终像素
d像素的base color = (238, 51, 136),modifier value = 29,则d pixel = (238 + 29, 51 + 29, 136 + 29) = (267, 80, 165) = (255, 80, 165)
对于其他ECT, 如COMPRESSED_RGB8_ETC2,是compressed_ETC1_RGB8的超集,增加了”H-mode”, “T-mode” 和”Planar” 三种模式,但是整套decoding的思路基本没变,只是表a)有所不同。