1. 程式人生 > >幾種主流貼圖壓縮演算法的實現原理詳解

幾種主流貼圖壓縮演算法的實現原理詳解

ETC壓縮演算法採用將影象中的chromatic和luminance分開儲存的方式,而在解碼時使用luminance對chromatic進行調製進而重現原始影象資訊。

 \

ETC也主要有兩種方法:ETC1和改進後的ETC2。

ETC1:

採用4x2的block進行分割(原始為4*2*24=192,壓縮後為32,壓縮率為6):

對於所有圖片都使用一個全域性的16個組table codeword,每組中有四個數值,且其中是有規律可循的,如下所示:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-8 -12 -31 -34 -50 -47 -80 -127 -16 -24 -62 -68 -100 -94 -160 -254
-2 -4 -6 -12 -8 -19 -28 -42 -4 -8 -12 -24 -16 -38 -56 -84
2 4 6 12 8 19 28 42 4 8 12 24 16 38 56 84
8 12 31 34 50 47 80 127 16 24 62 68 100 94 160 254
12bits:RBG444的一個basecolor,其在使用是需要被擴充套件到8bits;每個block使用32bits進行編輯儲存;比如對於RGB=(0,2,15) -> (0000 ,0010 , 1111),擴充套件後為(000000,00100010 , 11111111)->(0 , 34 , 255),擴充套件方法為直接將原始4位複製後拼接為8位即可;4bits:用來索引16個table codeword中的一組,比如{-10 , -1 , 4 , 7};16bits:對於block中的每個pixel分配2bits,就有4個值,用來索引當前畫素對應於table codeword中的每個modifier,該modifier需要組成三個通道的調整值,比如,對於某個pixel其對應的modifier索引值為2,也即對應上述table codeword中的4,如此一來該pixel的RGB = (0,34,255) + (4,4,4)=(4,38,259),最後需要將其clamp至0,255,因而即為(4,38,255)。

改進後採用4x4的block進行分割(原始為4*4*24= 384, 壓縮後為64, 壓縮率為6):

主要針對某兩個4x2的block間的顏色差異相對較小,因而可以使用一個更多的bit來表示一個更高精度的basecolor,而另外一個basecolor則在其基礎上通過一個bit較小的diff來進行動態計算得來。

對於所有圖片都使用一個全域性的8個組table codeword,每組中有四個數值:

0 1 2 3 4 5 6 7
-8 -17 -29 -42 -60 -80 -106 -183
-2 -5 -9 -13 -18 -24 -33 -47
2 5 9 13 18 24 33 47
8 17 29 42 60 80 106 183
1bit:用來記錄兩個字block是採用常規的4*2編碼還是基於差值的編碼;1bit:用來記錄4x4的block內兩個子block的朝向(可以兩個4*2,也可以兩個2*4)32bits:對於16個pixel,每個分配2bits的索引,指向到對應的modifier;6bits:對於每個子block,有一個3bits的索引,指向8個table codeword中的某一個(由原始的16組codeword縮減為8個);24bits: 分別對應兩個basecolor。對於常規編碼時,則是兩個RGB444,然後對每個擴充套件到RGB888;對於差值編碼時,則是一個RGB555(精度較高)的basecolor和一個差值RGB333(較低精度),先計算出先求值,然後再擴充套件。

ETC2:

根據ETC1的實現方式,如果其塊內的顏色分佈不均勻的話,則其儲存的兩個basecolor會較遠的分佈於插值趨線的較遠的兩側,進行解壓後會得到較低的壓縮質量,

\

因而ETC2就是解決如何針對這些較為特殊的顏色分佈來選擇更加優化的壓縮策略。

改進主要針對ETC1中的diff為1的情況下展開,即basecolor為RGB555和差值RGB333,此時另外一個顏色值= RGB555 + dRGB333,而其中的三個通道也是可以獨立開來計算的,比如對於紅色通道即為R = R5 + dR3,此時,若其中的R5為0且dR3為負值時得到的紅色通道值就沒有意義,此種情況下就可以對該block重新定義編碼方式。

