Show progress while loading reads the image sizes

Before decoding, loadImages reads every header to size the batch against
the free memory. That pass was serial, silent and could not be cancelled,
so the loading window sat at "0 of N". LoadProgress gains onSized, the
headers are read in parallel on the same cursor-driven workers as the
decodes, and a cancel stops the pass. The window's bar runs twice,
"Checking sizes" then "Decoding", and the CLI prints a sizing line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Si
2026-09-26 22:42:30 +02:00
co-authored by Claude Opus 5.5
parent cfaa773cf7
commit 8acf85ddb8
7 changed files with 101 additions and 43 deletions
+9
View File
@@ -1708,9 +1708,16 @@ int main() {
paths.push_back((dir / "missing.png").string());
std::atomic<std::size_t> calls{0};
std::atomic<std::size_t> sizedCalls{0};
std::atomic<bool> sizedAfterDecode{false};
std::size_t lastTotal = 0;
std::mutex mutex;
LoadProgress progress;
progress.onSized = [&](std::size_t done, std::size_t total, const std::string&) {
++sizedCalls;
if (calls.load() > 0) sizedAfterDecode = true;
check(done >= 1 && done <= total, "sizing step is within the batch");
};
progress.onFile = [&](std::size_t done, std::size_t total, const std::string&) {
std::lock_guard<std::mutex> lock(mutex);
++calls;
@@ -1723,6 +1730,8 @@ int main() {
check(images.size() == 6, "every readable image is returned");
check(failuresOut.size() == 1, "the unreadable one is reported");
check(calls.load() == paths.size(), "progress fires once per file");
check(sizedCalls.load() == paths.size() && !sizedAfterDecode.load(),
"every header is sized, all before the first decode");
check(lastTotal == paths.size(), "progress reports the batch size");
check(images.front().path() == paths.front(), "input order is preserved");