Coverage Report

Created: 2025-10-10 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/dec/bit_reader.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
/* Bit reading helpers */
8
9
#ifndef BRUNSLI_DEC_BIT_READER_H_
10
#define BRUNSLI_DEC_BIT_READER_H_
11
12
#include "../common/platform.h"
13
#include <brunsli/types.h>
14
15
namespace brunsli {
16
17
struct BrunsliBitReader {
18
  const uint8_t* next_;
19
  const uint8_t* end_;
20
  uint32_t num_bits_;
21
  uint32_t bits_;
22
  /*
23
     Number of "virtual" zero bytes located after the end of buffer being
24
     put into the bit buffer.
25
26
     The concept of debt is useful for two purposes:
27
      - postpone handling of "unexpected end of input"
28
      - allow efficient peeking of input near the end
29
30
     It is OK to have debt, while "balance" is non-negative.
31
     BrunsliBitReaderUnload returns debt, if possible.
32
   */
33
  uint32_t num_debt_bytes_;
34
  bool is_healthy_;
35
  bool is_optimistic_;
36
};
37
38
/**
39
 * Prepare instance.
40
 *
41
 * The instance lifecycle looks like:
42
 *  - Init
43
 *  - Resume
44
 *  - (read bits)
45
 *  - Suspend
46
 *  - (optionally, go back to Resume stage)
47
 *  - Finish
48
 */
49
void BrunsliBitReaderInit(BrunsliBitReader* br);
50
/**
51
 * Supply instance with new chunk of input.
52
 */
53
void BrunsliBitReaderResume(BrunsliBitReader* br, const uint8_t* buffer,
54
                          size_t length);
55
/**
56
 * Returns the number of unused bytes.
57
 */
58
size_t BrunsliBitReaderSuspend(BrunsliBitReader* br);
59
/**
60
 * Drops unused bits of the last used byte.
61
 *
62
 * Marks instance as unhealthy, if unused bits are not all 0.
63
 */
64
void BrunsliBitReaderFinish(BrunsliBitReader* br);
65
66
bool BrunsliBitReaderIsHealthy(BrunsliBitReader* br);
67
68
11.1M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
11.1M
  return ~((0xFFFFFFFFu) << n);
70
11.1M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
7.77M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
7.77M
  return ~((0xFFFFFFFFu) << n);
70
7.77M
}
context_map_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
37.9k
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
37.9k
  return ~((0xFFFFFFFFu) << n);
70
37.9k
}
histogram_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
262k
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
262k
  return ~((0xFFFFFFFFu) << n);
70
262k
}
huffman_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
1.86M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
1.86M
  return ~((0xFFFFFFFFu) << n);
70
1.86M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
1.16M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
1.16M
  return ~((0xFFFFFFFFu) << n);
70
1.16M
}
71
72
/* Internal. */
73
157k
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
157k
  br->num_bits_ += 8;
75
157k
  br->num_debt_bytes_++;
76
157k
}
brunsli_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
55
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
55
  br->num_bits_ += 8;
75
55
  br->num_debt_bytes_++;
76
55
}
context_map_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
743
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
743
  br->num_bits_ += 8;
75
743
  br->num_debt_bytes_++;
76
743
}
histogram_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
2.04k
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
2.04k
  br->num_bits_ += 8;
75
2.04k
  br->num_debt_bytes_++;
76
2.04k
}
huffman_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
154k
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
154k
  br->num_bits_ += 8;
75
154k
  br->num_debt_bytes_++;
76
154k
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Unexecuted instantiation: bit_reader.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
77
78
/* Internal. */
79
static BRUNSLI_INLINE void BrunsliBitReaderMaybeFetchByte(BrunsliBitReader* br,
80
9.97M
                                                          uint32_t n_bits) {
81
9.97M
  if (br->num_bits_ < n_bits) {
82
4.94M
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
157k
      BrunsliBitReaderOweByte(br);
84
4.78M
    } else {
85
4.78M
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
4.78M
      br->num_bits_ += 8;
87
4.78M
      br->next_++;
88
4.78M
    }
89
4.94M
  }
90
9.97M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
7.77M
                                                          uint32_t n_bits) {
81
7.77M
  if (br->num_bits_ < n_bits) {
82
4.70M
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
55
      BrunsliBitReaderOweByte(br);
84
4.70M
    } else {
85
4.70M
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
4.70M
      br->num_bits_ += 8;
87
4.70M
      br->next_++;
88
4.70M
    }
89
4.70M
  }
90
7.77M
}
context_map_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
38.2k
                                                          uint32_t n_bits) {
81
38.2k
  if (br->num_bits_ < n_bits) {
82
1.37k
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
743
      BrunsliBitReaderOweByte(br);
84
743
    } else {
85
636
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
636
      br->num_bits_ += 8;
87
636
      br->next_++;
88
636
    }
89
1.37k
  }
90
38.2k
}
histogram_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
268k
                                                          uint32_t n_bits) {
81
268k
  if (br->num_bits_ < n_bits) {
82
61.1k
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
2.04k
      BrunsliBitReaderOweByte(br);
84
59.1k
    } else {
85
59.1k
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
59.1k
      br->num_bits_ += 8;
87
59.1k
      br->next_++;
88
59.1k
    }
89
61.1k
  }
