diff --git a/.gitignore b/.gitignore index fab7372..6589fdf 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ Thumbs.db # qtcreator generated files *.pro.user* +CMakeLists.txt.user # xemacs temporary files *.flc @@ -71,3 +72,4 @@ Thumbs.db *.dll *.exe +/build* diff --git a/libxisf.cpp b/libxisf.cpp index 5de1095..8b9fba5 100644 --- a/libxisf.cpp +++ b/libxisf.cpp @@ -410,6 +410,8 @@ void XISFReader::readImageElement() { if(_xml->name() == "Property") image.properties.push_back(readPropertyElement()); + else if(_xml->name() == "FITSKeyword") + image.fitsKeywords.push_back(readFITSKeyword()); else if(_xml->name() == "ICCProfile") { DataBlock icc = readDataBlock(); @@ -442,6 +444,15 @@ Property XISFReader::readPropertyElement() return property; } +FITSKeyword XISFReader::readFITSKeyword() +{ + QXmlStreamAttributes attributes = _xml->attributes(); + if(attributes.hasAttribute("name") && attributes.hasAttribute("value") && attributes.hasAttribute("comment")) + return { attributes.value("name").toString(), attributes.value("value").toString(), attributes.value("comment").toString() }; + else + throw Error("Invalid FITSKeyword element"); +} + void XISFReader::readDataElement(DataBlock &dataBlock) { _xml->readNextStartElement(); @@ -552,15 +563,6 @@ void XISFWriter::save(QIODevice &io) } } -void XISFWriter::saveXML(const QString &name) -{ - QFile fw(name); - fw.open(QIODevice::WriteOnly); - QByteArray header = _xisfHeader.mid(16); - header.truncate(header.indexOf('\0')); - fw.write(header); -} - void XISFWriter::writeImage(const Image &image) { _images.push_back(image); @@ -633,6 +635,9 @@ void XISFWriter::writeImageElement(const Image &image) for(auto &property : image.properties) writePropertyElement(property); + for(auto &fitsKeyword : image.fitsKeywords) + writeFITSKeyword(fitsKeyword); + _xml->writeEndElement(); } @@ -703,6 +708,16 @@ void XISFWriter::writePropertyElement(const Property &property) throw Error("Failed to write property"); } +void XISFWriter::writeFITSKeyword(const FITSKeyword &keyword) +{ + _xml->writeEmptyElement("FITSKeyword"); + _xml->writeAttribute("name", keyword.name); + _xml->writeAttribute("value", keyword.value); + _xml->writeAttribute("comment", keyword.comment); + if(_xml->hasError()) + throw Error("Failed to write FITS keyword"); +} + void XISFWriter::writeMetadata() { _xml->writeStartElement("Metadata"); diff --git a/libxisf.h b/libxisf.h index 1979c86..23d33ca 100644 --- a/libxisf.h +++ b/libxisf.h @@ -66,6 +66,13 @@ struct Property value(QVariant::fromValue(_value)){} }; +struct FITSKeyword +{ + QString name; + QString value; + QString comment; +}; + struct Image { enum Type @@ -119,6 +126,7 @@ struct Image DataBlock dataBlock; QByteArray iccProfile; std::vector properties; + std::vector fitsKeywords; void convertPixelStorageTo(PixelStorage storage); @@ -138,7 +146,7 @@ public: XISFReader(); void open(const QString &name); void open(const QByteArray &data); - /** Open image from */ + /** Open image from QIODevice. This method takes ownership of *io pointer */ void open(QIODevice *io); void close(); int imagesCount() const; @@ -148,6 +156,7 @@ private: void readSignature(); void readImageElement(); Property readPropertyElement(); + FITSKeyword readFITSKeyword(); void readDataElement(DataBlock &dataBlock); DataBlock readDataBlock(); void readCompression(DataBlock &dataBlock); @@ -165,7 +174,6 @@ public: void save(const QString &name); void save(QByteArray &data); void save(QIODevice &io); - void saveXML(const QString &name); void writeImage(const Image &image); private: void writeHeader(); @@ -173,6 +181,7 @@ private: void writeDataBlockAttributes(const DataBlock &dataBlock); void writeCompressionAttributes(const DataBlock &dataBlock); void writePropertyElement(const Property &property); + void writeFITSKeyword(const FITSKeyword &keyword); void writeMetadata(); std::unique_ptr _xml; QByteArray _xisfHeader; diff --git a/test/main.cpp b/test/main.cpp index 95ff4e1..f3063c0 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -47,6 +47,8 @@ int main(int argc, char **argv) image.properties.push_back(Property("PropertyFloat64", (Float64) 0.64)); image.properties.push_back(Property("PropertyComplex32", Complex32{3.0, -2.0})); image.properties.push_back(Property("PropertyComplex64", Complex64{-3.0, 2.0})); + image.fitsKeywords.push_back({"RA", "226.9751163116387", "Right ascension of the center of the image (deg)"}); + image.fitsKeywords.push_back({"DEC", "62.02302376908295", "Declination of the center of the image (deg)"}); writer.writeImage(image); image.imageType = Image::Flat;