diff --git a/imageinfo.cpp b/imageinfo.cpp index 164102d..1f0d8a8 100644 --- a/imageinfo.cpp +++ b/imageinfo.cpp @@ -48,6 +48,7 @@ FITSRecord::FITSRecord(const LibXISF::Property &property) key = property.id.c_str(); value = QString::fromStdString(property.value.toString()); comment = property.comment.c_str(); + xisf = true; } QByteArray FITSRecord::valueToByteArray() const diff --git a/imageinfo.h b/imageinfo.h index 3f2fd7c..e6f3ac6 100644 --- a/imageinfo.h +++ b/imageinfo.h @@ -13,6 +13,7 @@ struct FITSRecord QByteArray key; QVariant value; QByteArray comment; + bool xisf = false; bool editable() const; FITSRecord(){} FITSRecord(const QByteArray &key, const QVariant &value, const QByteArray &comment); diff --git a/libXISF b/libXISF index 033a34e..4db1d86 160000 --- a/libXISF +++ b/libXISF @@ -1 +1 @@ -Subproject commit 033a34e2486223c358f60f7f7d532890e7afb9b4 +Subproject commit 4db1d865305405627d9db9579cb2f1dde1cad8ed diff --git a/loadrunable.cpp b/loadrunable.cpp index 0eb0dbd..6ec53cf 100644 --- a/loadrunable.cpp +++ b/loadrunable.cpp @@ -567,10 +567,12 @@ void writeFITSImage(fitsfile *fw, std::shared_ptr rawimage, ImageInfoD fits_write_pix(fw, TFLOAT, firstpix, rawimage->size(), planes[i].data(), &status); } break; + default: + return; } for(const FITSRecord &record : imageinfo.fitsHeader) { - if(skipKeys.contains(record.key))continue; + if(skipKeys.contains(record.key) || record.xisf)continue; bool isdouble; bool isint; @@ -598,10 +600,7 @@ void ConvertRunable::run() { ImageInfoData imageinfo; std::shared_ptr rawimage; - if(m_infile.endsWith(".FITS", Qt::CaseInsensitive) || m_infile.endsWith(".FIT", Qt::CaseInsensitive)) - loadFITS(m_infile, imageinfo, rawimage); - if(m_infile.endsWith(".XISF", Qt::CaseInsensitive)) - loadXISF(m_infile, imageinfo, rawimage); + loadImage(m_infile, imageinfo, rawimage); if(rawimage) { @@ -620,11 +619,26 @@ void ConvertRunable::run() default: return; } - LibXISF::Image image(rawimage->width(), rawimage->height(), channelCount, sampleFormat, channelCount == 1 ? LibXISF::Image::Gray : LibXISF::Image::RGB, LibXISF::Image::Normal); - std::memcpy(image.imageData(), rawimage->data(), image.imageDataSize()); + LibXISF::Image image(rawimage->width(), rawimage->height(), channelCount, sampleFormat, channelCount == 1 ? LibXISF::Image::Gray : LibXISF::Image::RGB, LibXISF::Image::Planar); + if(channelCount == 1) + { + std::memcpy(image.imageData(), rawimage->data(), image.imageDataSize()); + } + else + { + size_t off = 0; + std::vector planes = rawimage->split(); + for(const auto &plane : planes) + { + std::memcpy(image.imageData() + off, plane.data(), plane.size() * RawImage::typeSize(plane.type())); + off += plane.size() * RawImage::typeSize(plane.type()); + } + } for(auto &record : imageinfo.fitsHeader) { - if(record.value.type() == QVariant::Bool) + if(record.xisf)continue; + + if(record.value.typeId() == QMetaType::Bool) image.addFITSKeyword({record.key.toStdString(), record.value.toBool() ? "T" : "F", record.comment.toStdString()}); else image.addFITSKeyword({record.key.toStdString(), record.value.toString().toStdString(), record.comment.toStdString()}); @@ -648,5 +662,33 @@ void ConvertRunable::run() writeFITSImage(fw, rawimage, imageinfo); fits_close_file(fw, &status); } + + if(m_format == "QIMAGE") + { + QImage::Format format = QImage::Format_Invalid; + int width = rawimage->widthBytes(); + switch(rawimage->type()) + { + case RawImage::UINT8: + if(rawimage->channels() == 1)format = QImage::Format_Grayscale8; + else if(rawimage->channels() == 3)format = QImage::Format_RGBX8888; + else if(rawimage->channels() == 4)format = QImage::Format_RGBA8888; + break; + case RawImage::UINT16: + if(rawimage->channels() == 1)format = QImage::Format_Grayscale16; + else if(rawimage->channels() == 3)format = QImage::Format_RGBX64; + else if(rawimage->channels() == 4)format = QImage::Format_RGBA64; + width *= 2; + break; + default: + return; + } + if(format == QImage::Format_Invalid)return; + + QImage qimage(rawimage->width(), rawimage->height(), format); + for(uint32_t i=0; i < rawimage->height(); i++) + std::memcpy(qimage.scanLine(i), rawimage->data(i), width); + qimage.save(m_outfile); + } } } diff --git a/rawimage.cpp b/rawimage.cpp index 7af32aa..15d2dea 100644 --- a/rawimage.cpp +++ b/rawimage.cpp @@ -351,6 +351,11 @@ uint32_t RawImage::norm() const } } +uint32_t RawImage::widthBytes() const +{ + return m_ch * m_width; +} + void* RawImage::data() { return m_pixels.get(); @@ -387,6 +392,11 @@ const void *RawImage::origData(uint32_t row, uint32_t col) const return m_pixels.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_type); } +bool RawImage::planar() const +{ + return m_planar; +} + void RawImage::convertToThumbnail() { if(!valid()) @@ -735,6 +745,7 @@ std::shared_ptr RawImage::fromPlanar(const void *pixels, uint32_t w, u convert(static_cast(pixels), static_cast(image->data()), 1); break; } + image->m_planar = false; return image; } @@ -748,11 +759,11 @@ std::vector RawImage::split() const size_t s = size(); auto extract = [&](auto *in, auto *out, size_t off) { - for(size_t i=0; i < s; i+=m_ch) + for(size_t i=0; i < s; i++) out[i] = in[i*m_ch + off]; }; - for(uint32_t i=0; i