1
// Copyright 2018 Klaus Post. 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
// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
10
// bitWriter will write bits.
11
// First bit will be LSB of the first byte of output.
12
type bitWriter struct {
18
// bitMask16 is bitmasks. Has extra to avoid bounds check.
19
var bitMask16 = [32]uint16{
20
0, 1, 3, 7, 0xF, 0x1F,
21
0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
22
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0xFFFF,
23
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
24
0xFFFF, 0xFFFF} /* up to 16 bits */
26
// addBits16NC will add up to 16 bits.
27
// It will not check if there is space for them,
28
// so the caller must ensure that it has flushed recently.
29
func (b *bitWriter) addBits16NC(value uint16, bits uint8) {
30
b.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63)
34
// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.
35
// It will not check if there is space for them, so the caller must ensure that it has flushed recently.
36
func (b *bitWriter) addBits16Clean(value uint16, bits uint8) {
37
b.bitContainer |= uint64(value) << (b.nBits & 63)
41
// encSymbol will add up to 16 bits. value may not contain more set bits than indicated.
42
// It will not check if there is space for them, so the caller must ensure that it has flushed recently.
43
func (b *bitWriter) encSymbol(ct cTable, symbol byte) {
45
b.bitContainer |= uint64(enc.val) << (b.nBits & 63)
54
// encTwoSymbols will add up to 32 bits. value may not contain more set bits than indicated.
55
// It will not check if there is space for them, so the caller must ensure that it has flushed recently.
56
func (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) {
60
combined := uint64(encA.val) | (uint64(encB.val) << (encA.nBits & 63))
61
b.bitContainer |= combined << sh
70
b.nBits += encA.nBits + encB.nBits
73
// addBits16ZeroNC will add up to 16 bits.
74
// It will not check if there is space for them,
75
// so the caller must ensure that it has flushed recently.
76
// This is fastest if bits can be zero.
77
func (b *bitWriter) addBits16ZeroNC(value uint16, bits uint8) {
81
value <<= (16 - bits) & 15
82
value >>= (16 - bits) & 15
83
b.bitContainer |= uint64(value) << (b.nBits & 63)
87
// flush will flush all pending full bytes.
88
// There will be at least 56 bits available for writing when this has been called.
89
// Using flush32 is faster, but leaves less space for writing.
90
func (b *bitWriter) flush() {
99
b.bitContainer >>= 1 << 3
101
b.out = append(b.out,
102
byte(b.bitContainer),
103
byte(b.bitContainer>>8),
105
b.bitContainer >>= 2 << 3
107
b.out = append(b.out,
108
byte(b.bitContainer),
109
byte(b.bitContainer>>8),
110
byte(b.bitContainer>>16),
112
b.bitContainer >>= 3 << 3
114
b.out = append(b.out,
115
byte(b.bitContainer),
116
byte(b.bitContainer>>8),
117
byte(b.bitContainer>>16),
118
byte(b.bitContainer>>24),
120
b.bitContainer >>= 4 << 3
122
b.out = append(b.out,
123
byte(b.bitContainer),
124
byte(b.bitContainer>>8),
125
byte(b.bitContainer>>16),
126
byte(b.bitContainer>>24),
127
byte(b.bitContainer>>32),
129
b.bitContainer >>= 5 << 3
131
b.out = append(b.out,
132
byte(b.bitContainer),
133
byte(b.bitContainer>>8),
134
byte(b.bitContainer>>16),
135
byte(b.bitContainer>>24),
136
byte(b.bitContainer>>32),
137
byte(b.bitContainer>>40),
139
b.bitContainer >>= 6 << 3
141
b.out = append(b.out,
142
byte(b.bitContainer),
143
byte(b.bitContainer>>8),
144
byte(b.bitContainer>>16),
145
byte(b.bitContainer>>24),
146
byte(b.bitContainer>>32),
147
byte(b.bitContainer>>40),
148
byte(b.bitContainer>>48),
150
b.bitContainer >>= 7 << 3
152
b.out = append(b.out,
153
byte(b.bitContainer),
154
byte(b.bitContainer>>8),
155
byte(b.bitContainer>>16),
156
byte(b.bitContainer>>24),
157
byte(b.bitContainer>>32),
158
byte(b.bitContainer>>40),
159
byte(b.bitContainer>>48),
160
byte(b.bitContainer>>56),
166
panic(fmt.Errorf("bits (%d) > 64", b.nBits))
171
// flush32 will flush out, so there are at least 32 bits available for writing.
172
func (b *bitWriter) flush32() {
176
b.out = append(b.out,
177
byte(b.bitContainer),
178
byte(b.bitContainer>>8),
179
byte(b.bitContainer>>16),
180
byte(b.bitContainer>>24))
182
b.bitContainer >>= 32
185
// flushAlign will flush remaining full bytes and align to next byte boundary.
186
func (b *bitWriter) flushAlign() {
187
nbBytes := (b.nBits + 7) >> 3
188
for i := uint8(0); i < nbBytes; i++ {
189
b.out = append(b.out, byte(b.bitContainer>>(i*8)))
195
// close will write the alignment bit and write the final byte(s)
197
func (b *bitWriter) close() error {
199
b.addBits16Clean(1, 1)
200
// flush until next byte.
205
// reset and continue writing by appending to out.
206
func (b *bitWriter) reset(out []byte) {