1. 對於紅色通道的溢位情況:

1bit: diff mode8bits: R5,dR3,

剩餘64-1-8 =55bits可用來儲存其它的資訊,但是注意這些其中的R5與dR3之間的溢位方式有不同的16種,而也可以將其轉換為對應的資料儲存(可以儲存4bits的資訊),因而整個資訊儲存位數為59bits.

2. 對於綠色通道的溢位情況:

1bit: diff mode8bits: R5,dR38bits: G5, dG3

剩餘64-1-8-8 =47bits可用來儲存其它的資訊,但是注意此時R通道是沒有溢位的,共有256-16種狀態,因而其可以儲存7bits的資訊,G通道是有溢位的,其與R通道的溢位相同,也有16種不同的狀態,而也可以將其轉換為對應的資料儲存(可以儲存4bits的資訊),所以通過RG兩通道的狀態可以額外儲存的資訊bits數為7+4=11bits。所有在這種情況下的資訊儲存總數量為47+11=58bits。

3. 對於藍色通道的溢位情況:

1bit: diff mode8bits: R5,dR38bits: G5, dG38bits:B5, dB3

剩餘64-1-8-8-8=39bits可用來儲存其它的資訊。同樣對於RGB三個通道進行額外的資訊儲存之後的儲存空間為7+7+4=18bits。所以此種情況下的資訊儲存空間即為:39+18=57bits。

上述操作就巧妙地利用了三個通道中的資訊,來得到擴充套件的儲存空間,然後使用這些儲存空間來對影象資訊進行編碼與壓縮即可。但注意:這些通過三個通道的溢位情況來確定對應模式,並將其中的溢位狀態也利用為對應的儲存空間,看起來比較繞,為什麼不直接使用1位之外的其它63bits進行資料儲存呢?這裡主要是因為原始的ETC1採用了三個通道這樣的儲存方式,而ETC2又必須要相容ETC1,所以只能使用如此的方法。

接下來即需要合理利用57,58,59這三種情況下的bits儲存空間來進行原始資料的壓縮。針對顏色分佈不均勻的狀態,將其細分為了三種不同的分佈情況:

T字型分佈,一部分顏色沿插值趨線分佈,另外的顏色分佈於距離較遠的位置上,這裡將顏色分為不同的兩組,每組顏色統計出其對應的basecolor0,basecolor1(對應圖中的藍色點),每個basecolor為RGB444,而對於位於右下方的basecolor0儲存一個3bits的索引值,用來索引到一個operator(共有8個),然後得到其周圍的兩上basecolor3, basecolor4,如此一來就有4個basecolor,而block中的每個pixel均索引到4個basecolor中的一個。因而共需要儲存位數為:

12bits: RGB444 basecolor012bits: RGB444 basecolor13bits: operator32bits: 對於16個pixel,每個2bits的索引值

共計為:59bits

\

H字型分佈,兩部分的顏色均有不同的分佈趨向,同樣的原理,統計出兩組的basecolor,然後使用operator分別對兩個basecolor擴充套件為兩個basecolor(注意:對T字型只需要擴充套件一個),然後用4個新的basecolor來重建block中每個畫素的顏色資訊。

24bits: RGB444,RGB444兩個basecolor3bits: operator32bits:對於16個pixel,每個2bits的索引值

\

平面分佈型,其主要針對block塊內的顏色分佈於4個角落上的情形,如下所示:

\

這裡對應的計算模型也就比較簡單直觀,可以直接儲存C0,CH與CV三個顏色值,可將其處理為三角形(或四邊形)上的三個頂點(對應的頂點座標為00,30,03,33),然後對block內每個pixel點上的顏色通過插值的方法得到即可,這裡每個pixel點的座標可以使用其在block塊內的位置即可(如00,01,02,03,10,11,12,13...)。此種情況下不需要其它的資訊,所有我們可以直接把bits資訊全部用來儲存c0,ch,cv三個basecolor即可,在57bits的情況下可得到三個顏色的儲存為19,因而每個basecolorr的儲存格式為RGB676。