90
268k
}
huffman_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
1.86M
                                                          uint32_t n_bits) {
81
1.86M
  if (br->num_bits_ < n_bits) {
82
179k
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
154k
      BrunsliBitReaderOweByte(br);
84
154k
    } else {
85
25.1k
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
25.1k
      br->num_bits_ += 8;
87
25.1k
      br->next_++;
88
25.1k
    }
89
179k
  }
90
1.86M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
29.1k
                                                          uint32_t n_bits) {
81
29.1k
  if (br->num_bits_ < n_bits) {
82
0
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
0
      BrunsliBitReaderOweByte(br);
84
0
    } else {
85
0
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
0
      br->num_bits_ += 8;
87
0
      br->next_++;
88
0
    }
89
0
  }
90
29.1k
}
91
92
/**
93
 * Turns instance to optimistic mode.
94
 *
95
 * The only difference with regular operating mode is that CanRead always
96
 * returns "true". Use this mode only when instance is supplied with complete
97
 * input.
98
 */
99
void BrunsliBitReaderSetOptimistic(BrunsliBitReader* br);
100
101
/**
102
 * Returns true if there is enough input.
103
 *
104
 * Guaranteed to work correctly only in normalized state.
105
 */
106
bool BrunsliBitReaderCanRead(BrunsliBitReader* br, size_t n_bits);
107
108
static BRUNSLI_INLINE uint32_t BrunsliBitReaderGet(BrunsliBitReader* br,
109
9.96M
                                                   uint32_t n_bits) {
110
9.96M
  BRUNSLI_DCHECK(n_bits <= 24);
111
9.96M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
9.96M
  if (n_bits > 8) {
113
12.3k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
12.3k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
12.3k
  }
116
9.96M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
9.96M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
7.77M
                                                   uint32_t n_bits) {
110
7.77M
  BRUNSLI_DCHECK(n_bits <= 24);
111
7.77M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
7.77M
  if (n_bits > 8) {
113
5.60k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
5.60k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
5.60k
  }
116
7.77M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
7.77M
}
context_map_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
37.9k
                                                   uint32_t n_bits) {
110
37.9k
  BRUNSLI_DCHECK(n_bits <= 24);
111
37.9k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
37.9k
  if (n_bits > 8) {
113
307
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
307
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
307
  }
116
37.9k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
37.9k
}
histogram_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
262k
                                                   uint32_t n_bits) {
110
262k
  BRUNSLI_DCHECK(n_bits <= 24);
111
262k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
262k
  if (n_bits > 8) {
113
6.18k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
6.18k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
6.18k
  }
116
262k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
262k
}
huffman_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
1.86M
                                                   uint32_t n_bits) {
110
1.86M
  BRUNSLI_DCHECK(n_bits <= 24);
111
1.86M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
1.86M
  if (n_bits > 8) {
113
243
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
243
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
243
  }
116
1.86M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
1.86M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
29.1k
                                                   uint32_t n_bits) {
110
29.1k
  BRUNSLI_DCHECK(n_bits <= 24);
111
29.1k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
29.1k
  if (n_bits > 8) {
113
0
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
0
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
0
  }
116
29.1k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
29.1k
}
118
119
static BRUNSLI_INLINE void BrunsliBitReaderDrop(BrunsliBitReader* br,
120
9.96M
                                                uint32_t n_bits) {
121
9.96M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
9.96M
  br->bits_ >>= n_bits;
123
9.96M
  br->num_bits_ -= n_bits;
124
9.96M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
7.77M
                                                uint32_t n_bits) {
121
7.77M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
7.77M
  br->bits_ >>= n_bits;
123
7.77M
  br->num_bits_ -= n_bits;
124
7.77M
}
context_map_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
37.9k
                                                uint32_t n_bits) {
121
37.9k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
37.9k
  br->bits_ >>= n_bits;
123
37.9k
  br->num_bits_ -= n_bits;
124
37.9k
}
histogram_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
262k
                                                uint32_t n_bits) {
121
262k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
262k
  br->bits_ >>= n_bits;
123
262k
  br->num_bits_ -= n_bits;
124
262k
}
huffman_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
1.86M
                                                uint32_t n_bits) {
121
1.86M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
1.86M
  br->bits_ >>= n_bits;
123
1.86M
  br->num_bits_ -= n_bits;
124
1.86M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
29.1k
                                                uint32_t n_bits) {
121
29.1k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
29.1k
  br->bits_ >>= n_bits;
123
29.1k
  br->num_bits_ -= n_bits;
124
29.1k
}
125
126
BRUNSLI_INLINE uint32_t BrunsliBitReaderRead(BrunsliBitReader* br,
127
8.11M
                                                    uint32_t n_bits) {
128
8.11M
  uint32_t result = BrunsliBitReaderGet(br, n_bits);
129
8.11M
  BrunsliBitReaderDrop(br, n_bits);
130
8.11M
  return result;
131
8.11M
}
132
133
}  // namespace brunsli
134
135
#endif  // BRUNSLI_DEC_BIT_READER_H_