238 lines
7.5 KiB
C++
238 lines
7.5 KiB
C++
#include "libxisf.h"
|
|
#include <thumbcache.h>
|
|
#include "../rawimage.h"
|
|
#include <fitsio2.h>
|
|
|
|
bool OpenGLES = false;
|
|
|
|
void RawImageToHTBITMAP(std::shared_ptr<RawImage> &rawImage, HBITMAP *hbmp, UINT thumbSize)
|
|
{
|
|
rawImage->calcStats();
|
|
|
|
DWORD thre = 10;
|
|
DWORD dataSize = 4;
|
|
//HRESULT hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\nou\\Tenmon\\settings", L"thumbnailstretchthreshold", RRF_RT_DWORD, NULL, &thre, &dataSize));
|
|
|
|
float thref = 0.1f;
|
|
/*if(hr == S_OK)
|
|
thref = thre / 100.0f;*/
|
|
|
|
if(rawImage->imageStats().m_mean[0] < rawImage->norm() * thref)
|
|
{
|
|
//OutputDebugStringA("Stretch image");
|
|
MTFParam params = rawImage->calcMTFParams();
|
|
rawImage->applySTF(params);
|
|
}
|
|
|
|
UINT w = rawImage->width();
|
|
UINT h = rawImage->height();
|
|
|
|
UINT cw = thumbSize;
|
|
UINT ch = thumbSize;
|
|
if (w > h)
|
|
ch = h * thumbSize / w;
|
|
else
|
|
cw = w * thumbSize / h;
|
|
|
|
|
|
rawImage->resize(cw, ch);
|
|
rawImage->convertToType(RawImage::UINT8);
|
|
|
|
BITMAPINFO bmi = {};
|
|
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
|
bmi.bmiHeader.biWidth = cw;
|
|
bmi.bmiHeader.biHeight = -static_cast<LONG>(ch);
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
UINT lw = cw * 4;
|
|
|
|
BYTE *pBits;
|
|
HBITMAP bmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&pBits), NULL, 0);
|
|
|
|
const unsigned char *p = (const unsigned char*)rawImage->data();
|
|
const unsigned short *ps = (const unsigned short*)rawImage->data();
|
|
if(rawImage->channels() == 1)
|
|
{
|
|
for(UINT y = 0; y < ch; y++)
|
|
{
|
|
for(UINT x = 0; x < cw; x++)
|
|
{
|
|
pBits[(y * lw) + x * 4 + 0] = p[y * cw + x];
|
|
pBits[(y * lw) + x * 4 + 1] = p[y * cw + x];
|
|
pBits[(y * lw) + x * 4 + 2] = p[y * cw + x];
|
|
pBits[(y * lw) + x * 4 + 3] = 255;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(UINT y = 0; y < ch; y++)
|
|
{
|
|
for(UINT x = 0; x < cw; x++)
|
|
{
|
|
pBits[(y * lw) + x * 4 + 0] = p[y * cw * 4 + x * 4 + 2];
|
|
pBits[(y * lw) + x * 4 + 1] = p[y * cw * 4 + x * 4 + 1];
|
|
pBits[(y * lw) + x * 4 + 2] = p[y * cw * 4 + x * 4 + 0];
|
|
pBits[(y * lw) + x * 4 + 3] = 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
*hbmp = bmp;
|
|
}
|
|
|
|
bool loadXISF(const LibXISF::ByteArray &data, HBITMAP *hbmp, UINT thumbSize)
|
|
{
|
|
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: break;
|
|
}
|
|
|
|
LibXISF::Image tmpImage = xisfImage;
|
|
tmpImage.convertPixelStorageTo(LibXISF::Image::Planar);
|
|
std::shared_ptr<RawImage> rawImage;
|
|
|
|
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);
|
|
}
|
|
|
|
RawImageToHTBITMAP(rawImage, hbmp, thumbSize);
|
|
|
|
return true;
|
|
}
|
|
catch (LibXISF::Error &err)
|
|
{
|
|
char text[1024];
|
|
sprintf_s(text, 1000, "Failed to open XISF image %s", err.what());
|
|
OutputDebugStringA(text);
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool loadFITS(const LibXISF::ByteArray &data, HBITMAP *hbmp, UINT thumbSize)
|
|
{
|
|
fitsfile *file;
|
|
|
|
int status = 0;
|
|
int type = -1;
|
|
int num = 0;
|
|
long naxes[3] = {0};
|
|
|
|
auto checkError = [&status]()
|
|
{
|
|
char err[100];
|
|
char text[1000];
|
|
fits_get_errstatus(status, err);
|
|
sprintf_s(text, 1000, "Failed to load FITS file %s", err);
|
|
OutputDebugStringA(text);
|
|
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, IMAGE_HDU, &status);if(status)return checkError();
|
|
fits_get_hdu_type(file, &type, &status);if(status)return checkError();
|
|
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(type == 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;
|
|
}
|
|
|
|
std::shared_ptr<RawImage> image;
|
|
if(img.channels() == 1)
|
|
image = std::make_shared<RawImage>(std::move(img));
|
|
else
|
|
image = RawImage::fromPlanar(img);
|
|
|
|
RawImageToHTBITMAP(image, hbmp, thumbSize);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|