ETC1壓縮紋理格式詳解

本來以爲,ETC1作爲Android 設備的OpenGL標準,開源且最常用的的一種壓縮紋理格式,總會有人去翻譯一下khronos的文檔,讀一下代碼,給大家作個普及的,不料就是搜不到。沒辦法,儘管英文不好,還是硬啃了下文檔,把 ETC1壓縮紋理的實現原理弄清楚了。
https://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt

至於什麼是壓縮紋理,如何使用,可以參考:
http://blog.csdn.net/wanglang3081/article/details/8869589

ETC1的文件頭

文件頭大小爲16:

#define ETC_PKM_HEADER_SIZE 16

將ETC1紋理存成pkm文件時,加上這個文件頭,便於讀取時獲知大小、格式,上傳壓縮紋理時把這個頭去掉。

文件頭內容爲:特徵符——編碼寬——編碼高——實際寬——實際高

static const char kMagic[] = { 'P', 'K', 'M', ' ', '1', '0' };

static const etc1_uint32 ETC1_PKM_FORMAT_OFFSET = 6;
static const etc1_uint32 ETC1_PKM_ENCODED_WIDTH_OFFSET = 8;
static const etc1_uint32 ETC1_PKM_ENCODED_HEIGHT_OFFSET = 10;
static const etc1_uint32 ETC1_PKM_WIDTH_OFFSET = 12;
static const etc1_uint32 ETC1_PKM_HEIGHT_OFFSET = 14;

儘管ETC1是固定的壓縮比,但考慮到像素不對齊的情況,實際寬和實際高還是有必要存儲的。

編碼構成

Jpeg壓縮標準是把圖像劃分爲一系列8X8的像素塊,然後每個像素塊壓縮成變長編碼的。ETC1則是4X4的像素塊壓縮成固定的64位編碼(8字節),由於固定,才有利於GPU內部實現並行解壓縮。

#define ETC1_ENCODED_BLOCK_SIZE 8
#define ETC1_DECODED_BLOCK_SIZE 48 // RGB 三分量 * 4 * 4

因此,不考慮像素非4對齊的情況,它的壓縮比是固定的48/8=6,至於常用的把ARGB分別存儲爲兩張ETC1紋理的做法,壓縮比是64/16=4。
像素不對齊的情況如何處理,就自己想想吧,反正不是大問題。

4X4的像素點與64位編碼對應關係如下:
1、將 4X4 的像素點劃分爲兩個subblock,橫分或者豎分【1個位表示:flipbit】。
2、兩部分的像素RGB求均值,總共用24個位表示兩個RGB均值,分兩種方案【1個位表示:diffbit】
(1)兩個subblock的RGB均值都用4位表示。剛好4*3*2=24位。
(2)兩個subblock的RGB值相差在 [-4,3]區間(5位表示的情況下,對應常規的8位表示是[-32,24]),第一個subblock的RGB值用5位表示,第二個用3位差值表示。
3、解碼時,像素值由RGB均值加上差值而得,差值表爲8X4大小。每一個subblock使用的是其中一行【行號需要3個位,兩個subblock,加起來6個位】,每個像素點對應所取差值行中一個數【編號需要2個位,這樣就16X2=32個位】。PS:RGB三個分量是用同一個差值。

64位的編碼分成兩部分,高位和低位。
低位存儲每個像素點的差值行序號,按大端存儲方式,分兩部分,前一部分存儲高位,後一部分存儲低位。
高位存儲RGB均值,subblock所用的差值錶行號,再加上 flipbit 和 diffbit
詳細內容直接上文檔上的圖:
total

橫分/豎分示例圖,圖中每個字母代碼一個像素:
flip

編碼過程

ETC1的編碼流程如下:
1、將圖像劃分爲一系列 4X4 的子塊。
2、對每個子塊,嘗試所有的編碼可能性,取解碼後和原block像素差值和最小的一種編碼。
(1)是否flip,這個決定subblock如何劃分
(2)每個subblock用哪一行差值表
(3)每個像素取哪一列的差值
注:決定好flip之後,顏色均值和是否能用diff方式已經確定,這個不用遍歷。
3、合併所有子塊編碼。

不難看出,編碼過程需要遍歷所有可能性,其複雜度遠大於解碼,每一個 RGB 像素變成了一個精度較低的RGB均值和一個2位差值號,因此產生壓縮。這種預測式表述自然本身就存在偏差,壓縮損失亦來自於此。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章