| // Copyright 2011 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package bzip2 implements bzip2 decompression. |
| package bzip2 |
| |
| import "io" |
| |
| // There's no RFC for bzip2. I used the Wikipedia page for reference and a lot |
| // of guessing: https://en.wikipedia.org/wiki/Bzip2 |
| // The source code to pyflate was useful for debugging: |
| // http://www.paul.sladen.org/projects/pyflate |
| |
| // A StructuralError is returned when the bzip2 data is found to be |
| // syntactically invalid. |
| type StructuralError string |
| |
| func (s StructuralError) Error() string { |
| return "bzip2 data invalid: " + string(s) |
| } |
| |
| // A reader decompresses bzip2 compressed data. |
| type reader struct { |
| br bitReader |
| fileCRC uint32 |
| blockCRC uint32 |
| wantBlockCRC uint32 |
| setupDone bool // true if we have parsed the bzip2 header. |
| blockSize int // blockSize in bytes, i.e. 900 * 1000. |
| eof bool |
| c [256]uint // the ``C'' array for the inverse BWT. |
| tt []uint32 // mirrors the ``tt'' array in the bzip2 source and contains the P array in the upper 24 bits. |
| tPos uint32 // Index of the next output byte in tt. |
| |
| preRLE []uint32 // contains the RLE data still to be processed. |
| preRLEUsed int // number of entries of preRLE used. |
| lastByte int // the last byte value seen. |
| byteRepeats uint // the number of repeats of lastByte seen. |
| repeats uint // the number of copies of lastByte to output. |
| } |
| |
| // NewReader returns an io.Reader which decompresses bzip2 data from r. |
| // If r does not also implement io.ByteReader, |
| // the decompressor may read more data than necessary from r. |
| func NewReader(r io.Reader) io.Reader { |
| bz2 := new(reader) |
| bz2.br = newBitReader(r) |
| return bz2 |
| } |
| |
| const bzip2FileMagic = 0x425a // "BZ" |
| const bzip2BlockMagic = 0x314159265359 |
| const bzip2FinalMagic = 0x177245385090 |
| |
| // setup parses the bzip2 header. |
| func (bz2 *reader) setup(needMagic bool) error { |
| br := &bz2.br |
| |
| if needMagic { |
| magic := br.ReadBits(16) |
| if magic != bzip2FileMagic { |
| return StructuralError("bad magic value") |
| } |
| } |
| |
| t := br.ReadBits(8) |
| if t != 'h' { |
| return StructuralError("non-Huffman entropy encoding") |
| } |
| |
| level := br.ReadBits(8) |
| if level < '1' || level > '9' { |
| return StructuralError("invalid compression level") |
| } |
| |
| bz2.fileCRC = 0 |
| bz2.blockSize = 100 * 1000 * (level - '0') |
| if bz2.blockSize > len(bz2.tt) { |
| bz2.tt = make([]uint32, bz2.blockSize) |
| } |
| return nil |
| } |
| |
| func (bz2 *reader) Read(buf []byte) (n int, err error) { |
| if bz2.eof { |
| return 0, io.EOF |
| } |
| |
| if !bz2.setupDone { |
| err = bz2.setup(true) |
| brErr := bz2.br.Err() |
| if brErr != nil { |
| err = brErr |
| } |
| if err != nil { |
| return 0, err |
| } |
| bz2.setupDone = true |
| } |
| |
| n, err = bz2.read(buf) |
| brErr := bz2.br.Err() |
| if brErr != nil { |
| err = brErr |
| } |
| return |
| } |
| |
| func (bz2 *reader) readFromBlock(buf []byte) int { |
| // bzip2 is a block based compressor, except that it has a run-length |
| // preprocessing step. The block based nature means that we can |
| // preallocate fixed-size buffers and reuse them. However, the RLE |
| // preprocessing would require allocating huge buffers to store the |
| // maximum expansion. Thus we process blocks all at once, except for |
| // the RLE which we decompress as required. |
| n := 0 |
| for (bz2.repeats > 0 || bz2.preRLEUsed < len(bz2.preRLE)) && n < len(buf) { |
| // We have RLE data pending. |
| |
| // The run-length encoding works like this: |
| // Any sequence of four equal bytes is followed by a length |
| // byte which contains the number of repeats of that byte to |
| // include. (The number of repeats can be zero.) Because we are |
| // decompressing on-demand our state is kept in the reader |
| // object. |
| |
| if bz2.repeats > 0 { |
| buf[n] = byte(bz2.lastByte) |
| n++ |
| bz2.repeats-- |
| if bz2.repeats == 0 { |
| bz2.lastByte = -1 |
| } |
| continue |
| } |
| |
| bz2.tPos = bz2.preRLE[bz2.tPos] |
| b := byte(bz2.tPos) |
| bz2.tPos >>= 8 |
| bz2.preRLEUsed++ |
| |
| if bz2.byteRepeats == 3 { |
| bz2.repeats = uint(b) |
| bz2.byteRepeats = 0 |
| continue |
| } |
| |
| if bz2.lastByte == int(b) { |
| bz2.byteRepeats++ |
| } else { |
| bz2.byteRepeats = 0 |
| } |
| bz2.lastByte = int(b) |
| |
| buf[n] = b |
| n++ |
| } |
| |
| return n |
| } |
| |
| func (bz2 *reader) read(buf []byte) (int, error) { |
| for { |
| n := bz2.readFromBlock(buf) |
| if n > 0 || len(buf) == 0 { |
| bz2.blockCRC = updateCRC(bz2.blockCRC, buf[:n]) |
| return n, nil |
| } |
| |
| // End of block. Check CRC. |
| if bz2.blockCRC != bz2.wantBlockCRC { |
| bz2.br.err = StructuralError("block checksum mismatch") |
| return 0, bz2.br.err |
| } |
| |
| // Find next block. |
| br := &bz2.br |
| switch br.ReadBits64(48) { |
| default: |
| return 0, StructuralError("bad magic value found") |
| |
| case bzip2BlockMagic: |
| // Start of block. |
| err := bz2.readBlock() |
| if err != nil { |
| return 0, err |
| } |
| |
| case bzip2FinalMagic: |
| // Check end-of-file CRC. |
| wantFileCRC := uint32(br.ReadBits64(32)) |
| if br.err != nil { |
| return 0, br.err |
| } |
| if bz2.fileCRC != wantFileCRC { |
| br.err = StructuralError("file checksum mismatch") |
| return 0, br.err |
| } |
| |
| // Skip ahead to byte boundary. |
| // Is there a file concatenated to this one? |
| // It would start with BZ. |
| if br.bits%8 != 0 { |
| br.ReadBits(br.bits % 8) |
| } |
| b, err := br.r.ReadByte() |
| if err == io.EOF { |
| br.err = io.EOF |
| bz2.eof = true |
| return 0, io.EOF |
| } |
| if err != nil { |
| br.err = err |
| return 0, err |
| } |
| z, err := br.r.ReadByte() |
| if err != nil { |
| if err == io.EOF { |
| err = io.ErrUnexpectedEOF |
| } |
| br.err = err |
| return 0, err |
| } |
| if b != 'B' || z != 'Z' { |
| return 0, StructuralError("bad magic value in continuation file") |
| } |
| if err := bz2.setup(false); err != nil { |
| return 0, err |
| } |
| } |
| } |
| } |
| |
| // readBlock reads a bzip2 block. The magic number should already have been consumed. |
| func (bz2 *reader) readBlock() (err error) { |
| br := &bz2.br |
| bz2.wantBlockCRC = uint32(br.ReadBits64(32)) // skip checksum. TODO: check it if we can figure out what it is. |
| bz2.blockCRC = 0 |
| bz2.fileCRC = (bz2.fileCRC<<1 | bz2.fileCRC>>31) ^ bz2.wantBlockCRC |
| randomized := br.ReadBits(1) |
| if randomized != 0 { |
| return StructuralError("deprecated randomized files") |
| } |
| origPtr := uint(br.ReadBits(24)) |
| |
| // If not every byte value is used in the block (i.e., it's text) then |
| // the symbol set is reduced. The symbols used are stored as a |
| // two-level, 16x16 bitmap. |
| symbolRangeUsedBitmap := br.ReadBits(16) |
| symbolPresent := make([]bool, 256) |
| numSymbols := 0 |
| for symRange := uint(0); symRange < 16; symRange++ { |
| if symbolRangeUsedBitmap&(1<<(15-symRange)) != 0 { |
| bits := br.ReadBits(16) |
| for symbol := uint(0); symbol < 16; symbol++ { |
| if bits&(1<<(15-symbol)) != 0 { |
| symbolPresent[16*symRange+symbol] = true |
| numSymbols++ |
| } |
| } |
| } |
| } |
| |
| if numSymbols == 0 { |
| // There must be an EOF symbol. |
| return StructuralError("no symbols in input") |
| } |
| |
| // A block uses between two and six different Huffman trees. |
| numHuffmanTrees := br.ReadBits(3) |
| if numHuffmanTrees < 2 || numHuffmanTrees > 6 { |
| return StructuralError("invalid number of Huffman trees") |
| } |
| |
| // The Huffman tree can switch every 50 symbols so there's a list of |
| // tree indexes telling us which tree to use for each 50 symbol block. |
| numSelectors := br.ReadBits(15) |
| treeIndexes := make([]uint8, numSelectors) |
| |
| // The tree indexes are move-to-front transformed and stored as unary |
| // numbers. |
| mtfTreeDecoder := newMTFDecoderWithRange(numHuffmanTrees) |
| for i := range treeIndexes { |
| c := 0 |
| for { |
| inc := br.ReadBits(1) |
| if inc == 0 { |
| break |
| } |
| c++ |
| } |
| if c >= numHuffmanTrees { |
| return StructuralError("tree index too large") |
| } |
| treeIndexes[i] = mtfTreeDecoder.Decode(c) |
| } |
| |
| // The list of symbols for the move-to-front transform is taken from |
| // the previously decoded symbol bitmap. |
| symbols := make([]byte, numSymbols) |
| nextSymbol := 0 |
| for i := 0; i < 256; i++ { |
| if symbolPresent[i] { |
| symbols[nextSymbol] = byte(i) |
| nextSymbol++ |
| } |
| } |
| mtf := newMTFDecoder(symbols) |
| |
| numSymbols += 2 // to account for RUNA and RUNB symbols |
| huffmanTrees := make([]huffmanTree, numHuffmanTrees) |
| |
| // Now we decode the arrays of code-lengths for each tree. |
| lengths := make([]uint8, numSymbols) |
| for i := range huffmanTrees { |
| // The code lengths are delta encoded from a 5-bit base value. |
| length := br.ReadBits(5) |
| for j := range lengths { |
| for { |
| if length < 1 || length > 20 { |
| return StructuralError("Huffman length out of range") |
| } |
| if !br.ReadBit() { |
| break |
| } |
| if br.ReadBit() { |
| length-- |
| } else { |
| length++ |
| } |
| } |
| lengths[j] = uint8(length) |
| } |
| huffmanTrees[i], err = newHuffmanTree(lengths) |
| if err != nil { |
| return err |
| } |
| } |
| |
| selectorIndex := 1 // the next tree index to use |
| if len(treeIndexes) == 0 { |
| return StructuralError("no tree selectors given") |
| } |
| if int(treeIndexes[0]) >= len(huffmanTrees) { |
| return StructuralError("tree selector out of range") |
| } |
| currentHuffmanTree := huffmanTrees[treeIndexes[0]] |
| bufIndex := 0 // indexes bz2.buf, the output buffer. |
| // The output of the move-to-front transform is run-length encoded and |
| // we merge the decoding into the Huffman parsing loop. These two |
| // variables accumulate the repeat count. See the Wikipedia page for |
| // details. |
| repeat := 0 |
| repeatPower := 0 |
| |
| // The `C' array (used by the inverse BWT) needs to be zero initialized. |
| for i := range bz2.c { |
| bz2.c[i] = 0 |
| } |
| |
| decoded := 0 // counts the number of symbols decoded by the current tree. |
| for { |
| if decoded == 50 { |
| if selectorIndex >= numSelectors { |
| return StructuralError("insufficient selector indices for number of symbols") |
| } |
| if int(treeIndexes[selectorIndex]) >= len(huffmanTrees) { |
| return StructuralError("tree selector out of range") |
| } |
| currentHuffmanTree = huffmanTrees[treeIndexes[selectorIndex]] |
| selectorIndex++ |
| decoded = 0 |
| } |
| |
| v := currentHuffmanTree.Decode(br) |
| decoded++ |
| |
| if v < 2 { |
| // This is either the RUNA or RUNB symbol. |
| if repeat == 0 { |
| repeatPower = 1 |
| } |
| repeat += repeatPower << v |
| repeatPower <<= 1 |
| |
| // This limit of 2 million comes from the bzip2 source |
| // code. It prevents repeat from overflowing. |
| if repeat > 2*1024*1024 { |
| return StructuralError("repeat count too large") |
| } |
| continue |
| } |
| |
| if repeat > 0 { |
| // We have decoded a complete run-length so we need to |
| // replicate the last output symbol. |
| if repeat > bz2.blockSize-bufIndex { |
| return StructuralError("repeats past end of block") |
| } |
| for i := 0; i < repeat; i++ { |
| b := mtf.First() |
| bz2.tt[bufIndex] = uint32(b) |
| bz2.c[b]++ |
| bufIndex++ |
| } |
| repeat = 0 |
| } |
| |
| if int(v) == numSymbols-1 { |
| // This is the EOF symbol. Because it's always at the |
| // end of the move-to-front list, and never gets moved |
| // to the front, it has this unique value. |
| break |
| } |
| |
| // Since two metasymbols (RUNA and RUNB) have values 0 and 1, |
| // one would expect |v-2| to be passed to the MTF decoder. |
| // However, the front of the MTF list is never referenced as 0, |
| // it's always referenced with a run-length of 1. Thus 0 |
| // doesn't need to be encoded and we have |v-1| in the next |
| // line. |
| b := mtf.Decode(int(v - 1)) |
| if bufIndex >= bz2.blockSize { |
| return StructuralError("data exceeds block size") |
| } |
| bz2.tt[bufIndex] = uint32(b) |
| bz2.c[b]++ |
| bufIndex++ |
| } |
| |
| if origPtr >= uint(bufIndex) { |
| return StructuralError("origPtr out of bounds") |
| } |
| |
| // We have completed the entropy decoding. Now we can perform the |
| // inverse BWT and setup the RLE buffer. |
| bz2.preRLE = bz2.tt[:bufIndex] |
| bz2.preRLEUsed = 0 |
| bz2.tPos = inverseBWT(bz2.preRLE, origPtr, bz2.c[:]) |
| bz2.lastByte = -1 |
| bz2.byteRepeats = 0 |
| bz2.repeats = 0 |
| |
| return nil |
| } |
| |
| // inverseBWT implements the inverse Burrows-Wheeler transform as described in |
| // http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf, section 4.2. |
| // In that document, origPtr is called “I” and c is the “C” array after the |
| // first pass over the data. It's an argument here because we merge the first |
| // pass with the Huffman decoding. |
| // |
| // This also implements the “single array” method from the bzip2 source code |
| // which leaves the output, still shuffled, in the bottom 8 bits of tt with the |
| // index of the next byte in the top 24-bits. The index of the first byte is |
| // returned. |
| func inverseBWT(tt []uint32, origPtr uint, c []uint) uint32 { |
| sum := uint(0) |
| for i := 0; i < 256; i++ { |
| sum += c[i] |
| c[i] = sum - c[i] |
| } |
| |
| for i := range tt { |
| b := tt[i] & 0xff |
| tt[c[b]] |= uint32(i) << 8 |
| c[b]++ |
| } |
| |
| return tt[origPtr] >> 8 |
| } |
| |
| // This is a standard CRC32 like in hash/crc32 except that all the shifts are reversed, |
| // causing the bits in the input to be processed in the reverse of the usual order. |
| |
| var crctab [256]uint32 |
| |
| func init() { |
| const poly = 0x04C11DB7 |
| for i := range crctab { |
| crc := uint32(i) << 24 |
| for j := 0; j < 8; j++ { |
| if crc&0x80000000 != 0 { |
| crc = (crc << 1) ^ poly |
| } else { |
| crc <<= 1 |
| } |
| } |
| crctab[i] = crc |
| } |
| } |
| |
| // updateCRC updates the crc value to incorporate the data in b. |
| // The initial value is 0. |
| func updateCRC(val uint32, b []byte) uint32 { |
| crc := ^val |
| for _, v := range b { |
| crc = crctab[byte(crc>>24)^v] ^ (crc << 8) |
| } |
| return ^crc |
| } |