通過上述可以看出,ETC2對於原始影象的分析比ETC1要更為多樣,且要相容ETC1的格式,因而對應的壓縮演算法會更加複雜。ETC儲存格式是沒有處理alpha資訊,因而其不能直接應用於半透明影象的壓縮,但是這裡也有可先的方案來在ETC的基礎上使用alpha通道:ETC Texture compression and alphachannel handling

3. PVRTC

\

PVRTC的不是基於block的方式生成的,但是卻也可以理解為以block方式組織的。其生成壓縮後包含兩張(w/4,h/4)大小的縮圖(w,h為原始圖片的寬和高,可以理解為第4級的mipmap,但生成過程會比較mipmap的複雜),其中的每個pixel對映並對應到原始影象中的一個64x64的block上;然後使用1張與原始影象大小相同的modulate圖,對應的每個pixel佔2個bits,也即可對應四種調製方式,通過幾種不同的調製方式還原出近似的原始畫素值。

壓縮後的一個4x4的block中的bits的組成內容為:

1bit:對應的融合方式,透明或不透明;32bits:對應於16個pixel,每個pixel有2bits的調製因子;31bits:對應兩個縮圖中的該塊對映到的兩個畫素上的顏色,若是透明模式,則兩個顏色為RGBA44431,RGBA34431;若是不透明模式,則兩個顏色為RGBA5551,RGBA4551;

兩種模式下的調製因子分別為:

不透明 透明
00 0/8 0/8
01 3/8 4/8
10 5/8 --
11 8/8 8/8

透明情況下的10調製因子會強制設定當前pixel的alpha為0;

通過調節上述兩張縮圖的大小,可以相應的改變對應的壓縮比,比如由(w/4,h/4)修改為(w/8,h/4),而其它的對映方式不變,即可將壓縮比增大一倍。

4. ASTC

ASTC中ARM研發的一種較新的貼圖壓縮格式,相對於上述幾種方法具有較多的優勢,其應該會慢慢成為之後移動裝置上貼圖壓縮的主要標準和主流。其主要具有如下的特性:

較高的靈活性;可變的壓縮率;支援2d/3d貼圖;適用於移動平臺;支援LDR/HDR貼圖內容;

ASTC同樣是基於block的壓縮方式,但塊的大小卻較支援多種尺寸,比如從基本的4x4到12x12,而且塊的寬高也不限於pot,比如6x5;每個塊內的內容用128bits來進行儲存,因而不同的塊就對應著不同的壓縮率。

對於每個塊,同樣儲存兩個插值端點,稱為endpoints,但是這裡的endpoints不一定是基於顏色的(RGBA),也可以基於layer,比如對於R,G,B,A甚或其中的組合如RG等,這樣的話就可以用來對normal map或alpha map進行更好的壓縮;

對於塊中的每個texel,儲存其對應於endpoints的外掛weight,但是儲存的weight數量可以比texel少,特別是對於規格較大的塊(比如12x12),這種情況下會首先對於每個texel通過線性插值得到其對就應的weight,然後再進行顏色的計算;

對於塊內顏色分佈較為複雜的情況,分析塊內顏色的分佈,然後做partition,對於每個partition進行分別的處理(與ETC2中將顏色分佈對應到具體的預知分佈模式中的處理方法不同),分別儲存其對應的endpoints;這樣一來對於塊內的某個texel進行取值時就先定位其對應的partition,然後再計算在其在對應的小子塊內的顏色。

塊內資訊的儲存採用了BISE的方式來進行壓縮,儘可能的節省對應的儲存空間。比如對於一組5個表示範圍已知的整型數值,採用BISE儲存後可節省兩個bits,這樣就使用每個塊內較大量的資料儲存於128bits內成為可能;

對於單layer的一個block內的bits組織大概如下所示:

