100 lines
3.1 KiB
C++
100 lines
3.1 KiB
C++
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// 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<JFJochReaderImage> JFJochReader::CopyImage() {
|
|
return current_image;
|
|
}
|
|
|
|
void JFJochReader::CalcImageStatistics(const std::shared_ptr<JFJochReaderImage> &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<<PixelMask::ModuleGapPixelBit)
|
|
| (1<<PixelMask::ChipGapPixelBit)
|
|
| (1<<PixelMask::ModuleEdgePixelBit))) != 0) {
|
|
image->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 <iostream>
|
|
|
|
void JFJochReader::CalcROI(const std::shared_ptr<JFJochReaderImage> &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<ROIBox> &input) {
|
|
std::unique_lock lg(current_image_mutex);
|
|
if (input && (input->GetArea() == 0)) {
|
|
// Empty ROI is reset
|
|
roi = {};
|
|
} else {
|
|
roi = input;
|
|
CalcROI(current_image);
|
|
}
|
|
}
|