/src/brunsli/c/dec/ans_decode.h
Line | Count | Source |
1 | | // Copyright (c) Google LLC 2019 |
2 | | // |
3 | | // Use of this source code is governed by an MIT-style |
4 | | // license that can be found in the LICENSE file or at |
5 | | // https://opensource.org/licenses/MIT. |
6 | | |
7 | | // Library to decode the ANS population counts from the bit-stream and build a |
8 | | // decoding table from them. |
9 | | |
10 | | #ifndef BRUNSLI_DEC_ANS_DECODE_H_ |
11 | | #define BRUNSLI_DEC_ANS_DECODE_H_ |
12 | | |
13 | | #include <vector> |
14 | | |
15 | | #include "../common/ans_params.h" |
16 | | #include <brunsli/types.h> |
17 | | #include "./brunsli_input.h" |
18 | | |
19 | | namespace brunsli { |
20 | | |
21 | | typedef struct { |
22 | | uint16_t offset_; |
23 | | uint16_t freq_; |
24 | | uint8_t symbol_; |
25 | | } ANSSymbolInfo; |
26 | | |
27 | | struct ANSDecodingData { |
28 | 92.6k | ANSDecodingData() {} |
29 | | |
30 | | bool Init(const std::vector<uint32_t>& counts); |
31 | | |
32 | | ANSSymbolInfo map_[BRUNSLI_ANS_TAB_SIZE]; |
33 | | }; |
34 | | |
35 | | class ANSDecoder { |
36 | | public: |
37 | 21.9k | ANSDecoder() {} |
38 | | |
39 | 11.1k | void Init(WordSource* in) { |
40 | 11.1k | state_ = in->GetNextWord(); |
41 | 11.1k | state_ = (state_ << 16u) | in->GetNextWord(); |
42 | 11.1k | } |
43 | | |
44 | 8.28M | int ReadSymbol(const ANSDecodingData& code, WordSource* in) { |
45 | 8.28M | const uint32_t res = state_ & (BRUNSLI_ANS_TAB_SIZE - 1); |
46 | 8.28M | const ANSSymbolInfo& s = code.map_[res]; |
47 | 8.28M | state_ = s.freq_ * (state_ >> BRUNSLI_ANS_LOG_TAB_SIZE) + s.offset_; |
48 | 8.28M | if (state_ < (1u << 16u)) { |
49 | 497k | state_ = (state_ << 16u) | in->GetNextWord(); |
50 | 497k | } |
51 | 8.28M | return s.symbol_; |
52 | 8.28M | } |
53 | 10.7k | bool CheckCRC() const { return state_ == (BRUNSLI_ANS_SIGNATURE << 16u); } |
54 | | |
55 | | private: |
56 | | uint32_t state_; |
57 | | }; |
58 | | |
59 | | } // namespace brunsli |
60 | | |
61 | | #endif // BRUNSLI_DEC_ANS_DECODE_H_ |