2022-11-28 10:16:04 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "RawTree.h"
|
|
|
|
|
|
|
|
#include "HuffmanCodeLengthTable.h"
|
|
|
|
#include "HuffmanFixedCodes.h"
|
|
|
|
|
|
|
|
#include <vector>
|
2022-11-29 18:00:19 +00:00
|
|
|
#include <tuple>
|
2022-11-28 10:16:04 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
class PrefixCodeGenerator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~PrefixCodeGenerator() = default;
|
2022-11-29 12:05:08 +00:00
|
|
|
virtual std::optional<PrefixCode> getLiteralValue(unsigned char symbol) const = 0;
|
|
|
|
virtual std::optional<PrefixCode> getLengthValue(unsigned length) const = 0;
|
|
|
|
virtual std::optional<PrefixCode> getDistanceValue(unsigned distance) const = 0;
|
2022-11-28 10:16:04 +00:00
|
|
|
|
2022-11-29 12:05:08 +00:00
|
|
|
virtual std::optional<PrefixCode> getEndOfStreamValue() const = 0;
|
2022-11-28 10:16:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class HuffmanEncoder : public PrefixCodeGenerator
|
|
|
|
{
|
2022-11-29 18:00:19 +00:00
|
|
|
using CountPair = std::pair<unsigned, unsigned>;
|
|
|
|
using Hit = std::tuple<unsigned, unsigned, unsigned char>;
|
2022-11-28 10:16:04 +00:00
|
|
|
|
|
|
|
public:
|
2022-11-29 18:00:19 +00:00
|
|
|
void encode(const std::vector<unsigned>& counts);
|
2022-11-28 10:16:04 +00:00
|
|
|
void encode(const std::unordered_map<unsigned char, unsigned>& counts);
|
|
|
|
|
2022-11-29 12:05:08 +00:00
|
|
|
uint32_t getLengthValue(unsigned length);
|
|
|
|
|
|
|
|
std::optional<PrefixCode> getLiteralValue(unsigned char symbol) const override;
|
|
|
|
|
|
|
|
std::optional<PrefixCode> getLengthValue(unsigned length) const override;
|
|
|
|
|
|
|
|
std::optional<PrefixCode> getDistanceValue(unsigned distance) const override;
|
|
|
|
|
|
|
|
std::optional<PrefixCode> getEndOfStreamValue() const override;
|
|
|
|
|
2022-11-29 18:00:19 +00:00
|
|
|
void initializeTrees(const std::vector<Hit>& hits);
|
2022-11-29 12:05:08 +00:00
|
|
|
|
|
|
|
void setUseFixedCode(bool useFixed);
|
2022-11-28 10:16:04 +00:00
|
|
|
private:
|
2022-11-29 18:00:19 +00:00
|
|
|
void initializeLiteralLengthTable(const std::vector<Hit>& hits);
|
2022-11-29 12:05:08 +00:00
|
|
|
|
2022-11-28 10:16:04 +00:00
|
|
|
void dumpTree(const RawTree<CountPair>& tree) const;
|
|
|
|
void dumpNode(RawNode<CountPair>* node, unsigned depth) const;
|
|
|
|
|
|
|
|
bool mUseFixedCode{false};
|
|
|
|
bool mTableIsInitialized{false};
|
2022-11-29 18:00:19 +00:00
|
|
|
|
|
|
|
std::vector<unsigned char> mSymbolMapping;
|
2022-11-28 10:16:04 +00:00
|
|
|
HuffmanCodeLengthTable mLiteralLengthTable;
|
|
|
|
HuffmanCodeLengthTable mDistanceTable;
|
|
|
|
};
|