diff --git a/include/SPERR3D_Stream_Tools.h b/include/SPERR3D_Stream_Tools.h index 1f571ac0..db821a23 100644 --- a/include/SPERR3D_Stream_Tools.h +++ b/include/SPERR3D_Stream_Tools.h @@ -35,10 +35,10 @@ class SPERR3D_Stream_Tools { auto get_stream_header(const void*) const -> SPERR3D_Header; // Function that reads in portions of a bitstream to facilitate progressive access. - auto progressive_read(std::string filename, unsigned pct) -> vec8_type; + auto progressive_read(std::string filename, unsigned pct) const -> vec8_type; // Function that truncates a bitstream to facilitate progressive access. - auto progressive_truncate(const void* stream, size_t stream_len, unsigned pct) -> vec8_type; + auto progressive_truncate(const void* stream, size_t stream_len, unsigned pct) const -> vec8_type; private: const size_t m_header_magic_nchunks = 20; diff --git a/include/SPERR_C_API.h b/include/SPERR_C_API.h index b4ecccad..a635a0b2 100644 --- a/include/SPERR_C_API.h +++ b/include/SPERR_C_API.h @@ -37,11 +37,11 @@ extern "C" { * mode == 3 --> fixed point-wise error (PWE) * * Return value meanings: - * 0: success - * 1: `dst` is not pointing to a NULL pointer! - * 2: `mode` isn't valid - * 3: `is_float` value not supported - *-1: other error + * 0: success + * 1: `dst` is not pointing to a NULL pointer! + * 2: `mode` isn't valid + * 3: `is_float` value not supported + * -1: other error */ int sperr_comp_2d( const void* src, /* Input: buffer that contains a 2D slice */ @@ -57,9 +57,9 @@ int sperr_comp_2d( * Decompress a 2D SPERR-compressed buffer. * * Return value meanings: - * 0: success - * 1: `dst` not pointing to a NULL pointer! - * 2: `output_float` value not supported + * 0: success + * 1: `dst` not pointing to a NULL pointer! + * 2: `output_float` value not supported * -1: other error */ int sperr_decomp_2d( @@ -77,11 +77,11 @@ int sperr_decomp_2d( * mode == 3 --> fixed point-wise error (PWE) * * Return value meanings: - * 0: success - * 1: `dst` is not pointing to a NULL pointer! - * 2: `mode` or `quality` isn't valid - * 3: `is_float` value not supported - *-1: other error + * 0: success + * 1: `dst` is not pointing to a NULL pointer! + * 2: `mode` or `quality` isn't valid + * 3: `is_float` value not supported + * -1: other error */ int sperr_comp_3d( const void* src, /* Input: buffer that contains a 3D volume */ @@ -102,9 +102,9 @@ int sperr_comp_3d( * Decompress a 3D SPERR-compressed buffer. * * Return value meanings: - * 0: success - * 1: `dst` not pointing to a NULL pointer! - * 2: `output_float` value not supported + * 0: success + * 1: `dst` is not pointing to a NULL pointer! + * 2: `output_float` value not supported * -1: other error */ int sperr_decomp_3d( @@ -117,6 +117,21 @@ int sperr_decomp_3d( size_t* dimz, /* Output: Z (slowest-varying) dimension */ void** dst); /* Output: buffer for the output 3D slice, allocated by this function */ +/* + * Truncate a 3D SPERR-compressed bitstream to a percentage of its original length. + * + * Return value meanings: + * 0: success + * 1: `dst` is not pointing to a NULL pointer! + * -1: other error + */ +int sperr_trunc_3d( + const void* src, /* Input: buffer that contains a compressed bitstream */ + size_t src_len, /* Input: length of the input bitstream in byte */ + unsigned pct, /* Input: percentage of the bitstream to keep (0 <= pct <= 100) */ + void** dst, /* Output: buffer for the truncated bitstream, allocated by this function */ + size_t* dst_len); /* Output: length of `dst` in byte */ + #ifdef __cplusplus } /* end of extern "C" */ } /* end of namespace C_API */ diff --git a/src/SPERR3D_Stream_Tools.cpp b/src/SPERR3D_Stream_Tools.cpp index 535cd612..36181b8f 100644 --- a/src/SPERR3D_Stream_Tools.cpp +++ b/src/SPERR3D_Stream_Tools.cpp @@ -104,14 +104,15 @@ auto sperr::SPERR3D_Stream_Tools::get_stream_header(const void* p) const -> SPER return header; } -auto sperr::SPERR3D_Stream_Tools::progressive_read(std::string filename, unsigned pct) -> vec8_type +auto sperr::SPERR3D_Stream_Tools::progressive_read(std::string filename, unsigned pct) const + -> vec8_type { // Read the header of this bitstream. auto vec20 = sperr::read_n_bytes(filename, 20); if (vec20.empty()) return vec20; auto arr20 = std::array(); - std::copy(vec20.begin(), vec20.end(), arr20.begin()); + std::copy(vec20.cbegin(), vec20.cend(), arr20.begin()); const auto header_len = this->get_header_len(arr20); const auto header_buf = sperr::read_n_bytes(filename, header_len); if (header_buf.empty()) @@ -132,7 +133,7 @@ auto sperr::SPERR3D_Stream_Tools::progressive_read(std::string filename, unsigne auto sperr::SPERR3D_Stream_Tools::progressive_truncate(const void* stream, size_t stream_len, - unsigned pct) -> vec8_type + unsigned pct) const -> vec8_type { const auto* u8p = static_cast(stream); diff --git a/src/SPERR_C_API.cpp b/src/SPERR_C_API.cpp index 1a1752d1..232e5373 100644 --- a/src/SPERR_C_API.cpp +++ b/src/SPERR_C_API.cpp @@ -6,6 +6,8 @@ #include "SPERR3D_OMP_C.h" #include "SPERR3D_OMP_D.h" +#include "SPERR3D_Stream_Tools.h" + int C_API::sperr_comp_2d(const void* src, int is_float, size_t dimx, @@ -232,3 +234,25 @@ int C_API::sperr_decomp_3d(const void* src, return 0; } + +int C_API::sperr_trunc_3d(const void* src, + size_t src_len, + unsigned pct, + void** dst, + size_t* dst_len) +{ + if (*dst != NULL) + return 1; + + auto tools = sperr::SPERR3D_Stream_Tools(); + auto trunc = tools.progressive_truncate(src, src_len, pct); + if (trunc.empty()) + return -1; + else { + auto* buf = (uint8_t*)std::malloc(trunc.size()); + std::copy(trunc.cbegin(), trunc.cend(), buf); + *dst = buf; + *dst_len = trunc.size(); + return 0; + } +}