本發(fā)明數(shù)據(jù)壓縮和解壓縮技術領域,尤其是涉及一種無損自適應數(shù)據(jù)壓縮和解壓縮的系統(tǒng)。
背景技術:
在很多環(huán)境下,數(shù)據(jù)的高速電子收集往往會存在很多問題。例如,當通過病人監(jiān)護儀收集患者的臨床數(shù)據(jù)時,大量的數(shù)據(jù)可在較短的時間間隔內(nèi)完成收集。電腦系統(tǒng)則通過典型的方式將這些數(shù)據(jù)存儲在計算機內(nèi)存中等待后續(xù)處理。計算機內(nèi)存是一種有限的資源,能夠很快被所收集到的數(shù)據(jù)占滿。
為了減少所收集數(shù)據(jù)對計算機內(nèi)存的需求,一些計算機系統(tǒng)會在向內(nèi)存中存儲數(shù)據(jù)之前對數(shù)據(jù)進行壓縮。當后續(xù)處理需要所收集的數(shù)據(jù)時,電腦系統(tǒng)再將這些數(shù)據(jù)解壓縮。因此,當不需要對數(shù)據(jù)進行處理時,數(shù)據(jù)儲存所需要的內(nèi)存空間能夠?qū)崿F(xiàn)最小化。
目前有許多壓縮和解壓縮方法。不同的方法具有不同的優(yōu)點。例如,一些方法能夠大規(guī)模地減少數(shù)據(jù)儲存規(guī)模。其他方法則能在壓縮和解壓縮過程中很好地保護原數(shù)據(jù)。這些方法又被稱為無損壓縮解壓縮,因為在整個過程中數(shù)據(jù)沒有發(fā)生損壞。其它方法能夠很快地壓縮或者解壓縮數(shù)據(jù)。但是這些方法又存在著諸多不同的缺點。例如,一些方法不能大規(guī)模地減少數(shù)據(jù)儲存規(guī)模。其它方法在壓縮和解壓縮過程中不能夠保護原數(shù)據(jù)免于損失,因此解壓縮后的數(shù)據(jù)只是原數(shù)據(jù)的近似值。另外,一些方法的壓縮與解壓縮速度過于緩慢。一些方法在壓縮或者解壓縮時,占用過多的計算機內(nèi)存。
因此,開發(fā)一種能夠?qū)崟r快速、顯著減少數(shù)據(jù)大小,并且在壓縮和解壓縮過程中對計算機內(nèi)存占用需求較小的無損數(shù)據(jù)壓縮和解壓縮方法,是十分必要的。
技術實現(xiàn)要素:
本發(fā)明的目的在于提供一種無損自適應數(shù)據(jù)壓縮和解壓縮的系統(tǒng)。
為實現(xiàn)上述目的,本發(fā)明采用以下內(nèi)容:
一種無損自適應數(shù)據(jù)壓縮和解壓縮的系統(tǒng),所述系統(tǒng)包括:指示數(shù)據(jù)值頻率的頻率表;識別頻率表中一組數(shù)值的方法;根據(jù)壓縮頻率表中的頻率,為所識別集合中的每個數(shù)據(jù)值生成基于頻率的編碼;從分組中檢索數(shù)據(jù)值的方法;當檢索到的數(shù)據(jù)值在所識別的集合中時,輸出所生成的基于頻率的編碼用于檢索數(shù)據(jù)值的方法,或者當檢索到的數(shù)據(jù)值不在所識別的集合中時,以不基于頻率編碼的格式輸出檢索的數(shù)據(jù)值;將輸出產(chǎn)生的編碼和輸出數(shù)據(jù)值存儲為壓縮數(shù)據(jù)值分組的方法;以及根據(jù)多個分組中一個分組數(shù)據(jù)值的頻率,更新頻率表的方法。
進一步地,還包括:用于當連續(xù)檢索數(shù)據(jù)值相等時,輸出檢索數(shù)據(jù)值游程編碼的方法,游程編碼包括相等數(shù)據(jù)值數(shù)量的一個指示符和相等數(shù)據(jù)值。
進一步地,還包括:用于當所識別的數(shù)據(jù)值集合包括一個數(shù)據(jù)值,該數(shù)據(jù)值等于游程編碼中數(shù)據(jù)值數(shù)量的指示符,在游程編碼中輸出生成的基于頻率編碼的方法。
進一步地,還包括:用于以不基于頻率編碼的格式輸出指示符的方法當所識別的數(shù)據(jù)值集合不包括一個數(shù)據(jù)值,該數(shù)據(jù)值等于游程編碼中數(shù)據(jù)值數(shù)量的指示符。
進一步地,還包括:用于當游程編碼中相等數(shù)據(jù)值在所述識別的組中時,輸出所生成的基于頻率的編碼用于游程編碼中相等數(shù)據(jù)值的方法。
本發(fā)明具有以下優(yōu)點:
本發(fā)明的系統(tǒng)是通過以下方式來壓縮數(shù)據(jù)的:首先計算相鄰數(shù)據(jù)值之間的差異,識別確定出多個經(jīng)常發(fā)生的差異性,并跟蹤所識別出的差異的發(fā)生頻率,同時對所識別出的差異性生成一次編碼,該編碼長度基于差異發(fā)生的頻率;系統(tǒng)隨后為除被識別出的差異以外的全部差異性生成二次編碼,并在當計算差異不屬于能夠影響數(shù)據(jù)壓縮的已識別差異時,使用一次編碼進行差異編碼識別,使用二次編碼對每個計算差異性進行相應識別差異編碼。優(yōu)選地,系統(tǒng)根據(jù)被追蹤到的發(fā)生頻率再次生成一次編碼。
附圖說明
下面結(jié)合附圖對本發(fā)明的具體實施方式作進一步詳細的說明。
圖1是本發(fā)明系統(tǒng)壓縮和解壓縮技術原理的示意圖。
圖2是壓縮和解壓縮例程數(shù)據(jù)流示意圖。
圖3顯示了ivalue、value以及count的樣本數(shù)據(jù)結(jié)構(gòu)。
圖4顯示了針對圖3所示count數(shù)組數(shù)據(jù)而生成的編碼。
圖5顯示了針對圖3所示count數(shù)組數(shù)據(jù)而生成的編碼樹。
圖6是壓縮例程流程圖。
圖7-1和圖7-2是adapt例程流程圖。
圖8-1和圖8-2是dividecount例程流程圖。
圖9是outrun例程流程圖。
圖10是outvalue例程流程圖。
圖11是解壓縮例程流程圖。
圖12是getrun例程流程圖。
圖13是解碼例程流程圖。
具體實施方式
為了更清楚地說明本發(fā)明,下面結(jié)合優(yōu)選實施例對本發(fā)明做進一步的說明。本領域技術人員應當理解,下面所具體描述的內(nèi)容是說明性的而非限制性的,不應以此限制本發(fā)明的保護范圍。
實施例
圖1是本發(fā)明系統(tǒng)壓縮和解壓縮技術原理的示意圖。系統(tǒng)通過病人監(jiān)護儀110收集病患數(shù)據(jù)并在記錄儀112上進行數(shù)據(jù)的記錄。病人監(jiān)護儀110能夠收集多種病患信息,并能以每條通道每秒鐘約448字節(jié)的傳輸速度,向中央處理單元111提供12條信息傳輸處理通道。有效整體數(shù)據(jù)傳輸速率約為5.376千字節(jié)/秒。當中央處理單元111從病人監(jiān)護儀110處接收到字節(jié)數(shù)據(jù)信息時,其會將數(shù)據(jù)儲存在原始數(shù)據(jù)隨機存取存儲器113中。當數(shù)據(jù)“包”存儲在原始數(shù)據(jù)隨機存取存儲器113中之后,中央處理單元111發(fā)起存儲在壓縮軟件隨機存取存儲器116中的壓縮例程。在本發(fā)明的實施例中,數(shù)據(jù)包的大小由數(shù)據(jù)字節(jié)的多少預先確定。專業(yè)技術人員將會感受到本發(fā)明系統(tǒng)的這一好處,即數(shù)據(jù)包能夠以其它方式進行定義,例如通過預先定義好的時間間隔來收集獲取數(shù)據(jù)。壓縮例程從原始數(shù)據(jù)隨機存取存儲器113中檢索到數(shù)據(jù)包,進行壓縮并將數(shù)據(jù)儲存在壓縮數(shù)據(jù)隨機存取存儲器114中。壓縮數(shù)據(jù)隨機存取存儲器114可同時處理數(shù)個壓縮數(shù)據(jù)包。當中央處理單元111決定記錄讀寫某一數(shù)據(jù)包時,將會發(fā)起存儲在解壓縮程序隨機訪問內(nèi)存ram117中的解壓縮例程。
解壓縮例程在壓縮數(shù)據(jù)隨機存取存儲器114中檢索到壓縮數(shù)據(jù),并進行解壓縮,之后將其存儲在解壓數(shù)據(jù)隨機存取存儲器115中。中央處理單元111從解壓數(shù)據(jù)隨機存取存儲器115中檢索到已解壓數(shù)據(jù)并將數(shù)據(jù)寫入到記錄器112中。本發(fā)明的壓縮和解壓縮技術能夠用于其它系統(tǒng)實現(xiàn)中。例如,本發(fā)明的方法能夠用于進行與醫(yī)療數(shù)據(jù)無關的其它數(shù)據(jù)壓縮。此外,數(shù)據(jù)還可以在接收之時就進行壓縮,無需先存儲到原始數(shù)據(jù)隨機存取存儲器113中。同樣地,壓縮數(shù)據(jù)也可以直接在記錄器112中讀寫,無需先存儲到壓縮數(shù)據(jù)隨機存取存儲器114中。被記錄的數(shù)據(jù)可在完成處理之后再進行解壓縮。
在一個優(yōu)選實施方式中,壓縮系統(tǒng)將數(shù)據(jù)包中的數(shù)據(jù)(16位字)轉(zhuǎn)化為后綴有一系列“增量”的初始值。每個增量是數(shù)據(jù)包中兩個相鄰字之間的差異。如果生成了增量“運算”的指令,系統(tǒng)會將“運算”轉(zhuǎn)化為一個運算指示器,一個運算計數(shù),以及一個增量運算值?!斑\算”是一系列的相同數(shù)值的相鄰增量。對于病患數(shù)據(jù)而言,其大多數(shù)增量已被確定屬于-16到+16的范圍中,該范圍也就是所謂的編碼范圍。專業(yè)技術人員將會感受到本發(fā)明系統(tǒng)的這一好處,也就是編碼范圍能夠滿足不同類型的待壓縮數(shù)據(jù)的需求。本發(fā)明的方法能夠用于多種編碼范圍。系統(tǒng)通過采用哈夫曼編碼的改良型版本,也就是香農(nóng)-范諾編碼方法來對編碼范圍以及換碼符號進行編譯。系統(tǒng)從-16到+16,以及加上換碼符號,共編譯34個值。系統(tǒng)會跟蹤這34個編譯值在壓縮過程中相互遇見的頻率。在每個數(shù)據(jù)包壓縮之后(或者在數(shù)據(jù)包解壓縮之前),系統(tǒng)根據(jù)更新后的頻率數(shù)據(jù)生成了一種新的香農(nóng)-范諾編碼。因此,編碼能夠自適應于壓縮數(shù)據(jù)?!耙绯觥狈窃诰幋a范圍之外(也就是17)的數(shù)值,用來指示(1)后續(xù)數(shù)據(jù)不在編碼范圍之內(nèi),或者指示(2)某一“運行”已被編譯。如果數(shù)據(jù)不在編碼范圍內(nèi),那么表明該數(shù)據(jù)是8位的或者16位的。例如,如果增量為64,那么系統(tǒng)將產(chǎn)生如下位流(比特流):
"01001000000”
在本例中,換碼符號編譯為“01.”。二進制數(shù)字“0”在換碼符號之后,指示一個8位數(shù)值的開始。二進制數(shù)字“01000000”是十進制數(shù)字64的8位元表示。如果增量為512,那么系統(tǒng)將產(chǎn)生如下位流(比特流):
"01100000001000000000”
在本例中,換碼符號編譯為“01.”。二進制數(shù)字“10”在溢出符之后,指示一個16位數(shù)值的開始。二進制數(shù)字“0000001000000000”是十進制數(shù)字512的16位元表示。一個運算則被編譯為換碼符號、運算計數(shù)以及運算增量。例如,一個由10個等于5的增量組成的運算,系統(tǒng)會產(chǎn)生以下位流:
“01111111101001110110”
在本例中,換碼符號編譯為“01.”。二進制數(shù)字“11”在換碼符號之后,指示一個運行編碼。其中位數(shù)“111110100”是指計數(shù)為10的一個運算。位數(shù)“1110110”則是指運算增量為5。同樣地,如果運算計數(shù)或者運算增量沒有在編碼范圍內(nèi),系統(tǒng)將會為運算計數(shù)與運算增量編譯相應的換碼符號。例如,一個由32個等于5的增量組成的運算,系統(tǒng)會產(chǎn)生以下位流:
"0111010001000001110110”
在本例中,換碼符號編譯為“4)1”。位數(shù)“11”緊接換碼符號,指示后續(xù)運算編碼。之后的位數(shù)“01”代表換碼符號,表示運算計數(shù)不在編碼范圍內(nèi)。此換碼符號后的“0”是指,在其之后的本運算計數(shù)系一個8位元數(shù)值。其中位數(shù)“00100000”是指計數(shù)為32的一個運算。位數(shù)則是指運算增量為5。如果運算增量不再編碼范圍內(nèi),那么它也會被編譯有一個換碼符號。
系統(tǒng)將根據(jù)運算增量值與最小可能運算長度來決定何時編譯運算。如果運算增量不在編碼范圍內(nèi),那么系統(tǒng)將會對運算進行編碼。如果最小可能運算編碼長度小于運算計數(shù)與編譯運算增量值所需位數(shù)的乘積,那么系統(tǒng)將會對運算進行編譯。最小運算編碼長度等于換碼符號加2(用來指示運算的字位)加上2,再乘以最短編碼的長度。專業(yè)技術人員將會感受到本發(fā)明系統(tǒng)的這一好處,也就是能夠根據(jù)其它因素來決定是否對運算進行編碼。在本發(fā)明的實施例中,一個運算被定義有兩個或者多個增量,因此相應運算計數(shù)被編譯為實際運算計數(shù)減去2。同樣地,可通過將特定運算長度表示為負值的方法來對最長可達35位的運算進行編譯。
壓縮例程通過遞歸算法的香農(nóng)-范諾編碼方法來生成34個字符的編碼。在本發(fā)明的首選表現(xiàn)方案中,相關方法是通過一種迭代算法來實現(xiàn)的,詳盡描述如下文所示。例程開始于一個待編譯全部符號頻率計數(shù)的分類數(shù)組。本發(fā)明中的該步驟編碼方法將會計算總頻率數(shù)。然后從最頻繁的符號處開始,對數(shù)組中的頻率進行求和,直到和數(shù)達到總數(shù)的一半。之后將符號劃分為兩組。第一組為上述求和過程中使用到的符號,第二組為除第一組符號以外的其它符號。第一組中的符號被分派指定一個值為“0”的字位,第二組中的符號則被分派指定一個值為“1”的字位。本發(fā)明中的該步驟編碼方法將遞歸地運用該種算法來生成編碼。表1展示了一個由采用了香農(nóng)-范諾編碼的混雜式c編程語言編寫的遞歸例程。當例程完成,“字位模式”(bitpatten)數(shù)組中會包含有每個編碼值的編碼模式,并且“規(guī)?!?size)數(shù)組中會包含有相應字位模式(bitpatten)的長度。例程輸入一個針對“計數(shù)”(count)數(shù)組中每個編譯值的頻率計數(shù)分類數(shù)組。當初次發(fā)起時,變量“起始”(start)與“結(jié)束”(end)劃定了“計數(shù)”(count)數(shù)組的起始與終止處,變量“總計”(total)則含有頻率的總數(shù),變量“字位大小”(bitsize)以及變量“字位”(bits)設為0。例程將遞歸地根據(jù)條目的總和來劃分數(shù)組,并對變量“字位”(bits)進行設定,以表明相應編碼。當“count“數(shù)組被進一步細分為包含有1個條目(起始==結(jié)束)時,例程將“size”數(shù)組的【start】條目設為等于變量“bitsize”并將數(shù)組“bitpattem”的【start】條目設為等于變量“字位”(bits)。
表1
霍夫曼編碼的主要特點是,即便每個符號的字位數(shù)目不盡相同,也不需要在符號之間進行界定。該編碼方式能夠確保,較短編碼中所使用的字位模式將不會以較長編碼中字位模式之起始的形式出現(xiàn)。
解壓縮系統(tǒng)通過采用與建立編碼時所使用的相同頻率計數(shù)值,建立一個二叉樹。在本發(fā)明的首選表現(xiàn)方案中,香農(nóng)-范諾編碼方法也被用于建立二叉樹,當進行解壓縮時,該方法將會創(chuàng)建二叉樹上的節(jié)點,而非是創(chuàng)建字位。二叉樹的形成將在下文進行詳盡的描述。為了解碼,系統(tǒng)輸入被壓縮數(shù)據(jù)的位流。在“0”字位上,例程跟隨二叉樹上的分支節(jié)點“0”,在“1”字位上,例程跟隨二叉樹上的分支節(jié)點“1”。如達到了葉節(jié)點,那么節(jié)點中則包含有相應的被解碼數(shù)值,否則例程將輸入下一個字位并通過二叉樹繼續(xù)執(zhí)行。當34個符號被編譯后,二叉樹將包含有34個葉節(jié)點,以及33個非葉節(jié)點。在本發(fā)明的實施例中,一個字節(jié)表示一個節(jié)點。因此,解碼二叉樹中的長度為67個字節(jié)。二叉樹通過一個長度為67的數(shù)組來進行表示。每個節(jié)點(或者數(shù)組中的字節(jié))包含有是否該節(jié)點為葉節(jié)點的指示器。如果節(jié)點為葉節(jié)點,那么它將含有相應的解碼數(shù)值。如果節(jié)點不是葉節(jié)點,那么它將含有指向分支節(jié)點“1”的相應偏移值。分支“0”處的節(jié)點被保存在二叉樹的下一個字節(jié)中。
盡管該編碼方法是自適應的,但它仍需要從首個數(shù)據(jù)包編碼的默認頻率值開始執(zhí)行。在本發(fā)明的實施例中,通過生成數(shù)個數(shù)據(jù)包的頻率來獲得默認頻率值。
在一個優(yōu)選實施方式中,頻率計數(shù)只是進行了部分分類,而不是完全分類。頻率計數(shù)是通過建立一條穿過頻率計數(shù)數(shù)組的通路,并在第二條目大于第一條目時交換相鄰條目來實現(xiàn)部分分類的。該種部分分類減緩了自適應過程。一般而言,默認頻率值相對于初始數(shù)據(jù)包的數(shù)據(jù)頻率而言,具有更富代表性的頻率特點。因此,在最初的少數(shù)幾個數(shù)據(jù)包處理過程中,部分分類更能夠反映出默認頻率的更具代表性的頻率特征。
圖2是壓縮和解壓縮例程數(shù)據(jù)流示意圖?!皦嚎s202”例程將數(shù)組“源201”中的數(shù)據(jù)進行壓縮,并生成數(shù)組“壓縮源203”?!敖鈮嚎s204”例程將“壓縮源203”進行壓縮,并生成“解壓縮源205”。因為本發(fā)明中的壓縮方法為無損壓縮方法,數(shù)組“解壓縮源205”中含有與數(shù)組“源201”中相同的數(shù)據(jù)。數(shù)組“計數(shù)206”以及“計數(shù)207”則分別包含有“壓縮202”例程以及“解壓縮204”例程的頻率計數(shù)值。在每次壓縮之后,“壓縮202”例程會更新數(shù)組“計數(shù)206”中的頻率值。相似地,在每次解壓縮之后,“壓縮204”例程會更新數(shù)組“count207”中的頻率值。在最開始,數(shù)組“計數(shù)206”以及數(shù)組“count207”中包含有相同的默認頻率值。在數(shù)據(jù)包被壓縮又被解壓之后,數(shù)組“count206”與數(shù)組“count207”中所包含的數(shù)據(jù)也是完全相同的。
圖3、4、5顯示了在樣本數(shù)據(jù)值壓縮和解壓縮例程中所采用的數(shù)據(jù)結(jié)構(gòu)。圖3顯示了ivalue301、value302,以及count303的樣本數(shù)據(jù)結(jié)構(gòu)。數(shù)組“count303”中包含有編碼范圍以內(nèi)的,以及包括換碼符號在內(nèi)的每個符號的頻率計數(shù)值。數(shù)組“value302”包含有每個已編譯符號的數(shù)值。在數(shù)組“count303”與數(shù)組“value302”之間存在著一一對應的數(shù)據(jù)關系。例如,數(shù)組“value”中的第5條目是符號3。數(shù)組“count”中第5條目是10197,這說明符號3的頻率計數(shù)為10197。數(shù)組“ivalue301”包含有來自于已編譯符號并指向“value”數(shù)組以及“count”數(shù)組中相應條目的映射。例如,數(shù)組ivalue【16+3】條目包含有a4,a4就是指向包含有符號3頻率計數(shù)的“count”數(shù)組的指針。因此,符號3的頻率就在“count”數(shù)組的【ivalue【16-f3】】條目中。當“ivalue”數(shù)組的索引位于0-33范圍之內(nèi)時,符號增加16。圖4顯示了針對count303所示計數(shù)數(shù)組數(shù)據(jù)而生成的編碼。數(shù)組“bitpattem401”包含有針對每個已編譯符號的相應編碼。數(shù)組“size402”則包含有數(shù)組“bitpattem”中相應編碼的長度。例如,正如數(shù)組“規(guī)?!睏l目【4】所顯示的數(shù)值那樣,數(shù)組“bitpattem”的第5條目“1100”其長度為4,在本發(fā)明的首選表現(xiàn)方案中,數(shù)組“bitpattem”所含條目長度為16位,這也就將最大編碼長度限制在16位上。數(shù)組“字位模式”的【ivalue【16+3】】條目包含有符號3的字位模式。圖5顯示了針對數(shù)組“count303”中的數(shù)據(jù)而生成的解碼二叉樹數(shù)組“二叉樹501”包含有67個單字節(jié)的條目,該解碼二叉樹中每個節(jié)點對應一個字節(jié)。每個節(jié)點包含有能夠指示該節(jié)點是否為葉節(jié)點的狀態(tài)標志。如果節(jié)點為葉節(jié)點,那么該節(jié)點則含有該葉節(jié)點的符號數(shù)值。如果節(jié)點非為葉節(jié)點,那么該節(jié)點則含有指向分支節(jié)點“1”的偏移量。分支節(jié)點“0”是數(shù)組“二叉樹”中的緊隨條目。為了將位流“1100”解碼為符號3,系統(tǒng)將按照以下步驟進行處理。系統(tǒng)從數(shù)組“二叉樹”索引為“0”的條目,也就是二叉樹的根節(jié)點開始執(zhí)行。當遇見首個字位“1”時,系統(tǒng)會通過對數(shù)組“二叉樹”的當前位置加上數(shù)組“二叉樹”條目【0】偏移值來對分支“1”進行跟蹤。
這會將當前位置重置到“二叉樹”條目【4】處。由于數(shù)組“二叉樹”條目【4】不是葉節(jié)點,因此系統(tǒng)輸入下一個字位,也就是字位“1”。系統(tǒng)通過對數(shù)組“二叉樹”的當前位置加上數(shù)組“二叉樹”條目【4】偏移值來對分支“1”進行跟蹤。這會將當前位置重置到“二叉樹”條目【8】處。由于數(shù)組“二叉樹”的條目【8】不是葉節(jié)點,因此系統(tǒng)會輸入下一個字位,也就是“0”。系統(tǒng)通過在數(shù)組“二叉樹”的當前位置上加1來跟隨分支節(jié)點“0”。這會將當前位置重置到“二叉樹”條目【9】處。由于數(shù)組“二叉樹”的條目【9】不是葉節(jié)點,因此系統(tǒng)會輸入下一個字位,也就是“0”。系統(tǒng)通過在數(shù)組“二叉樹”的當前位置上加1來跟隨分支節(jié)點“0”。這會將當前位置重置到“二叉樹”條目【10】處。由于數(shù)組“二叉樹”的條目【10】是葉節(jié)點,因此系統(tǒng)將會檢索恢復條目【10】的數(shù)值,也就是3。因此,字位“1100”就完成了對符號3的編碼。
圖6是壓縮例程流程圖。“壓縮”例程輸入原數(shù)據(jù)并輸出壓縮后的原數(shù)據(jù)。輸入到“壓縮”例程中的參數(shù)分別為“源”數(shù)組、“計數(shù)”count,以及“數(shù)組”value。例程返回至“destination”數(shù)組、“計數(shù)”count,以及“數(shù)組”value?!皦嚎s”例程首先通過發(fā)起能夠?qū)⒕幋a儲存在“bitpattem”以及“size”數(shù)組中的“adapt”例程來生成相應編碼。之后,“壓縮”例程在首次發(fā)起進程時將“count”數(shù)組設為零。清空默認頻率計數(shù),并初始化實際頻率計數(shù)數(shù)組。隨后,“壓縮”例程計算增量值,并通過使用“bitpattem”數(shù)組中的編碼、運算編碼,并對位于編碼范圍之外的增量值進行編碼,來儲存壓縮后的數(shù)據(jù)。在框601中,例程調(diào)用“adapt”例程來針對壓縮生成自適應性編碼,并將返回至“size”以及“bitpattem”數(shù)組。在框602中,如果“首次使用”狀態(tài)標志為“真”,那么意味著這是第一次調(diào)用“壓縮”例程且例程將會在框603中繼續(xù)執(zhí)行,否則例程將會在框604中繼續(xù)執(zhí)行。在框603中,例程初始化“count”數(shù)組的條目,并將“首次使用”狀態(tài)標志設定為“假”。當?shù)谝淮伟l(fā)起“adapt”例程時,“count”數(shù)組的值將被設定為默認頻率計數(shù)。隨后,“壓縮”例程將“count”數(shù)組的值設定為實際頻率計數(shù),來影響自適應性。在框604中,例程將變量“minrunsize”設定為等于2加上溢出字位的大小再加上2,乘以最小字位模式的長度。這就是已編譯運算的最小字位長度。在框605到塊613中,例程循環(huán)并處理“源”數(shù)組中的每個條目。例程計算增量值并向“destination”數(shù)組輸出編碼。在框605中,例程對在“源”數(shù)組中循環(huán)并向“destination”數(shù)組輸出初始數(shù)據(jù)的相關變量進行初始化。例程將變量“runcount”設定為0,將“destination”數(shù)組中的【1】條目設為“源”數(shù)組中的【0】條目,并將變量“l(fā)astdelta”設為等于“源”數(shù)組中的【0】條目減去“destination”數(shù)組中的【1】條目。變量lastdelta包含有當前與先前“源”數(shù)組條目之間的差異。在框606中,如果“源”數(shù)組中的全部數(shù)據(jù)都已被處理過,那么例程將在框609中繼續(xù)執(zhí)行,以向“destination”數(shù)組輸出最后編譯的數(shù)據(jù),否則例程將在框607中繼續(xù)執(zhí)行。在框607中,例程將變量“nextdelta”設定為當前與后續(xù)“源”數(shù)組條目之間的差異。如果變量“nextdelta”等于變量“l(fā)astdelta”,那么系統(tǒng)將發(fā)起一個運算,同時例程將會在框608中繼續(xù)執(zhí)行,否則例程將在框609中繼續(xù)執(zhí)行。在框608中,例程增加一個“runcount”變量并循環(huán)至框606中。在框609中,如果變量“runcount”等于0,那么意味著不存在任何運算,且例程將在框611中繼續(xù)執(zhí)行,否則例程會在框610中繼續(xù)執(zhí)行。在框610中,例程發(fā)起“outrun”例程以向“destination”數(shù)組中輸出運算數(shù)據(jù)。在框611中,例程在變量lastdelta發(fā)起“outvalue”例程以向“destination”數(shù)組中輸出運算數(shù)據(jù)。在框612中,如果“源”數(shù)組中的數(shù)據(jù)已被全部處理過,那么壓縮過程完成、例程返回,否則例程將在框613中繼續(xù)執(zhí)行。在框613中,例程將變量“runcount”重置為0,將變量“l(fā)astdelta”設置為變量“nextdelta”,前進到“源”數(shù)組的下一個條目上,并循環(huán)至塊606中以處理下一個增量值。
圖7-1和圖7-2是adapt例程流程圖。在本發(fā)明的實施例中,編碼以及解碼數(shù)據(jù)的生成是在相同的例程中完成的。在壓縮數(shù)據(jù)時,“adapt”例程根據(jù)“count”數(shù)組為相應數(shù)據(jù)生成編碼,并將編碼信息儲存在“bitpattem”數(shù)組以及“size”數(shù)組中。在解壓縮數(shù)據(jù)時,“adapt”例程根據(jù)“count”和value數(shù)組為相應數(shù)據(jù)生成編碼,并將編碼信息儲存在數(shù)組樹中?!癮dapt”例程的輸入?yún)?shù)分別是“count”數(shù)組、“value”數(shù)組以及指示壓縮或者解壓縮的狀態(tài)標志。當壓縮數(shù)據(jù)時,例程將返回“bitpattem”數(shù)組以及“size”數(shù)組。當解壓縮時,例程將返回“二叉樹”數(shù)組?!癮dapt”例程是上述遞歸例程在壓縮時的一種迭代實現(xiàn)。例程通過采用棧的方式來實現(xiàn)例程的遞歸性。在可選擇的實施方案中,adapt程序作為直接插入碼在壓縮程序中執(zhí)行。緊接著,當出棧時,出棧的數(shù)據(jù)保存在結(jié)構(gòu)stack中。同樣的,當入棧時,來自結(jié)構(gòu)stack的數(shù)據(jù)存入棧中。數(shù)據(jù)結(jié)構(gòu)stack中包含有各種要素:變量start(開始)、end(末尾)、total(總數(shù))、bitsize(位大小)和n,下文有詳細說明。與“1”分支有關的信息推進棧中。在對應的“0”分支處理完后,信息再從棧中彈出。在框701中,程序?qū)ount數(shù)組進行部分排序。程序?qū)Ρ萩ount數(shù)組,如一個條目小于后續(xù)的條目,則相互交換。如此,程序完成count數(shù)組排序。程序還交換value數(shù)組中的項,以便保持數(shù)組間的一致。在框702中,程序初始化ivalue數(shù)組。ivalue數(shù)組包含有編碼符號與count數(shù)組和value數(shù)組中對應項索引的映射。-因此,數(shù)組條目count【ivalue【16+escape】】包含有換碼符號的頻率計數(shù)。在框703中,程序設置對應count數(shù)組中所有項之和的變量total(總數(shù))。在優(yōu)選的實施方案中,當變量total大于26000時,為防止溢出,程序?qū)ount數(shù)組中所有的計數(shù)分成兩組,然后重新計算總數(shù)。在框704中,程序?qū)⒆兞縮tart、n、bits和bitsize初始化為0,變量end初始化為33,escapeencoded標志設定為false。變量start和end是count數(shù)組的索引;變量bitsize包括編碼字位模式的大小;變量bits包括有編碼字位模式;變量n是樹數(shù)組的索引;escapeencoded標志表明換碼字符何時已被編碼。從框705到721,程序根據(jù)輸入的參數(shù),循環(huán)進行編碼或解碼。在框705到706中,程序循環(huán)調(diào)用dividecount程序。
dividecount程序的詳細說明見下文。dividecount程序返回變量start和end來限定“0”分支,與“1”分支有關的數(shù)據(jù)進棧。在框705中,如果變量start等于變量end,則識別編碼的葉,從框707繼續(xù),否則程序從706繼續(xù)。在框706中,程序調(diào)用dividecount程序,并循環(huán)返回框705。在框707中,如果變量bitsize大于16,那么程序?qū)目?11繼續(xù),否則程序從框708繼續(xù)。因為bitpattern數(shù)組為16位,超過16位的編碼作為轉(zhuǎn)碼編碼壓縮和處理。在框708中,如果是壓縮處理,那么程序從框709繼續(xù),否則從框710繼續(xù)???09中,程序設定數(shù)組條目value【start】中符號的編碼字位模式。程序設置數(shù)組條目size【start】等于變量bitsize,并設置數(shù)組條目bitpattern【start】等于變量bits。在框710中,程序設置數(shù)組項tree【n】等于數(shù)組條目value【start】,表明為葉結(jié)點,增加變量n,為數(shù)組tree的下一條目加索引。在框711中,如果是壓縮處理,那么程序從框712繼續(xù),否則從框713繼續(xù)???12中,程序設置數(shù)組條目size【start】等于0,表明對應條目的delta值未編碼。-在框713中,程序設置數(shù)組項tree【n】,表明無編碼和葉結(jié)點,增加變量n,為數(shù)組tree的下一條目加索引。在框714中,如果數(shù)組條目value【start】等于換碼符號,那么程序設置變量escapeencoded為true。變量escapeencoded負責跟蹤換碼符號是否已經(jīng)被編碼。換碼符號必須編碼。程序設置換碼符號的頻率計數(shù),以便確保其編碼不大于16位,并已編碼完畢。在框716中,如果堆棧為空,程序?qū)目?22繼續(xù),否則程序?qū)目?17繼續(xù),在框717中,程序?qū)棾龆褩?。在?18中,如果是壓縮處理,那么程序從框719繼續(xù),否則從框721繼續(xù)。在框719中,程序根據(jù)出棧值設置變量start、end、total、和bitsize的值。在框720中,程序用1左移(16減去變量bitsize次數(shù))位對變量bits進行按位“或”操作,這將設置變量bits中的一個位來表明為“1”編碼,并循環(huán)返回框705。在框722中,如果變量escapeencoded等于true,那么程序返回,否則程序從框723繼續(xù)。換碼字符必須編碼。在框723中,程序設置數(shù)組條目countivalue【16+escape】】為高頻率,以便換碼符號將被編碼,然后程序循環(huán)返回,重新開始adapt程序。
圖8-1和圖8-2是dividecount例程流程圖。dividecount程序基于條目的總數(shù),將count數(shù)組分為從以變量start為索引的項,到以變量end為索引的條目。dividecount程序重置變量end以便界定“0”分支,并將數(shù)據(jù)入棧來界定“1”分支。在框801中,程序增加bitsize的值,bitsize包括有編碼字位模式的大小。在框802中,如果變量bitsize大于16,那么程序從框814繼續(xù),否則程序從框803繼續(xù)。如上所述,如果編碼位大小大于16,那么對應的符號未編碼。從框803到807,程序?qū)ount數(shù)組中,從變量start指明的條目開始的項相加,直到總和接近變量total的一半,變量total包括有count數(shù)組中從變量start指明的條目到變量end指明的項之間各條目的總和。在框803中,程度將索引i初始化為變量start的值,變量a設置為0。索引i步進通過count數(shù)組,變量a包括有count數(shù)組中從變量start指明的條目開始到索引i指明的條目之間各項的總和。在框804中,如果索引i小于變量end,且變量a乘2加數(shù)組條目count【i】小于變量total,那么說明程序的步驟并非在所有項的中間計數(shù)點,程序從框805繼續(xù),否則程序從框806繼續(xù)。在框805中,程序?qū)?shù)組條目count【i】與變量a相加,索引i加1,循環(huán)到框804。在框806和807中,程序確保變量a的設置和索引i增加。在框806中,如果索引i等于變量start,那么程序?qū)目?07繼續(xù),否則程序從框808繼續(xù)。在框807中,程序設置變量a等于count【i】,索引i加1。在框808中,程序設置了結(jié)構(gòu)stack中的變量。程度設置stack。start等于索引i,stack。end等于變量end,stack。total等于變量total減去變量a,以及stack。bitsize等于變量bitsize。結(jié)構(gòu)stack中包含處理“1”分支的數(shù)據(jù)。在框809中,程序設置變量total等于變量a,索引i的變量end減去1.變量start、end、total、和bitsize包含處理“0”分支的數(shù)據(jù)。在框810中,如果是壓縮處理,那么程序從框811繼續(xù),否則從框812繼續(xù)。在框811中,程序用1的補碼左移(16減去變量bitsize)位對變量bits進行按位“與”操作,這將設置bits中的位為0,表明為“0”編碼。在框812中,程序設置stack.n等于變量n,變量n加1,再加1。變量n的增加為tree數(shù)組增加了一個節(jié)點。stack.n設定跟蹤“1”分支,以便“1”分支的節(jié)點增加時,為當前的節(jié)點增加偏移量。在框813中,程序?qū)?shù)據(jù)送入棧中并返回。在框814中,如果是壓縮處理,那么程序從框815繼續(xù),否則從框817繼續(xù)。在框815和816中,由于字位模式將大于16,程序?qū)ize數(shù)組中介于變量start和end索引之間的項清零。count數(shù)組數(shù)值為0時表明無對應符號的編碼。在框815中,如果變量end大于變量start,那么程序從框816繼續(xù),否則完成清零,程序返回。在框816中,程序設置數(shù)組條目size[end]等于0,變量end加1,循環(huán)返回框815。在框817中,由于字位模式將大于16,因此程度設置變量end等于變量start并返回。
圖9是outrun例程流程圖。outrun程序接收一個rundelta(行程delta)值、run計數(shù)、輸出編碼run數(shù)據(jù),存入數(shù)組destination。在框901中,如果變量lastdelta的絕對值大于16,或數(shù)組項size【ivalue【16+lastdelta】】乘以變量runcount大于變量minrunsize,那么run(行程)就作為run編碼,程序從框905繼續(xù),否則程序從框902繼續(xù)。從框902到904,程序輸出變量lastdelta到destination,次數(shù)由變量runcount指明???02中,如果變量runcount等于0,則輸出完成,程序返回,否則程序從框903繼續(xù)。
在框903中,程序調(diào)用outvalue程序來輸出變量lastdelta的值。在框904中,例程減少一個“runcount”變量并循環(huán)至框902中。在框905中,程序?qū)?shù)組條目bitpattem【ivalue【16-escape】】輸出到數(shù)組destination,此項中包含有換碼符號的編碼。在框906中,程序增加數(shù)組條目count【ivalue【16+escape】】的值,以便跟蹤換碼符號的使用頻率。在框907中,程序輸出“11”,表示是一個編碼run。在框908中,程序調(diào)用outvalue程序輸出變量runcount減2,此值為run的長度(行程長度)。在框909中程序調(diào)用outvalue程序輸出變量lastdelta,此值為rundelta值,然后程序返回。
圖10是outvalue例程流程圖。程序outvalue接收值,然后輸出編碼值到數(shù)組destination。在框1001中,如果變量value的絕對值大于16,那么此值無法編碼,程序從框1005繼續(xù),否則程序從框1002繼續(xù)。在框1002中,如果數(shù)組條目sizefiva-lue【16+value】】大于0,那么此值可以編碼,程序從框1003繼續(xù),否則程序從框1005繼續(xù)。在框1003中,程序?qū)?shù)組條目bitpattem【ivalue【16+value】】輸出到數(shù)組destination,其包含變量value中的編碼值。在框1004中,程序增加數(shù)組條目count【ivalue【16+-value】】的值,以便跟蹤增值數(shù)值的頻率和程序的返回。從框1005到1011中,程序輸出范圍在—16到+16之外的值。在框1005中,程序?qū)?shù)組條目bitpattem【ivalue【16+escape】】輸出到數(shù)組destination,此項中包含有換碼符號的編碼。在框1006中,程序增加數(shù)組條目count-【ivalue【16+escape】】的值,以便跟蹤換碼符號的使用頻率。在框1007中,如果變量value大于127或小于—128,那么value不適合8位,程序從框1008繼續(xù),否則程序從框1010繼續(xù)。在框1008中,程序輸出“10”來表明后續(xù)的16位包含有數(shù)值。在框1009中,程序輸出16位的變量value,然后返回。在框1010中,程序輸出“0”來表明后續(xù)的8位包含有數(shù)值。在框1011中,程序輸出8位的變量value,然后返回。
圖11是解壓縮例程流程圖?!敖鈮嚎s”例程輸入壓縮源數(shù)據(jù)并輸出壓縮后的原數(shù)據(jù)。輸入到“解壓縮”例程中的參數(shù)分別為“源”數(shù)組、“計數(shù)”count,以及“數(shù)組”value。例程返回至“destination”數(shù)組、“數(shù)組”count,以及“數(shù)組”value。解壓縮程序首先通過調(diào)用adapt程序來產(chǎn)生一個解碼樹,解碼樹保存在tree數(shù)組中。之后,“解壓縮”例程在首次發(fā)起進程時將“count”數(shù)組設為零。清空默認頻率計數(shù),并初始化實際頻率計數(shù)數(shù)組。解壓縮程序調(diào)用getrun程序取回下一個數(shù)據(jù),getrun程序返回一個delta值和一個run計數(shù)。然后解壓縮程序使用delta值建立destination數(shù)組項。在框1101中,程序調(diào)用adapt程序來生成解碼樹,adapt程序返回tree數(shù)組。在框1102中,如果是壓縮處理,那么程序從框1103繼續(xù),否則從框1104繼續(xù)。在框1103中,程序?qū)?shù)組count中的每一項設置為0,如上文compress程序的說明。在框1104中,程序設置數(shù)組條目destination【0】等于數(shù)組項sourcefl],設定初始值。程序還將索引i設置為0。索引i為destination數(shù)組的索引。在框1105中,如果數(shù)組source中所有的數(shù)據(jù)都已被處理,那么程序返回,否則程序從框1106繼續(xù)。在框1106中,程序調(diào)用getrun程序,取得下一個delta值和run計數(shù)。從框1107到1110,程序循環(huán)解壓縮run中的數(shù)據(jù)。在框1107中,如果變量“runcount”等于0,那么意味著運算得到解壓縮,且例程將在框1105中繼續(xù)執(zhí)行,否則例程會在框1108中繼續(xù)執(zhí)行。在框1108中,程序增加索引i的值。在框1109中,程序設置數(shù)組條目destina-tion【i】等于數(shù)組項destination【—1】減去delta的值,來解壓縮數(shù)據(jù)。在框1110中,變量runcount減1,循環(huán)返回1107來確定是否所有的壓縮數(shù)據(jù)已被解壓縮。
圖12是getrun例程流程圖。getrun程序解碼delta值(或下一個delta值)的下一個run,并返回delta值和run計數(shù)。在框1201中,程序調(diào)用decode程序,decode程序返回來自source數(shù)組的下一個解碼值。在框1202中,例行程序?qū)⒆兞縭uncount設置為1。在框1203至1207中,例行程序識別并解碼8位和16位增量值。在框1203中,如果變量value是換碼符號,則例行程序在框1204繼續(xù),否則變量value包含增量值,并且例行程序返回。-在框1204中,如果數(shù)組source中的下一位是0,則8位增量值被編碼,并且例行程序在框1205繼續(xù),否則例行程序在框1206繼續(xù)。在框1205中,例行程序?qū)⒆兞縱alue設置為數(shù)組source中的下一個8位,并且例行程序返回。在框1206中,如果數(shù)組source中的下一個位是0,則編碼16位增量值,并且例行程序在框1207繼續(xù),否則運行被編碼并且例行程序在框1208繼續(xù)。在框1207中,例行程序?qū)⒆兞縱alue設置為數(shù)組source中的下一個16位,并且例行程序返回。在框1208中,例行程序調(diào)用例行程序解碼運行計數(shù)。在框1209中,如果例行程序decode返回值是換碼符號,則運行計數(shù)以8位或16位編碼,并且例行程序在框1210中繼續(xù),否則運行計數(shù)不被編碼,并且例行程序在框1213中繼續(xù)。解碼運行計數(shù)加了2以指示實際游程。在框1210中,如果數(shù)組source中的下一個位是0,則運行數(shù)值以8位進行增量,并且例行程序在框1212繼續(xù),否則運行以16位被編碼并且例行程序在框1211繼續(xù)。在框1211中,例行程序?qū)⒆兞縭uncount設置為數(shù)組source中的下一個16位。在框1212中,例行程序?qū)⒆兞縭uncount設置為數(shù)組source中的下一個8位。在框1213中,例行程序調(diào)用例行程序decode來解碼運行值。在框1214中,如果例行程序decode返回值是換碼符號,則運行計數(shù)以8位或16位編碼,并且例行程序在框1215中繼續(xù),否則運行計數(shù)不被編碼,并且例行程序返回。在框1215中,如果數(shù)組source中的下一個位是0,則運行數(shù)值以8位進行解碼,并且例行程序在框1217繼續(xù),否則運行數(shù)值以16位被編碼并且例行程序在框1216繼續(xù)。在框1216中,例行程序?qū)⒆兞縱alue設置為數(shù)組source中的下一個16位,并且程序返回。在框1217中,例行程序?qū)⒆兞縱alue設置為數(shù)組source中的下一個8位,并且例行程序返回。
圖13是解碼例程流程圖。例行程序解碼使用數(shù)組樹在數(shù)組source中為下一個編碼符號返回符號值。在框1301到1306中,例行程序在數(shù)組樹中搜索葉節(jié)點。在框1301中,例程設置索引pto0;索引p指示數(shù)組樹。在框1302中,例行程序從數(shù)組“源”獲得下一位。在框1303中,如果該位是1,則指示“1”分支,并且例行程序在框1304繼續(xù),否則指示“0”分支,并且例行程序在框1305繼續(xù)。在框1304中,例行程序添加數(shù)組入口樹【p】。偏移到索引p跟隨“1”分支。在框1305中,例行程序?qū)⑺饕齪遞增為跟隨“0”分支。在框1306中,如果數(shù)組入口樹【p】是葉,則該值被解碼,并且例行程序在框1307繼續(xù),否則例行程序循環(huán)到框1302以獲得下一位。在框1307中,例程將變量value設置為數(shù)組入口樹【p】。數(shù)值。在框1308中,例行程序增量數(shù)組條目count【ivalue【16+值】】跟蹤增量值頻率,并且例行程序返回。
顯然,本發(fā)明的上述實施例僅僅是為清楚地說明本發(fā)明所作的舉例,而并非是對本發(fā)明的實施方式的限定,對于所屬領域的普通技術人員來說,在上述說明的基礎上還可以做出其它不同形式的變化或變動,這里無法對所有的實施方式予以窮舉,凡是屬于本發(fā)明的技術方案所引伸出的顯而易見的變化或變動仍處于本發(fā)明的保護范圍之列。