From bd4590082137508764552b028ea8b5e327680cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Mon, 10 Mar 2025 11:01:45 +0100 Subject: [PATCH] Finish standalone thumbnailer under --- imagewidget.cpp | 4 ++-- loadrunable.cpp | 7 +------ rawimage.cpp | 12 +++++++++--- rawimage.h | 1 + thumbnailer/CMakeLists.txt | 2 +- thumbnailer/main.cpp | 34 ++++++++++++++++++++++++---------- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/imagewidget.cpp b/imagewidget.cpp index 7bd69a0..05b3788 100644 --- a/imagewidget.cpp +++ b/imagewidget.cpp @@ -392,9 +392,9 @@ void swPaint(std::shared_ptr &rawImage, float dx, float dy, float scal float iptr; float fy = std::modf((y + oy) * iscale, &iptr); int64_t py = iptr; - int64_t w = py * rawImage->widthBytes(); + int64_t w = py * rawImage->widthSamples(); int64_t w2 = w; - if(py+1 < imgHeight)w2 += rawImage->widthBytes(); + if(py+1 < imgHeight)w2 += rawImage->widthSamples(); if(py >= imgHeight)break; for(int64_t x = std::max((int64_t)0, -ox); x < width; x++) diff --git a/loadrunable.cpp b/loadrunable.cpp index 8f06432..79d41f8 100644 --- a/loadrunable.cpp +++ b/loadrunable.cpp @@ -293,7 +293,6 @@ void ConvertRunable::run() // if nothing else try QImage { QImage::Format format = QImage::Format_Invalid; - int width = rawimage->widthBytes(); switch(rawimage->type()) { @@ -306,7 +305,6 @@ void ConvertRunable::run() 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; case RawImage::FLOAT16: case RawImage::FLOAT32: @@ -316,15 +314,12 @@ void ConvertRunable::run() 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; } 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 qimage((const uchar*)rawimage->data(), rawimage->width(), rawimage->height(), rawimage->widthBytes(), format); qimage.save(m_outfile); } } diff --git a/rawimage.cpp b/rawimage.cpp index c4878d1..7b36a5b 100644 --- a/rawimage.cpp +++ b/rawimage.cpp @@ -198,7 +198,7 @@ void calcStats(const T *data, size_t n, size_t w, RawImage::Stats &stats) auto findMedian = [histSize](std::vector &histogram, size_t n) -> size_t { size_t histSum = 0; - for(size_t o=0; o < histSize; o++) + for(size_t o=1; o < histSize; o++) { histSum += histogram[o]; if(histSum >= n/2) @@ -299,7 +299,8 @@ void calcStats(const T *data, size_t n, size_t w, RawImage::Stats &stats) double sum2 = (double)sum[i] * sum[i]; stats.m_stdDev[i] = std::sqrt((sumSq[i] - sum2 / na[i]) / (na[i] - 1)); - uint32_t median = findMedian(histogram[i], na[i]); + size_t naclip = na[i] - histogram[i][0]; + uint32_t median = findMedian(histogram[i], naclip); stats.m_median[i] = median; std::vector madHist(histSize, 0); madHist[0] = histogram[i][median]; @@ -308,7 +309,7 @@ void calcStats(const T *data, size_t n, size_t w, RawImage::Stats &stats) if(median + o < histSize)madHist[o] += histogram[i][median + o]; if(o <= median)madHist[o] += histogram[i][median - o]; } - stats.m_mad[i] = findMedian(madHist, na[i]); + stats.m_mad[i] = findMedian(madHist, naclip); if constexpr(!std::numeric_limits::is_integer) { stats.m_median[i] /= 65535.0; @@ -403,6 +404,11 @@ uint32_t RawImage::norm() const } uint32_t RawImage::widthBytes() const +{ + return m_ch * m_width * typeSize(m_type); +} + +uint32_t RawImage::widthSamples() const { return m_ch * m_width; } diff --git a/rawimage.h b/rawimage.h index a03bcf8..6878e82 100644 --- a/rawimage.h +++ b/rawimage.h @@ -98,6 +98,7 @@ public: DataType type() const; uint32_t norm() const; uint32_t widthBytes() const; + uint32_t widthSamples() const; void* data(); const void* data() const; void* data(uint32_t row, uint32_t col = 0); diff --git a/thumbnailer/CMakeLists.txt b/thumbnailer/CMakeLists.txt index 38f7c02..e91a96d 100644 --- a/thumbnailer/CMakeLists.txt +++ b/thumbnailer/CMakeLists.txt @@ -17,9 +17,9 @@ if(BUILD_THUMBNAILER) else(WIN32) qt_add_executable(tenmonthumbnailer main.cpp + ../loadimage.cpp ../rawimage.cpp ../rawimage_sse.cpp - ../loadimage.cpp ../imageinfodata.cpp) target_link_libraries(tenmonthumbnailer PRIVATE Qt6::Core Qt6::Gui ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB} ${WCS_LIB} ${LCMS2_LIB} XISF) diff --git a/thumbnailer/main.cpp b/thumbnailer/main.cpp index f67f3ec..6ae01d7 100644 --- a/thumbnailer/main.cpp +++ b/thumbnailer/main.cpp @@ -28,21 +28,35 @@ int main(int argc, char *argv[]) ImageInfoData info; std::shared_ptr rawImage; if(!loadImage(input, info, rawImage)) - return 1; - - if(!rawImage) return 2; + if(!rawImage) + return 3; + + bool ok; + int size = parser.value("s").toInt(&ok); + if(!ok) + size = 128; + + QSize rect(rawImage->width(), rawImage->height()); + rect.scale(size, size, Qt::KeepAspectRatio); + rawImage->calcStats(); + rawImage->resize(rect.width(), rect.height()); + if(rawImage->imageStats().m_median[0] < rawImage->norm() * 0.2f) + { + MTFParam mtfParams = rawImage->calcMTFParams(true); + rawImage->applySTF(mtfParams); + } rawImage->convertToType(RawImage::UINT8); - QImage img((const uchar*)rawImage->data(), rawImage->width(), rawImage->height(), QImage::Format_RGBA8888); - bool ok = false; - int size = parser.value("s").toInt(&ok); - if(!ok)size = 128; - img = img.scaled(size, size, Qt::KeepAspectRatio); - img.save(output, "png"); + QImage img; + if(rawImage->channels() == 1) + img = QImage((const uchar*)rawImage->data(), rawImage->width(), rawImage->height(), rawImage->widthBytes(), QImage::Format_Grayscale8); + else + img = QImage((const uchar*)rawImage->data(), rawImage->width(), rawImage->height(), rawImage->widthBytes(), QImage::Format_RGBA8888); - //rawImage->convertTosRGB(); + if(!img.save(output, "png")) + return 4; return 0; }