// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochReader.h" #include "../common/PixelMask.h" void JFJochReader::LoadImage(int64_t image_number) { // It would be a mess to load two images at the same time // so loading is protected via mutex // yet copying share_ptr pointer is atomic and needs no mutex protection std::unique_lock ul(current_image_mutex); current_image = LoadImageInternal(image_number); CalcImageStatistics(current_image); CalcROI(current_image); } std::shared_ptr JFJochReader::CopyImage() { return current_image; } void JFJochReader::CalcImageStatistics(const std::shared_ptr &image) { if (!image || (!image->dataset)) return; size_t good_pixel = 0; for (int i = 0; i < image->image.size(); i++) { int32_t value = image->image[i]; uint32_t mask_val = 0; if (!image->dataset->pixel_mask.empty()) mask_val = image->dataset->pixel_mask.at(i); if ((mask_val & ( (1<image[i] = GAP_PXL_VALUE; } else if (image->image[i] <= image->dataset->error_value || (mask_val != 0)) { image->image[i] = ERROR_PXL_VALUE; image->error_pixel.emplace(i); } else if (image->image[i] >= image->dataset->saturation_value) { image->image[i] = SATURATED_PXL_VALUE; image->saturated_pixel.emplace(i); } else { good_pixel++; image->valid_pixel.emplace(value, i); } } } #include void JFJochReader::CalcROI(const std::shared_ptr &image) { if (!image || (!image->dataset)) return; if (!roi) { image->roi = {}; return; } int64_t width = image->dataset->image_size_x; int64_t height = image->dataset->image_size_y; int64_t roi_val = 0; uint64_t roi_val_2 = 0; int64_t roi_max = INT64_MIN; uint64_t roi_npixel = 0; for (int64_t y = roi->GetYMin(); y < std::min(roi->GetYMax(), height); y++) { for (int64_t x = roi->GetXMin(); x < std::min(roi->GetXMax(), width); x++) { int32_t val = image->image[x + width * y]; if ((val != SATURATED_PXL_VALUE) && (val != ERROR_PXL_VALUE) && (val != GAP_PXL_VALUE)) { roi_val += val; roi_val_2 += val * val; if (val > roi_max) roi_max = val; roi_npixel++; } } } image->roi = ROIMessage{ .sum = roi_val, .sum_square = roi_val_2, .max_count = roi_max, .pixels = roi_npixel }; } void JFJochReader::SetROI(const std::optional &input) { std::unique_lock lg(current_image_mutex); if (input && (input->GetArea() == 0)) { // Empty ROI is reset roi = {}; } else { roi = input; CalcROI(current_image); } }