Skip to content

Commit 6e281a6

Browse files
committed
Add member functions for common size computations.
1 parent f887c7d commit 6e281a6

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

include/huffman.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,11 @@ template <typename Symbol> class HuffmanCode {
166166
HuffmanCode(const std::pair<Symbol, Symbol> &endpoints, const It begin,
167167
const It end);
168168

169-
//! Smallest and largest symbols (inclusive) to receive codewords.
169+
//! Smallest and largest symbols (inclusive) eligible for codewords.
170170
std::pair<Symbol, Symbol> endpoints;
171171

172-
//! Number of symbols that will be assigned codewords (including one for the
173-
//! 'missed' symbol).
172+
//! Number of symbols eligible for codewords (including one for the 'missed'
173+
//! symbol).
174174
std::size_t ncodewords;
175175

176176
//! Frequencies of the symbols in the input stream.
@@ -179,10 +179,16 @@ template <typename Symbol> class HuffmanCode {
179179
//! Codewords associated to the symbols.
180180
std::vector<HuffmanCodeword> codewords;
181181

182+
//! Report the number of symbols in the stream.
183+
std::size_t nsymbols() const;
184+
182185
//! Report the number of out-of-range symbols encountered in the stream or
183186
//! given in the frequency table pairs.
184187
std::size_t nmissed() const;
185188

189+
//! Report the size in bits of the encoded stream.
190+
std::size_t nbits_hit() const;
191+
186192
//! Check whether a symbol is eligible for a codeword.
187193
bool out_of_range(const Symbol symbol) const;
188194

include/huffman.tpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,23 @@ HuffmanCode<Symbol>::HuffmanCode(const std::pair<Symbol, Symbol> &endpoints,
149149
recursively_set_codewords(queue.top(), {});
150150
}
151151

152+
template <typename Symbol> std::size_t HuffmanCode<Symbol>::nsymbols() const {
153+
return std::accumulate(frequencies.begin(), frequencies.end(),
154+
static_cast<std::size_t>(0));
155+
}
156+
152157
template <typename Symbol> std::size_t HuffmanCode<Symbol>::nmissed() const {
153158
return frequencies.at(0);
154159
}
155160

161+
template <typename Symbol> std::size_t HuffmanCode<Symbol>::nbits_hit() const {
162+
std::size_t nbits = 0;
163+
for (std::size_t i = 0; i < ncodewords; ++i) {
164+
nbits += frequencies.at(i) * codewords.at(i).length;
165+
}
166+
return nbits;
167+
}
168+
156169
template <typename Symbol>
157170
bool HuffmanCode<Symbol>::out_of_range(const Symbol symbol) const {
158171
return symbol < endpoints.first or symbol > endpoints.second;
@@ -403,13 +416,7 @@ MemoryBuffer<unsigned char> huffman_encode(Symbol const *const begin,
403416
const std::size_t n) {
404417
const HuffmanCode<Symbol> code(begin, begin + n);
405418

406-
std::vector<std::size_t> lengths;
407-
for (const HuffmanCodeword &codeword : code.codewords) {
408-
lengths.push_back(codeword.length);
409-
}
410-
const std::size_t nbits =
411-
std::inner_product(code.frequencies.begin(), code.frequencies.end(),
412-
lengths.begin(), static_cast<std::size_t>(0));
419+
const std::size_t nbits = code.nbits_hit();
413420
const std::size_t nbytes_hit = (nbits + CHAR_BIT - 1) / CHAR_BIT;
414421

415422
pb::HuffmanHeader header;
@@ -568,11 +575,8 @@ MemoryBuffer<Symbol> huffman_decode(const MemoryBuffer<unsigned char> &buffer) {
568575
const HuffmanCode<Symbol> code(endpoints,
569576
chained_frequency_supertable.begin(),
570577
chained_frequency_supertable.end());
571-
// TODO: Maybe add a member function for this.
572-
const std::size_t nout =
573-
std::accumulate(code.frequencies.begin(), code.frequencies.end(),
574-
static_cast<std::size_t>(0));
575-
MemoryBuffer<Symbol> out(nout);
578+
const std::size_t nsymbols = code.nsymbols();
579+
MemoryBuffer<Symbol> out(nsymbols);
576580
Symbol *q = out.data.get();
577581

578582
const Bits bits(window.current, window.current + nbits / CHAR_BIT,
@@ -581,7 +585,7 @@ MemoryBuffer<Symbol> huffman_decode(const MemoryBuffer<unsigned char> &buffer) {
581585
const typename HuffmanCode<Symbol>::Node root = code.queue.top();
582586
assert(root);
583587
Bits::iterator b = bits.begin();
584-
for (std::size_t i = 0; i < nout; ++i) {
588+
for (std::size_t i = 0; i < nsymbols; ++i) {
585589
typename HuffmanCode<Symbol>::Node node;
586590
for (node = root; node->left;
587591
node = *b++ ? node->right : node->left, ++nbits_read)

src/huffman.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,7 @@ HuffmanEncodedStream huffman_encoding(long int const *const quantized_data,
248248
const HuffmanCode<Symbol> code(nql_endpoints, quantized_data,
249249
quantized_data + n);
250250

251-
std::vector<std::size_t> lengths;
252-
for (const HuffmanCodeword &codeword : code.codewords) {
253-
lengths.push_back(codeword.length);
254-
}
255-
const std::size_t nbits =
256-
std::inner_product(code.frequencies.begin(), code.frequencies.end(),
257-
lengths.begin(), static_cast<std::size_t>(0));
251+
const std::size_t nbits = code.nbits_hit();
258252
const std::size_t nnz =
259253
code.ncodewords -
260254
std::count(code.frequencies.begin(), code.frequencies.end(), 0);

0 commit comments

Comments
 (0)