天天看點

H264 CAVLC 研究

目錄

  • 1 CAVLC概念
  • 2 CAVLC原理
  • 3 CAVLC編碼流程
  • 4 CAVLC解碼流程
  • 展開全部
  • 1 CAVLC概念
  • 2 CAVLC原理
  • 3 CAVLC編碼流程
  • 4 CAVLC解碼流程
  • 收起

摘要 糾錯編輯摘要

CAVLC即基于上下文的自适應變長編碼。H.264标準中使用CAVLC對4*4子產品的亮度和色度殘差資料進行編碼。

CAVLC-CAVLC概念

CAVLC的全稱是Context-Adaptive Varialbe-Length Coding,即基于上下文的自适應變長編碼。CAVLC的本質是變長編碼,它的特性主要展現在自适應能力上,CAVLC可以根據已編碼句法元素的情況動态的選擇編碼中使用的碼表,并且随時更新拖尾系數字尾的長度,進而獲得極高的壓縮比。H.264标準中使用CAVLC對4×4子產品的亮度和色度殘差資料進行編碼。

CAVLC-CAVLC原理

在H.264标準編碼體系中,視訊圖像在經過了預測、變換及量化編碼後表現出如下的特性:4×4塊殘差資料塊比較稀疏,其中非零系數主要集中在低頻部分,而高頻系數大部分是零;量化後的資料經過zig-zag掃描,DC系數附近的非零系數值較大,而高頻位置上的非零系數值大部分是+1和-1;相鄰的4×4塊的非零系數的數目是相關的。CAVLC就是利用編碼後殘差資料的這些特性,通過自适應對不同碼表的選擇,利用較少的編碼資料對殘差資料進行無損的熵編碼,進一步減少了編碼資料的備援和相關性,提高了H.264的壓縮效率。

CAVLC-CAVLC編碼流程

視訊圖像在經過預測、變換和量化編碼後,需要經過Zig-zag掃描和重新的排序過程,為後序的CAVLC編碼進行準備。一個殘差資料塊的CAVLC熵編碼的流程如圖所示:

H264 CAVLC 研究

CAVLC熵編碼處理流程

1、TotalCoeffs和TrailingOnes的編碼

從碼流的起始位置開始計算整個編碼塊中非零系數的數目(TotalCoeffs),非零系數的數目為從0-16,非零系數的數目被指派給變量TotalCoeffs。

拖尾系數是指碼流中正或者負1的個數(+/-1)。拖尾系數的數目(TrailingOnes)被限定在3個以内,如果+/-1的數目超過3個,則隻有最後3個被視為拖尾系數,其餘的被視為普通的非零系數,拖尾系數的數目被指派為變量TrailingOnes。 

2、判斷計算nC值

nC(Number Current 目前塊值)值的計算集中展現了CAVLC的基于上下文的思想,通過nC值選擇不同H.264标準附錄CAVLC碼表。 

3、查表獲得coeff_token編碼

根據之前編碼和計算過程所得的變量TotalCoeffs、TrailingOnes和nC值可以查H.264标準附錄CAVLC碼表,即可得出coeff_token編碼序列。

4、編碼每個拖尾系數的符号:前面的coeff_token編碼中已經包含了拖尾系數的總數,還需進一步對拖尾系數的符号進行編碼。由于拖尾系數符合為正(+)或負(-),是以,在H.264标準中規定用0表示正1(+1)、1表示負1(-1)。當拖尾系數的數目超過3個隻有最後3個被認定為拖尾系數,是以對符号的編碼順序應按照反向掃描的順序進行。

5、編碼除拖尾系數之外的非零系數的幅值(Levels)

非零系數的幅值(Levels)由兩個部分組成:字首(level_prefix)和字尾(level_suffix)。levelCode、levelSuffixsSize和suffixLength是編碼過程中需要使用的三個變量,其中levelCode是中間過程中用到的無符号數,levelSuffixsSize表示字尾長度位數,suffixLength代表Level的碼表序号。

6、編碼最後一個非零系數前零的數目(TotalZeros)

TotalZeros指的是在最後一個非零系數前零的數目,此非零系數指的是按照正向掃描的最後一個非零系數。因為非零系數數目(TotalCoeffs)是已知,這就決定了TotalZeros可能的最大值。根據TotalCoeffs值,H.264标準共提供了25個變長表格供查找,其中編碼亮度資料時有15個表格供查找,編碼色度DC 2×2塊(4:2:0格式)有3個表格、編碼色度DC 2×4塊(4:2:2格式)有7個表格。

