// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "ImagePreprocessor.h" ImagePreprocessor::ImagePreprocessor(const DiffractionExperiment &experiment, const PixelMask &mask) : npixels(experiment.GetPixelsNum()), experiment(experiment), mask_1bit(npixels, false), saturation_limit(experiment.GetSaturationLimit()) { for (int i = 0; i < npixels; i++) mask_1bit[i] = (mask.GetMask().at(i) != 0); } ImageStatistics ImagePreprocessor::Analyze(std::vector &processed_image, const uint8_t *image_ptr, CompressedImageMode image_mode) { switch (image_mode) { case CompressedImageMode::Int8: return Analyze(processed_image, image_ptr, INT8_MIN, INT8_MAX); case CompressedImageMode::Int16: return Analyze(processed_image, image_ptr, INT16_MIN, INT16_MAX); case CompressedImageMode::Int32: return Analyze(processed_image, image_ptr, INT32_MIN, INT32_MAX); case CompressedImageMode::Uint8: return Analyze(processed_image, image_ptr, UINT8_MAX, UINT8_MAX); case CompressedImageMode::Uint16: return Analyze(processed_image, image_ptr, UINT16_MAX, UINT16_MAX); case CompressedImageMode::Uint32: return Analyze(processed_image, image_ptr, UINT32_MAX, UINT32_MAX); default: throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "RGB/float mode not supported"); } } template ImageStatistics ImagePreprocessor::Analyze(std::vector &processed_image, const uint8_t *input, T err_pixel_val, T sat_pixel_val) { if (processed_image.size() != npixels) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Processed image size mismatch"); auto image = reinterpret_cast(input); ImageStatistics ret{}; if (sat_pixel_val > saturation_limit) sat_pixel_val = static_cast(saturation_limit); for (int i = 0; i < npixels; i++) { if (mask_1bit[i] != 0) { processed_image[i] = INT32_MIN; ++ret.masked_pixel_count; } else if (image[i] >= sat_pixel_val) { processed_image[i] = INT32_MAX; ++ret.saturated_pixel_count; } else if (std::is_signed::value && (image[i] == err_pixel_val)) { // Error pixels are possible only for signed types processed_image[i] = INT32_MIN; ++ret.error_pixel_count; } else { processed_image[i] = static_cast(image[i]); if (image[i] > ret.max_value) ret.max_value = image[i]; if (image[i] < ret.min_value) ret.min_value = image[i]; } } return ret; }