4 Commits

Author SHA1 Message Date
nou de757840b3 Add std::filesystem::path methods variant 2026-04-20 16:10:09 +02:00
nou 7b70b6a081 More precise std::to_char support 2025-11-02 23:00:46 +01:00
nou 2e74d94641 Fix bug in XISFModify that corrupted files 2025-10-20 17:51:43 +02:00
nou 556bb22d26 Do not use bundled zlib by default 2025-08-12 18:37:58 +02:00
5 changed files with 83 additions and 19 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(USE_BUNDLED_LIBS "Use bundled LZ4 PugiXML and Zlib. You can still exclude some" ON) option(USE_BUNDLED_LIBS "Use bundled LZ4 PugiXML and Zlib. You can still exclude some" ON)
cmake_dependent_option(USE_BUNDLED_LZ4 "Use bundled LZ4" ON "USE_BUNDLED_LIBS" OFF) cmake_dependent_option(USE_BUNDLED_LZ4 "Use bundled LZ4" ON "USE_BUNDLED_LIBS" OFF)
cmake_dependent_option(USE_BUNDLED_PUGIXML "Use bundled PugiXML" ON "USE_BUNDLED_LIBS" OFF) cmake_dependent_option(USE_BUNDLED_PUGIXML "Use bundled PugiXML" ON "USE_BUNDLED_LIBS" OFF)
cmake_dependent_option(USE_BUNDLED_ZLIB "Use bundled Zlib" ON "USE_BUNDLED_LIBS" OFF) cmake_dependent_option(USE_BUNDLED_ZLIB "Use bundled Zlib" OFF "USE_BUNDLED_LIBS" OFF)
find_package(PkgConfig) find_package(PkgConfig)
+69 -9
View File
@@ -17,21 +17,21 @@
************************************************************************/ ************************************************************************/
#include "libxisf.h" #include "libxisf.h"
#include <unordered_map> #include "streambuffer.h"
#include <unordered_set>
#include <cstring>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cmath> #include <cmath>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <lz4.h> #include <lz4.h>
#include <lz4hc.h> #include <lz4hc.h>
#include <pugixml.hpp> #include <pugixml.hpp>
#include <sstream>
#include <unordered_map>
#include <zlib.h> #include <zlib.h>
#ifdef HAVE_ZSTD #ifdef HAVE_ZSTD
#include <zstd.h> #include <zstd.h>
#endif #endif
#include "streambuffer.h"
namespace LibXISF namespace LibXISF
{ {
@@ -701,6 +701,7 @@ public:
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 */
void open(std::istream *io); void open(std::istream *io);
void open(const std::filesystem::path &path);
/** Close opended file release all data. */ /** Close opended file release all data. */
void close(); void close();
/** Return number of images inside file */ /** Return number of images inside file */
@@ -754,6 +755,14 @@ void XISFReaderPrivate::open(std::istream *io)
readXISFHeader(); readXISFHeader();
} }
void XISFReaderPrivate::open(const std::filesystem::path &path)
{
close();
_io = std::make_unique<std::ifstream>(path, std::ios_base::in | std::ios_base::binary);
readSignature();
readXISFHeader();
}
void XISFReaderPrivate::close() void XISFReaderPrivate::close()
{ {
_io.reset(); _io.reset();
@@ -1032,6 +1041,7 @@ public:
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 save(const std::filesystem::path &path);
void writeImage(const Image &image); void writeImage(const Image &image);
static void writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword); static void writeFITSKeyword(pugi::xml_node &node, const FITSKeyword &keyword);
static void writePropertyElement(pugi::xml_node &node, const Property &property); static void writePropertyElement(pugi::xml_node &node, const Property &property);
@@ -1084,6 +1094,16 @@ void XISFWriterPrivate::save(std::ostream &io)
} }
} }
void XISFWriterPrivate::save(const std::filesystem::path &path)
{
std::ofstream fw(path, std::ios_base::out | std::ios_base::binary);
if(fw.fail())
throw Error("Failed to open file");
save(fw);
}
void XISFWriterPrivate::writeImage(const Image &image) void XISFWriterPrivate::writeImage(const Image &image)
{ {
_images.push_back(image); _images.push_back(image);
@@ -1304,6 +1324,11 @@ void XISFReader::open(std::istream *io)
p->open(io); p->open(io);
} }
void XISFReader::open(const std::filesystem::path &path)
{
p->open(path);
}
void XISFReader::close() void XISFReader::close()
{ {
p->close(); p->close();
@@ -1349,6 +1374,11 @@ void XISFWriter::save(std::ostream &io)
p->save(io); p->save(io);
} }
void XISFWriter::save(const std::filesystem::path &path)
{
p->save(path);
}
void XISFWriter::writeImage(const Image &image) void XISFWriter::writeImage(const Image &image)
{ {
p->writeImage(image); p->writeImage(image);
@@ -1361,12 +1391,14 @@ public:
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 */
void open(std::istream *io); void open(std::istream *io);
void open(const std::filesystem::path &path);
/** Close opended file release all data. */ /** Close opended file release all data. */
void close(); void close();
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 save(const std::filesystem::path &path);
void addFITSKeyword(uint32_t image, const FITSKeyword &keyword); void addFITSKeyword(uint32_t image, const FITSKeyword &keyword);
void updateFITSKeyword(uint32_t image, const FITSKeyword &keyword, bool add); void updateFITSKeyword(uint32_t image, const FITSKeyword &keyword, bool add);
@@ -1383,7 +1415,6 @@ private:
pugi::xml_document _doc; pugi::xml_document _doc;
pugi::xml_node _root; pugi::xml_node _root;
std::map<int, std::pair<uint64_t, uint64_t>> _attachmentPos;// pair contain position and size std::map<int, std::pair<uint64_t, uint64_t>> _attachmentPos;// pair contain position and size
std::map<int, std::pair<uint64_t, uint64_t>> _attachmentPosNew;
}; };
@@ -1409,6 +1440,13 @@ void XISFModifyPrivate::open(std::istream *io)
readXISFHeader(); readXISFHeader();
} }
void XISFModifyPrivate::open(const std::filesystem::path &path)
{
close();
_io = std::make_unique<std::ifstream>(path, std::ios_base::in | std::ios_base::binary);
readXISFHeader();
}
void XISFModifyPrivate::close() void XISFModifyPrivate::close()
{ {
_io.reset(); _io.reset();
@@ -1446,6 +1484,8 @@ void XISFModifyPrivate::save(std::ostream &io)
doc.append_child(pugi::node_comment).set_value("\nExtensible Image Serialization Format - XISF version 1.0\nCreated with libXISF - https://nouspiro.space\n"); doc.append_child(pugi::node_comment).set_value("\nExtensible Image Serialization Format - XISF version 1.0\nCreated with libXISF - https://nouspiro.space\n");
pugi::xml_node root_copy = doc.append_copy(_root); pugi::xml_node root_copy = doc.append_copy(_root);
parseAttachmentPos(_root);
uint32_t size = 0; uint32_t size = 0;
std::string header; std::string header;
while(true) while(true)
@@ -1486,6 +1526,16 @@ void XISFModifyPrivate::save(std::ostream &io)
} }
} }
void XISFModifyPrivate::save(const std::filesystem::path &path)
{
std::ofstream fw(path, std::ios_base::out | std::ios_base::binary);
if(fw.fail())
throw Error("Failed to open file");
save(fw);
}
void XISFModifyPrivate::addFITSKeyword(uint32_t image, const FITSKeyword &keyword) void XISFModifyPrivate::addFITSKeyword(uint32_t image, const FITSKeyword &keyword)
{ {
if(!_root) if(!_root)
@@ -1601,6 +1651,7 @@ void XISFModifyPrivate::readXISFHeader()
void XISFModifyPrivate::parseAttachmentPos(pugi::xml_node &root) void XISFModifyPrivate::parseAttachmentPos(pugi::xml_node &root)
{ {
_attachmentPos.clear();
pugi::xpath_node_set locationAttributes = root.select_nodes("//@location"); pugi::xpath_node_set locationAttributes = root.select_nodes("//@location");
int i = 0; int i = 0;
for(auto &attr : locationAttributes) for(auto &attr : locationAttributes)
@@ -1625,7 +1676,6 @@ void XISFModifyPrivate::updateAttachmentPos(pugi::xml_node &root, size_t offset)
pugi::xml_attribute attr = locationAttributes[pos.first].attribute(); pugi::xml_attribute attr = locationAttributes[pos.first].attribute();
uint64_t attachmentSize = pos.second.second; uint64_t attachmentSize = pos.second.second;
std::string locationStr = "attachment:" + std::to_string(offset) + ":" + std::to_string(attachmentSize); std::string locationStr = "attachment:" + std::to_string(offset) + ":" + std::to_string(attachmentSize);
_attachmentPosNew[pos.first] = pos.second;
offset += attachmentSize; offset += attachmentSize;
attr.set_value(locationStr.c_str()); attr.set_value(locationStr.c_str());
} }
@@ -1656,6 +1706,11 @@ void XISFModify::open(std::istream *io)
p->open(io); p->open(io);
} }
void XISFModify::open(const std::filesystem::path &path)
{
p->open(path);
}
void XISFModify::close() void XISFModify::close()
{ {
p->close(); p->close();
@@ -1676,6 +1731,11 @@ void XISFModify::save(std::ostream &io)
p->save(io); p->save(io);
} }
void XISFModify::save(const std::filesystem::path &path)
{
p->save(path);
}
void XISFModify::addFITSKeyword(uint32_t image, const FITSKeyword &keyword) void XISFModify::addFITSKeyword(uint32_t image, const FITSKeyword &keyword)
{ {
p->addFITSKeyword(image, keyword); p->addFITSKeyword(image, keyword);
+11 -7
View File
@@ -20,15 +20,15 @@
#define LIBXISF_H #define LIBXISF_H
#include "libXISF_global.h" #include "libXISF_global.h"
#include <memory>
#include <map>
#include <variant>
#include <fstream>
#include <cstring>
#include <vector>
#include <cstdint> #include <cstdint>
#include <memory> #include <cstring>
#include <ctime> #include <ctime>
#include <filesystem>
#include <map>
#include <memory>
#include <memory>
#include <variant>
#include <vector>
namespace LibXISF namespace LibXISF
{ {
@@ -370,6 +370,7 @@ public:
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 */
void open(std::istream *io); void open(std::istream *io);
void open(const std::filesystem::path &path);
/** Close opended file release all data. */ /** Close opended file release all data. */
void close(); void close();
/** Return number of images inside file */ /** Return number of images inside file */
@@ -396,6 +397,7 @@ public:
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 save(const std::filesystem::path &path);
void writeImage(const Image &image); void writeImage(const Image &image);
private: private:
XISFWriterPrivate *p; XISFWriterPrivate *p;
@@ -419,10 +421,12 @@ public:
void open(const String &name); void open(const String &name);
void open(const ByteArray &data); void open(const ByteArray &data);
void open(std::istream *io); void open(std::istream *io);
void open(const std::filesystem::path &path);
void close(); void close();
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 save(const std::filesystem::path &path);
/** /**
* @brief addFITSKeyword append new keyword to image * @brief addFITSKeyword append new keyword to image
+1 -1
View File
@@ -102,7 +102,7 @@ int main(int argc, char **argv)
else else
{ {
LibXISF::XISFReader reader; LibXISF::XISFReader reader;
reader.open(argv[1]); reader.open(LibXISF::String(argv[1]));
TEST(reader.imagesCount() != 1, "No image"); TEST(reader.imagesCount() != 1, "No image");
const LibXISF::Image &image = reader.getImage(0); const LibXISF::Image &image = reader.getImage(0);
+1 -1
View File
@@ -440,7 +440,7 @@ String Variant::toString() const
ss << "{"; ss << "{";
for(int o=0; o<matrix.cols(); o++) for(int o=0; o<matrix.cols(); o++)
{ {
#if __GNUC__ >= 11 || __clang__ #if __GNUC__ >= 11 || __clang_major__ >= 15
char str[128] = {0}; char str[128] = {0};
char *end = str + sizeof(str); char *end = str + sizeof(str);
std::to_chars(str, end, matrix(i, o)); std::to_chars(str, end, matrix(i, o));