7、編碼每個非零系數前零的個數(RunBefore)

在CAVLC中,變量 ZerosLeft表示目前非零系數左邊的所有零的個數,ZerosLeft的初始值等于TotalZeros。每個非零系數前零的個數(RunBefore)是按照反序來進行編碼的,從最高頻的非零系數開始。H.264标準中根據不同ZerosLeft和RunBefore,建構了RunBefore編碼表格供編碼查找使用。根據表格每編碼完一個RunBefore,對ZerosLeft的值進行更新,繼續編碼下一個RunBefore,直至全部完成所有非零系數前零的個數的編碼。當ZerosLeft=0即沒有剩餘0需要編碼時或者隻有一個非零系數時,均不需要再進行RunBefore編碼。

CAVLC-CAVLC解碼流程

CAVLC熵解碼是上述CAVLC熵編碼的逆過程,CAVLC熵解碼的輸入資料是來自片層資料的比特流,解碼的基本機關是一個4×4的像素塊,輸出為包含4×4塊每個像素點所有幅值的序列。CAVLC解碼步驟如下:

1. 初始化所有的系數幅值

2. 解碼非零系數個數(TotalCoeff)和拖尾系數個數(TrailingOnes)。

3. 解碼拖尾系數符号(trailing_ones_sign_flag)

4. 解碼非零系數幅值

5. 解碼total_zeros和run_before

6. 組合非零系數幅值和遊程資訊,得到整個殘差資料塊

H.264 CAVLC編解碼詳解 2007-04-20 21:53

CAVLC: Context-Adaptive Variable-Length Coding

用于亮度和色度殘差資料的編碼.

經過變化量化後的殘差有如下特性:非零系數集中在低頻部分,而高頻系數大部分是零; 量化後的資料經Zig-Zag掃描後DC系數附近的非零系數數值較大,而高頻位置上的非零系數值大部分是+1和-1;相鄰4*4塊的非零系數的數位是相關的.

CAVLC模型選擇主要展現:非零系數編碼所需表格的選擇和拖尾系數字尾長度的更新;

編碼過程

1.初始化

确定NC值

NC則與目前塊左邊非零系數數目NA和上面塊的非零系數數目NB求得的:

NC = (NA+NB)/2   NA,NB都可以能是沒有的(處于邊緣時),此時以0計之

色度的直流系數NC=-1

NC值與表格的對應 0-1:Num-VLC0 2-3:Num-VLC1 4-7:Num-VLC2 >=8:FLC(定長表格)

2.編碼非零系數的數目(TotalCoeffs: 0-16)和拖尾系數數目(TrailingOnes: 0-3)

兩個數目的編碼過程是通過查表實作的,而表格的選擇是根據變量NC(Number Current,目前塊值);

3.編碼每個拖尾系數的符号

符号用一個比特表示 0表示+ 1表示-

4.編碼除了拖尾系數之外的非零系數的幅值Levels

過程:

1)将有符号的Level[i]轉換成無符号的LevelCode

Level[i]為正, levelCode=(Level[i]<<1)-2;

Level[i]為負, levelCode=-(Level[i]<<1)-1;

2)計算level_prefix

level_prefix=levelCode/(1<<suffixLength), 查标準中的表9-6可得對應的bit_string

3)計算level_suffix

level_suffix=levelCode%(1<<suffixLength)

4)根據suffixLength的值确定字尾的長度

5)更新suffixLength

if(suffixLength == 0)++suffixLength;

else if(levelCode > (3<<suffixLength-1) && suffixLength < 6)++suffixLength

5.編碼最後一個非零系數前零的數目TotalZeros

查标準中的表9-7

6.編碼每個非零系數前零的個數RunBefore

查标準中的表9-10

解碼過程

1.初始化

确定NC值

2.确定TotalCoeffs和TrailingOnes

根據NC值和coeff_token值查表9-5

3.根據TrailingOnes确定拖尾1的符号

4.解析除拖尾系數之外的非零系數的幅值(解碼Levels)

1)确定suffixLength初始值

if(TotalCoeffs>10 && TrailingOnes<3)suffixLength=1;

else suffixLength=0;

2)計算得到Level[i]

先得到level_prefix(形式如{0}^*1: n個0後一個1)