11bits: 儲存weight, height, 以及特殊塊的標識,比如void-extent等;2bits: part數量;4bits: 儲存16種不同的endpoints的模式,比如是LDR或HDR,RGB或是RGBA;111bit:其中儲存endpoints,texel weight以及其它的配置資訊,(注意,每種具體的儲存大小是可變的,因其採用BISE進行壓縮放置);

4.1 Bounded Integer sequence encoding

主要是針對範圍限定的整數序列進行壓縮儲存進而節省空間。比如對於三個數4,78,55,其直接用binary的表示為0000100,1001110,0110111,直接儲存二進位制序列的話需要7bits * 3 = 21bits(在已知最大範圍為78的情況下,不需要儲存滿8bits)。但是能不能在21bits的基礎上再減少呢?BISE就是實現這樣的目的的。

假設序列的範圍為N,對應的bit位數為n:

若N<= 3*2^n-2,則其可用基於5的BISE壓縮;若N<=5*2^n-3,則其可用基於3的BISE壓縮。

這裡的背後其實是基於這樣的一個事實,比如在基於3的壓縮中,如果N<=3*2^n-2,那麼在N的最高兩位bit上,其並不會出現2^2種情況的所有組合(因其大小是受限的),到少11這樣的組合就是沒有的,否則其對應的值必定大於N。所以BISE壓縮就是將受限的整數序列中的前兩位資料中的無效bits進行合理使用。比如,在上述4,78,55的序列中,78 <= 5 * 2^4 = 80,所以可以使用基於5的BISE,將三個數的二進位制序列構造為{000 0100, 100 1100, 011 0111},高三位的組合為{000,100,011},因這三個3位bits序列中的最大值是5,所以每三個bits最多有5種情況,那麼這個高三位組合的序列共可能有5^3=125種組合情況,這樣的話就可以使用7bits的空間來儲存所有的這些組合,如此一來就可以將原來3*3=9bits的儲存空間儲存在7bits中,進而達到壓縮的目的。

相關推薦

主流壓縮演算法實現原理

