#include "Inverter.h" #include #include #include #include namespace photoconv { StageResult Inverter::process(ImageData data) const { if (data.rgb.empty()) { return std::unexpected(make_error( ErrorCode::InversionFailed, "Inverter received empty image")); } switch (data.film_type) { case FilmType::ColorNegative: std::cout << "[Invert] Inverting color negative (C-41)" << std::endl; return invert_color_negative(std::move(data)); case FilmType::BWNegative: std::cout << "[Invert] Inverting B&W negative" << std::endl; return invert_bw_negative(std::move(data)); case FilmType::ColorPositive: case FilmType::BWPositive: std::cout << "[Invert] Positive detected, skipping inversion" << std::endl; return data; case FilmType::Unknown: std::cout << "[Invert] Unknown film type, applying default inversion" << std::endl; return invert_color_negative(std::move(data)); } return data; // Unreachable, but satisfies compiler } StageResult Inverter::invert_color_negative(ImageData data) { // TODO: Implement proper C-41 orange mask removal. // Strategy: // 1. Sample unexposed border regions to characterize the orange mask // 2. Compute per-channel mask color (typically R > G > B) // 3. Subtract mask contribution from each channel // 4. Apply bitwise_not inversion // 5. Apply per-channel scaling to normalize levels // Basic inversion for now cv::bitwise_not(data.rgb, data.rgb); return data; } StageResult Inverter::invert_bw_negative(ImageData data) { cv::bitwise_not(data.rgb, data.rgb); return data; } } // namespace photoconv