File: C:/Users/fred/anaconda3/Library/include/zfp/internal/codec/zfpheader.hpp
// zfp::codec::zfp_base::header
class header : public zfp::array::header {
public:
// serialization: construct header from array
header(const zfp::array& a) :
zfp::array::header(a),
bit_rate(a.rate())
{
std::string error;
// set up zfp stream and field for generating header
bitstream* stream = stream_open(buffer, sizeof(buffer));
zfp_stream* zfp = zfp_stream_open(stream);
bit_rate = zfp_stream_set_rate(zfp, bit_rate, type, dimensionality(), zfp_true);
if (zfp_stream_mode(zfp) > ZFP_MODE_SHORT_MAX)
error = "zfp serialization supports only short headers";
else {
// set up field
zfp_field* field = 0;
switch (dimensionality()) {
case 1:
field = zfp_field_1d(0, type, nx);
break;
case 2:
field = zfp_field_2d(0, type, nx, ny);
break;
case 3:
field = zfp_field_3d(0, type, nx, ny, nz);
break;
case 4:
field = zfp_field_4d(0, type, nx, ny, nz, nw);
break;
default:
error = "zfp serialization supports only 1D, 2D, 3D, and 4D arrays";
break;
}
if (field) {
// write header to buffer
size_t bits = zfp_write_header(zfp, field, ZFP_HEADER_FULL);
if (bits != bit_size)
error = "zfp header length does not match expected length";
zfp_stream_flush(zfp);
zfp_field_free(field);
}
}
zfp_stream_close(zfp);
stream_close(stream);
if (!error.empty())
throw zfp::exception(error);
}
// deserialization: construct header from memory buffer of optional size
header(const void* data, size_t bytes = 0) :
bit_rate(0)
{
std::string error;
// ensure byte size matches
if (bytes && bytes != byte_size)
error = "zfp header length does not match expectations";
else {
// copy and parse header
std::fill(buffer, buffer + word_size, 0);
std::memcpy(buffer, data, byte_size);
bitstream* stream = stream_open(buffer, sizeof(buffer));
zfp_stream* zfp = zfp_stream_open(stream);
zfp_field field;
size_t bits = zfp_read_header(zfp, &field, ZFP_HEADER_FULL);
if (!bits)
error = "zfp header is corrupt";
else if (bits != bit_size)
error = "zfp deserialization supports only short headers";
else if (zfp_stream_compression_mode(zfp) != zfp_mode_fixed_rate)
error = "zfp deserialization supports only fixed-rate mode";
else {
// success; initialize fields
type = field.type;
nx = field.nx;
ny = field.ny;
nz = field.nz;
nw = field.nw;
bit_rate = double(zfp->maxbits) / (1u << (2 * dimensionality()));
}
zfp_stream_close(zfp);
stream_close(stream);
}
// throw exception upon error
if (!error.empty())
throw zfp::exception(error);
}
virtual ~header() {}
// rate in bits per value
double rate() const { return bit_rate; }
// header data
const void* data() const { return buffer; }
// header byte size
size_t size_bytes(uint mask = ZFP_DATA_HEADER) const
{
size_t size = 0;
if (mask & ZFP_DATA_META)
size += sizeof(*this) - byte_size;
if (mask & ZFP_DATA_HEADER)
size += byte_size;
return size;
}
protected:
// header size measured in bits, bytes, and 64-bit words
static const size_t bit_size = ZFP_MAGIC_BITS + ZFP_META_BITS + ZFP_MODE_SHORT_BITS;
static const size_t byte_size = (bit_size + CHAR_BIT - 1) / CHAR_BIT;
static const size_t word_size = (byte_size + sizeof(uint64) - 1) / sizeof(uint64);
using zfp::array::header::type;
using zfp::array::header::nx;
using zfp::array::header::ny;
using zfp::array::header::nz;
using zfp::array::header::nw;
double bit_rate; // array rate in bits per value
uint64 buffer[word_size]; // header data
};