164 lines
5.3 KiB
C++
164 lines
5.3 KiB
C++
#include "libxisf.h"
|
|
#include "../rawimage.h"
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
#include <fitsio2.h>
|
|
|
|
bool OpenGLES = false;
|
|
|
|
bool loadXISF(const LibXISF::ByteArray &data, std::shared_ptr<RawImage> &rawImage)
|
|
{
|
|
try
|
|
{
|
|
LibXISF::XISFReader xisf;
|
|
xisf.open(data);
|
|
|
|
const LibXISF::Image &xisfImage = xisf.getImage(0);
|
|
|
|
RawImage::DataType type;
|
|
switch(xisfImage.sampleFormat())
|
|
{
|
|
case LibXISF::Image::UInt8: type = RawImage::UINT8; break;
|
|
case LibXISF::Image::UInt16: type = RawImage::UINT16; break;
|
|
case LibXISF::Image::UInt32: type = RawImage::UINT32; break;
|
|
case LibXISF::Image::Float32: type = RawImage::FLOAT32; break;
|
|
case LibXISF::Image::Float64: type = RawImage::FLOAT64; break;
|
|
default: return false;
|
|
}
|
|
|
|
LibXISF::Image tmpImage = xisfImage;
|
|
tmpImage.convertPixelStorageTo(LibXISF::Image::Planar);
|
|
|
|
if(tmpImage.colorSpace() == LibXISF::Image::ColorSpace::Gray)
|
|
{
|
|
rawImage = std::make_shared<RawImage>(tmpImage.width(), tmpImage.height(), 1, type);
|
|
std::memcpy(rawImage->data(), tmpImage.imageData(), tmpImage.imageDataSize() / tmpImage.channelCount());
|
|
}
|
|
else if(tmpImage.channelCount() == 3 || tmpImage.channelCount() == 4)
|
|
{
|
|
rawImage = RawImage::fromPlanar(tmpImage.imageData(), tmpImage.width(), tmpImage.height(), tmpImage.channelCount(), type);
|
|
}
|
|
return true;
|
|
}
|
|
catch (LibXISF::Error &err)
|
|
{
|
|
#ifdef WIN32
|
|
char text[1024];
|
|
sprintf_s(text, 1000, "Failed to open XISF image %s", err.what());
|
|
OutputDebugStringA(text);
|
|
#endif
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool loadFITS(const LibXISF::ByteArray &data, std::shared_ptr<RawImage> &rawImage)
|
|
{
|
|
fitsfile *file;
|
|
|
|
int status = 0;
|
|
int hdutype = -1;
|
|
int num = 0;
|
|
long naxes[3] = {0};
|
|
|
|
auto checkError = [&status]()
|
|
{
|
|
char err[100];
|
|
fits_get_errstatus(status, err);
|
|
#ifdef WIN32
|
|
char text[1000];
|
|
sprintf_s(text, 1000, "Failed to load FITS file %s", err);
|
|
OutputDebugStringA(text);
|
|
#endif
|
|
return false;
|
|
};
|
|
|
|
const void *dataPtr = data.data();
|
|
size_t size = data.size();
|
|
fits_open_memfile(&file, "file.fits", READONLY, (void**)&dataPtr, &size, 0, nullptr, &status);
|
|
if(status)return checkError();
|
|
fits_get_num_hdus(file, &num, &status);
|
|
if(status)return checkError();
|
|
|
|
int imgtype;
|
|
int naxis;
|
|
for(int i=1; i <= num; i++)
|
|
{
|
|
fits_movabs_hdu(file, i, &hdutype, &status);if(status)return checkError();
|
|
if(hdutype == IMAGE_HDU)
|
|
{
|
|
naxes[0] = naxes[1] = naxes[2] = 0;
|
|
fits_get_img_param(file, 3, &imgtype, &naxis, naxes, &status);if(status)return checkError();
|
|
fits_get_img_equivtype(file, &imgtype, &status);if(status)return checkError();
|
|
|
|
if(hdutype == IMAGE_HDU && naxis >= 2 && naxis <= 3 && status == 0)
|
|
{
|
|
RawImage::DataType type;
|
|
int fitstype;
|
|
long fpixel[3] = {1,1,1};
|
|
switch(imgtype)
|
|
{
|
|
case BYTE_IMG:
|
|
type = RawImage::UINT8;
|
|
fitstype = TBYTE;
|
|
break;
|
|
case SHORT_IMG:
|
|
type = RawImage::UINT16;
|
|
fitstype = TSHORT;
|
|
break;
|
|
case USHORT_IMG:
|
|
type = RawImage::UINT16;
|
|
fitstype = TUSHORT;
|
|
break;
|
|
case ULONG_IMG:
|
|
type = RawImage::UINT32;
|
|
fitstype = TUINT;
|
|
break;
|
|
case FLOAT_IMG:
|
|
type = RawImage::FLOAT32;
|
|
fitstype = TFLOAT;
|
|
break;
|
|
case DOUBLE_IMG:
|
|
type = RawImage::FLOAT64;
|
|
fitstype = TDOUBLE;
|
|
break;
|
|
default:
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
size_t size = naxes[0]*naxes[1];
|
|
size_t w = naxes[0];
|
|
size_t h = naxes[1];
|
|
|
|
RawImage img(w, h, naxis == 2 ? 1 : naxes[2], type);
|
|
uint8_t *data = static_cast<uint8_t*>(img.data());
|
|
for (int i=1; i==1 || i<=naxes[2]; i++)
|
|
{
|
|
fpixel[2] = i;
|
|
fits_read_pix(file, fitstype, fpixel, size, NULL, data + img.size() * RawImage::typeSize(type) * (i-1), NULL, &status);
|
|
if(status)return checkError();
|
|
}
|
|
if(fitstype == TSHORT)
|
|
{
|
|
uint16_t *s = static_cast<uint16_t*>(img.data());
|
|
size_t size = img.size() * img.channels();
|
|
for(size_t i=0; i<size; i++)
|
|
s[i] -= INT16_MIN;
|
|
}
|
|
|
|
if(img.channels() == 1)
|
|
rawImage = std::make_shared<RawImage>(std::move(img));
|
|
else
|
|
rawImage = RawImage::fromPlanar(img);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|