// Copyright (c) 2010, Andrei Vieru. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package lzma type lenCoder struct { choice []uint16 lowCoder []*rangeBitTreeCoder midCoder []*rangeBitTreeCoder highCoder *rangeBitTreeCoder } func newLenCoder(numPosStates /*1 << pb*/ uint32) *lenCoder { lc := &lenCoder{ choice: initBitModels(2), lowCoder: make([]*rangeBitTreeCoder, kNumPosStatesMax), midCoder: make([]*rangeBitTreeCoder, kNumPosStatesMax), highCoder: newRangeBitTreeCoder(kNumHighLenBits), } for i := uint32(0); i < numPosStates; i++ { lc.lowCoder[i] = newRangeBitTreeCoder(kNumLowLenBits) lc.midCoder[i] = newRangeBitTreeCoder(kNumMidLenBits) } return lc } func (lc *lenCoder) decode(rd *rangeDecoder, posState uint32) (res uint32) { i := rd.decodeBit(lc.choice, 0) if i == 0 { res = lc.lowCoder[posState].decode(rd) return } res = kNumLowLenSymbols j := rd.decodeBit(lc.choice, 1) if j == 0 { k := lc.midCoder[posState].decode(rd) res += k return } else { l := lc.highCoder.decode(rd) res = res + kNumMidLenSymbols + l return } return } func (lc *lenCoder) encode(re *rangeEncoder, symbol, posState uint32) { if symbol < kNumLowLenSymbols { re.encode(lc.choice, 0, 0) lc.lowCoder[posState].encode(re, symbol) } else { symbol -= kNumLowLenSymbols re.encode(lc.choice, 0, 1) if symbol < kNumMidLenSymbols { re.encode(lc.choice, 1, 0) lc.midCoder[posState].encode(re, symbol) } else { re.encode(lc.choice, 1, 1) lc.highCoder.encode(re, symbol-kNumMidLenSymbols) } } } // write prices into prices []uint32 func (lc *lenCoder) setPrices(prices []uint32, posState, numSymbols, st uint32) { a0 := getPrice0(lc.choice[0]) a1 := getPrice1(lc.choice[0]) b0 := a1 + getPrice0(lc.choice[1]) b1 := a1 + getPrice1(lc.choice[1]) var i uint32 for i = 0; i < kNumLowLenSymbols; i++ { if i >= numSymbols { return } prices[st+i] = a0 + lc.lowCoder[posState].getPrice(i) } for ; i < kNumLowLenSymbols+kNumMidLenSymbols; i++ { if i >= numSymbols { return } prices[st+i] = b0 + lc.midCoder[posState].getPrice(i-kNumLowLenSymbols) } for ; i < numSymbols; i++ { prices[st+i] = b1 + lc.highCoder.getPrice(i-kNumLowLenSymbols-kNumMidLenSymbols) } } type lenPriceTableCoder struct { lc *lenCoder prices []uint32 counters []uint32 tableSize uint32 } func newLenPriceTableCoder(tableSize, numPosStates uint32) *lenPriceTableCoder { pc := &lenPriceTableCoder{ lc: newLenCoder(numPosStates), prices: make([]uint32, kNumLenSymbols<