Bzip2 använder flera lager av komprimeringstekniker staplade ovanpå varandra, som förekommer i följande ordning under komprimering och omvänd ordning under dekompression:
- Körlängdskodning (RLE) av initialdata.
- Burrows – Wheeler transform (BWT), eller block sortering.
- Move-to-front (MTF) transform.
- Körningslängdskodning (RLE) för MTF-resultat.
- Huffman-kodning.
- Val mellan flera Huffman-tabeller.
- Unary bas-1-kodning för val av Huffman-tabell.
- Delta-kodning (Δ) av Huffman-kodbitlängder.
- Sparsam bitmatris som visar vilka symboler som används.
Initial körningslängdskodning Redigera
Varje sekvens med 4 till 255 på varandra följande duplikatsymboler ersätts av de första 4 symbolerna och en repeteringslängd mellan 0 och 251. Således följer sekvensen AAAAAAABBBBCCCD
ersätts med AAAA\3BBBB\0CCCD
, där \3
och \0
representerar bytevärdena 3 respektive 0. Kör av symboler omvandlas alltid efter fyra på varandra följande symboler, även om körningslängden är inställd på noll, för att hålla transformationen reversibel.
I värsta fall kan det orsaka en expansion på 1,25 och i i bästa fall en minskning till < 0,02. Medan specifikationen teoretiskt möjliggör kodning av körningar med längden 256–259, kommer inte referenskodaren att producera sådan utdata. för att skydda den ursprungliga BWT-implementeringen från patologiska fall.
Burrows – Wheeler transformEdit
Detta är den reversibla blocksorten som är kärnan i bzip2. Blocket är helt fristående, med in- och utgångsbuffertar kvar av samma storlek – i bzip2 är driftsgränsen för detta steg 900 kB. För blocksorteringen skapas en (teoretisk) matris, i vilken rad i innehåller hela bufferten, roterad för att börja från i-th-symbolen. Efter rotation sorteras raderna i matrisen i alfabetisk (numerisk) ordning. En 24-bitars pekare lagras som markerar startpositionen för när blocket inte transformeras. I praktiken är det inte nödvändigt att konstruera hela matrisen; snarare utförs sorteringen med hjälp av pekare för varje position i bufferten. Utmatningsbufferten är den sista kolumnen i matrisen; detta innehåller hela bufferten, men omordnas så att det sannolikt kommer att innehålla stora körningar av identiska symboler.
Flytta till front transformEdit
Återigen ändrar inte transformationen storleken på det bearbetade blocket. Var och en av symbolerna som används i dokumentet placeras i en matris. När en symbol bearbetas ersätts den med dess plats (index) i matrisen och den symbolen blandas fram till matrisen. Effekten är att omedelbart återkommande symboler ersätts med nollsymboler (långa körningar av vilken godtycklig symbol som helst blir körningar med nollsymboler), medan andra symboler ombildas enligt deras lokala frekvens.
Mycket ”naturliga” data innehåller identiska symboler som återkommer inom ett begränsat intervall (text är ett bra exempel). Eftersom MTF-transformen tilldelar låga värden till symboler som återkommer ofta, resulterar detta i en dataström som innehåller många symboler i det låga heltalsområdet, varav många är identiska (olika återkommande ingångssymboler kan faktiskt mappas till samma utgångssymbol). Sådana data kan kodas mycket effektivt med vilken äldre komprimeringsmetod som helst.
Kodning av körningslängd för MTF resultEdit
Långa strängar av nollor i utgången från omvandling till framåt-fram ( som kommer från upprepade symboler i utgången från BWT) ersätts av en sekvens av två specialkoder, RUNA och RUNB, som representerar körlängden som ett binärt tal. Faktiska nollor kodas aldrig i utgången; en ensam noll blir RUNA. (Detta steg görs faktiskt samtidigt som MTF är; när MTF skulle producera noll, ökar det istället en räknare för att sedan koda med RUNA och RUNB.)
Sekvensen 0, 0, 0, 0, 0, 1
skulle representeras som RUNA, RUNB, 1
; RUNA, RUNB
representerar värdet 5 enligt beskrivningen nedan. Körlängdskoden avslutas genom att nå en annan normal symbol. Denna RLE-process är mer flexibel än det ursprungliga RLE-steget, eftersom den kan koda godtyckligt långa heltal (i praktiken är detta vanligtvis begränsat av blockstorleken, så att detta steg inte kodar en körning på mer än 900000 byte). Körlängden kodas på detta sätt: tilldela platsvärden 1 till den första biten, 2 till den andra, 4 till den tredje, etc. i sekvensen, multiplicera varje platsvärde i en RUNB-plats med 2 och lägg till alla de resulterande platsvärdena (för både RUNA- och RUNB-värden) tillsammans. Detta liknar bas-2-binativ siffra.Således resulterar sekvensen RUNA, RUNB
i värdet (1 + 2 × 2) = 5. Som ett mer komplicerat exempel:
RUNA RUNB RUNA RUNA RUNB (ABAAB) 1 2 4 8 16 1 4 4 8 32 = 49
Huffman codingEdit
Denna process ersätter symboler med fast längd i intervallet 0–258 med koder med variabel längd baserat på användningsfrekvensen. Ofta använda koder hamnar kortare (2-3 bitar), medan sällsynta koder kan tilldelas upp till 20 bitar. Kodarna väljs noggrant så att ingen sekvens av bitar kan förväxlas för en annan kod.
Slutströmskoden är särskilt intressant. Om det finns n olika byte (symboler) som används i okomprimerad data, kommer Huffman-koden att bestå av två RLE-koder (RUNA och RUNB), n – 1-symbolkoder och en slutkod. På grund av det kombinerade resultatet av MTF- och RLE-kodningarna i de föregående två stegen finns det aldrig något behov av att uttryckligen hänvisa till den första symbolen i MTF-tabellen (skulle vara noll i den vanliga MTF), vilket sparar en symbol för slut- of-stream markör (och förklara varför endast n – 1 symboler är kodade i Huffman-trädet). I extrema fall där endast en symbol används i okomprimerad data, kommer det inte att finnas några symbolkoder alls i Huffman-trädet, och hela blocket kommer att bestå av RUNA och RUNB (implicit upprepa den enskilda byten) och en slut på -strömmarkör med värde 2.
0: RUNA, 1: RUNB, 2–257: bytevärden 0–255, 258: slutet på strömmen, avsluta bearbetningen (kan vara så låg som 2).
Flera Huffman-tabeller Redigera
Flera Huffman-tabeller med samma storlek kan användas med ett block om vinsten från att använda dem är större än kostnaden för att inkludera extrabordet. Minst 2 och upp till 6 tabeller kan vara närvarande, varvid den mest lämpliga tabellen väljs om före varje 50 symboler som behandlas. Detta har fördelen att ha mycket lyhörd Huffman-dynamik utan att kontinuerligt behöva leverera nya tabeller, vilket skulle krävas i DEFLATE. Körningslängdskodning i föregående steg är utformad för att ta hand om koder som har en omvänd sannolikhet för användning högre än den kortaste koden Huffman-koden som används.
Unary kodning av Huffman-tabellval Redigera
Om flera Huffman-tabeller används används valet av varje tabell (numrerad 0 till 5) från en lista med en nollavslutad bit som går mellan 1 och 6 bitar i längd. Valet ingår i en MTF-lista över tabellerna. Att använda den här funktionen resulterar i en maximal expansion på cirka 1.015, men i allmänhet mindre. Denna expansion kommer sannolikt att bli mycket överskuggad av fördelen med att välja mer lämpliga Huffman-tabeller, och det vanliga fallet att fortsätta använda samma Huffman-tabell representeras som en enda bit. Istället för enkodig kodning är detta i själva verket en extrem form av ett Huffman-träd, där varje kod har hälften av sannolikheten för den föregående koden. krävs för att rekonstruera var och en av de använda kanoniska Huffman-tabellerna. Varje bitlängd lagras som en kodad skillnad mot den tidigare kodlängden. En nollbit (0) betyder att den tidigare bitlängden ska dupliceras för den aktuella koden, medan en bit (1) betyder att ytterligare en bit ska läsas och bitlängden ökas eller minskas baserat på det värdet.
I det vanliga fallet används en enda bit per symbol per tabell och i värsta fall – från längd 1 till längd 20 – krävs cirka 37 bitar. Som ett resultat av den tidigare MTF-kodningen skulle kodlängderna börja med 2–3 bitar långa (mycket ofta använda koder) och öka gradvis, vilket innebär att deltaformatet är ganska effektivt och kräver cirka 300 bitar (38 byte) per hela Huffman-tabell .
Sparse bit arrayEdit
En bitmapp används för att visa vilka symboler som används inuti blocket och ska ingå i Huffman-träden. Binär data kommer sannolikt att använda alla 256 symboler som kan representeras av en byte, medan textdata endast kan använda en liten delmängd av tillgängliga värden, som kanske täcker ASCII-intervallet mellan 32 och 126. Att lagra 256 nollbitar skulle vara ineffektivt om de mestadels inte användes. En gles metod används: 256 symboler är uppdelade i 16 områden, och endast om symboler används inom det blocket ingår en 16-bitars array. Närvaron av vart och ett av dessa 16 intervall indikeras av en ytterligare 16-bitars array längst fram.
Den totala bitmappen använder mellan 32 och 272 bitar lagring (4–34 byte). Däremot skulle DEFLATE-algoritmen visa frånvaron av symboler genom att koda symbolerna som nollbitlängd med körningslängdskodning och ytterligare Huffman-kodning.