Fix bug when saving color FITS/XISF files

This commit is contained in:
2024-03-24 23:55:50 +01:00
parent f35db9d1af
commit 4fe56acbd9
6 changed files with 70 additions and 11 deletions
+1
View File
@@ -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
+1
View File
@@ -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);
+1 -1
Submodule libXISF updated: 033a34e248...4db1d86530
+49 -7
View File
@@ -567,10 +567,12 @@ void writeFITSImage(fitsfile *fw, std::shared_ptr<RawImage> 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> 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);
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<RawImage> planes = rawimage->split();
for(const auto &plane : planes)
{
std::memcpy(image.imageData<uint8_t>() + 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);
}
}
}
+13 -2
View File
@@ -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> RawImage::fromPlanar(const void *pixels, uint32_t w, u
convert(static_cast<const double*>(pixels), static_cast<double*>(image->data()), 1);
break;
}
image->m_planar = false;
return image;
}
@@ -748,11 +759,11 @@ std::vector<RawImage> 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<m_ch; i++)
for(uint32_t i=0; i<m_channels; i++)
{
switch(m_type)
{
+4
View File
@@ -71,6 +71,7 @@ protected:
DataType m_origType = UINT8;
float m_thumbAspect = 0.0;
Stats m_stats;
bool m_planar = false;
void allocate(uint32_t w, uint32_t h, uint32_t ch, DataType type);
public:
RawImage();
@@ -88,12 +89,15 @@ public:
uint32_t size() const;
DataType type() const;
uint32_t norm() const;
uint32_t widthBytes() const;
void* data();
const void* data() const;
void* data(uint32_t row, uint32_t col = 0);
const void* data(uint32_t row, uint32_t col = 0) const;
const void *origData() const;
const void *origData(uint32_t row, uint32_t col = 0) const;
bool planar() const;
void setPlanar();
void convertToThumbnail();
void convertToGLFormat();
float thumbAspect() const;