diff --git a/reader/CMakeLists.txt b/reader/CMakeLists.txt index a5168f185..5fb20d52a 100644 --- a/reader/CMakeLists.txt +++ b/reader/CMakeLists.txt @@ -2,6 +2,10 @@ ADD_LIBRARY(JFJochReader STATIC JFJochReader.cpp JFJochReader.h JFJochHDF5Reader.cpp JFJochHDF5Reader.h + MiniCBF.cpp + MiniCBF.h + JFJochCBFReader.cpp + JFJochCBFReader.h HDF5ImageLocator.cpp HDF5ImageLocator.h HDF5ImageSource.cpp diff --git a/reader/JFJochCBFReader.cpp b/reader/JFJochCBFReader.cpp new file mode 100644 index 000000000..cd404f14d --- /dev/null +++ b/reader/JFJochCBFReader.cpp @@ -0,0 +1,235 @@ +// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute +// SPDX-License-Identifier: GPL-3.0-only + +#include "JFJochCBFReader.h" + +#include +#include +#include +#include +#include +#include + +#include "../common/JFJochException.h" +#include "../common/JFJochMath.h" + +namespace { + +bool HasCBFExtension(const std::filesystem::path &p) { + std::string ext = p.extension().string(); + std::transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c) { return std::tolower(c); }); + return ext == ".cbf"; +} + +// The sweep a file belongs to, as a template: everything before the trailing run of digits, the +// number of digits, and the extension. "o8_1_0042.cbf" -> {"o8_1_", 4}. A directory can hold several +// sweeps ("o8_1_*" beside "o8_2_*"), so collecting every .cbf in it would silently splice two +// crystals together; matching the template is what makes "point at any frame" safe. +struct Template { + std::string prefix; + size_t digits = 0; + + bool Matches(const std::string &name) const { + if (name.size() != prefix.size() + digits + 4) // + ".cbf" + return false; + if (name.compare(0, prefix.size(), prefix) != 0) + return false; + for (size_t i = 0; i < digits; i++) + if (!std::isdigit(static_cast(name[prefix.size() + i]))) + return false; + return true; + } +}; + +std::optional