main
Raw Download raw file
  1// Copyright 2014-2022 Ulrich Kunitz. All rights reserved.
  2// Use of this source code is governed by a BSD-style
  3// license that can be found in the LICENSE file.
  4
  5package lzma
  6
  7// literalCodec supports the encoding of literal. It provides 768 probability
  8// values per literal state. The upper 512 probabilities are used with the
  9// context of a match bit.
 10type literalCodec struct {
 11	probs []prob
 12}
 13
 14// deepcopy initializes literal codec c as a deep copy of the source.
 15func (c *literalCodec) deepcopy(src *literalCodec) {
 16	if c == src {
 17		return
 18	}
 19	c.probs = make([]prob, len(src.probs))
 20	copy(c.probs, src.probs)
 21}
 22
 23// init initializes the literal codec.
 24func (c *literalCodec) init(lc, lp int) {
 25	switch {
 26	case !(minLC <= lc && lc <= maxLC):
 27		panic("lc out of range")
 28	case !(minLP <= lp && lp <= maxLP):
 29		panic("lp out of range")
 30	}
 31	c.probs = make([]prob, 0x300<<uint(lc+lp))
 32	for i := range c.probs {
 33		c.probs[i] = probInit
 34	}
 35}
 36
 37// Encode encodes the byte s using a range encoder as well as the current LZMA
 38// encoder state, a match byte and the literal state.
 39func (c *literalCodec) Encode(e *rangeEncoder, s byte,
 40	state uint32, match byte, litState uint32,
 41) (err error) {
 42	k := litState * 0x300
 43	probs := c.probs[k : k+0x300]
 44	symbol := uint32(1)
 45	r := uint32(s)
 46	if state >= 7 {
 47		m := uint32(match)
 48		for {
 49			matchBit := (m >> 7) & 1
 50			m <<= 1
 51			bit := (r >> 7) & 1
 52			r <<= 1
 53			i := ((1 + matchBit) << 8) | symbol
 54			if err = probs[i].Encode(e, bit); err != nil {
 55				return
 56			}
 57			symbol = (symbol << 1) | bit
 58			if matchBit != bit {
 59				break
 60			}
 61			if symbol >= 0x100 {
 62				break
 63			}
 64		}
 65	}
 66	for symbol < 0x100 {
 67		bit := (r >> 7) & 1
 68		r <<= 1
 69		if err = probs[symbol].Encode(e, bit); err != nil {
 70			return
 71		}
 72		symbol = (symbol << 1) | bit
 73	}
 74	return nil
 75}
 76
 77// Decode decodes a literal byte using the range decoder as well as the LZMA
 78// state, a match byte, and the literal state.
 79func (c *literalCodec) Decode(d *rangeDecoder,
 80	state uint32, match byte, litState uint32,
 81) (s byte, err error) {
 82	k := litState * 0x300
 83	probs := c.probs[k : k+0x300]
 84	symbol := uint32(1)
 85	if state >= 7 {
 86		m := uint32(match)
 87		for {
 88			matchBit := (m >> 7) & 1
 89			m <<= 1
 90			i := ((1 + matchBit) << 8) | symbol
 91			bit, err := d.DecodeBit(&probs[i])
 92			if err != nil {
 93				return 0, err
 94			}
 95			symbol = (symbol << 1) | bit
 96			if matchBit != bit {
 97				break
 98			}
 99			if symbol >= 0x100 {
100				break
101			}
102		}
103	}
104	for symbol < 0x100 {
105		bit, err := d.DecodeBit(&probs[symbol])
106		if err != nil {
107			return 0, err
108		}
109		symbol = (symbol << 1) | bit
110	}
111	s = byte(symbol - 0x100)
112	return s, nil
113}
114
115// minLC and maxLC define the range for LC values.
116const (
117	minLC = 0
118	maxLC = 8
119)
120
121// minLC and maxLC define the range for LP values.
122const (
123	minLP = 0
124	maxLP = 4
125)