diff --git a/libxisf.cpp b/libxisf.cpp index d215e3b..7f64041 100644 --- a/libxisf.cpp +++ b/libxisf.cpp @@ -19,6 +19,7 @@ #include "libxisf.h" #include #include +#include #include #include #include @@ -49,6 +50,7 @@ static std::unordered_map sampleFormatToEnum; static std::unordered_map sampleFormatToString; static std::unordered_map colorSpaceToEnum; static std::unordered_map colorSpaceToString; +static std::unordered_map vectorTypeSizes; static void byteShuffle(QByteArray &data, int itemSize) { @@ -425,16 +427,16 @@ size_t Image::sampleFormatSize(SampleFormat sampleFormat) { switch(sampleFormat) { - case Image::UInt8: return sizeof(UInt8); - case Image::UInt16: return sizeof(UInt16); - case Image::UInt32: return sizeof(UInt32); - case Image::UInt64: return sizeof(UInt64); - case Image::Float32: return sizeof(Float32); - case Image::Float64: return sizeof(Float64); - case Image::Complex32: return sizeof(Complex32); - case Image::Complex64: return sizeof(Complex64); + case Image::UInt8: return sizeof(LibXISF::UInt8); + case Image::UInt16: return sizeof(LibXISF::UInt16); + case Image::UInt32: return sizeof(LibXISF::UInt32); + case Image::UInt64: return sizeof(LibXISF::UInt64); + case Image::Float32: return sizeof(LibXISF::Float32); + case Image::Float64: return sizeof(LibXISF::Float64); + case Image::Complex32: return sizeof(LibXISF::Complex32); + case Image::Complex64: return sizeof(LibXISF::Complex64); } - return UInt16; + return sizeof(UInt16); } XISFReader::XISFReader() @@ -594,7 +596,7 @@ Property XISFReader::readPropertyElement() QVariant value; - if(type == "String") + if(type == "String" && !attributes.hasAttribute("location")) { property.value = _xml->readElementText(); } @@ -606,15 +608,15 @@ Property XISFReader::readPropertyElement() } else { - //TODO properly handle data block properties - throw Error("Data block properties not supported"); - /*DataBlock dataBlock = readDataBlock(); + DataBlock dataBlock = readDataBlock(); if(dataBlock.attachmentPos) { _io->seek(dataBlock.attachmentPos); dataBlock.decompress(_io->read(dataBlock.attachmentSize)); } - property.value = dataBlock.data;*/ + property.value = dataBlock.data; + if(!property.value.convert(typeToId[type])) + throw Error("Failed to convert property data"); } return property; @@ -872,8 +874,18 @@ void XISFWriter::writePropertyElement(const Property &property) if(type == QMetaType::QString) _xml->writeCharacters(property.value.toString()); + else if(type == QMetaType::Bool) + _xml->writeAttribute("value", property.value.toBool() ? "1" : "0"); else if(type == QMetaType::SChar || type == QMetaType::UChar) _xml->writeAttribute("value", QString::number(property.value.toInt())); + else if(vectorTypeSizes.count(type)) + { + DataBlock dataBlock; + dataBlock.data = property.value.toByteArray(); + writeDataBlockAttributes(dataBlock); + _xml->writeAttribute("length", QString::number(dataBlock.data.size() / vectorTypeSizes[type])); + _xml->writeCharacters(dataBlock.data.toBase64()); + } else _xml->writeAttribute("value", property.value.toString()); _xml->writeEndElement(); @@ -899,11 +911,19 @@ void XISFWriter::writeMetadata() _xml->writeEndElement(); } -#define REGISTER_METATYPE(type) { int id = qRegisterMetaType("LibXISF::"#type); \ +#define REGISTER_METATYPE(type) { int id = qMetaTypeId(); \ typeToId.insert({#type, id}); idToType.insert({id, #type}); } #define STRING_ENUM(map, map2, c, e) { map.insert({#e, c::e}); map2.insert({c::e, #e}); } -//#define ENUM_STRING(e) {#e, e} + +#define REGISTER_VECTOR_TYPE(type) { vectorTypeSizes.insert({typeToId[#type], sizeof(type::value_type)}); \ + QMetaType::registerConverter([](const type &v) { \ + return QByteArray((const char*)&v[0], v.size() * sizeof(type::value_type)); \ + }); \ + QMetaType::registerConverter([](const QByteArray &v) { \ + type t(v.size() / sizeof(type::value_type)); std::memcpy(&t[0], v.constData(), v.size()); \ + return t; \ + }); } struct Init { @@ -922,6 +942,7 @@ struct Init REGISTER_METATYPE(Float64); REGISTER_METATYPE(Complex32); REGISTER_METATYPE(Complex64); + REGISTER_METATYPE(TimePoint); REGISTER_METATYPE(I8Vector); REGISTER_METATYPE(UI8Vector); REGISTER_METATYPE(I16Vector); @@ -976,6 +997,19 @@ struct Init STRING_ENUM(colorSpaceToEnum, colorSpaceToString, Image, RGB); STRING_ENUM(colorSpaceToEnum, colorSpaceToString, Image, CIELab); + REGISTER_VECTOR_TYPE(I8Vector); + REGISTER_VECTOR_TYPE(UI8Vector); + REGISTER_VECTOR_TYPE(I16Vector); + REGISTER_VECTOR_TYPE(UI16Vector); + REGISTER_VECTOR_TYPE(I32Vector); + REGISTER_VECTOR_TYPE(UI32Vector); + REGISTER_VECTOR_TYPE(I64Vector); + REGISTER_VECTOR_TYPE(UI64Vector); + REGISTER_VECTOR_TYPE(F32Vector); + REGISTER_VECTOR_TYPE(F64Vector); + REGISTER_VECTOR_TYPE(C32Vector); + REGISTER_VECTOR_TYPE(C64Vector); + QMetaType::registerConverter([](const Complex32 &c){ return QString("(%1,%2)").arg(c.real).arg(c.imag); }); QMetaType::registerConverter([](const Complex64 &c){ return QString("(%1,%2)").arg(c.real).arg(c.imag); }); QMetaType::registerConverter([](QString s) diff --git a/libxisf.h b/libxisf.h index a98888c..1caffc5 100644 --- a/libxisf.h +++ b/libxisf.h @@ -24,6 +24,7 @@ #include #include #include +#include class QXmlStreamReader; @@ -316,6 +317,7 @@ Q_DECLARE_METATYPE(LibXISF::Float32); Q_DECLARE_METATYPE(LibXISF::Float64); Q_DECLARE_METATYPE(LibXISF::Complex32); Q_DECLARE_METATYPE(LibXISF::Complex64); +Q_DECLARE_METATYPE(LibXISF::TimePoint); Q_DECLARE_METATYPE(LibXISF::I8Vector); Q_DECLARE_METATYPE(LibXISF::UI8Vector); Q_DECLARE_METATYPE(LibXISF::I16Vector); diff --git a/test/main.cpp b/test/main.cpp index 7608f39..2dbdaed 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -46,6 +46,8 @@ int main(int argc, char **argv) image.addProperty(Property("PropertyFloat64", (Float64) 0.64)); image.addProperty(Property("PropertyComplex32", Complex32{3.0, -2.0})); 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.addFITSKeyword({"RA", "226.9751163116387", "Right ascension of the center of the image (deg)"}); image.addFITSKeyword({"DEC", "62.02302376908295", "Declination of the center of the image (deg)"}); writer.writeImage(image);