Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
6.7 KiB
204 lines
6.7 KiB
#ifndef MATLAB_IO_HPP_ |
|
#define MATLAB_IO_HPP_ |
|
|
|
#include <sstream> |
|
#include <fstream> |
|
#include <zlib.h> |
|
#include <opencv2/core.hpp> |
|
#include <opencv2/core/persistence.hpp> |
|
#include "primitives.hpp" |
|
#include "bridge.hpp" |
|
#include "mxarray.hpp" |
|
#include "map.hpp" |
|
|
|
namespace Matlab { |
|
namespace IO { |
|
class RandomAccessRead {}; |
|
class SequentialWrite {}; |
|
static const int Version5 = 5; |
|
static const int Version73 = 73; |
|
} |
|
|
|
// predeclarations |
|
class IONode; |
|
class IONodeIterator; |
|
class MatlabIO; |
|
|
|
|
|
// ---------------------------------------------------------------------------- |
|
// FILE AS A DATA STRUCTURE |
|
// ---------------------------------------------------------------------------- |
|
class IONode { |
|
protected: |
|
//! the name of the field (if associative container) |
|
std::string name_; |
|
//! the size of the field |
|
std::vector<size_t> size_; |
|
//! beginning of the data field in the file |
|
size_t begin_; |
|
//! address after the last data field |
|
size_t end_; |
|
//! Matlab stored-type |
|
int stored_type_; |
|
//! Matlab actual type (sometimes compression is used) |
|
int type_; |
|
//! is the field compressed? |
|
bool compressed_; |
|
//! are the descendents associative (mappings) |
|
bool associative_; |
|
//! is this a leaf node containing data, or an interior node |
|
bool leaf_; |
|
//! the data stream from which the file was indexed |
|
cv::Ptr<std::istream> stream_; |
|
//! valid if the container is a sequence (list) |
|
std::vector<IONode> sequence_; |
|
//! valid if the container is a mapping (associative) |
|
Map<std::string, IONode> mapping_; |
|
IONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, bool compressed, bool associative, bool leaf, istream& stream) : |
|
name_(name), size_(size), begin_(begin), end_(end), stored_type_(stored_type), type_(type), |
|
compressed_(compressed), associative_(associative), leaf_(leaf), stream_(stream) {} |
|
public: |
|
std::string name() const { return name_; } |
|
std::vector<size_t> size() const { return size_; } |
|
size_t begin() const { return begin_; } |
|
size_t end() const { return end_; } |
|
int stored_type() const { return stored_type_; } |
|
int type() const { return type_; } |
|
bool compressed() const { return compressed_; } |
|
bool associative() const { return associative_; } |
|
bool leaf() const { return leaf_; } |
|
IONode() : begin_(0), end_(0), stored_type_(0), type_(0), leaf_(true) {} |
|
|
|
#if __cplusplus >= 201103L |
|
// conversion operators |
|
template <typename T> void operator=(const T& obj) { static_assert(0, "Unimplemented specialization for given type"); } |
|
template <typename T> operator T() { static_assert(0, "Unimplemented specialization for given type"); } |
|
#else |
|
// conversion operators |
|
template <typename T> void operator=(const T& obj) { T::unimplemented_specialization; } |
|
template <typename T> operator T() { T::unimplemented_specialization; } |
|
#endif |
|
|
|
void swap(const IONode& other) { |
|
using std::swap; |
|
swap(name_, other.name_); |
|
swap(size_, other.size_); |
|
swap(begin_, other.begin_); |
|
swap(end_, other.end_); |
|
swap(stored_type_, other.stored_type_); |
|
swap(type_, other.type_); |
|
swap(compressed_, other.compressed_); |
|
swap(associative_, other.associative_); |
|
swap(leaf_, other.leaf_); |
|
swap(stream_, other.stream_); |
|
swap(sequence_, other.sequence_); |
|
swap(mapping_, other.mapping_); |
|
} |
|
}; |
|
|
|
class SequenceIONode : public IONode { |
|
public: |
|
std::vector<IONode>& sequence() { return sequence_; } |
|
SequenceIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, const std::istream& stream) : |
|
IONode(name, size, begin, end, stored_type, type, false, false, false, stream) {} |
|
}; |
|
|
|
class MappingIONode : public IONode { |
|
public: |
|
Map<std::string, IONode>& mapping() { return mapping_; } |
|
MappingIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, const std::istream& stream) : |
|
IONode(name, size, begin, end, stored_type, type, false, true, false, stream) {} |
|
}; |
|
|
|
class LeafIONode : public IONode { |
|
LeafIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, const std::istream& stream) : |
|
IONode(name, size, begin, end, stored_type, type, false, false, true, stream) {} |
|
}; |
|
|
|
class CompressedIONode : public IONode { |
|
private: |
|
std::istringstream uncompressed_stream_; |
|
std::vector<char> data_; |
|
public: |
|
CompressedIONode(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, const std::stream& stream) : |
|
IONode(name, size, begin, end, stored_type, type, true, false, false, stream) {} |
|
}; |
|
|
|
class Header : public IONode { |
|
Header(const std::string& name, const std::Vector<size_t>& size, size_t begin, size_t end, |
|
int stored_type, int type, const std::stream& stream) : |
|
IONode(name, size, begin, end, stored_type, type, true, false, false, stream) {} |
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------- |
|
// FILE NODE |
|
// ---------------------------------------------------------------------------- |
|
class IONodeIterator : public std::iterator<std::random_access_iterator_tag, MatlabIONode> { |
|
|
|
}; |
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------- |
|
// MATLABIO |
|
// ---------------------------------------------------------------------------- |
|
class MatlabIO { |
|
private: |
|
// member variables |
|
static const int HEADER_LENGTH = 116; |
|
static const int SUBSYS_LENGTH = 8; |
|
static const int ENDIAN_LENGTH = 2; |
|
std::string header_; |
|
std::string subsys_; |
|
std::string endian_; |
|
int version_; |
|
bool byte_swap_; |
|
std::string filename_; |
|
// uses a custom stream buffer for fast memory-mapped access and endian swapping |
|
std::fstream stream_; |
|
std::ifstream::pos_type stream_pos_; |
|
//! the main file index. The top-level index must be associative |
|
IONode index_; |
|
|
|
// internal methods |
|
void getFileHeader(); |
|
void setFileHeader(); |
|
|
|
void getHeader(); |
|
void setHeader(); |
|
|
|
CompressedIONode uncompress(const IONode& node); |
|
|
|
public: |
|
// construct/destruct |
|
MatlabIO() : header_(HEADER_LENGTH+1, '\0'), subsys_(SUBSYS_LENGTH+1, '\0'), |
|
endian_(ENDIAN_LENGTH+1, '\0'), byte_swap(false), stream_pos_(0) {} |
|
~MatlabIO {} |
|
|
|
// global read and write routines |
|
std::string filename(void); |
|
bool open(const std::string& filename, std::ios_base::openmode mode); |
|
bool isOpen() const; |
|
void close(); |
|
void clear(); |
|
|
|
// index the contents of the file |
|
void index(); |
|
|
|
// print all of the top-level variables in the file |
|
void printRootIndex() const; |
|
void printFullIndex() const; |
|
|
|
// FileNode operations |
|
IONode root() const; |
|
IONode operator[](const String& nodename) const; |
|
}; |
|
|
|
#endif
|
|
|