根據suffixLength讀取編碼中的suffixLength位作為level_suffix

levelCode=level_prefix<<suffixLength+level_suffix

if(levelCode%2==0)Level[i]=(levelCode+2)/2

else Level[i]=(-levelCode-1)/2

3)更新suffixLength

if(suffixLength == 0)++suffixLength;

else if(levelCode > (3<<suffixLength-1) && suffixLength < 6)++suffixLength

5.根據得到的TotalCoeff數值和TotalZeros編碼值得到TotalZeros數值

6.解析每個非零系數前零的數目(解碼RunBefore)

zeroleft = TotalZeros;

i=TotalCoeffs-1;

while(zeroleft>0 && i>0)

{

   根據zeroleft查找比對的run_before[i]值;

   i=i-1;

   zeroleft = zeroleft-runbefore[i];

   if(zeroleft==0 || i==0)

   {

     run_before[i]=zeroleft;

     break;

   }

}

例子:假定用了Num-VLC0表

4*4 Block

{

0,3,-1,0;

0,-1,1,0;

1,0,0,0;

0,0,0,0;

}

Reodered block:

0,3,0,1,-1,-1,0,1,0,...

TotalCoeffs=5

TotalZeros=3

TrailingOnes=3

編碼

Element   Value      Code

coeff_token   TotalCoeffs=5, T1s=3    0000100;根據coeff_token到TotalCoeff和TrailingOnes映射表

T1 sign (4)   +      0

T1 sign (3)   -      1

T1 sign (2)   -      1

Level (1)   +1 (use Level_VLC0)    1;

Level (0)   +3 (use Level_VLC1)    0010;

TotalZeros   3      111;TotalCoeff和TotalZeros的映射表

run_before(4)   ZerosLeft=3; run_before=1   10;run_before表

run_before(3)   ZerosLeft=2; run_before=0   1

run_before(2)   ZerosLeft=2; run_before=0   1

run_before(1)   ZerosLeft=2; run_before=1   01

run_before(0)   ZerosLeft=1; run_before=1   No code required; last coefficient.

Decoding:

Code    Element Value      Output array

0000100   coeff_token TotalCoeffs=5, T1s=3   Empty

0    T1 sign +      1

1    T1 sign -      -1, 1

1    T1 sign -      -1, -1, 1

1    Level +1      1, -1, -1, 1

0010    Level +3      3, 1, -1, -1, 1

111    TotalZeros 3      3, 1, -1, -1, 1

10    run_before 1      3, 1, -1, -1, 0, 1

1    run_before 0      3, 1, -1, -1, 0, 1

1    run_before 0      3, 1, -1, -1, 0, 1

01    run_before 1      3, 0, 1, -1, -1, 0, 1

[轉貼] CAVLC編碼過程詳解——Sunrise

謹以此文獻給QQ群“H.264樂園”和群裡那些無私奉獻的同行朋友!

也希望能對剛進入這個領域的朋友有所幫助,歡迎做過CAVLC的同行能批評指正!

編碼過程:

假設有一個4*4資料塊

{

0, 3, -1, 0,

0, -1, 1, 0,

1, 0, 0, 0,

0, 0, 0, 0

}

資料重排列:0,3,0,1,-1,-1,0,1,0……

1) 初始值設定:

非零系數的數目(TotalCoeffs) = 5;

拖尾系數的數目(TrailingOnes)= 3;

最後一個非零系數前零的數目(Total_zeros) = 3;

變量NC=1;

(說明:NC值的确定:色度的直流系數NC=-1;其他系數類型NC值是根據目前塊左邊4*4塊的非零系數數目(NA)目前塊上面4*4塊的非零系數數目(NB)求得的,見畢厚傑書P120表6.10)

suffixLength = 0;

i = TotalCoeffs = 5;

2) 編碼coeff_token:

查标準(BS ISO/IEC 14496-10:2003)Table 9-5,可得:

If (TotalCoeffs == 5 && TrailingOnes == 3 && 0 <= NC < 2)

coeff_token = 0000 100;

Code = 0000 100;

3) 編碼所有TrailingOnes的符号:

逆序編碼,三個拖尾系數的符号依次是+(0),-(1),-(1);

即:

TrailingOne sign[i--] = 0;

TrailingOne sign[i--] = 1;

TrailingOne sign[i--] = 1;

Code = 0000 1000 11;

4) 編碼除了拖尾系數以外非零系數幅值Levels:

