#ifndef SPECK_INT_H
#define SPECK_INT_H
#include "sperr_helper.h"
#include "Bitmask.h"
#include "Bitstream.h"
namespace sperr {
auto speck_int_get_num_bitplanes(const void* bitstream) -> uint8_t;
template <typename T>
class SPECK_INT {
using uint_type = T;
using vecui_type = std::vector<uint_type>;
public:
SPECK_INT();
virtual ~SPECK_INT() = default;
static const size_t header_size = 9;
auto integer_len() const -> size_t;
void set_budget(size_t);
void set_dims(dims_type);
auto get_speck_num_bits(const void*) const -> uint64_t;
auto get_stream_full_len(const void*) const -> uint64_t;
void encode();
void decode();
auto use_coeffs(vecui_type coeffs, Bitmask signs) -> RTNType;
void use_bitstream(const void* p, size_t len);
auto encoded_bitstream_len() const -> size_t;
void append_encoded_bitstream(vec8_type& buf) const;
auto release_coeffs() -> vecui_type&&;
auto release_signs() -> Bitmask&&;
auto view_coeffs() const -> const vecui_type&;
auto view_signs() const -> const Bitmask&;
protected:
virtual void m_clean_LIS() = 0;
virtual void m_sorting_pass() = 0;
virtual void m_initialize_lists() = 0;
virtual void m_bitplane_init() {}
virtual void m_refinement_extra() {}
void m_refinement_pass_encode();
void m_refinement_pass_decode();
uint64_t m_total_bits = 0; uint64_t m_avail_bits = 0; size_t m_budget = std::numeric_limits<size_t>::max();
uint_type m_threshold = 0;
uint8_t m_num_bitplanes = 0;
dims_type m_dims = {0, 0, 0};
vecui_type m_coeff_buf;
std::vector<uint64_t> m_LSP_new;
Bitmask m_LSP_mask, m_LIP_mask, m_sign_array;
Bitstream m_bit_buffer;
};
};
#endif