save numpy files frame by frame (#37)

Co-authored-by: Bechir <bechir.brahem420@gmail.com>
This commit is contained in:
Bechir Braham
2024-04-02 11:35:58 +02:00
committed by GitHub
parent 643ea39670
commit 449c5119a4
23 changed files with 357 additions and 101 deletions

View File

@ -1,17 +1,45 @@
#include "aare/NumpyFile.hpp"
void NumpyFile::write(Frame &frame) {
if (fp == nullptr) {
throw std::runtime_error("File not open");
}
if (not(mode == "w" or mode == "a")) {
throw std::runtime_error("File not open for writing");
}
fseek(fp, 0, SEEK_END);
fwrite(frame._get_data(), frame.size(), 1, fp);
}
NumpyFile::NumpyFile(std::filesystem::path fname_) {
this->m_fname = fname_;
fp = fopen(this->m_fname.c_str(), "rb");
}
NumpyFile::NumpyFile(FileConfig config, header_t header) {
this->mode = "w";
this->m_fname = config.fname;
this->m_bitdepth = config.dtype.bitdepth();
this->m_rows = config.rows;
this->m_cols = config.cols;
this->header = header;
this->header.shape = {0, config.rows, config.cols};
fp = fopen(this->m_fname.c_str(), "wb");
if (!fp) {
throw std::runtime_error(fmt::format("Could not open: {} for reading", this->m_fname.c_str()));
}
this->initial_header_len =
aare::NumpyHelpers::write_header(std::filesystem::path(this->m_fname.c_str()), this->header);
}
Frame NumpyFile::get_frame(size_t frame_number) {
Frame frame(header.shape[1], header.shape[2], header.dtype.itemsize*8);
get_frame_into(frame_number,frame._get_data());
Frame frame(header.shape[1], header.shape[2], header.dtype.bitdepth());
get_frame_into(frame_number, frame._get_data());
return frame;
}
void NumpyFile::get_frame_into( size_t frame_number,std::byte* image_buf) {
void NumpyFile::get_frame_into(size_t frame_number, std::byte *image_buf) {
if (fp == nullptr) {
throw std::runtime_error("File not open");
}
@ -22,13 +50,10 @@ void NumpyFile::get_frame_into( size_t frame_number,std::byte* image_buf) {
fread(image_buf, bytes_per_frame(), 1, fp);
}
size_t NumpyFile::pixels() {
return std::accumulate(header.shape.begin() + 1, header.shape.end(), 1, std::multiplies<uint64_t>());
};
size_t NumpyFile::bytes_per_frame() { return header.dtype.itemsize * pixels(); };
size_t NumpyFile::bytes_per_frame() { return header.dtype.bitdepth() / 8 * pixels(); };
std::vector<Frame> NumpyFile::read(size_t n_frames) {
// TODO: implement this in a more efficient way
@ -45,4 +70,30 @@ void NumpyFile::read_into(std::byte *image_buf, size_t n_frames) {
this->get_frame_into(this->current_frame++, image_buf);
image_buf += this->bytes_per_frame();
}
}
NumpyFile::~NumpyFile() {
if (mode == "w" or mode == "a") {
// determine number of frames
fseek(fp, 0, SEEK_END);
size_t file_size = ftell(fp);
size_t data_size = file_size - initial_header_len;
size_t n_frames = data_size / bytes_per_frame();
// update number of frames in header (first element of shape)
this->header.shape[0] = n_frames;
fseek(fp, 0, SEEK_SET);
// create string stream to contain header
std::stringstream ss;
aare::NumpyHelpers::write_header(ss, this->header);
std::string header_str = ss.str();
// write header
fwrite(header_str.c_str(), header_str.size(), 1, fp);
}
if (fp != nullptr) {
fclose(fp);
}
}