Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libXISF for openSUSE:Factory checked 
in at 2026-10-22 17:00:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libXISF (Old)
 and      /work/SRC/openSUSE:Factory/.libXISF.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libXISF"

Thu Oct 22 17:00:14 2026 rev:16 rq:1387053 version:0.2.14+git1.fa35ae2

Changes:
--------
--- /work/SRC/openSUSE:Factory/libXISF/libXISF.changes  2025-12-05 
16:58:06.828115570 +0100
+++ /work/SRC/openSUSE:Factory/.libXISF.new.2252680/libXISF.changes     
2026-10-22 17:00:18.388989386 +0200
@@ -1,0 +2,10 @@
+Thu Oct 22 06:50:15 UTC 2026 - Paolo Stivanin <[email protected]>
+
+- Update to version 0.2.14+git1.fa35ae2:
+  * Add XISFModify::removeProperty()
+  * Use CROTA to calculate CD_i_j if it is not available
+  * Add support for AstrometricSolution
+  * Bug fixes from Pleiades Astrophoto
+  * Add std::filesystem::path methods variant
+
+-------------------------------------------------------------------

Old:
----
  libXISF-0.2.13+git5.7b70b6a.tar.xz

New:
----
  libXISF-0.2.14+git1.fa35ae2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libXISF.spec ++++++
--- /var/tmp/diff_new_pack.PGi1TN/_old  2026-10-22 17:00:20.685085412 +0200
+++ /var/tmp/diff_new_pack.PGi1TN/_new  2026-10-22 17:00:20.687085495 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libXISF
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,10 +21,10 @@
 %endif
 
 %define sover 0
-%define full_sover 0.2.13
+%define full_sover 0.2.14
 
 Name:           libXISF
-Version:        0.2.13+git5.7b70b6a
+Version:        0.2.14+git1.fa35ae2
 Release:        0
 Summary:        Library to read/write PixInsight XISF files
 License:        GPL-3.0-or-later

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.PGi1TN/_old  2026-10-22 17:00:20.733087419 +0200
+++ /var/tmp/diff_new_pack.PGi1TN/_new  2026-10-22 17:00:20.738087628 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://gitea.nouspiro.space/nou/libXISF</param>
-              <param 
name="changesrevision">7b70b6a08183241aad4fd825f16b75a391866a65</param></service></servicedata>
+              <param 
name="changesrevision">fa35ae21a8c0f05a915e47a1a3300877f33c5581</param></service></servicedata>
 (No newline at EOF)
 

++++++ libXISF-0.2.13+git5.7b70b6a.tar.xz -> libXISF-0.2.14+git1.fa35ae2.tar.xz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/CMakeLists.txt 
new/libXISF-0.2.14+git1.fa35ae2/CMakeLists.txt
--- old/libXISF-0.2.13+git5.7b70b6a/CMakeLists.txt      2025-11-02 
23:00:46.000000000 +0100
+++ new/libXISF-0.2.14+git1.fa35ae2/CMakeLists.txt      2026-10-21 
23:02:00.000000000 +0200
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.14)
 
