Fix bug when saving color FITS/XISF files
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user