239 lines
5.5 KiB
C++
239 lines
5.5 KiB
C++
#include "RawFileStream.h"
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <mutex>
|
|
#include <future>
|
|
|
|
namespace RawFileTools
|
|
{
|
|
constexpr int FileNotExit = 400;
|
|
constexpr int FileOpenFaild = 401;
|
|
constexpr int FileFrameNotFull = 402;
|
|
|
|
using MyStream = GuideRawFileStream;
|
|
using MyIterator = MyStream::GuideRawFileStreamIterator;
|
|
|
|
struct MyStream::privateData
|
|
{
|
|
size_t totalFrame_ = 0;
|
|
size_t frameSize_ = 0;
|
|
size_t ImageSize_ = 0;
|
|
GFrameFormat fromat_;
|
|
std::string filePath_;
|
|
int errorCode_ = 0;
|
|
std::mutex queueMutex_;
|
|
std::vector<char> FrameDataVector_;
|
|
std::future<bool> taskFuture_;
|
|
bool result=false;
|
|
};
|
|
|
|
|
|
MyStream::GuideRawFileStream(const std::string& rawPath,
|
|
const GFrameFormat& format) :impl(std::make_unique<privateData>())
|
|
{
|
|
impl->fromat_ = format;
|
|
impl->filePath_ = rawPath;
|
|
const int c_nPixelBytes = format.dBytesOfPixel;
|
|
impl->frameSize_ = format.nImageWidth * (format.nImageHeight + format.nParamLineCount) * c_nPixelBytes;
|
|
impl->ImageSize_ = format.nImageWidth * format.nImageHeight * c_nPixelBytes;
|
|
startReadFile();
|
|
}
|
|
|
|
MyStream::~GuideRawFileStream()
|
|
{
|
|
impl->FrameDataVector_.clear();
|
|
}
|
|
|
|
|
|
|
|
size_t MyStream::getTotalFrameCount()const
|
|
{
|
|
return impl->totalFrame_;
|
|
|
|
}
|
|
|
|
|
|
MyStream::ErrorCode MyStream::getErrorCode()const
|
|
{
|
|
return impl->errorCode_;
|
|
}
|
|
std::string MyStream::getErrorWhat()
|
|
{
|
|
switch (impl->errorCode_)
|
|
{
|
|
case 400:
|
|
return "文件不存在";
|
|
case 401:
|
|
return "文件打开失败";
|
|
case 402:
|
|
return "读取的文件数据不完整";
|
|
default:
|
|
return "未知原因";
|
|
}
|
|
}
|
|
bool MyStream::isReadReady()const
|
|
{
|
|
if (impl->taskFuture_.valid())
|
|
{
|
|
impl->result= impl->taskFuture_.get();
|
|
}
|
|
return impl->result;
|
|
}
|
|
|
|
std::optional<std::vector<char>> MyStream::getImageDataWithParame(size_t currentFrame)const
|
|
{
|
|
if (impl->result)
|
|
{
|
|
std::vector<char> buffer(impl->frameSize_);
|
|
std::copy(impl->FrameDataVector_.begin()+currentFrame*impl->frameSize_,
|
|
impl->FrameDataVector_.begin() + currentFrame * impl->frameSize_+ impl->frameSize_,
|
|
buffer.begin());
|
|
return buffer;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
std::optional<std::vector<char>> MyStream::getImageData(size_t currentFrame)const
|
|
{
|
|
if (impl->result)
|
|
{
|
|
std::vector<char> buffer(impl->ImageSize_);
|
|
if (impl->fromat_.nParamStartLine > 2)
|
|
{
|
|
//头参数行
|
|
size_t HeadOffset = (impl->fromat_.nParamLineCount) *
|
|
(impl->fromat_.nImageWidth) *
|
|
(impl->fromat_.dBytesOfPixel);
|
|
|
|
std::copy(impl->FrameDataVector_.begin() + (currentFrame * impl->frameSize_)+HeadOffset,
|
|
impl->FrameDataVector_.begin() + (currentFrame * impl->frameSize_)+ HeadOffset + impl->ImageSize_,
|
|
buffer.begin());
|
|
}
|
|
else {
|
|
//尾参数行
|
|
// std::lock_guard<std::mutex> lock(impl->queueMutex_);
|
|
//auto ptr = (impl->FrameDataVector_.data() + ((currentFrame * impl->frameSize_)));
|
|
|
|
std::copy(impl->FrameDataVector_.begin()+ (currentFrame * impl->frameSize_),
|
|
impl->FrameDataVector_.begin()+ (currentFrame * impl->frameSize_)+ impl->ImageSize_,
|
|
buffer.begin());
|
|
}
|
|
return buffer;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
void MyStream::startReadFile()
|
|
{
|
|
impl->taskFuture_ = std::async(std::launch::async, [this]() {
|
|
std::filesystem::path filePath = impl->filePath_;
|
|
if (!std::filesystem::exists(impl->filePath_))
|
|
{
|
|
impl->errorCode_ = FileNotExit;
|
|
return false;
|
|
}
|
|
uintmax_t fileSize = std::filesystem::file_size(impl->filePath_);
|
|
std::ifstream file(impl->filePath_, std::ios::binary);
|
|
if (!file)
|
|
{
|
|
impl->errorCode_ = FileOpenFaild;
|
|
return false;
|
|
}
|
|
impl->totalFrame_ = fileSize / impl->frameSize_;
|
|
std::lock_guard lock(impl->queueMutex_);
|
|
impl->FrameDataVector_.reserve(fileSize);
|
|
size_t framesRead = 0;
|
|
while (framesRead < impl->totalFrame_)
|
|
{
|
|
std::vector<char> frame(impl->frameSize_);
|
|
file.read(reinterpret_cast<char*>(frame.data()), impl->frameSize_);
|
|
if (file.gcount() != impl->frameSize_)
|
|
{
|
|
|
|
impl->errorCode_ = FileFrameNotFull;
|
|
return false;
|
|
}
|
|
impl->FrameDataVector_.insert(impl->FrameDataVector_.end(), frame.begin(), frame.end());
|
|
framesRead++;
|
|
}
|
|
file.close();
|
|
return true;
|
|
});
|
|
}
|
|
|
|
|
|
MyIterator& MyIterator::operator++()noexcept
|
|
{
|
|
if (current_frame < stream_->getTotalFrameCount())
|
|
{
|
|
++current_frame;
|
|
}
|
|
return *this;
|
|
}
|
|
MyIterator MyIterator::operator++(int)noexcept
|
|
{
|
|
MyIterator temp = *this;
|
|
++(*this);
|
|
return temp;
|
|
}
|
|
|
|
MyIterator& MyIterator::operator--()noexcept
|
|
{
|
|
if (current_frame > 0)
|
|
{
|
|
--current_frame;
|
|
}
|
|
return *this;
|
|
}
|
|
MyIterator MyIterator::operator--(int)noexcept
|
|
{
|
|
MyIterator temp = *this;
|
|
--(*this);
|
|
return temp;
|
|
}
|
|
bool MyIterator::operator ==(const MyIterator& other) const
|
|
{
|
|
return current_frame == other.current_frame;
|
|
}
|
|
|
|
bool MyIterator::operator != (const MyIterator& other) const
|
|
{
|
|
return current_frame != other.current_frame;
|
|
}
|
|
|
|
MyIterator MyStream::begin()const
|
|
{
|
|
return MyIterator(this, 0);
|
|
}
|
|
MyIterator MyStream::end()const
|
|
{
|
|
return MyIterator(this, this->getTotalFrameCount());
|
|
}
|
|
|
|
MyIterator::GuideRawFileStreamIterator(const GuideRawFileStream* stream, size_t currentFrame)
|
|
:stream_(stream),current_frame(currentFrame)
|
|
{
|
|
|
|
}
|
|
|
|
GuideRawFileStream::GuideRawFileStreamIterator::GuideRawFileStreamIterator(const GuideRawFileStreamIterator& rhs)noexcept
|
|
{
|
|
this->current_frame = rhs.current_frame;
|
|
this->stream_ = rhs.stream_;
|
|
}
|
|
|
|
std::optional<std::vector<char>> MyIterator::getImageDataWithParame()
|
|
{
|
|
return stream_->getImageDataWithParame(current_frame);
|
|
}
|
|
|
|
std::optional<std::vector<char>> MyIterator::getImageData()
|
|
{
|
|
return stream_->getImageData(current_frame);
|
|
}
|
|
|
|
size_t MyIterator::getCurrentFrameCount() const
|
|
{
|
|
return current_frame;
|
|
}
|
|
}//namespaceRawFileTools
|