Skip to content

Commit

Permalink
Add member functions for common size computations.
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-e-whitney committed Jul 5, 2022
1 parent 078b996 commit 4d3a394
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
12 changes: 9 additions & 3 deletions include/huffman.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ template <typename Symbol> class HuffmanCode {
HuffmanCode(const std::pair<Symbol, Symbol> &endpoints, const It begin,
const It end);

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

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

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

//! Report the number of symbols in the stream.
std::size_t nsymbols() const;

//! Report the number of out-of-range symbols encountered in the stream or
//! given in the frequency table pairs.
std::size_t nmissed() const;

//! Report the size in bits of the encoded stream.
std::size_t nbits_hit() const;

//! Check whether a symbol is eligible for a codeword.
bool out_of_range(const Symbol symbol) const;

Expand Down
30 changes: 17 additions & 13 deletions include/huffman.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,23 @@ HuffmanCode<Symbol>::HuffmanCode(const std::pair<Symbol, Symbol> &endpoints,
recursively_set_codewords(queue.top(), {});
}

template <typename Symbol> std::size_t HuffmanCode<Symbol>::nsymbols() const {
return std::accumulate(frequencies.begin(), frequencies.end(),
static_cast<std::size_t>(0));
}

template <typename Symbol> std::size_t HuffmanCode<Symbol>::nmissed() const {
return frequencies.at(0);
}

template <typename Symbol> std::size_t HuffmanCode<Symbol>::nbits_hit() const {
std::size_t nbits = 0;
for (std::size_t i = 0; i < ncodewords; ++i) {
nbits += frequencies.at(i) * codewords.at(i).length;
}
return nbits;
}

template <typename Symbol>
bool HuffmanCode<Symbol>::out_of_range(const Symbol symbol) const {
return symbol < endpoints.first or symbol > endpoints.second;
Expand Down Expand Up @@ -403,13 +416,7 @@ MemoryBuffer<unsigned char> huffman_encode(Symbol const *const begin,
const std::size_t n) {
const HuffmanCode<Symbol> code(begin, begin + n);

std::vector<std::size_t> lengths;
for (const HuffmanCodeword &codeword : code.codewords) {
lengths.push_back(codeword.length);
}
const std::size_t nbits =
std::inner_product(code.frequencies.begin(), code.frequencies.end(),
lengths.begin(), static_cast<std::size_t>(0));
const std::size_t nbits = code.nbits_hit();
const std::size_t nbytes_hit = (nbits + CHAR_BIT - 1) / CHAR_BIT;

pb::HuffmanHeader header;
Expand Down Expand Up @@ -568,11 +575,8 @@ MemoryBuffer<Symbol> huffman_decode(const MemoryBuffer<unsigned char> &buffer) {
const HuffmanCode<Symbol> code(endpoints,
chained_frequency_supertable.begin(),
chained_frequency_supertable.end());
// TODO: Maybe add a member function for this.
const std::size_t nout =
std::accumulate(code.frequencies.begin(), code.frequencies.end(),
static_cast<std::size_t>(0));
MemoryBuffer<Symbol> out(nout);
const std::size_t nsymbols = code.nsymbols();
MemoryBuffer<Symbol> out(nsymbols);
Symbol *q = out.data.get();

const Bits bits(window.current, window.current + nbits / CHAR_BIT,
Expand All @@ -581,7 +585,7 @@ MemoryBuffer<Symbol> huffman_decode(const MemoryBuffer<unsigned char> &buffer) {
const typename HuffmanCode<Symbol>::Node root = code.queue.top();
assert(root);
Bits::iterator b = bits.begin();
for (std::size_t i = 0; i < nout; ++i) {
for (std::size_t i = 0; i < nsymbols; ++i) {
typename HuffmanCode<Symbol>::Node node;
for (node = root; node->left;
node = *b++ ? node->right : node->left, ++nbits_read)
Expand Down
8 changes: 1 addition & 7 deletions src/huffman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,7 @@ HuffmanEncodedStream huffman_encoding(long int const *const quantized_data,
const HuffmanCode<Symbol> code(nql_endpoints, quantized_data,
quantized_data + n);

std::vector<std::size_t> lengths;
for (const HuffmanCodeword &codeword : code.codewords) {
lengths.push_back(codeword.length);
}
const std::size_t nbits =
std::inner_product(code.frequencies.begin(), code.frequencies.end(),
lengths.begin(), static_cast<std::size_t>(0));
const std::size_t nbits = code.nbits_hit();
const std::size_t nnz =
code.ncodewords -
std::count(code.frequencies.begin(), code.frequencies.end(), 0);
Expand Down

0 comments on commit 4d3a394

Please sign in to comment.