// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include class ImagePreprocessorBuffer { protected: std::vector buffer; public: explicit ImagePreprocessorBuffer(size_t npixels); virtual ~ImagePreprocessorBuffer() = default; // Standard CPU operation. Defined here rather than in the .cpp: these are called once per pixel by // the CPU preprocessor, the CPU azimuthal integrator and the CPU spot finder, and the build has no // link-time optimisation - so out of line they are a real call per pixel, and they stop the callers // vectorising at all. Inlining them costs about a third of the per-image CPU work on every path // that does not have a GPU, and leaves the results bit-identical. std::vector &getBuffer() { return buffer; } const std::vector &getBuffer() const { return buffer; } int32_t &operator[](size_t i) { return buffer[i]; } const int32_t &operator[](size_t i) const { return buffer[i]; } size_t size() const { return buffer.size(); } int32_t *data() { return buffer.data(); } const int32_t *data() const { return buffer.data(); } // GPU operations (overriden in ImagePreprocessorBufferGPU virtual int32_t *getGPUBuffer(); virtual const int32_t *getGPUBuffer() const; // Values of the pixels with the given flat indices. Not just operator[] in a loop: on the GPU the // preprocessed image can live in device memory only, and then this gathers them there. virtual void Gather(const std::vector &npixel, std::vector &values) const; };