/* Copyright (C) Teemu Suutari */ #ifndef BLOCKCODEC_H #define BLOCKCODEC_H #include #include #include #include "onekpaq_common.h" #include "ArithEncoder.hpp" #include "ArithDecoder.hpp" class BlockCodec { public: enum class BlockCodecType { Single=0, Standard, TypeLast=Standard }; struct Probability; struct BitCounts; private: struct Model { uint model; uint weight; }; template class CompressorModel; class CompressorModelBase { public: CompressorModelBase() = default; virtual ~CompressorModelBase() = default; virtual uint GetModelCount() const = 0; virtual uint GetStartOffset() const = 0; virtual void CalculateAllProbabilities(std::vector &dest,const std::vector &src,uint bitPos,uint shift) = 0; virtual float EstimateBitLength(const std::vector &probabilities,const std::vector &models) = 0; virtual u32 CalculateSubRange(const std::vector &src,int bitPos,const std::vector &models,u32 range,uint shift) = 0; private: virtual void CreateWeightProfile(std::vector> &dest,const std::vector &src,uint bitPos,const std::vector &models,uint shift) = 0; }; public: BlockCodec(BlockCodecType type,uint shift); ~BlockCodec() = default; const std::vector &GetHeader() const { return _header; } void SetHeader(const std::vector &header,uint size); void CreateContextModels(const std::vector &src,bool multipleRetryPoints,bool multipleInitPoints); void Encode(const std::vector &src,ArithEncoder &ec); uint GetRawLength() const { return _rawLength; } float GetEstimatedLength() const { return _estimatedLength; } std::string PrintModels() const; std::vector Decode(const std::vector &header,ArithDecoder &dc); private: std::vector EncodeHeaderAndClean(std::vector &models); void DecodeHeader(const std::vector &header); void CreateCompressorModel(); BlockCodecType _type; std::vector _models; // models, for encoding and decoding uint _rawLength=0; // unencoded data length std::vector _header; // for encoding only float _estimatedLength=0; // with header, encoding only uint _shift; // shift for encoding and decoding std::unique_ptr _cm; }; #endif