1// Copyright 2014-2019 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)
126
127// minState and maxState define a range for the state values stored in
128// the State values.
129const (
130	minState = 0
131	maxState = 11
132)
133