Move implementation to Private class

This commit is contained in:
2023-03-06 18:42:09 +01:00
parent b24bc8ecdd
commit f2ad012542
3 changed files with 159 additions and 56 deletions
+143 -26
View File
@@ -35,8 +35,6 @@ namespace LibXISF
void deserializeVariant(const pugi::xml_node &node, Variant &variant, const ByteArray &data); void deserializeVariant(const pugi::xml_node &node, Variant &variant, const ByteArray &data);
void serializeVariant(pugi::xml_node &node, const Variant &variant); void serializeVariant(pugi::xml_node &node, const Variant &variant);
static std::unordered_map<String, int> typeToId;
static std::unordered_map<int, String> idToType;
static std::unordered_map<String, Image::Type> imageTypeToEnum; static std::unordered_map<String, Image::Type> imageTypeToEnum;
static std::unordered_map<Image::Type, String> imageTypeToString; static std::unordered_map<Image::Type, String> imageTypeToString;
static std::unordered_map<String, Image::SampleFormat> sampleFormatToEnum; static std::unordered_map<String, Image::SampleFormat> sampleFormatToEnum;
@@ -506,7 +504,38 @@ size_t Image::sampleFormatSize(SampleFormat sampleFormat)
return sizeof(UInt16); return sizeof(UInt16);
} }
void XISFReader::open(const String &name) class XISFReaderPrivate
{
public:
void open(const String &name);
void open(const ByteArray &data);
/** Open image from istream. This method takes ownership of *io pointer */
void open(std::istream *io);
/** Close opended file release all data. */
void close();
/** Return number of images inside file */
int imagesCount() const;
/** Return reference to Image
* @param n index of image
* @param readPixel when false it will read pixel data from file and imageData()
* will return nullptr */
const Image& getImage(uint32_t n, bool readPixels = true);
private:
void readXISFHeader();
void readSignature();
void parseCompression(const pugi::xml_node &node, DataBlock &dataBlock);
DataBlock parseDataBlock(const pugi::xml_node &node);
Property parseProperty(const pugi::xml_node &node);
FITSKeyword parseFITSKeyword(const pugi::xml_node &node);
ColorFilterArray parseCFA(const pugi::xml_node &node);
Image parseImage(const pugi::xml_node &node);
std::unique_ptr<std::istream> _io;
std::vector<Image> _images;
std::vector<Property> _properties;
};
void XISFReaderPrivate::open(const String &name)
{ {
close(); close();
_io = std::make_unique<std::ifstream>(name.c_str(), std::ios_base::in | std::ios_base::binary); _io = std::make_unique<std::ifstream>(name.c_str(), std::ios_base::in | std::ios_base::binary);
@@ -514,7 +543,7 @@ void XISFReader::open(const String &name)
readXISFHeader(); readXISFHeader();
} }
void XISFReader::open(const ByteArray &data) void XISFReaderPrivate::open(const ByteArray &data)
{ {
close(); close();
std::string str((char*)data.data(), data.size()); std::string str((char*)data.data(), data.size());
@@ -523,7 +552,7 @@ void XISFReader::open(const ByteArray &data)
readXISFHeader(); readXISFHeader();
} }
void XISFReader::open(std::istream *io) void XISFReaderPrivate::open(std::istream *io)
{ {
close(); close();
_io.reset(io); _io.reset(io);
@@ -531,19 +560,19 @@ void XISFReader::open(std::istream *io)
readXISFHeader(); readXISFHeader();
} }
void XISFReader::close() void XISFReaderPrivate::close()
{ {
_io.reset(); _io.reset();
_images.clear(); _images.clear();
_properties.clear(); _properties.clear();
} }
int XISFReader::imagesCount() const int XISFReaderPrivate::imagesCount() const
{ {
return _images.size(); return _images.size();
} }
const Image& XISFReader::getImage(uint32_t n, bool readPixels) const Image& XISFReaderPrivate::getImage(uint32_t n, bool readPixels)
{ {
if(n >= _images.size()) if(n >= _images.size())
throw Error("Out of bounds"); throw Error("Out of bounds");
@@ -559,7 +588,7 @@ const Image& XISFReader::getImage(uint32_t n, bool readPixels)
return img; return img;
} }
void XISFReader::readXISFHeader() void XISFReaderPrivate::readXISFHeader()
{ {
uint32_t headerLen[2] = {0}; uint32_t headerLen[2] = {0};
_io->read((char*)&headerLen, sizeof(headerLen)); _io->read((char*)&headerLen, sizeof(headerLen));
@@ -583,7 +612,7 @@ void XISFReader::readXISFHeader()
else throw Error("Unknown root XML element"); else throw Error("Unknown root XML element");
} }
void XISFReader::readSignature() void XISFReaderPrivate::readSignature()
{ {
char signature[8]; char signature[8];
_io->read(signature, sizeof(signature)); _io->read(signature, sizeof(signature));
@@ -594,7 +623,7 @@ void XISFReader::readSignature()
throw Error("Not valid XISF 1.0 file"); throw Error("Not valid XISF 1.0 file");
} }
void XISFReader::parseCompression(const pugi::xml_node &node, DataBlock &dataBlock) 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 = split_string(node.attribute("compression").as_string(), ':');
if(compression.size() >= 2) if(compression.size() >= 2)
@@ -620,7 +649,7 @@ void XISFReader::parseCompression(const pugi::xml_node &node, DataBlock &dataBlo
} }
} }
DataBlock XISFReader::parseDataBlock(const pugi::xml_node &node) DataBlock XISFReaderPrivate::parseDataBlock(const pugi::xml_node &node)
{ {
DataBlock dataBlock; DataBlock dataBlock;
std::vector<std::string> location = split_string(node.attribute("location").as_string(), ':'); std::vector<std::string> location = split_string(node.attribute("location").as_string(), ':');
@@ -663,7 +692,7 @@ DataBlock XISFReader::parseDataBlock(const pugi::xml_node &node)
return dataBlock; return dataBlock;
} }
Property XISFReader::parseProperty(const pugi::xml_node &node) Property XISFReaderPrivate::parseProperty(const pugi::xml_node &node)
{ {
Property property; Property property;
@@ -691,7 +720,7 @@ Property XISFReader::parseProperty(const pugi::xml_node &node)
return property; return property;
} }
FITSKeyword XISFReader::parseFITSKeyword(const pugi::xml_node &node) FITSKeyword XISFReaderPrivate::parseFITSKeyword(const pugi::xml_node &node)
{ {
FITSKeyword fitsKeyword; FITSKeyword fitsKeyword;
fitsKeyword.name = node.attribute("name").as_string(); fitsKeyword.name = node.attribute("name").as_string();
@@ -700,7 +729,7 @@ FITSKeyword XISFReader::parseFITSKeyword(const pugi::xml_node &node)
return fitsKeyword; return fitsKeyword;
} }
ColorFilterArray XISFReader::parseCFA(const pugi::xml_node &node) ColorFilterArray XISFReaderPrivate::parseCFA(const pugi::xml_node &node)
{ {
ColorFilterArray cfa; ColorFilterArray cfa;
if(node.attribute("pattern") && node.attribute("width") && node.attribute("height")) if(node.attribute("pattern") && node.attribute("width") && node.attribute("height"))
@@ -716,7 +745,7 @@ ColorFilterArray XISFReader::parseCFA(const pugi::xml_node &node)
return cfa; return cfa;
} }
Image XISFReader::parseImage(const pugi::xml_node &node) Image XISFReaderPrivate::parseImage(const pugi::xml_node &node)
{ {
Image image; Image image;
@@ -758,8 +787,26 @@ Image XISFReader::parseImage(const pugi::xml_node &node)
return image; return image;
} }
class XISFWriterPrivate
{
public:
void save(const String &name);
void save(ByteArray &data);
void save(std::ostream &io);
void writeImage(const Image &image);
private:
void writeHeader();
void writeImageElement(pugi::xml_node &node, const Image &image);
void writeDataBlockAttributes(pugi::xml_node &image_node, const DataBlock &dataBlock);
void writePropertyElement(pugi::xml_node &node, const Property &property);
void writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword);
void writeMetadata(pugi::xml_node &node);
ByteArray _xisfHeader;
ByteArray _attachmentsData;
std::vector<Image> _images;
};
void XISFWriter::save(const String &name) void XISFWriterPrivate::save(const String &name)
{ {
std::ofstream fw(name.c_str(), std::ios_base::out | std::ios_base::binary); std::ofstream fw(name.c_str(), std::ios_base::out | std::ios_base::binary);
@@ -769,7 +816,7 @@ void XISFWriter::save(const String &name)
save(fw); save(fw);
} }
void XISFWriter::save(ByteArray &data) void XISFWriterPrivate::save(ByteArray &data)
{ {
std::ostringstream oss; std::ostringstream oss;
save(oss); save(oss);
@@ -777,7 +824,7 @@ void XISFWriter::save(ByteArray &data)
data = ByteArray(str.data(), str.size()); data = ByteArray(str.data(), str.size());
} }
void XISFWriter::save(std::ostream &io) void XISFWriterPrivate::save(std::ostream &io)
{ {
writeHeader(); writeHeader();
@@ -789,14 +836,14 @@ void XISFWriter::save(std::ostream &io)
} }
} }
void XISFWriter::writeImage(const Image &image) void XISFWriterPrivate::writeImage(const Image &image)
{ {
_images.push_back(image); _images.push_back(image);
_images.back()._dataBlock.attachmentPos = 1; _images.back()._dataBlock.attachmentPos = 1;
_images.back()._dataBlock.compress(image.sampleFormatSize(image.sampleFormat())); _images.back()._dataBlock.compress(image.sampleFormatSize(image.sampleFormat()));
} }
void XISFWriter::writeHeader() void XISFWriterPrivate::writeHeader()
{ {
const char signature[16] = {'X', 'I', 'S', 'F', '0', '1', '0', '0', 0, 0, 0, 0, 0, 0, 0, 0}; const char signature[16] = {'X', 'I', 'S', 'F', '0', '1', '0', '0', 0, 0, 0, 0, 0, 0, 0, 0};
@@ -840,7 +887,7 @@ void XISFWriter::writeHeader()
_xisfHeader = ByteArray(header.c_str(), header.size()); _xisfHeader = ByteArray(header.c_str(), header.size());
} }
void XISFWriter::writeImageElement(pugi::xml_node &node, const Image &image) void XISFWriterPrivate::writeImageElement(pugi::xml_node &node, const Image &image)
{ {
pugi::xml_node image_node = node.append_child("Image"); pugi::xml_node image_node = node.append_child("Image");
std::string geometry = std::to_string(image._width) + ":" + std::to_string(image._height) + ":" + std::to_string(image._channelCount); std::string geometry = std::to_string(image._width) + ":" + std::to_string(image._height) + ":" + std::to_string(image._channelCount);
@@ -881,7 +928,7 @@ void XISFWriter::writeImageElement(pugi::xml_node &node, const Image &image)
} }
} }
void XISFWriter::writeDataBlockAttributes(pugi::xml_node &image_node, const DataBlock &dataBlock) void XISFWriterPrivate::writeDataBlockAttributes(pugi::xml_node &image_node, const DataBlock &dataBlock)
{ {
if(dataBlock.embedded) if(dataBlock.embedded)
{ {
@@ -919,7 +966,7 @@ void XISFWriter::writeDataBlockAttributes(pugi::xml_node &image_node, const Data
} }
} }
void XISFWriter::writePropertyElement(pugi::xml_node &node, const Property &property) void XISFWriterPrivate::writePropertyElement(pugi::xml_node &node, const Property &property)
{ {
pugi::xml_node property_node = node.append_child("Property"); pugi::xml_node property_node = node.append_child("Property");
property_node.append_attribute("id").set_value(property.id.c_str()); property_node.append_attribute("id").set_value(property.id.c_str());
@@ -930,7 +977,7 @@ void XISFWriter::writePropertyElement(pugi::xml_node &node, const Property &prop
property_node.append_attribute("comment").set_value(property.comment.c_str()); property_node.append_attribute("comment").set_value(property.comment.c_str());
} }
void XISFWriter::writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword) void XISFWriterPrivate::writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword)
{ {
pugi::xml_node fits_node = node.append_child("FITSKeyword"); pugi::xml_node fits_node = node.append_child("FITSKeyword");
fits_node.append_attribute("name").set_value(keyword.name.c_str()); fits_node.append_attribute("name").set_value(keyword.name.c_str());
@@ -938,7 +985,7 @@ void XISFWriter::writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keywo
fits_node.append_attribute("comment").set_value(keyword.comment.c_str()); fits_node.append_attribute("comment").set_value(keyword.comment.c_str());
} }
void XISFWriter::writeMetadata(pugi::xml_node &node) void XISFWriterPrivate::writeMetadata(pugi::xml_node &node)
{ {
pugi::xml_node metadata = node.append_child("Metadata"); pugi::xml_node metadata = node.append_child("Metadata");
std::time_t t = std::time(nullptr); std::time_t t = std::time(nullptr);
@@ -947,6 +994,76 @@ void XISFWriter::writeMetadata(pugi::xml_node &node)
writePropertyElement(metadata, Property("XISF:CreatorApplication", "LibXISF")); writePropertyElement(metadata, Property("XISF:CreatorApplication", "LibXISF"));
} }
XISFReader::XISFReader()
{
p = new XISFReaderPrivate;
}
XISFReader::~XISFReader()
{
delete p;
}
void XISFReader::open(const String &name)
{
p->open(name);
}
void XISFReader::open(const ByteArray &data)
{
p->open(data);
}
void XISFReader::open(std::istream *io)
{
p->open(io);
}
void XISFReader::close()
{
p->close();
}
int XISFReader::imagesCount() const
{
return p->imagesCount();
}
const Image &XISFReader::getImage(uint32_t n, bool readPixels)
{
return p->getImage(n, readPixels);
}
XISFWriter::XISFWriter()
{
p = new XISFWriterPrivate;
}
XISFWriter::~XISFWriter()
{
delete p;
}
void XISFWriter::save(const String &name)
{
p->save(name);
}
void XISFWriter::save(ByteArray &data)
{
p->save(data);
}
void XISFWriter::save(std::ostream &io)
{
p->save(io);
}
void XISFWriter::writeImage(const Image &image)
{
p->writeImage(image);
}
#define STRING_ENUM(map, map2, c, e) { map.insert({#e, c::e}); map2.insert({c::e, #e}); } #define STRING_ENUM(map, map2, c, e) { map.insert({#e, c::e}); map2.insert({c::e, #e}); }
struct Init struct Init
+14 -29
View File
@@ -27,12 +27,13 @@
#include <cstring> #include <cstring>
#include "propertyvariant.h" #include "propertyvariant.h"
namespace pugi { class xml_node; }
namespace LibXISF namespace LibXISF
{ {
struct DataBlock class XISFReaderPrivate;
class XISFWriterPrivate;
struct LIBXISF_EXPORT DataBlock
{ {
enum CompressionCodec enum CompressionCodec
{ {
@@ -190,7 +191,7 @@ public:
static String pixelStorageString(PixelStorage storage); static String pixelStorageString(PixelStorage storage);
static SampleFormat sampleFormatEnum(const String &format); static SampleFormat sampleFormatEnum(const String &format);
template<typename T> template<typename T>
static SampleFormat sampleFormatEnum(); constexpr static SampleFormat sampleFormatEnum();
static String sampleFormatString(SampleFormat format); static String sampleFormatString(SampleFormat format);
static ColorSpace colorSpaceEnum(const String &colorSpace); static ColorSpace colorSpaceEnum(const String &colorSpace);
static String colorSpaceString(ColorSpace colorSpace); static String colorSpaceString(ColorSpace colorSpace);
@@ -212,14 +213,15 @@ private:
std::map<String, uint32_t> _propertiesId; std::map<String, uint32_t> _propertiesId;
std::vector<FITSKeyword> _fitsKeywords; std::vector<FITSKeyword> _fitsKeywords;
friend class XISFReader; friend class XISFReaderPrivate;
friend class XISFWriter; friend class XISFWriterPrivate;
friend class XISFReaderNoQt;
}; };
class LIBXISF_EXPORT XISFReader class LIBXISF_EXPORT XISFReader
{ {
public: public:
XISFReader();
virtual ~XISFReader();
void open(const String &name); void open(const String &name);
void open(const ByteArray &data); void open(const ByteArray &data);
/** Open image from istream. This method takes ownership of *io pointer */ /** Open image from istream. This method takes ownership of *io pointer */
@@ -234,37 +236,20 @@ public:
* will return nullptr */ * will return nullptr */
const Image& getImage(uint32_t n, bool readPixels = true); const Image& getImage(uint32_t n, bool readPixels = true);
private: private:
void readXISFHeader(); XISFReaderPrivate *p;
void readSignature();
void parseCompression(const pugi::xml_node &node, DataBlock &dataBlock);
DataBlock parseDataBlock(const pugi::xml_node &node);
Property parseProperty(const pugi::xml_node &node);
FITSKeyword parseFITSKeyword(const pugi::xml_node &node);
ColorFilterArray parseCFA(const pugi::xml_node &node);
Image parseImage(const pugi::xml_node &node);
std::unique_ptr<std::istream> _io;
std::vector<Image> _images;
std::vector<Property> _properties;
}; };
class LIBXISF_EXPORT XISFWriter class LIBXISF_EXPORT XISFWriter
{ {
public: public:
XISFWriter();
virtual ~XISFWriter();
void save(const String &name); void save(const String &name);
void save(ByteArray &data); void save(ByteArray &data);
void save(std::ostream &io); void save(std::ostream &io);
void writeImage(const Image &image); void writeImage(const Image &image);
private: private:
void writeHeader(); XISFWriterPrivate *p;
void writeImageElement(pugi::xml_node &node, const Image &image);
void writeDataBlockAttributes(pugi::xml_node &image_node, const DataBlock &dataBlock);
void writePropertyElement(pugi::xml_node &node, const Property &property);
void writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword);
void writeMetadata(pugi::xml_node &node);
ByteArray _xisfHeader;
ByteArray _attachmentsData;
std::vector<Image> _images;
}; };
class LIBXISF_EXPORT Error : public std::exception class LIBXISF_EXPORT Error : public std::exception
@@ -278,7 +263,7 @@ public:
}; };
template<typename T> template<typename T>
Image::SampleFormat Image::sampleFormatEnum() constexpr Image::SampleFormat Image::sampleFormatEnum()
{ {
if(std::is_same<T, LibXISF::UInt8>::value)return Image::UInt8; if(std::is_same<T, LibXISF::UInt8>::value)return Image::UInt8;
if(std::is_same<T, LibXISF::UInt16>::value)return Image::UInt16; if(std::is_same<T, LibXISF::UInt16>::value)return Image::UInt16;
+2 -1
View File
@@ -27,11 +27,12 @@
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
#include <sstream> #include <sstream>
#include "libXISF_global.h"
namespace LibXISF namespace LibXISF
{ {
class ByteArray class LIBXISF_EXPORT ByteArray
{ {
using PtrType = std::vector<char>; using PtrType = std::vector<char>;
using Ptr = std::shared_ptr<PtrType>; using Ptr = std::shared_ptr<PtrType>;