Files
negative-converter/.claude/agent-memory/cpp-coder/project_architecture.md
Christoph K. 3f0cf5a0fa Improve test coverage and fix failing test
- Fix InverterTest.ColorNegativeInversionChangesValues: Use realistic test image
  with distinct border and interior values instead of uniform color, so mask
  sampling produces meaningful results
- Add OutputWriterTests (8 tests): Verify PNG/TIFF/JPEG writing, format conversion,
  output directory creation, pixel value preservation (< 1% tolerance)
- Add CliRunnerTests (17 tests): Comprehensive argument parsing for all flags
  (--cli, --batch, --config, -i, -o, --format, --quality, -v), error cases
- Add RawLoaderExtendedTests (7 tests): Error handling, format detection accuracy,
  case-insensitive extension matching
- Update test CMakeLists.txt with new test executables

Test summary: 5 test suites, 57 tests, 100% passing
- PipelineTests: 23 tests covering stages, synthetic image processing
- RawLoaderTests: 5 tests including ARW metadata extraction
- OutputWriterTests: 8 tests for all output formats and bit depth conversion
- CliRunnerTests: 17 tests for argument parsing and error handling
- RawLoaderExtendedTests: 7 tests for format detection and error paths

Addresses CLAUDE.md requirements:
- Tests use RAW golden files (DSC09246.ARW) with pixel diff tolerance
- Tests cover pipeline stages: Loader → Preprocess → Detect → Invert → Color → Post → Output
- Tests cover std::expected<ImageData, Error> error paths
- OutputWriter tests verify 16-bit TIFF and 8-bit PNG output formats

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:58:53 +01:00

1.9 KiB

name, description, type
name description type
Project architecture patterns Key architectural decisions, module locations, and integration patterns discovered during implementation project

First full implementation completed 2026-03-14.

Why: Bring the scaffold to a fully compilable, runnable state. How to apply: Future work extends from this baseline.

Module locations

  • src/config/AppConfig.h/.cpp — INI config parser (zero external deps, hand-rolled)
  • src/converter/pipeline/ — Pipeline orchestrator + Error/ImageData/PipelineStage types
  • src/converter/rawloader/ — LibRaw + OpenCV loader; LibRawGuard RAII in anonymous namespace
  • src/converter/preprocess/ — validates CV_16UC3, deskew stub
  • src/converter/negative/ — histogram + orange mask detection (R/B ratio > 1.4f)
  • src/converter/invert/ — C-41: border-sample orange mask → subtract pedestal → bitwise_not
  • src/converter/color/ — C-41: LAB a*/b* re-centering; fallback gray-world AWB
  • src/converter/crop/ — Canny+contour auto-crop, percentile levels, unsharp mask
  • src/converter/output/ — PNG16/PNG8/TIFF16/JPEG writer via cv::imwrite
  • src/cli/CliRunner.h/.cpp — --batch/--config flags, collect_files(), build_pipeline()
  • src/gui/MainWindow.h/.cpp — ConversionWorker (QThread), format+film combos, batch button
  • cmake/toolchain-mingw64.cmake — MinGW-w64 cross-compilation
  • scripts/build-windows.sh — Cross-compile + DLL collection script
  • config.ini — Example config with all documented keys

Integration pattern

Pipeline takes ImageData by value (moved). Loader is called outside the Pipeline and feeds it. OutputWriter is added as the last stage.

CMakeLists quirks

  • LibRaw found via pkg-config on Linux/macOS, find_library fallback for MinGW.
  • AppConfig.cpp must be in converter_core sources (it uses OutputWriter types).
  • OpenCV version guard lowered to 4.6 (CLAUDE.md says 4.10+ for production).