Files
kouryu/serfile.cpp
T
2025-10-14 18:14:01 +02:00

136 lines
2.8 KiB
C++

#include "serfile.h"
#include <QImage>
#include <QDateTime>
static_assert(sizeof(SERHeader) == 178);
SERFileWriter::SERFileWriter()
{
}
SERFileWriter::~SERFileWriter()
{
close();
}
bool SERFileWriter::open(const QString &path, int w, int h, SERPixelFormat format, int bitdepth)
{
if(_fw.isOpen())return false;
_fw.setFileName(path);
if(!_fw.open(QIODevice::WriteOnly))
return false;
_header = SERHeader();
_header.imagewidth = w;
_header.imageheight = h;
_header.colorid = format;
_header.pixeldepth = bitdepth;
_fw.write((char*)&_header, sizeof(_header));
return true;
}
void SERFileWriter::close()
{
if(_fw.isOpen())
{
_fw.write((char*)&_timestamps[0], _timestamps.size() * sizeof(int64_t));
_fw.seek(0);
if(_timestamps.size())
_header.datetime_utc = _header.datetime = _timestamps[0];
_fw.write((char*)&_header, sizeof(_header));
_fw.close();
}
}
bool SERFileWriter::writeFrame(const QImage &img)
{
_header.framecount++;
_fw.write((const char*)img.bits(), img.sizeInBytes());
_timestamps.push_back(getTimestamp());
return true;
}
int64_t SERFileWriter::getTimestamp()
{
static QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0), Qt::UTC);
static int64_t epochMS = -epoch.toMSecsSinceEpoch();
return (QDateTime::currentMSecsSinceEpoch() + epochMS) * 10000;
}
bool SERFileReader::open(const QString &path)
{
_fr.setFileName(path);
if(!_fr.open(QIODevice::ReadOnly))
return false;
if(_fr.read((char*)&_header, sizeof(SERHeader)) != sizeof(SERHeader))
return false;
return true;
}
void SERFileReader::close()
{
_fr.close();
std::memset(&_header, 0, sizeof(SERHeader));
}
uint32_t SERFileReader::width() const
{
return _header.imagewidth;
}
uint32_t SERFileReader::height() const
{
return _header.imageheight;
}
uint32_t SERFileReader::frameCount() const
{
return _header.framecount;
}
uint64_t SERFileReader::frameSize() const
{
return static_cast<uint64_t>(_header.imagewidth) * _header.imageheight * _header.pixeldepth / 8;
}
uint32_t SERFileReader::pixelDepth() const
{
return _header.pixeldepth;
}
SERPixelFormat SERFileReader::pixelFormat() const
{
return _header.colorid;
}
void SERFileReader::getFrame(int32_t index, std::vector<uint8_t> &data)
{
if(index >= static_cast<int32_t>(_header.framecount))return;
data.resize(frameSize());
if(index >= 0)
_fr.seek(sizeof(SERHeader) + frameSize() * index);
_fr.read((char*)&data[0], data.size());
}
void SERFileReader::getFrame(int32_t index, char *data)
{
if(index >= static_cast<int32_t>(_header.framecount))return;
if(index >= 0)
_fr.seek(sizeof(SERHeader) + frameSize() * index);
_fr.read(data, frameSize());
}