-project(libXISF VERSION 0.2.13 LANGUAGES CXX C
+project(libXISF VERSION 0.2.14 LANGUAGES CXX C
     HOMEPAGE_URL https://gitea.nouspiro.space/nou/libXISF
     DESCRIPTION "LibXISF is C++ library that can read and write XISF files 
produced by PixInsight.")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/bytearray.cpp 
new/libXISF-0.2.14+git1.fa35ae2/bytearray.cpp
--- old/libXISF-0.2.13+git5.7b70b6a/bytearray.cpp       2025-11-02 
23:00:46.000000000 +0100
+++ new/libXISF-0.2.14+git1.fa35ae2/bytearray.cpp       2026-10-21 
23:02:00.000000000 +0200
@@ -59,6 +59,13 @@
     return (*_data)[i];
 }
 
+ByteArray& ByteArray::operator=(const ByteArray &d)
+{
+    if(this != &d)
+        _data = d._data;
+    return *this;
+}
+
 size_t ByteArray::size() const
 {
     return _data->size();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/libxisf.cpp 
new/libXISF-0.2.14+git1.fa35ae2/libxisf.cpp
--- old/libXISF-0.2.13+git5.7b70b6a/libxisf.cpp 2025-11-02 23:00:46.000000000 
+0100
+++ new/libXISF-0.2.14+git1.fa35ae2/libxisf.cpp 2026-10-21 23:02:00.000000000 
+0200
@@ -17,21 +17,22 @@
  ************************************************************************/
 
 #include "libxisf.h"
-#include <unordered_map>
-#include <unordered_set>
+#include "streambuffer.h"
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
 #include <cstring>
+#include <fstream>
 #include <iostream>
-#include <sstream>
-#include <cstdlib>
-#include <cmath>
 #include <lz4.h>
 #include <lz4hc.h>
 #include <pugixml.hpp>
+#include <sstream>
+#include <unordered_map>
 #include <zlib.h>
 #ifdef HAVE_ZSTD
 #include <zstd.h>
 #endif
-#include "streambuffer.h"
 
 namespace LibXISF
 {
@@ -161,18 +162,36 @@
             off = byteUnshuffleSSE<2>(input.data(), output.data(), num);
 #endif
 
-        const char *s = input.constData() + off;
         for(int i=0; i<itemSize; i++)
         {
+            const char *s = input.constData() + i * num + off / itemSize;
             char *u = output.data() + i + off;
             for(size_t o = off / itemSize; o < num; o++, s++, u += itemSize)
                 *u = *s;
         }
-        memcpy(output.data() + num * itemSize, s, input.size() % itemSize);
+        memcpy(output.data() + num * itemSize, input.constData() + num * 
itemSize, input.size() % itemSize);
         data = output;
     }
 }
 
+/*
+ * XISF 1.0 Revision 2, section 10.6.1. A subblock whose compressed and
+ * uncompressed lengths are equal is an uncompressed subblock, unless it
+ * decompresses to exactly its uncompressed length (encoders implementing
+ * earlier revisions could generate such subblocks). Every other subblock must
+ * decompress to exactly its uncompressed length.
+ */
+static void uncompressedSubblock(bool decompressed, const std::pair<uint64_t, 
uint64_t> &block,
+                                 const char *srcPtr, char *dstPtr, const char 
*errorMessage)
+{
+    if(!decompressed)
+    {
+        if(block.first != block.second)
+            throw Error(errorMessage);
+        std::memcpy(dstPtr, srcPtr, block.second);
+    }
+}
+
 void DataBlock::decompress(const ByteArray &input, const String &encoding)
 {
     ByteArray tmp = input;
@@ -198,7 +217,8 @@
         for(auto &block : subblocks)
         {
             uLongf size = block.second;
-            ::uncompress((Bytef*)dstPtr, &size, (const Bytef*)srcPtr, 
block.first);
+            bool ok = ::uncompress((Bytef*)dstPtr, &size, (const 
Bytef*)srcPtr, block.first) == Z_OK && size == block.second;
+            uncompressedSubblock(ok, block, srcPtr, dstPtr, "Zlib 
decompression failed");
             srcPtr += block.first;
             dstPtr += block.second;
         }
@@ -212,8 +232,8 @@
         char *dstPtr = data.data();
         for(auto &block : subblocks)
         {
-            if(LZ4_decompress_safe(srcPtr, dstPtr, block.first, block.second) 
< 0)
-                throw Error("LZ4 decompression failed");
+            bool ok = LZ4_decompress_safe(srcPtr, dstPtr, block.first, 
block.second) == static_cast<int>(block.second);
+            uncompressedSubblock(ok, block, srcPtr, dstPtr, "LZ4 decompression 
failed");
             srcPtr += block.first;
             dstPtr += block.second;
         }
@@ -227,8 +247,9 @@
         char *dstPtr = data.data();
         for(auto &block : subblocks)
         {
-            if(ZSTD_isError(ZSTD_decompress(dstPtr, block.second, srcPtr, 
block.first)))
-                throw Error("ZSTD decompression failed");
+            size_t size = ZSTD_decompress(dstPtr, block.second, srcPtr, 
block.first);
+            bool ok = !ZSTD_isError(size) && size == block.second;
+            uncompressedSubblock(ok, block, srcPtr, dstPtr, "ZSTD 
decompression failed");
             srcPtr += block.first;
             dstPtr += block.second;
         }
@@ -507,6 +528,58 @@
     return false;
 }
 
+bool Image::convertWCSToAstrometricSolution()
+{
+    auto findKeyword = [this](const String &key, String &value) -> bool {
+        auto keyEqual = [&key](const FITSKeyword &entry) {
+            return entry.name == key;
+        };
+        auto it = std::find_if(_fitsKeywords.begin(), _fitsKeywords.end(), 
keyEqual);
+        if(it != _fitsKeywords.end())
+        {
+            value = it->value;
+            return true;
+        }
+        return false;
+    };
+    String crval1, crval2, crpix1, crpix2, cd1_1, cd1_2, cd2_1, cd2_2, ctype1, 
ctype2, crota1, cdelt1, cdelt2;
+    bool cdFound = findKeyword("CD1_1", cd1_1) && findKeyword("CD1_2", cd1_2) 
&& findKeyword("CD2_1", cd2_1) && findKeyword("CD2_2", cd2_2);
+    bool crotaFound = findKeyword("CROTA1", crota1) && findKeyword("CDELT1", 
cdelt1) && findKeyword("CDELT2", cdelt2);
+    if(findKeyword("CRVAL1", crval1) && findKeyword("CRVAL2", crval2) &&
+       findKeyword("CRPIX1", crpix1) && findKeyword("CRPIX2", crpix2) &&
+       (cdFound || crotaFound) &&
+       findKeyword("CTYPE1", ctype1) && findKeyword("CTYPE2", ctype2))
+    {
+        Property ver("AstrometricSolution:Version", "1.0");
+        Property ps("AstrometricSolution:ProjectionSystem", "Gnomonic");
+        Property rcc("AstrometricSolution:ReferenceCelestialCoordinates", 
F64Vector{std::stod(crval1), std::stod(crval2)});
+        Property ric("AstrometricSolution:ReferenceImageCoordinates", 
F64Vector{std::stod(crpix1), std::stod(crpix2)});
+        F64Matrix mx(2, 2);
+        if(cdFound)
+        {
+            mx(0, 0) = std::stod(cd1_1); mx(0, 1) = std::stod(cd1_2); mx(1, 0) 
= std::stod(cd2_1); mx(1, 1) = std::stod(cd2_2);
+        }
+        if(crotaFound)
+        {
+            double cdeltx = std::stod(cdelt1);
+            double cdelty = std::stod(cdelt2);
+            double rotationRad = std::stod(crota1) / 180.0 * M_PI;
+            mx(0, 0) = std::cos(rotationRad) * cdeltx;
+            mx(0, 1) =-std::sin(rotationRad) * cdelty;
+            mx(1, 0) = std::sin(rotationRad) * cdeltx;
+            mx(1, 1) = std::cos(rotationRad) * cdelty;
+        }
+        Property ltm("AstrometricSolution:LinearTransformationMatrix", mx);
+        updateProperty(ver);
+        updateProperty(ps);
+        updateProperty(rcc);
+        updateProperty(ric);
+        updateProperty(ltm);
+        return true;
+    }
+    return false;
+}
+
 const ByteArray &Image::iccProfile() const
 {
     return _iccProfile;
@@ -701,6 +774,7 @@
     void open(const ByteArray &data);
     /** Open image from istream. This method takes ownership of *io pointer */
     void open(std::istream *io);
+    void open(const std::filesystem::path &path);
     /** Close opended file release all data. */
     void close();
     /** Return number of images inside file */
@@ -754,6 +828,14 @@
     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()
 {
     _io.reset();
@@ -1032,6 +1114,7 @@
     void save(const String &name);
     void save(ByteArray &data);
     void save(std::ostream &io);
+    void save(const std::filesystem::path &path);
     void writeImage(const Image &image);
     static void writeFITSKeyword(pugi::xml_node &node, const FITSKeyword 
&keyword);
     static void writePropertyElement(pugi::xml_node &node, const Property 
&property);
@@ -1084,6 +1167,16 @@
     }
 }
 
+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)
 {
     _images.push_back(image);
@@ -1304,6 +1397,11 @@
     p->open(io);
 }
 
+void XISFReader::open(const std::filesystem::path &path)
+{
+    p->open(path);
+}
+
 void XISFReader::close()
 {
     p->close();
@@ -1349,6 +1447,11 @@
     p->save(io);
 }
 
+void XISFWriter::save(const std::filesystem::path &path)
+{
+    p->save(path);
+}
+
 void XISFWriter::writeImage(const Image &image)
 {
     p->writeImage(image);
@@ -1361,17 +1464,20 @@
     void open(const ByteArray &data);
     /** Open image from istream. This method takes ownership of *io pointer */
     void open(std::istream *io);
+    void open(const std::filesystem::path &path);
     /** Close opended file release all data. */
     void close();
 
     void save(const String &name);
     void save(ByteArray &data);
     void save(std::ostream &io);
+    void save(const std::filesystem::path &path);
 
     void addFITSKeyword(uint32_t image, const FITSKeyword &keyword);
     void updateFITSKeyword(uint32_t image, const FITSKeyword &keyword, bool 
add);
     void removeFITSKeyword(uint32_t image, const String &name);
     void updateProperty(uint32_t image, const Property &property);
+    void removeProperty(uint32_t image, const String &id);
 private:
     void readXISFHeader();
     void parseAttachmentPos(pugi::xml_node &root);
@@ -1408,6 +1514,13 @@
     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()
 {
     _io.reset();
@@ -1487,6 +1600,16 @@
     }
 }
 
+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)
 {
     if(!_root)
@@ -1574,6 +1697,25 @@
     XISFWriterPrivate::writePropertyElement(imageNode, property);
 }
 
+void XISFModifyPrivate::removeProperty(uint32_t image, const String &id)
+{
+    if(!_root)
+        throw Error("No input file opened");
+
+    pugi::xpath_node_set images = _root.select_nodes("//Image");
+
+    if(image >= images.size())
+        throw Error("Out of bounds");
+
+    pugi::xpath_variable_set variables;
+    variables.set("id", id.c_str());
+    pugi::xml_node imageNode = images[image].node();
+    pugi::xml_node propertyNode = 
imageNode.select_node("Property[@id=string($id)]", &variables).node();
+
+    if(propertyNode)
+        imageNode.remove_child(propertyNode);
+}
+
 void XISFModifyPrivate::readXISFHeader()
 {
     char signature[8];
@@ -1657,6 +1799,11 @@
     p->open(io);
 }
 
+void XISFModify::open(const std::filesystem::path &path)
+{
+    p->open(path);
+}
+
 void XISFModify::close()
 {
     p->close();
@@ -1677,6 +1824,11 @@
     p->save(io);
 }
 
+void XISFModify::save(const std::filesystem::path &path)
+{
+    p->save(path);
+}
+
 void XISFModify::addFITSKeyword(uint32_t image, const FITSKeyword &keyword)
 {
     p->addFITSKeyword(image, keyword);
@@ -1697,6 +1849,11 @@
     p->updateProperty(image, property);
 }
 
+void XISFModify::removeProperty(uint32_t image, const String &id)
+{
+    p->removeProperty(image, id);
+}
+
 #define STRING_ENUM(map, map2, c, e) { map.insert({#e, c::e}); 
map2.insert({c::e, #e}); }
 
 struct Init
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/libxisf.h 
new/libXISF-0.2.14+git1.fa35ae2/libxisf.h
--- old/libXISF-0.2.13+git5.7b70b6a/libxisf.h   2025-11-02 23:00:46.000000000 
+0100
+++ new/libXISF-0.2.14+git1.fa35ae2/libxisf.h   2026-10-21 23:02:00.000000000 
+0200
@@ -20,15 +20,15 @@
 #define LIBXISF_H
 
 #include "libXISF_global.h"
-#include <memory>
+#include <cstdint>
+#include <cstring>
+#include <ctime>
+#include <filesystem>
 #include <map>
+#include <memory>
+#include <memory>
 #include <variant>
-#include <fstream>
-#include <cstring>
 #include <vector>
-#include <cstdint>
-#include <memory>
-#include <ctime>
 
 namespace LibXISF
 {
@@ -56,9 +56,10 @@
     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); }
+    ByteArray& operator=(const ByteArray &d);
+    char* data() { return size() ? _data->data() : nullptr; }
+    const char* data() const { return size() ? _data->data() : nullptr; }
+    const char* constData() const { return size() ? _data->data() : nullptr; }
     size_t size() const;
     void resize(size_t newsize);
     void append(char c);
@@ -204,6 +205,8 @@
     Property(const String &_id, const T& _value) :
         id(_id),
         value(_value){}
+
+    Property& operator=(const Property &d) = default;
 };
 
 struct LIBXISF_EXPORT FITSKeyword
@@ -306,6 +309,11 @@
      *  For example OBSERVER => Observer:Name, SITELAT => 
Observation:Location:Latitude
     */
     bool addFITSKeywordAsProperty(const String &name, const String &value);
+    /**
+     * Convert FITS WCS keywords added previosly with addFITSKeyword() to XISF 
properties AstrometricSolution
+     * 
https://pixinsight.com/doc/docs/XISF-1.0-spec/XISF-1.0-spec.html#__XISF_Core_Elements_:_Image_Core_Element_:_Astronomical_Image_Properties_:_AstrometricSolution_Namespace__
+    */
+    bool convertWCSToAstrometricSolution();
     const ByteArray& iccProfile() const;
     void setIccProfile(const ByteArray &iccProfile);
 
@@ -370,6 +378,7 @@
     void open(const ByteArray &data);
     /** Open image from istream. This method takes ownership of *io pointer */
     void open(std::istream *io);
+    void open(const std::filesystem::path &path);
     /** Close opended file release all data. */
     void close();
     /** Return number of images inside file */
@@ -396,6 +405,7 @@
     void save(const String &name);
     void save(ByteArray &data);
     void save(std::ostream &io);
+    void save(const std::filesystem::path &path);
     void writeImage(const Image &image);
 private:
     XISFWriterPrivate *p;
@@ -419,10 +429,12 @@
     void open(const String &name);
     void open(const ByteArray &data);
     void open(std::istream *io);
+    void open(const std::filesystem::path &path);
     void close();
     void save(const String &name);
     void save(ByteArray &data);
     void save(std::ostream &io);
+    void save(const std::filesystem::path &path);
 
     /**
      * @brief addFITSKeyword append new keyword to image
@@ -449,6 +461,12 @@
      * @param property new value of property
      */
     void updateProperty(uint32_t image, const Property &property);
+    /**
+     * @brief removeProperty remove existing property
+     * @param image index of image to update
+     * @param id of property to remove
+     */
+    void removeProperty(uint32_t image, const String &id);
 private:
     XISFModifyPrivate *p;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/test/main.cpp 
new/libXISF-0.2.14+git1.fa35ae2/test/main.cpp
--- old/libXISF-0.2.13+git5.7b70b6a/test/main.cpp       2025-11-02 
23:00:46.000000000 +0100
+++ new/libXISF-0.2.14+git1.fa35ae2/test/main.cpp       2026-10-21 
23:02:00.000000000 +0200
@@ -48,12 +48,19 @@
             image.addProperty(Property("PropertyComplex64", Complex64{-3.0, 
2.0}));
             image.addProperty(Property("VectorUInt16", UI16Vector({23, 45, 
86})));
             image.addProperty(Property("VectorComplex32", C32Vector({{1, 2}, 
{3, 4}, {5, 6}})));
+            image.addProperty(Property("Vector64", F64Vector({1.0, 2.0, 
3.0})));
+            image.addProperty(Property("Vector64Empty", F64Vector()));
             UI16Matrix m(2, 3);
             m(0, 0) = 0;
             m(0, 1) = 1;
             m(0, 2) = 2;
             m(1, 0) = 10;
             image.addProperty(Property("UI16Matrix", m));
+            uint16_t *imageData = image.imageData<uint16_t>();
+            for(uint64_t i = 0; i < image.height() * image.width(); i++)
+            {
+                imageData[i] = i;
+            }
             std::tm tm = {12, 22, 23, 1, 2, 2023, 0, 0, 0};
             image.addProperty(Property("TimeObs", tm));
             image.addFITSKeyword({"RA", "226.9751163116387", "Right ascension 
of the center of the image (deg)"});
@@ -102,7 +109,7 @@
         else
         {
             LibXISF::XISFReader reader;
-            reader.open(argv[1]);
+            reader.open(LibXISF::String(argv[1]));
             TEST(reader.imagesCount() != 1, "No image");
 
             const LibXISF::Image &image = reader.getImage(0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libXISF-0.2.13+git5.7b70b6a/variant.cpp 
new/libXISF-0.2.14+git1.fa35ae2/variant.cpp
--- old/libXISF-0.2.13+git5.7b70b6a/variant.cpp 2025-11-02 23:00:46.000000000 
+0100
+++ new/libXISF-0.2.14+git1.fa35ae2/variant.cpp 2026-10-21 23:02:00.000000000 
+0200
@@ -139,7 +139,8 @@
     v = T();
     v.value<T>().resize(len);
     size_t size = len * sizeof(typename T::value_type);
-    std::memcpy(&v.value<T>()[0], data.data(), size);
+    if(size)
+        std::memcpy(&v.value<T>()[0], data.data(), size);
 }
 
 template<typename T>
@@ -147,7 +148,8 @@
 {
     v = T(rows, cols);
     size_t size = rows * cols * sizeof(typename T::value_type);
-    std::memcpy(&v.value<T>()(0, 0), data.data(), size);
+    if(size)
+        std::memcpy(&v.value<T>()(0, 0), data.data(), size);
 }
 
 template<typename T>
@@ -173,7 +175,8 @@
     len = v.value<T>().size();
     size_t size = len * sizeof(typename T::value_type);
     data.resize(size);
-    std::memcpy(data.data(), &v.value<T>()[0], size);
+    if(size)
+        std::memcpy(data.data(), &v.value<T>()[0], size);
     data.encodeBase64();
     data.append('\0');
 }
@@ -185,7 +188,8 @@
     cols = v.value<T>().cols();
     size_t size = rows * cols * sizeof(typename T::value_type);
     data.resize(size);
-    std::memcpy(data.data(), &v.value<T>()(0, 0), size);
+    if(size)
+        std::memcpy(data.data(), &v.value<T>()(0, 0), size);
     data.encodeBase64();
     data.append('\0');
 }

Reply via email to