Code reorganiation

This commit is contained in:
2023-03-09 16:22:08 +01:00
parent 14a109b21c
commit 5ef773b3fb
8 changed files with 229 additions and 323 deletions
+4 -3
View File
@@ -11,13 +11,14 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
add_library(XISF
bytearray.cpp
bytearray.h
libXISF_global.h
libxisf.cpp
libxisf.h
utils.cpp
utils.h
propertyvariant.cpp
propertyvariant.h
variant.cpp
variant.h
lz4/lz4.c
lz4/lz4.h
lz4/lz4hc.c
+162
View File
@@ -0,0 +1,162 @@
#include "libxisf.h"
namespace LibXISF
{
void ByteArray::makeUnique()
{
if(!_data.unique())
_data = std::make_unique<PtrType>(_data->begin(), _data->end());
}
ByteArray::ByteArray(size_t size)
{
_data = std::make_shared<std::vector<char>>();
_data->resize(size);
}
ByteArray::ByteArray(const char *ptr) : ByteArray((size_t)0)
{
size_t len = std::strlen(ptr);
if(len)
{
_data->resize(len);
std::memcpy(data(), ptr, len);
}
}
ByteArray::ByteArray(const ByteArray &d)
{
_data = d._data;
}
char& ByteArray::operator[](size_t i)
{
makeUnique();
return (*_data)[i];
}
const char& ByteArray::operator[](size_t i) const
{
return (*_data)[i];
}
size_t ByteArray::size() const
{
return _data->size();
}
void ByteArray::resize(size_t newsize)
{
makeUnique();
_data->resize(newsize);
}
void ByteArray::append(char c)
{
_data->push_back(c);
}
void ByteArray::decodeBase64()
{
int i = 0;
Ptr tmp = std::make_unique<PtrType>();
uint8_t c4[4] = {0};
for(uint8_t c : *_data)
{
if(c >= 'A' && c <= 'Z')c4[i++] = c - 'A';
else if(c >= 'a' && c <= 'z')c4[i++] = c - 'a' + 26;
else if(c >= '0' && c <= '9')c4[i++] = c - '0' + 52;
else if(c == '+')c4[i++] = 62;
else if(c == '/')c4[i++] = 63;
if(i == 4)
{
tmp->push_back((c4[0] << 2) | (c4[1] >> 4));
tmp->push_back((c4[1] << 4) | (c4[2] >> 2));
tmp->push_back((c4[2] << 6) | c4[3]);
i = 0;
}
}
if(i > 1)tmp->push_back((c4[0] << 2) | (c4[1] >> 4));
if(i > 2)tmp->push_back((c4[1] << 4) | (c4[2] >> 2));
std::swap(_data, tmp);
}
void ByteArray::encodeBase64()
{
static const char *base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Ptr tmp = std::make_unique<PtrType>();
int i = 0;
uint8_t sextet[4] = {0};
for(uint8_t c : *_data)
{
switch(i)
{
case 0:
sextet[0] |= c >> 2 & 0x3f;
sextet[1] |= c << 4 & 0x3f;
i++;
break;
case 1:
sextet[1] |= c >> 4 & 0x3f;
sextet[2] |= c << 2 & 0x3f;
i++;
break;
case 2:
sextet[2] |= c >> 6 & 0x3f;
sextet[3] = c & 0x3f;
i = 0;
for(int o=0; o<4; o++)
tmp->push_back(base64[sextet[o]]);
std::memset(sextet, 0, sizeof(sextet));
break;
}
}
for(int o = 0; o <= i && i; o++)
tmp->push_back(base64[sextet[o]]);
if(tmp->size() % 4)
tmp->resize(tmp->size() + 4 - (tmp->size() % 4), '=');
std::swap(_data, tmp);
}
void ByteArray::encodeHex()
{
static const char *hex = "0123456789abcdef";
Ptr tmp = std::make_unique<PtrType>(_data->size() * 2);
for(size_t i = 0; i< _data->size(); i++)
{
uint8_t t = static_cast<uint8_t>(_data->at(i));
(*tmp)[2*i + 0] = hex[(t & 0xf0) >> 4];
(*tmp)[2*i + 1] = hex[t & 0xf];
}
std::swap(_data, tmp);
}
void ByteArray::decodeHex()
{
auto toByte = [](char c) -> char
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return c - '7';
if(c >= 'a' && c <= 'f')
return c - 'W';
return 0;
};
Ptr tmp = std::make_unique<PtrType>(size() / 2);
for(size_t i = 0; i< tmp->size(); i++)
{
(*tmp)[i] = (toByte(_data->at(i*2)) << 4) | toByte(_data->at(i*2+1));
}
std::swap(_data, tmp);
}
}
+8 -6
View File
@@ -16,12 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#ifndef UTILS_H
#define UTILS_H
#ifndef LIBXISF_BYTEARRAY_H
#define LIBXISF_BYTEARRAY_H
#include <vector>
#include <string>
namespace LibXISF
{
std::vector<std::string> split_string(const std::string &str, char delimiter);
#endif // UTILS_H
}
#endif // LIBXISF_BYTEARRAY_H
+8 -8
View File
@@ -27,11 +27,11 @@
#include "lz4/lz4hc.h"
#include "pugixml/pugixml.hpp"
#include "zlib/zlib.h"
#include "utils.h"
namespace LibXISF
{
std::vector<std::string> splitString(const std::string &str, char delimiter);
void deserializeVariant(const pugi::xml_node &node, Variant &variant, const ByteArray &data);
void serializeVariant(pugi::xml_node &node, const Variant &variant);
@@ -118,9 +118,9 @@ void DataBlock::decompress(const ByteArray &input, const String &encoding)
ByteArray tmp = input;
if(encoding == "base64")
tmp.decode_base64();
tmp.decodeBase64();
else if(encoding == "base16")
tmp.decode_hex();
tmp.decodeHex();
switch(codec)
{
@@ -625,7 +625,7 @@ void XISFReaderPrivate::readSignature()
void XISFReaderPrivate::parseCompression(const pugi::xml_node &node, DataBlock &dataBlock)
{
std::vector<std::string> compression = split_string(node.attribute("compression").as_string(), ':');
std::vector<std::string> compression = splitString(node.attribute("compression").as_string(), ':');
if(compression.size() >= 2)
{
if(compression[0].find("zlib") == 0)
@@ -652,7 +652,7 @@ void XISFReaderPrivate::parseCompression(const pugi::xml_node &node, DataBlock &
DataBlock XISFReaderPrivate::parseDataBlock(const pugi::xml_node &node)
{
DataBlock dataBlock;
std::vector<std::string> location = split_string(node.attribute("location").as_string(), ':');
std::vector<std::string> location = splitString(node.attribute("location").as_string(), ':');
parseCompression(node, dataBlock);
@@ -749,14 +749,14 @@ Image XISFReaderPrivate::parseImage(const pugi::xml_node &node)
{
Image image;
std::vector<std::string> geometry = split_string(node.attribute("geometry").as_string(), ':');
std::vector<std::string> geometry = splitString(node.attribute("geometry").as_string(), ':');
if(geometry.size() != 3)throw Error("We support only 2D images");
image._width = std::stoul(geometry[0]);
image._height = std::stoul(geometry[1]);
image._channelCount = std::stoul(geometry[2]);
if(!image._width || !image._height || !image._channelCount)throw Error("Invalid image geometry");
std::vector<std::string> bounds = split_string(node.attribute("bounds").as_string(), ':');
std::vector<std::string> bounds = splitString(node.attribute("bounds").as_string(), ':');
if(bounds.size() == 2)
{
image._bounds.first = std::stod(bounds[0]);
@@ -921,7 +921,7 @@ void XISFWriterPrivate::writeImageElement(pugi::xml_node &node, const Image &ima
if(image._iccProfile.size())
{
ByteArray base64 = image._iccProfile;
base64.decode_base64();
base64.decodeBase64();
pugi::xml_node icc_node = image_node.append_child("ICCProfile");
icc_node.append_attribute("location").set_value("inline:base64");
icc_node.append_child(pugi::node_pcdata).set_value(base64.data());
+32 -1
View File
@@ -25,7 +25,7 @@
#include <variant>
#include <fstream>
#include <cstring>
#include "propertyvariant.h"
#include "variant.h"
namespace LibXISF
{
@@ -33,6 +33,37 @@ namespace LibXISF
class XISFReaderPrivate;
class XISFWriterPrivate;
class LIBXISF_EXPORT ByteArray
{
using PtrType = std::vector<char>;
using Ptr = std::shared_ptr<PtrType>;
Ptr _data;
void makeUnique();
public:
ByteArray() : ByteArray((size_t)0) {}
explicit ByteArray(size_t size);
explicit ByteArray(const char *ptr);
ByteArray(const char *ptr, size_t size)
{
_data = std::make_shared<std::vector<char>>();
_data->resize(size);
std::memcpy(data(), ptr, size);
}
ByteArray(const ByteArray &d);
char& operator[](size_t i);
const char& operator[](size_t i) const;
char* data() { return &_data->at(0); }
const char* data() const { return &_data->at(0); }
const char* constData() const { return &_data->at(0); }
size_t size() const;
void resize(size_t newsize);
void append(char c);
void decodeBase64();
void encodeBase64();
void encodeHex();
void decodeHex();
};
struct LIBXISF_EXPORT DataBlock
{
enum CompressionCodec
+9 -2
View File
@@ -16,9 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "utils.h"
#include <vector>
#include <string>
#include <cstdint>
std::vector<std::string> split_string(const std::string &str, char delimiter)
namespace LibXISF
{
std::vector<std::string> splitString(const std::string &str, char delimiter)
{
std::vector<std::string> ret;
size_t cur = 0;
@@ -122,3 +127,5 @@ void sha1(uint8_t *data, size_t len, uint8_t *hash)
hash[12] = h3 >> 24 & 0xff; hash[13] = h3 >> 16 & 0xff; hash[14] = h3 >> 8 & 0xff; hash[15] = h3 & 0xff;
hash[16] = h4 >> 24 & 0xff; hash[17] = h4 >> 16 & 0xff; hash[18] = h4 >> 8 & 0xff; hash[19] = h4 & 0xff;
}
}
+3 -245
View File
@@ -16,20 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "propertyvariant.h"
#include "variant.h"
#include <charconv>
#include <type_traits>
#include <array>
#include <map>
#include <iostream>
#include <regex>
#include <iomanip>
#include "libxisf.h"
#include "pugixml/pugixml.hpp"
template<class... Ts> struct overload : Ts... { bool fail = true; using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;
namespace LibXISF
{
@@ -180,7 +175,7 @@ void toCharsVector(const Variant &v, size_t &len, ByteArray &data)
size_t size = len * sizeof(typename T::value_type);
data.resize(size);
std::memcpy(data.data(), &v.value<T>()[0], size);
data.encode_base64();
data.encodeBase64();
}
template<typename T>
@@ -191,7 +186,7 @@ void toCharsMatrix(const Variant &v, size_t &rows, size_t &cols, ByteArray &data
size_t size = rows * cols * sizeof(typename T::value_type);
data.resize(size);
std::memcpy(data.data(), &v.value<T>()(0, 0), size);
data.encode_base64();
data.encodeBase64();
}
void deserializeVariant(const pugi::xml_node &node, Variant &variant, const ByteArray &data)
@@ -378,243 +373,6 @@ void serializeVariant(pugi::xml_node &node, const Variant &variant)
}
}
void ByteArray::makeUnique()
{
if(!_data.unique())
_data = std::make_unique<PtrType>(_data->begin(), _data->end());
}
ByteArray::ByteArray(size_t size)
{
_data = std::make_shared<std::vector<char>>();
_data->resize(size);
}
ByteArray::ByteArray(const char *ptr) : ByteArray((size_t)0)
{
size_t len = std::strlen(ptr);
if(len)
{
_data->resize(len);
std::memcpy(data(), ptr, len);
}
}
ByteArray::ByteArray(const ByteArray &d)
{
_data = d._data;
}
char& ByteArray::operator[](size_t i)
{
makeUnique();
return (*_data)[i];
}
const char& ByteArray::operator[](size_t i) const
{
return (*_data)[i];
}
size_t ByteArray::size() const
{
return _data->size();
}
void ByteArray::resize(size_t newsize)
{
makeUnique();
_data->resize(newsize);
}
void ByteArray::append(char c)
{
_data->push_back(c);
}
void ByteArray::decode_base64()
{
int i = 0;
Ptr tmp = std::make_unique<PtrType>();
uint8_t c4[4] = {0};
for(uint8_t c : *_data)
{
if(c >= 'A' && c <= 'Z')c4[i++] = c - 'A';
else if(c >= 'a' && c <= 'z')c4[i++] = c - 'a' + 26;
else if(c >= '0' && c <= '9')c4[i++] = c - '0' + 52;
else if(c == '+')c4[i++] = 62;
else if(c == '/')c4[i++] = 63;
if(i == 4)
{
tmp->push_back((c4[0] << 2) | (c4[1] >> 4));
tmp->push_back((c4[1] << 4) | (c4[2] >> 2));
tmp->push_back((c4[2] << 6) | c4[3]);
i = 0;
}
}
if(i > 1)tmp->push_back((c4[0] << 2) | (c4[1] >> 4));
if(i > 2)tmp->push_back((c4[1] << 4) | (c4[2] >> 2));
std::swap(_data, tmp);
}
void ByteArray::encode_base64()
{
static const char *base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Ptr tmp = std::make_unique<PtrType>();
int i = 0;
uint8_t sextet[4] = {0};
for(uint8_t c : *_data)
{
switch(i)
{
case 0:
sextet[0] |= c >> 2 & 0x3f;
sextet[1] |= c << 4 & 0x3f;
i++;
break;
case 1:
sextet[1] |= c >> 4 & 0x3f;
sextet[2] |= c << 2 & 0x3f;
i++;
break;
case 2:
sextet[2] |= c >> 6 & 0x3f;
sextet[3] = c & 0x3f;
i = 0;
for(int o=0; o<4; o++)
tmp->push_back(base64[sextet[o]]);
std::memset(sextet, 0, sizeof(sextet));
break;
}
}
for(int o = 0; o <= i && i; o++)
tmp->push_back(base64[sextet[o]]);
if(tmp->size() % 4)
tmp->resize(tmp->size() + 4 - (tmp->size() % 4), '=');
std::swap(_data, tmp);
}
void ByteArray::encode_hex()
{
static const char *hex = "0123456789abcdef";
Ptr tmp = std::make_unique<PtrType>(_data->size() * 2);
for(size_t i = 0; i< _data->size(); i++)
{
uint8_t t = static_cast<uint8_t>(_data->at(i));
(*tmp)[2*i + 0] = hex[(t & 0xf0) >> 4];
(*tmp)[2*i + 1] = hex[t & 0xf];
}
std::swap(_data, tmp);
}
void ByteArray::decode_hex()
{
auto toByte = [](char c) -> char
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return c - '7';
if(c >= 'a' && c <= 'f')
return c - 'W';
return 0;
};
Ptr tmp = std::make_unique<PtrType>(size() / 2);
for(size_t i = 0; i< tmp->size(); i++)
{
(*tmp)[i] = (toByte(_data->at(i*2)) << 4) | toByte(_data->at(i*2+1));
}
std::swap(_data, tmp);
}
ByteStream::ByteStream()
{
//setg(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
}
ByteStream::~ByteStream()
{
}
const ByteArray &ByteStream::buffer() const
{
return _buffer;
}
void ByteStream::stats()
{
std::cout << "pbase " << (void*)pbase() << std::endl;
std::cout << "pptr " << (void*)pptr() << std::endl;
std::cout << "epptr " << (void*)epptr() << std::endl;
std::cout << "eback " << (void*)eback() << std::endl;
std::cout << "gptr " << (void*)gptr() << std::endl;
std::cout << "egptr " << (void*)egptr() << std::endl;
}
ByteStream::pos_type ByteStream::seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode)
{
return pos_type(off_type(-1));
}
ByteStream::pos_type ByteStream::seekpos(pos_type, std::ios_base::openmode)
{
return pos_type(off_type(-1));
}
/*std::streamsize ByteStream::showmanyc()
{
return _buffer.size() - ipos;
}
std::streamsize ByteStream::xsgetn(char_type *s, std::streamsize n)
{
if((std::streamoff)_buffer.size() > ipos + n)
{
std::memcpy(s, _buffer.data() + ipos, n);
return n;
}
return pos_type(off_type(-1));
}
ByteStream::int_type ByteStream::underflow()
{
if(ipos >= (std::streamoff)_buffer.size())return traits_type::eof();
return traits_type::to_int_type(_buffer[ipos]);
}*/
std::streamsize ByteStream::xsputn(const char_type *s, std::streamsize n)
{
if(opos + n >= (std::streamsize)_buffer.size())
{
_buffer.resize(opos + n);
setoptr();
}
std::memcpy(_buffer.data() + opos, s, n);
opos += n;
return n;
}
ByteStream::int_type ByteStream::overflow(int_type c)
{
_buffer.append(c);
return c;
}
void ByteStream::setoptr()
{
size_t off = gptr() - eback();
setg(_buffer.data(), _buffer.data() + off, _buffer.data() + _buffer.size());
}
Variant::Type Variant::type() const
{
return (Variant::Type)_value.index();
+3 -58
View File
@@ -16,8 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#ifndef PROPERTYVARIANT_H
#define PROPERTYVARIANT_H
#ifndef LIBXISF_VARIANT_H
#define LIBXISF_VARIANT_H
#include <variant>
#include <cstdint>
@@ -32,61 +32,6 @@
namespace LibXISF
{
class LIBXISF_EXPORT ByteArray
{
using PtrType = std::vector<char>;
using Ptr = std::shared_ptr<PtrType>;
Ptr _data;
void makeUnique();
public:
ByteArray() : ByteArray((size_t)0) {}
explicit ByteArray(size_t size);
explicit ByteArray(const char *ptr);
ByteArray(const char *ptr, size_t size)
{
_data = std::make_shared<std::vector<char>>();
_data->resize(size);
std::memcpy(data(), ptr, size);
}
ByteArray(const ByteArray &d);
char& operator[](size_t i);
const char& operator[](size_t i) const;
char* data() { return &_data->at(0); }
const char* data() const { return &_data->at(0); }
const char* constData() const { return &_data->at(0); }
size_t size() const;
void resize(size_t newsize);
void append(char c);
void decode_base64();
void encode_base64();
void encode_hex();
void decode_hex();
};
class ByteStream : public std::basic_streambuf<char>
{
ByteArray _buffer;
pos_type opos = 0;
pos_type ipos = 0;
public:
ByteStream();
~ByteStream();
const ByteArray& buffer() const;
void stats();
protected:
pos_type seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode = std::ios_base::in | std::ios_base::out) override;
pos_type seekpos(pos_type, std::ios_base::openmode = std::ios_base::in | std::ios_base::out) override;
/*std::streamsize showmanyc() override;
std::streamsize xsgetn(char_type *s, std::streamsize n) override;
int_type underflow() override;*/
std::streamsize xsputn(const char_type *s, std::streamsize n) override;
int_type overflow(int_type c = traits_type::eof()) override;
void setoptr();
};
struct Complex32
{
float real;
@@ -186,4 +131,4 @@ public:
}
#endif // PROPERTYVARIANT_H
#endif // LIBXISF_VARIANT_H