Viewer: stop copying the image in LoadImageInternal, parallelise it

"auto img = image->Image()" deduced std::vector<int32_t> by value, so every
frame copied the whole detector image before converting it -- 72 MB on a 16 Mpx
detector. Bind a const reference instead.

The sentinel-to-float conversion also ran single-threaded on the GUI thread;
spread it over rows the same way RenderImage does. 18.1 Mpx: 11.8 -> ~1 ms,
plus the copy that is now gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 19:00:37 +02:00
co-authored by Claude Opus 5
parent 417170bc13
commit fd9f93e1f1
+21 -13
View File
@@ -21,6 +21,7 @@
#include <QMenu>
#include <cmath>
#include <QMouseEvent>
#include <QtConcurrent/QtConcurrent>
#include "JFJochSimpleImage.h"
@@ -129,19 +130,26 @@ void JFJochDiffractionImage::LoadImageInternal() {
image_fp.resize(W*H);
auto img = image->Image();
// Fill the QImage with pixel data from the array
for (int pxl = 0; pxl < W * H; pxl++) {
auto val = img[pxl];
if (val == GAP_PXL_VALUE)
image_fp[pxl] = NAN;
else if (val == ERROR_PXL_VALUE)
image_fp[pxl] = -INFINITY;
else if (val == SATURATED_PXL_VALUE)
image_fp[pxl] = INFINITY;
else
image_fp[pxl] = static_cast<float>(val);
}
const auto &img = image->Image();
QVector<int> rows;
rows.reserve(H);
for (int y = 0; y < H; ++y) rows.push_back(y);
// Fill the float image with pixel data from the array
QtConcurrent::blockingMap(rows, [&](int y) {
for (size_t pxl = y * W; pxl < (y + 1) * W; pxl++) {
auto val = img[pxl];
if (val == GAP_PXL_VALUE)
image_fp[pxl] = NAN;
else if (val == ERROR_PXL_VALUE)
image_fp[pxl] = -INFINITY;
else if (val == SATURATED_PXL_VALUE)
image_fp[pxl] = INFINITY;
else
image_fp[pxl] = static_cast<float>(val);
}
});
}
void JFJochDiffractionImage::DrawSpots() {