C++20 playground for experimenting with RAW image processing primitives.
The core implementation lives in rawdev_core; the CLI is intentionally minimal for now, and most behavior is validated through tests.
rawdev_core: image model, pipeline, PNG writer, processing stages, a LibRaw-backed RAW import boundary (rawdev::coreapi::importRawImage), and a core processing facade (rawdev::coreapi::processImage) for frontend integrationWhiteBalanceStageBlackLevelStageColorMatrixStageGammaCorrectionStageToneMappingStage(OpenMP-enabled on a safe pixel loop when available)ColorTransformSrgbStage
rawdev_cli: command-line interface with argument parsing and command routing (--help,--version,process), linked torawdev_core; supports end-to-end RAW-to-PNG with structured--white-balance r,g,bparsing and full pipeline option coveragerawdev_tests: GoogleTest suite for IO, pipeline, golden behavior, coreapi/CLI coverage, and LLVM JIT examples, now including stage-contract coverage, deterministic golden fixtures, interleaved-layout/copy-back regressions, OpenMP parity coverage for tone mapping, and RAW import success/failure coveragerawdev_benchmarks: lightweight benchmark harness for Milestone 5 baseline capture intests/benchmark/benchmark_pipeline.cpprawdev_gui: Qt6 GUI executable insrc/gui/(rawdev_gui), with phase-1 wiring, phase-2 preview widget behavior, and phase-3 GUI-core adapter integration (rawdev::gui::adapters::toQImageused byAppController)
src/core/: core library (rawdev_core)src/cli/: CLI executable (rawdev_cli) withmain.cpp,cli_options.*, andcli_runner.*src/modules/: third-party integration (libraw,libraw-cmake,llvmsubmodules)src/gui/: Qt6 GUI (rawdev_gui) withmain_gui.cpp,main_window.*,controllers/, andwidgets/tests/: test and benchmark code (rawdev_tests,rawdev_benchmarks)
rawdev::image::Image stores pixel data in std::vector<float> sized width * height * 3.
Layout is interleaved RGB (not planar), matching ImageView::at(x, y, c):
index = y * stride + x * channels + c
stride = width * 3
When writing tests directly against Image::data, keep indexing consistent with this layout.
- Open project in CLion
- Reload/Update CMake
- Build targets (
rawdev_tests,rawdev_benchmarks,rawdev_cli, orrawdev_gui) - Run tests from CLion (GoogleTest/CTest)
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failurecmake --build build --target rawdev_benchmarks
./build/tests/benchmark/rawdev_benchmarks --out tests/benchmark/baseline_0.3.0-alpha.csv --runs 20 --warmup 5 --max-size 4096 --tag m5-baseline-macosBaseline artifacts are tracked under tests/benchmark/ for reproducible trend comparisons.
- C++20
- CMake (project currently requires
cmake_minimum_required(VERSION 4.1)) - GoogleTest via
FetchContent(v1.14.0) withgtest_discover_tests(rawdev_tests) - LibRaw via submodules (
src/modules/libraw,src/modules/libraw-cmake) - LLVM required by tests (
find_package(LLVM REQUIRED CONFIG)intests/CMakeLists.txt) - OpenMP optional in
rawdev_core - Qt6 (
Core,Gui,Widgets) required bysrc/gui/CMakeLists.txt
If OpenMP is not found in CLion:
-DOpenMP_ROOT=/opt/homebrew/opt/libompIf LLVM is not found in tests, set LLVM_DIR to a folder containing LLVMConfig.cmake (for example .../dist/lib/cmake/llvm).
If Qt6 is not found in CLion, set one of these CMake options:
-DCMAKE_PREFIX_PATH=/opt/homebrew/opt/qtor
-DQt6_DIR=/opt/homebrew/opt/qt/lib/cmake/Qt6Pipeline::execute()now includes empty/single-stage fast paths and a reusable scratch buffer, but the general multi-stage path still uses ping-pong + copy-back.- Benchmark timing is sensitive to thermals/frequency scaling; compare medians across runs/machines.
- RAW import is implemented in core via LibRaw and wired in CLI
process; GUI has phase-1/2/3 foundations (state wiring, preview widget, GUI-core adapter), but end-to-end file-processing flow is still pending - LLVM test target can expose warnings from LLVM headers depending on compiler flags
- CLI white-balance parsing now validates strict
r,g,bfloat format; all major options covered
rawdev_cliis structured in three parts:main.cpp: collects argv and dispatches parsed commandscli_options.*: parses CLI flags into typed command optionscli_runner.*: executes commands and manages exit codes/messages
- Current command surface includes
--help,--version, andprocessoptions scaffolding. - Integration strategy: keep parsing/execution flow in CLI modules and move reusable image-processing logic to
rawdev_core.
rawdev_guiis an executable target created withqt_add_executable.- Layer responsibilities:
main_gui.cpp:QApplicationbootstrapmain_window.*: window composition and user actionscontrollers/app_controller.*: orchestrates GUI-to-core operationswidgets/image_view_widget.*: image preview surface
- Current phase-1/phase-2/phase-3 behavior:
AppControllerstores minimal state (hasImage_,currentPath_,lastStatus_)MainWindowconsumesstatusMessageChangedandimageAvailabilityChangedRun Pipelineis disabled until an image is considered loadedImageViewWidgetprovidessetImage(...),clearImage(),hasImage()and fit-centered rendering for loaded imagesAppController::openRaw()currently converts a synthetic core image throughrawdev::gui::adapters::toQImage(...)and emitspreviewImageChanged
- Keep image-processing logic in
rawdev_core; GUI code should call core APIs via controllers. - Avoid using Qt types in public
rawdev_coreheaders unless strictly necessary.
Apache License 2.0. See LICENSE.