123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- package rardecode
-
- const (
- mainSize = 299
- offsetSize = 60
- lowOffsetSize = 17
- lengthSize = 28
- tableSize = mainSize + offsetSize + lowOffsetSize + lengthSize
- )
-
- var (
- lengthBase = [28]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20,
- 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224}
- lengthExtraBits = [28]uint{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
- 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}
-
- offsetBase = [60]int{0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96,
- 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096,
- 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,
- 131072, 196608, 262144, 327680, 393216, 458752, 524288,
- 589824, 655360, 720896, 786432, 851968, 917504, 983040,
- 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2621440,
- 2883584, 3145728, 3407872, 3670016, 3932160}
- offsetExtraBits = [60]uint{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
- 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
- 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}
-
- shortOffsetBase = [8]int{0, 4, 8, 16, 32, 64, 128, 192}
- shortOffsetExtraBits = [8]uint{2, 2, 3, 4, 5, 6, 6, 6}
- )
-
- type lz29Decoder struct {
- codeLength [tableSize]byte
-
- mainDecoder huffmanDecoder
- offsetDecoder huffmanDecoder
- lowOffsetDecoder huffmanDecoder
- lengthDecoder huffmanDecoder
-
- offset [4]int // history of previous offsets
- length int // previous length
- lowOffset int
- lowOffsetRepeats int
-
- br *rarBitReader
- }
-
- func (d *lz29Decoder) reset() {
- for i := range d.offset {
- d.offset[i] = 0
- }
- d.length = 0
- for i := range d.codeLength {
- d.codeLength[i] = 0
- }
- }
-
- func (d *lz29Decoder) init(br *rarBitReader) error {
- d.br = br
- d.lowOffset = 0
- d.lowOffsetRepeats = 0
-
- n, err := d.br.readBits(1)
- if err != nil {
- return err
- }
- addOld := n > 0
-
- cl := d.codeLength[:]
- if err = readCodeLengthTable(d.br, cl, addOld); err != nil {
- return err
- }
-
- d.mainDecoder.init(cl[:mainSize])
- cl = cl[mainSize:]
- d.offsetDecoder.init(cl[:offsetSize])
- cl = cl[offsetSize:]
- d.lowOffsetDecoder.init(cl[:lowOffsetSize])
- cl = cl[lowOffsetSize:]
- d.lengthDecoder.init(cl)
-
- return nil
- }
-
- func (d *lz29Decoder) readFilterData() (b []byte, err error) {
- flags, err := d.br.ReadByte()
- if err != nil {
- return nil, err
- }
-
- n := (int(flags) & 7) + 1
- switch n {
- case 7:
- n, err = d.br.readBits(8)
- n += 7
- if err != nil {
- return nil, err
- }
- case 8:
- n, err = d.br.readBits(16)
- if err != nil {
- return nil, err
- }
- }
-
- buf := make([]byte, n+1)
- buf[0] = flags
- err = d.br.readFull(buf[1:])
-
- return buf, err
- }
-
- func (d *lz29Decoder) readEndOfBlock() error {
- n, err := d.br.readBits(1)
- if err != nil {
- return err
- }
- if n > 0 {
- return endOfBlock
- }
- n, err = d.br.readBits(1)
- if err != nil {
- return err
- }
- if n > 0 {
- return endOfBlockAndFile
- }
- return endOfFile
- }
-
- func (d *lz29Decoder) decode(win *window) ([]byte, error) {
- sym, err := d.mainDecoder.readSym(d.br)
- if err != nil {
- return nil, err
- }
-
- switch {
- case sym < 256:
- // literal
- win.writeByte(byte(sym))
- return nil, nil
- case sym == 256:
- return nil, d.readEndOfBlock()
- case sym == 257:
- return d.readFilterData()
- case sym == 258:
- // use previous offset and length
- case sym < 263:
- i := sym - 259
- offset := d.offset[i]
- copy(d.offset[1:i+1], d.offset[:i])
- d.offset[0] = offset
-
- i, err := d.lengthDecoder.readSym(d.br)
- if err != nil {
- return nil, err
- }
- d.length = lengthBase[i] + 2
- bits := lengthExtraBits[i]
- if bits > 0 {
- n, err := d.br.readBits(bits)
- if err != nil {
- return nil, err
- }
- d.length += n
- }
- case sym < 271:
- i := sym - 263
- copy(d.offset[1:], d.offset[:])
- offset := shortOffsetBase[i] + 1
- bits := shortOffsetExtraBits[i]
- if bits > 0 {
- n, err := d.br.readBits(bits)
- if err != nil {
- return nil, err
- }
- offset += n
- }
- d.offset[0] = offset
-
- d.length = 2
- default:
- i := sym - 271
- d.length = lengthBase[i] + 3
- bits := lengthExtraBits[i]
- if bits > 0 {
- n, err := d.br.readBits(bits)
- if err != nil {
- return nil, err
- }
- d.length += n
- }
-
- i, err = d.offsetDecoder.readSym(d.br)
- if err != nil {
- return nil, err
- }
- offset := offsetBase[i] + 1
- bits = offsetExtraBits[i]
-
- switch {
- case bits >= 4:
- if bits > 4 {
- n, err := d.br.readBits(bits - 4)
- if err != nil {
- return nil, err
- }
- offset += n << 4
- }
-
- if d.lowOffsetRepeats > 0 {
- d.lowOffsetRepeats--
- offset += d.lowOffset
- } else {
- n, err := d.lowOffsetDecoder.readSym(d.br)
- if err != nil {
- return nil, err
- }
- if n == 16 {
- d.lowOffsetRepeats = 15
- offset += d.lowOffset
- } else {
- offset += n
- d.lowOffset = n
- }
- }
- case bits > 0:
- n, err := d.br.readBits(bits)
- if err != nil {
- return nil, err
- }
- offset += n
- }
-
- if offset >= 0x2000 {
- d.length++
- if offset >= 0x40000 {
- d.length++
- }
- }
- copy(d.offset[1:], d.offset[:])
- d.offset[0] = offset
- }
- win.copyBytes(d.length, d.offset[0])
- return nil, nil
- }
|