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 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<Image::Type, String> imageTypeToString;
static std::unordered_map<String, Image::SampleFormat> sampleFormatToEnum;
@@ -506,7 +504,38 @@ size_t Image::sampleFormatSize(SampleFormat sampleFormat)
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();
_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();
}
void XISFReader::open(const ByteArray &data)
void XISFReaderPrivate::open(const ByteArray &data)
{
close();
std::string str((char*)data.data(), data.size());
@@ -523,7 +552,7 @@ void XISFReader::open(const ByteArray &data)
readXISFHeader();
}
void XISFReader::open(std::istream *io)
void XISFReaderPrivate::open(std::istream *io)
{
close();
_io.reset(io);
@@ -531,19 +560,19 @@ void XISFReader::open(std::istream *io)
readXISFHeader();
}
void XISFReader::close()
void XISFReaderPrivate::close()
{
_io.reset();
_images.clear();
_properties.clear();
}
int XISFReader::imagesCount() const
int XISFReaderPrivate::imagesCount() const
{
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())
throw Error("Out of bounds");
@@ -559,7 +588,7 @@ const Image& XISFReader::getImage(uint32_t n, bool readPixels)
return img;
}
void XISFReader::readXISFHeader()
void XISFReaderPrivate::readXISFHeader()
{
uint32_t headerLen[2] = {0};
_io->read((char*)&headerLen, sizeof(headerLen));
@@ -583,7 +612,7 @@ void XISFReader::readXISFHeader()
else throw Error("Unknown root XML element");
}
void XISFReader::readSignature()
void XISFReaderPrivate::readSignature()
{
char signature[8];
_io->read(signature, sizeof(signature));
@@ -594,7 +623,7 @@ void XISFReader::readSignature()
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(), ':');
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;
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;
}
Property XISFReader::parseProperty(const pugi::xml_node &node)
Property XISFReaderPrivate::parseProperty(const pugi::xml_node &node)
{
Property property;
@@ -691,7 +720,7 @@ Property XISFReader::parseProperty(const pugi::xml_node &node)
return property;
}
FITSKeyword XISFReader::parseFITSKeyword(const pugi::xml_node &node)
FITSKeyword XISFReaderPrivate::parseFITSKeyword(const pugi::xml_node &node)
{
FITSKeyword fitsKeyword;
fitsKeyword.name = node.attribute("name").as_string();
@@ -700,7 +729,7 @@ FITSKeyword XISFReader::parseFITSKeyword(const pugi::xml_node &node)
return fitsKeyword;
}
ColorFilterArray XISFReader::parseCFA(const pugi::xml_node &node)
ColorFilterArray XISFReaderPrivate::parseCFA(const pugi::xml_node &node)
{
ColorFilterArray cfa;
if(node.attribute("pattern") && node.attribute("width") && node.attribute("height"))
@@ -716,7 +745,7 @@ ColorFilterArray XISFReader::parseCFA(const pugi::xml_node &node)
return cfa;
}
Image XISFReader::parseImage(const pugi::xml_node &node)
Image XISFReaderPrivate::parseImage(const pugi::xml_node &node)
{
Image image;
@@ -758,8 +787,26 @@ Image XISFReader::parseImage(const pugi::xml_node &node)
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);
@@ -769,7 +816,7 @@ void XISFWriter::save(const String &name)
save(fw);
}
void XISFWriter::save(ByteArray &data)
void XISFWriterPrivate::save(ByteArray &data)
{
std::ostringstream oss;
save(oss);
@@ -777,7 +824,7 @@ void XISFWriter::save(ByteArray &data)
data = ByteArray(str.data(), str.size());
}
void XISFWriter::save(std::ostream &io)
void XISFWriterPrivate::save(std::ostream &io)
{
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.back()._dataBlock.attachmentPos = 1;
_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};
@@ -840,7 +887,7 @@ void XISFWriter::writeHeader()
_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");
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)
{
@@ -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");
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());
}
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");
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());
}
void XISFWriter::writeMetadata(pugi::xml_node &node)
void XISFWriterPrivate::writeMetadata(pugi::xml_node &node)
{
pugi::xml_node metadata = node.append_child("Metadata");
std::time_t t = std::time(nullptr);
@@ -947,6 +994,76 @@ void XISFWriter::writeMetadata(pugi::xml_node &node)
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}); }
struct Init
+14 -29
View File
@@ -27,12 +27,13 @@
#include <cstring>
#include "propertyvariant.h"
namespace pugi { class xml_node; }
namespace LibXISF
{
struct DataBlock
class XISFReaderPrivate;
class XISFWriterPrivate;
struct LIBXISF_EXPORT DataBlock
{
enum CompressionCodec
{
@@ -190,7 +191,7 @@ public:
static String pixelStorageString(PixelStorage storage);
static SampleFormat sampleFormatEnum(const String &format);
template<typename T>
static SampleFormat sampleFormatEnum();
constexpr static SampleFormat sampleFormatEnum();
static String sampleFormatString(SampleFormat format);
static ColorSpace colorSpaceEnum(const String &colorSpace);
static String colorSpaceString(ColorSpace colorSpace);
@@ -212,14 +213,15 @@ private:
std::map<String, uint32_t> _propertiesId;
std::vector<FITSKeyword> _fitsKeywords;
friend class XISFReader;
friend class XISFWriter;
friend class XISFReaderNoQt;
friend class XISFReaderPrivate;
friend class XISFWriterPrivate;
};
class LIBXISF_EXPORT XISFReader
{
public:
XISFReader();
virtual ~XISFReader();
void open(const String &name);
void open(const ByteArray &data);
/** Open image from istream. This method takes ownership of *io pointer */
@@ -234,37 +236,20 @@ public:
* 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;
XISFReaderPrivate *p;
};
class LIBXISF_EXPORT XISFWriter
{
public:
XISFWriter();
virtual ~XISFWriter();
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;
XISFWriterPrivate *p;
};
class LIBXISF_EXPORT Error : public std::exception
@@ -278,7 +263,7 @@ public:
};
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::UInt16>::value)return Image::UInt16;
+2 -1
View File
@@ -27,11 +27,12 @@
#include <cstring>
#include <ctime>
#include <sstream>
#include "libXISF_global.h"
namespace LibXISF
{
class ByteArray
class LIBXISF_EXPORT ByteArray
{
using PtrType = std::vector<char>;
using Ptr = std::shared_ptr<PtrType>;