FRG是一種優化從磁盤加載和解碼到顯示需要的時間的圖像文件格式. (更多介紹: http://blog.csdn.net/housisong/article/details/9077059 )
這裏介紹FRG涉及到的一些編碼技術.
Alpha通道獨立壓縮,現在的實現是無損壓縮;
如果圖像的alpha通道只有一個值(或沒有alpha通道),則只需要儲存一個alpha值就可以了;
如果不是單色alpha,數據壓縮使用RLE行程壓縮算法(格式簡單,編解碼快速), 由於數據中一般來說0和255的值居多,所以進行了特殊處理;
編碼分成控制數據和未壓縮alpha數據;
控制數據按照: "類型\長度\類型\長度\…\類型\長度"來編碼;
"類型"佔用2個bit位, 00表示後面存的壓縮0數據, 01表示後面存的壓縮255數據, 10表示後面存的壓縮數據(alpha數據包中只需儲存一個字節數據), 11表示後面存的未壓縮數據 ("未壓縮alpha數據"中連續原樣儲存多個字節數據); "長度"用的變長編碼,1個bit來表示後面的字節是否被用於編碼,"類型"佔用的那個字節剩餘的6bit也用於長度編碼(也就是如果"長度"值<=5bit則可以和"類型"共享一個字節);
RGB數據的處理:
基本方案:將圖片分成8x8的塊;對一個8x8的塊找到能夠最精確的描述這64個像素的16個或以下不同的顏色(稱爲局部調色板);對於原來的64個像素的每一個像素只保存一個4bit的索引值來指向一個最接近的局部調色板顏色(如果顏色數較少就會使用更小的bit位來儲存索引,單顏色的調色板不需要儲存索引); 將得到的局部調色板顏色儲存到一個公共調色板中;
無損壓縮:
將64個顏色壓縮到16個顏色的過程中, 8x8的塊顏色數超過16,而要求無損失儲存或強制壓縮顏色數會造成損失過於嚴重,這時可以使用無損壓縮方案;直接將64個顏色存入公共調色板,而不存儲索引數據;
調色板優化:
儲存該單元的局部調色板的時候,先在公共調色板中查找有沒有一段顏色和該調色板等價;從而不需要儲存該局部調色板;
算法: 長度n的調色板在公共調色板中查找匹配到一段(1<<getBit(n))長的顏色數據位置;這和字符串的查找匹配算法類似,但這裏的挑戰在於匹配時n個顏色無順序;甚至顏色相等的判斷可以允許有小的誤差; (ps:如果讓你實現該算法, 時間可以做到可接受級別嗎? )
重複圖像的優化:
一幅圖像中可能有很多區域可能都是重複的(重複方式可能是平移\左右對稱\上下對稱等),這在美工作出的圖像中很常見; 那麼可以不用儲存這些區域;
算法: 在處理當前的8x8的塊的時候,先在當前區域前面的整幅圖片中查找重複的區域位置,重複方式可能是平移\左右對稱\上下對稱等 (其他重複方式較少見而沒有特別處理); 該算法很簡單,難度只在於實現的匹配速度;
FRZ壓縮算法:
(FRG1.1.1默認改用LZ4)
爲了進一步壓縮RLE生成的Alpha通道編碼數據,開發了一種能夠快速解壓的通用字節流壓縮算法FRZ; (當要求輸出較小的編碼數據時,FRZ也被用於RGB的編碼數據的進一步壓縮); FRZ的設計目的是生成一種能夠快速解壓的壓縮數據格式,而不太在意壓縮時的時間和內存空間佔用;
不使用zip\LZMA等通用的數據壓縮算法是因爲這些算法的解壓對FRG的要求來說是實在是太慢了;
嘗試過專門爲快速編解碼應用而設計的lzo算法,一般情況下壓縮率和解壓速度曲線 比FRZ差;
FRZ的更詳細介紹和性能測試: http://blog.csdn.net/housisong/article/details/9104643 ; 可以看到FRZ,壓縮率中等,編碼格式簡單(解碼器也超簡單),解碼特別的快(甚至能達到每秒解碼1GB以上的數據!)