過程如下:

(1)将有符号的Level[ i ]轉換成無符号的levelCode;

如果Level[ i ]是正的,levelCode = (Level[ i ]<<1) – 2;  

如果Level[ i ]是負的,levelCode = - (Level[ i ]<<1) – 1;

(2)計算level_prefix:level_prefix = levelCode / (1<<suffixLength);

查表9-6可得所對應的bit string;

(3)計算level_suffix:level_suffix = levelCode % (1<<suffixLength);

(4)根據suffixLength的值來确定字尾的長度;

(5)suffixLength updata:

If ( suffixLength == 0 )

suffixLength++;

else if ( levelCode > (3<<suffixLength-1) && suffixLength <6)

suffixLength++;

回到例子中,依然按照逆序,Level[i--] = 1;(此時i = 1)

levelCode = 0;level_prefix = 0;

查表9-6,可得level_prefix = 0時對應的bit string = 1;

因為suffixLength初始化為0,故該Level沒有字尾;

因為suffixLength = 0,故suffixLength++;

Code = 0000 1000 111;

編碼下一個Level:Level[0] = 3;

levelCode = 4;level_prefix = 2;查表得bit string = 001;

level_suffix = 0;suffixLength = 1;故碼流為0010;

Code = 0000 1000 1110 010;

i = 0,編碼Level結束。

5)編碼最後一個非零系數前零的數目(TotalZeros):

查表9-7,當TotalCoeffs = 5,total_zero = 3時,bit string = 111;

Code = 0000 1000 1110 0101 11;

6) 對每個非零系數前零的個數(RunBefore)進行編碼:

i = TotalCoeffs = 5;ZerosLeft = Total_zeros = 3;查表9-10:

依然按照逆序編碼

ZerosLeft =3, run_before = 1 run_before[4]=10;

ZerosLeft =2, run_before = 0 run_before[3]=1;

ZerosLeft =2, run_before = 0 run_before[2]=1;

ZerosLeft =2, run_before = 1 run_before[1]=01;

ZerosLeft =1, run_before = 1 run_before[0]不需要碼流來表示

Code = 0000 1000 1110 0101 1110 1101;

編碼完畢。

----------------------------------Sunrise------

[[i] 本帖最後由 firstime 于 2008-9-4 02:49 PM 編輯 [/i]]

davesliu 發表于 2006-11-20 12:03 PM

請問斑竹,老畢書上120頁表6.10中第2行和第三行的NA和NB是不是給弄反了?

vcforever 發表于 2006-12-7 11:06 PM

應該是弄反了

dmsd 發表于 2006-12-18 05:42 PM

請問trailing ones是指所有絕對值為1的系數的個數還是連續絕對值為1的系數的個數。

謝謝。

firstime 發表于 2006-12-18 11:29 PM

倒數三個 +/-1

