#include "libxisf.h" #include #include "../rawimage.h" #include bool OpenGLES = false; void RawImageToHTBITMAP(std::shared_ptr &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(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(&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; if(tmpImage.colorSpace() == LibXISF::Image::ColorSpace::Gray) { rawImage = std::make_shared(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(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(img.data()); size_t size = img.size() * img.channels(); for(size_t i=0; i image; if(img.channels() == 1) image = std::make_shared(std::move(img)); else image = RawImage::fromPlanar(img); RawImageToHTBITMAP(image, hbmp, thumbSize); return true; } } return false; }