ETC壓縮演算法採用將影象中的chromatic和luminance分開儲存的方式,而在解碼時使用luminance對chromatic進行調製進而重現原始影象資訊。   ETC也主要有兩種方法:ETC1和改進後的ETC2。 ETC1: 採用4x2的block進行分割(原始為4*2*24=192,壓

壓縮演算法實現原理

gzip 、zlib以及圖形格式png,使用的壓縮演算法都是deflate演算法。從gzip的原始碼中,我們瞭解到了defalte演算法的原理和實現。我閱讀的gzip版本為 gzip-1.2.4。下面我們將要對deflate演算法做一個分析和說明。首先簡單介紹一下基本原理,

演算法:KMP 演算法實現

未完待續 、、、 求下標 K 所對應的 next 陣列對應值的具體方法為: 觀察下標 K -1 對應字串的值,令 X 為下標 K -1 對應的 next 陣列的值 若 X 為-1,則下標 K對應的 next 陣列值為 0,否則進入步驟3 觀察下標為 X 的字串的值是

SHA1演算法實現

1 SHA1演算法簡介 安全雜湊演算法(Secure Hash Algorithm)主要適用於數字簽名標準(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度

譜聚類matlab演算法實現

    此時此景,我想先講個故事。我哈哈哈。    譜聚類(spectral clustering)的思想最早可以追溯到一個古老的希臘傳說,話說當時有一個公主,由於其父王去世後,長兄上位,想獨攬大權,便殺害了她的丈夫,而為逃命,公主來到了一個部落,想與當地的酋長買一塊地,於是

反射和多型實現原理

Table of Contents 反射和多型 多型 多型的定義和用法 多型的實現原理 反射 反射的實現原理 反射的應用 反射的弊端 反射和多型 這兩種技術並無直接聯絡,之所以把它們放在一起說,是因為Java提供讓我們在執行時識別物件和類的資訊,主要有

Java LinkedList的實現原理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java HashSet的實現原理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Python Web開發中,WSGI協議的作用和實現原理

首先理解下面三個概念: WSGI:全稱是Web Server Gateway Interface,WSGI不是伺服器,python模組,框架,API或者任何軟體,只是一種規範,描述web server如何與web application通訊的規範。 uwsgi:與WSGI一樣是一種協議,是uWSGI伺服器

HashMap底層實現原理(轉載)

本文轉自:https://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap詳解 HashMap 和 HashSet 是 Java Collection Framework 的兩個重要成員,其中 HashMap 是

golang net/http包部分實現原理

net/http包在編寫golang web應用中有很重要的作用,它主要提供了基於HTTP協議進行工作的client實現和server實現,可用於編寫HTTP服務端和客戶端。 其使用方法也跟其他面嚮物件語言很相似,我們可以先從它的一些基礎用法來感受一下: 以下是

Spring Aop之Cglib實現原理

Spring Aop實現對目標物件的代理,AOP的兩種實現方式:Jdk代理和Cglib代理。這兩種代理的區別在於,Jdk代理與目標類都會實現同一個介面,並且在代理類中會呼叫目標類中被代理的方法,呼叫者實際呼叫的則是代理類的方法,通過這種方式我們就可以在代理類中織入切面邏輯;Jdk代理存在的問題在於目標類被代

MVC之前的那點事兒系列(7):WebActivator的實現原理

文章內容 上篇文章,我們分析如何動態註冊HttpModule的實現,本篇我們來分析一下通過上篇程式碼原理實現的WebActivator類庫,WebActivator提供了3種功能,允許我們分別在HttpApplication初始化之前,之後以及ShutDown的時候分別執行指定的程式碼,示例如下: [

併發容器之ArrayBlockingQueue和LinkedBlockingQueue實現原理

1. ArrayBlockingQueue簡介 在多執行緒程式設計過程中,為了業務解耦和架構設計,經常會使用併發容器用於儲存多執行緒間的共享資料,這樣不僅可以保證執行緒安全,還可以簡化各個執行緒操作。例如在“生產者-消費者”問題中,會使用阻塞佇列(Blocki

String類在記憶體中實現原理

(1) ==  比較引用型別比較的是地址值是否相同 equals:比較引用型別預設也是比較地址值是否相同,而String類重寫了equals()方法,比較的是內容是否相同。 (2) 區分下面兩種語句在記憶體中的實現: <span style="font-size:14

XFS實現原理

0 檔案系統      引用維基百科對檔案系統的定義:“計算機的檔案系統是一種儲存和組織計算機資料的方法,它使得對其訪問和查詢變得容易,檔案系統使用檔案和樹形目錄的抽象邏輯概念代替了硬碟和光碟等物理裝置使用資料塊的概念,使用者使用檔案系統來儲存資料不必關心資料實際儲存在硬碟

HashMap實現原理

HashMap定義 HashMap實現了Map介面,一種將鍵對映到值得物件。 一個對映不能包含重複的鍵;每個鍵只能對映到一個值上。 HashMap的元素是無序的。要實現有序排列必須實現hashc

Scala中HashSet的實現原理

HashSet是平時常用到的資料結構之一,其保證元素是不重複的。 本文將用一個簡單的例子來解釋下scala語言中HashSet內部的工作原理,看下add和remove到底是怎樣工作的。 用法示例 val s = mutable.HashSet

Java ArrayList的實現原理

ArrayList是Java List型別的集合類中最常使用的,本文基於Java1.8,對於ArrayList的實現原理做一下詳細講解。 一、ArrayList實現原理總結 ArrayList的實現原理總結如下: ①資料儲存是基於陣列實現的,預設初始容量為10; ②

Java執行緒池實現原理

原理概述 其實java執行緒池的實現原理很簡單,說白了就是一個執行緒集合workerSet和一個阻塞佇列workQueue。當用戶向執行緒池提交一個任務(也就是執行緒)時,執行緒池會先將任務放入workQueue中。workerSet中的執行緒會不斷的從w