另:可結合本論壇文章“[url=http://bbs.chinavideo.org/viewthread.php?tid=1057][color=blue][b]CAVLC中的字首和字尾[/b][/color][/url]”學習。

[[i] 本帖最後由 firstime 于 2008-5-20 09:59 PM 編輯 [/i]]

achen 發表于 2007-1-17 05:50 PM

“如果Level[ i ]是負的,levelCode = - (Level[ i ]<<1) – 1”

假如Level[ i ]=-3,levelCode值是多少啊?

還有能不能詳細講解一下如何确定suffixLength的取值,它跟域值的關系怎麼确定?

謝謝!

[[i] 本帖最後由 firstime 于 2007-1-27 10:06 PM 編輯 [/i]]

dcfarmer 發表于 2007-1-28 11:22 AM

讨論

是JM86運作後的trace記錄

@160   Luma # c & tr.1s(0,0) vlc=0 #c=11 #t1=1         000000000001110 ( 11)

@175   Luma trailing ones sign (0,0)                                 0 (  0)

@176   Luma lev (0,0) k=9 vlc=1 lev= -2                             11 ( -1)

@178   Luma lev (0,0) k=8 vlc=1 lev= -1                             11 ( -1)

@180   Luma lev (0,0) k=7 vlc=1 lev=  1                             10 (  1)

@182   Luma lev (0,0) k=6 vlc=1 lev= -5                         000011 ( -5)

@188   Luma lev (0,0) k=5 vlc=2 lev=-11                       00000101 (-11)

@196   Luma lev (0,0) k=4 vlc=3 lev= -3                           1101 ( -3)

@200   Luma lev (0,0) k=3 vlc=3 lev=  3                           1100 (  3)

@204   Luma lev (0,0) k=2 vlc=3 lev=  3                           1100 (  3)

@208   Luma lev (0,0) k=1 vlc=3 lev=-12                         001111 (-12)

@214   Luma lev (0,0) k=0 vlc=3 lev=  9                         001000 (  9)

上面這段是trace.txt中的記錄,根據前面的vlc=0 #c=11 #t1=1,就是trailing_ones 的個數是1個(@175   Luma trailing ones sign (0,0)        0 (  0) )也能說明,但是在下面的level中,明明還要-1,1可以作為trailing_ones的,為什麼不把這兩個數當作trailing_ones呢??而是作為level呢????

dcfarmer 發表于 2007-1-28 11:40 AM

回答

接上面的問題,在群裡面讨論弄明白了

在CAVLC編碼中,從右往左看,算trailing_ones時,在右邊不能有abs()>1的數,還有算trailing_ones的個數的話,也不能被别的abs()>1的數隔斷,如果隔斷的話,隻能計數到隔斷數為止,而且要保證個數<=3。例如。。。。2,3,0,0,0,1,1,1,0,0,2 ,這個序列中triailing_ones是沒有的。還有。。。。。1,0,0,-1,3,1,0,0,0,0,算trailing_ones 個數時,隻能有一個也就是3後面的“1”算一個,3前面的-1和1由于被3隔斷,是以不能算入其中。

[[i] 本帖最後由 dcfarmer 于 2007-6-7 03:27 PM 編輯 [/i]]

zjh1004 發表于 2007-8-26 09:55 PM

ZerosLeft =1, run_before = 1      run_before[0]不需要碼流來表示

請問:為什麼不需要碼流來表示?

是因為是最後一位嗎?

查表知:此時 run_before[0]=0

timek 發表于 2007-9-11 06:35 PM

回複 #6 achen 的文章

Level[ i ]=-3,levelCode值是多少啊?

levelcode應該是3

grassland_fly 發表于 2007-9-12 03:47 PM

[size=12px]ZerosLeft =1, run_before = 1      run_before[0]不需要碼流來表示

請問:為什麼不需要碼流來表示?

是因為是最後一位嗎?

查表知:此時 run_before[0]=0[/size]

[size=12px] [/size]

[size=12px]---------------------------------------------------------[/size]

[size=12px] [/size]

[size=12px]I think it's because can know the vaule based on the value before. :)[/size]

generalair 發表于 2007-10-22 02:51 PM

2007-1-28 11:22 AM dcfarmer

讨論

是JM86運作後的trace記錄

@160   Luma # c & tr.1s(0,0) vlc=0 #c=11 #t1=1         000000000001110 ( 11)

@175   Luma trailing ones sign (0,0)                                 0 (  0)

@176   Luma lev (0,0) k=9 vlc=1 lev= -2                             11 ( -1)

@178   Luma lev (0,0) k=8 vlc=1 lev= -1                             11 ( -1)

@180   Luma lev (0,0) k=7 vlc=1 lev=  1                             10 (  1)

@182   Luma lev (0,0) k=6 vlc=1 lev= -5                         000011 ( -5)

@188   Luma lev (0,0) k=5 vlc=2 lev=-11                       00000101 (-11)

@196   Luma lev (0,0) k=4 vlc=3 lev= -3                           1101 ( -3)

@200   Luma lev (0,0) k=3 vlc=3 lev=  3                           1100 (  3)

@204   Luma lev (0,0) k=2 vlc=3 lev=  3                           1100 (  3)

@208   Luma lev (0,0) k=1 vlc=3 lev=-12                         001111 (-12)

@214   Luma lev (0,0) k=0 vlc=3 lev=  9                         001000 (  9)

請問上面這段TRACE記錄對應的16個系數序列是什麼?謝謝

boleaon 發表于 2007-11-8 04:46 PM

好貼...

kdjwang 發表于 2008-10-10 03:52 PM

回複 #10 timek 的文章

levelcode應該是5,level先乘2為-6,再取反減1

解碼時因為levelcode為奇數,level = (‐levelCode‐1)/2

libra811 發表于 2008-12-29 10:44 PM

剛學習,受用了。謝謝

peiyangpr 發表于 2009-1-4 05:28 PM

畢厚傑P123,6.8.6節中所給例子是否有誤?是否應如下編碼?

0        0        -1        0

5        2        0        0

3        0        0        0

1        0        0        0        

資料重排:0,0,5,3,2,-1,0,0,0,1……

其中TotalCoeffs = 5, TrailingOnes = 2, Total_zeros = 5, NC = 3

編碼過程:

元素                                                   數值                                                            編碼

Coeff_token                                      TotalCoeffs = 5, TrailingOnes = 2               0000101

Trailingones_sign_flag(1)                 +                                                                  0

Tranlingones_sign_flag(0)                -                                                                   1

Level(2)                                            1 (suffixLenth = 0)                                        1

Level(1)                                            3 (suffixLength = 1)                                      0010

Level(0)                                            5 (suffixLength = 1)                                      000010

Total_zeros                                      5                                                                   101

Run_before(4)                                 Zeroleft = 5, run_before = 3                          010

Run_before(4)                                 Zeroleft = 2, run_before = 0                          1

Run_before(4)                                 Zeroleft = 2, run_before = 0                          1

Run_before(4)                                 Zeroleft = 2, run_before = 0                          1

Run_before(4)                                    Zeroleft = 2, run_before = 2                               無

最終編碼輸出:000010110010000010101010111

[[i] 本帖最後由 peiyangpr 于 2009-1-4 09:16 PM 編輯 [/i]]

residual_block_cavlc( coeffLevel, maxNumCoeff ) {  C      Descriptor

    for( i = 0; i < maxNumCoeff; i++ )          

        coeffLevel[ i ] = 0     

    // coeff_token      指明了非零系數的個數,拖尾系數的個數。      

    coeff_token 

    if( TotalCoeff( coeff_token ) > 0 ) {          

        if( TotalCoeff( coeff_token ) > 10    &&    TrailingOnes( coeff_token ) <

3 )

            suffixLength = 1          

        else          

            suffixLength = 0          

        for( i = 0; i < TotalCoeff( coeff_token ); i++ )          

            if( i < TrailingOnes( coeff_token ) ) {           

                // trailing_ones_sign_flag  拖尾系數的符号

                    -     如果trailing_ones_sign_flag = 0,  相應的拖尾系數是+1。

                    -     否則,trailing_ones_sign_flag =1,相應的拖尾系數是-1。 

                trailing_ones_sign_flag  

                level[ i ] = 1 – 2 * trailing_ones_sign_flag          

            } else {          

                // level_prefix and level_suffix  非零系數值的字首和字尾。 

                level_prefix 

                levelCode = ( level_prefix << suffixLength )          

                if( suffixLength > 0    | |    level_prefix >= 14 ) {          

                    level_suffix  

                    levelCode += level_suffix          

                }          

                if( level_prefix    = =    15    &&    suffixLength    = =    0 )          

                    levelCode += 15          

                if( i    = =    TrailingOnes( coeff_token )    &&    

                      TrailingOnes( coeff_token ) < 3 )

                    levelCode += 2          

                if( levelCode % 2    = =    0 )          

                    level[ i ] = ( levelCode + 2 ) >> 1          

                else          

                    level[ i ] = ( –levelCode – 1 ) >> 1          

                if( suffixLength    = =    0 )          

                    suffixLength = 1          

                if( Abs( level[ i ] )    >    ( 3 << ( suffixLength – 1 ) )    &&    

                      suffixLength < 6 )

                    suffixLength++          

            }          

        if( TotalCoeff( coeff_token ) < maxNumCoeff ) {          

            // total_zeros    系數中 0 的總個數。

            total_zeros   

            zerosLeft = total_zeros          

        } else          

            zerosLeft = 0          

        for( i = 0; i < TotalCoeff( coeff_token ) – 1; i++ ) {          

            if( zerosLeft > 0 ) {          

                run_before   

                run[ i ] = run_before          

            } else          

                run[ i ] = 0          

            zerosLeft = zerosLeft – run[ i ]          

        }          

        run[ TotalCoeff( coeff_token ) – 1 ] = zerosLeft          

        coeffNum = -1          

        for( i = TotalCoeff( coeff_token ) – 1; i >= 0; i-- ) {          

            coeffNum += run[ i ] + 1          

            coeffLevel[ coeffNum ] = level[ i ]            

        }          

    }          

}

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/xfding/archive/2010/04/12/5477464.aspx

繼續閱讀