229 lines
6.7 KiB
C++
229 lines
6.7 KiB
C++
#include "grayMatch.h"
|
|
#include "privateType.h"
|
|
|
|
#include <opencv2/core/hal/intrin.hpp>
|
|
|
|
class Buffer {
|
|
public:
|
|
Buffer(const int size_, unsigned char *data_)
|
|
: m_size(size_)
|
|
, m_data(data_) {}
|
|
|
|
virtual ~Buffer() = default;
|
|
|
|
virtual void operator&(uchar &val) = 0;
|
|
virtual void operator&(std::vector<cv::Mat> &val) = 0;
|
|
virtual void operator&(std::vector<cv::Scalar> &val) = 0;
|
|
virtual void operator&(std::vector<double> &val) = 0;
|
|
virtual void operator&(std::vector<uchar> &val) = 0;
|
|
|
|
void operator&(Model &val) {
|
|
this->operator&(val.pyramids);
|
|
this->operator&(val.mean);
|
|
this->operator&(val.normal);
|
|
this->operator&(val.invArea);
|
|
this->operator&(val.equal1);
|
|
this->operator&(val.borderColor);
|
|
}
|
|
|
|
[[nodiscard]] int count() const {
|
|
return m_size;
|
|
}
|
|
|
|
protected:
|
|
int m_size = 0;
|
|
unsigned char *m_data = nullptr;
|
|
};
|
|
|
|
void binWrite(void *const dst, const void *src, const int size) {
|
|
memcpy(dst, src, size);
|
|
}
|
|
|
|
void fakeWrite(void *const dst, const void *src, const int size) {
|
|
(void)dst;
|
|
(void)src;
|
|
(void)size;
|
|
}
|
|
|
|
using Write = void (*)(void *, const void *, int);
|
|
|
|
template <Write write> class OutBuffer final : public Buffer {
|
|
public:
|
|
explicit OutBuffer(unsigned char *const data_)
|
|
: Buffer(0, data_) {}
|
|
|
|
void operator&(uchar &val) override {
|
|
write(m_data + m_size, &val, sizeof(val));
|
|
m_size += static_cast<int>(sizeof(val));
|
|
}
|
|
void operator&(std::vector<cv::Mat> &val) override {
|
|
const int size = static_cast<int>(val.size());
|
|
write(m_data + m_size, &size, sizeof(size));
|
|
m_size += static_cast<int>(sizeof(size));
|
|
|
|
for (auto &element : val) {
|
|
writeElement(element);
|
|
}
|
|
}
|
|
void writeElement(cv::Mat &val) {
|
|
write(m_data + m_size, &val.cols, sizeof(int));
|
|
m_size += static_cast<int>(sizeof(int));
|
|
|
|
write(m_data + m_size, &val.rows, sizeof(int));
|
|
m_size += static_cast<int>(sizeof(int));
|
|
|
|
for (int i = 0; i < val.rows; i++) {
|
|
write(m_data + m_size, val.ptr<unsigned char>(i), val.cols);
|
|
m_size += val.cols;
|
|
}
|
|
}
|
|
void operator&(std::vector<cv::Scalar> &val) override {
|
|
const int size = static_cast<int>(val.size());
|
|
write(m_data + m_size, &size, sizeof(size));
|
|
m_size += static_cast<int>(sizeof(size));
|
|
|
|
for (auto &element : val) {
|
|
writeElement(element);
|
|
}
|
|
}
|
|
void writeElement(const cv::Scalar &val) {
|
|
write(m_data + m_size, val.val, sizeof(double) * 4);
|
|
m_size += static_cast<int>(sizeof(double)) * 4;
|
|
}
|
|
void operator&(std::vector<double> &val) override {
|
|
const int size = static_cast<int>(val.size());
|
|
write(m_data + m_size, &size, sizeof(size));
|
|
m_size += static_cast<int>(sizeof(size));
|
|
|
|
write(m_data + m_size, val.data(), static_cast<int>(sizeof(double)) * size);
|
|
m_size += static_cast<int>(sizeof(double)) * size;
|
|
}
|
|
void operator&(std::vector<uchar> &val) override {
|
|
const int size = static_cast<int>(val.size());
|
|
write(m_data + m_size, &size, sizeof(size));
|
|
m_size += static_cast<int>(sizeof(size));
|
|
|
|
write(m_data + m_size, val.data(), sizeof(uchar) * size);
|
|
m_size += static_cast<int>(sizeof(uchar)) * size;
|
|
}
|
|
};
|
|
|
|
using SizeCountBuffer = OutBuffer<fakeWrite>;
|
|
using WriteBuffer = OutBuffer<binWrite>;
|
|
|
|
class ReadBuffer final : public Buffer {
|
|
public:
|
|
explicit ReadBuffer(unsigned char *data_)
|
|
: Buffer(0, data_) {}
|
|
|
|
void operator&(uchar &val) override {
|
|
memcpy(&val, m_data + m_size, sizeof(uchar));
|
|
m_size += static_cast<int>(sizeof(uchar));
|
|
}
|
|
void operator&(std::vector<cv::Mat> &val) override {
|
|
int count = 0;
|
|
memcpy(&count, m_data + m_size, sizeof(int));
|
|
val.resize(count);
|
|
m_size += static_cast<int>(sizeof(count));
|
|
|
|
for (auto &element : val) {
|
|
read(element);
|
|
}
|
|
}
|
|
void read(cv::Mat &val) {
|
|
int width = 0;
|
|
memcpy(&width, m_data + m_size, sizeof(int));
|
|
m_size += static_cast<int>(sizeof(int));
|
|
|
|
int height = 0;
|
|
memcpy(&height, m_data + m_size, sizeof(int));
|
|
m_size += static_cast<int>(sizeof(int));
|
|
|
|
const int alignedWidth = static_cast<int>(cv::alignSize(width, simdSize(cv::v_uint8)));
|
|
const auto img = cv::Mat::zeros(height, alignedWidth, CV_8UC1);
|
|
val = img(cv::Rect(0, 0, width, height));
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
auto *ptr = val.ptr<uchar>(y);
|
|
memcpy(ptr, m_data + m_size, width);
|
|
m_size += width;
|
|
}
|
|
}
|
|
void operator&(std::vector<cv::Scalar> &val) override {
|
|
int count = 0;
|
|
memcpy(&count, m_data + m_size, sizeof(int));
|
|
val.resize(count);
|
|
m_size += static_cast<int>(sizeof(count));
|
|
|
|
for (auto &element : val) {
|
|
read(element);
|
|
}
|
|
}
|
|
void read(cv::Scalar &val) {
|
|
memcpy(val.val, m_data + m_size, sizeof(double) * 4);
|
|
m_size += static_cast<int>(sizeof(double)) * 4;
|
|
}
|
|
void operator&(std::vector<double> &val) override {
|
|
int count = 0;
|
|
memcpy(&count, m_data + m_size, sizeof(int));
|
|
val.resize(count);
|
|
m_size += static_cast<int>(sizeof(count));
|
|
|
|
memcpy(val.data(), m_data + m_size, sizeof(double) * count);
|
|
m_size += static_cast<int>(sizeof(double)) * count;
|
|
}
|
|
void operator&(std::vector<uchar> &val) override {
|
|
int count = 0;
|
|
memcpy(&count, m_data + m_size, sizeof(int));
|
|
val.resize(count);
|
|
m_size += static_cast<int>(sizeof(count));
|
|
|
|
memcpy(val.data(), m_data + m_size, sizeof(bool) * count);
|
|
m_size += static_cast<int>(sizeof(uchar)) * count;
|
|
}
|
|
};
|
|
|
|
void operation(Buffer *buf, Model &model) {
|
|
*buf &model;
|
|
}
|
|
|
|
bool serialize(Model *const model, unsigned char *buffer, int *size) {
|
|
if (nullptr == size) {
|
|
return false;
|
|
}
|
|
|
|
if (nullptr == model) {
|
|
*size = 0;
|
|
return false;
|
|
}
|
|
|
|
SizeCountBuffer counter(buffer);
|
|
operation(&counter, *model);
|
|
|
|
if (nullptr == buffer) {
|
|
*size = counter.count();
|
|
return true;
|
|
}
|
|
|
|
if (counter.count() > *size) {
|
|
*size = 0;
|
|
return false;
|
|
}
|
|
|
|
WriteBuffer writer(buffer);
|
|
operation(&writer, *model);
|
|
return true;
|
|
}
|
|
|
|
Model_t deserialize(unsigned char *buffer, const int size) {
|
|
if (size < 1 || nullptr == buffer) {
|
|
return nullptr;
|
|
}
|
|
|
|
ReadBuffer reader(buffer);
|
|
auto *model = new Model;
|
|
operation(&reader, *model);
|
|
|
|
return model;
|
|
}
|