CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
working_image_cpu.cpp
Go to the documentation of this file.
1
10
11#include <OpenImageIO/imagebuf.h>
12#include <OpenImageIO/imagebufalgo.h>
13#include <spdlog/spdlog.h>
14
16
18{
20}
21
22std::expected<std::unique_ptr<Common::ImageRegion>, ErrorHandling::CoreError>
24{
25 if (!isValid() || m_view_data_image.working_data.empty()) {
26 spdlog::warn("[WorkingImageCPU::downsample]: Image view is invalid");
28 }
29
30 if (target_width == 0 || target_height == 0) {
31 spdlog::error("[WorkingImageCPU::downsample]: Target dimensions are invalid ({}x{})", target_width, target_height);
33 }
34
35 try {
36
37 spdlog::debug("[WorkingImageCPU::downsample]: Start downsample.");
38
39 // ============================================================
40 if (m_view_data_image.width == target_width && m_view_data_image.height == target_height)
41 {
42 spdlog::debug("[WorkingImageCPU::downsample]: No downsample required.");
43
44 return std::make_unique<Common::ImageRegion>(
46 static_cast<int>(m_view_data_image.width),
47 static_cast<int>(m_view_data_image.height),
48 static_cast<int>(m_view_data_image.channels)
49 );
50 }
51
52 // ============================================================
53 // Step 1: Create source buffer (Zero-Copy view via m_view_data_image)
54 // ============================================================
55 OIIO::ImageSpec src_spec(
56 static_cast<int>(m_view_data_image.width),
57 static_cast<int>(m_view_data_image.height),
58 static_cast<int>(m_view_data_image.channels),
59 OIIO::TypeDesc::FLOAT
60 );
61
62 OIIO::ImageBuf src_buf(src_spec, m_view_data_image.working_data.data());
63
64 // ============================================================
65 // Step 2 & 3: Allocate dest and Resample
66 // ============================================================
67 std::vector<float> result_data(target_width * target_height * m_view_data_image.channels);
68
69 OIIO::ImageSpec dst_spec(
70 static_cast<int>(target_width),
71 static_cast<int>(target_height),
72 static_cast<int>(m_view_data_image.channels),
73 OIIO::TypeDesc::FLOAT
74 );
75 OIIO::ImageBuf dst_buf(dst_spec, result_data.data());
76
77 if (!OIIO::ImageBufAlgo::resample(dst_buf, src_buf, false)) {
78 spdlog::error("[WorkingImageCPU::downsample]: OIIO resample failed: {}", OIIO::geterror());
79 return std::unexpected(ErrorHandling::CoreError::AllocationFailed);
80 }
81
82 // ============================================================
83 // Step 4: Create ImageRegion (move semantics)
84 // ============================================================
85
86 spdlog::debug("WorkingImageCPU::downsample]: Downsample successful, creating ImageRegion from {}x{} to {}x{}.",
87 m_view_data_image.width, m_view_data_image.height, target_width, target_height);
88 return std::make_unique<Common::ImageRegion>(
89 std::move(result_data),
90 static_cast<int>(target_width),
91 static_cast<int>(target_height),
92 static_cast<int>(m_view_data_image.channels)
93 );
94 }
95 catch (const std::bad_alloc& e) {
96 spdlog::critical("[WorkingImageCPU::downsample]: Allocation failed: {}", e.what());
97 return std::unexpected(ErrorHandling::CoreError::AllocationFailed);
98 }
99 catch (const std::exception& e) {
100 spdlog::critical("[WorkingImageCPU::downsample]: Exception: {}", e.what());
101 return std::unexpected(ErrorHandling::CoreError::Unexpected);
102 }
103}
104
105std::expected<std::unique_ptr<Common::ImageRegion>, ErrorHandling::CoreError>
107{
108 if (!isValid()) {
109 spdlog::warn("[WorkingImageCPU::getFullResImage]: Current image is invalid, cannot export");
110 return std::unexpected(ErrorHandling::CoreError::InvalidWorkingImage);
111 }
112
113 try {
114 auto cpu_image_copy { std::make_unique<Common::ImageRegion>() };
115
116
117 cpu_image_copy->m_width = static_cast<int>(m_view_data_image.width);
118 cpu_image_copy->m_height = static_cast<int>(m_view_data_image.height);
119 cpu_image_copy->m_channels = static_cast<int>(m_view_data_image.channels);
120 cpu_image_copy->m_format = Common::PixelFormat::RGBA_F32;
121
122 cpu_image_copy->m_data.assign(m_view_data_image.working_data.begin(), m_view_data_image.working_data.end());
123
124 if (!cpu_image_copy->isValid()) {
125 return std::unexpected(ErrorHandling::CoreError::InvalidImageRegion);
126 }
127
128 spdlog::debug("[WorkingImageCPU::getFullResImage]: Exported ImageRegion ({}x{}, {} ch)",
129 cpu_image_copy->m_width, cpu_image_copy->m_height, cpu_image_copy->m_channels);
130
131 return cpu_image_copy;
132
133 } catch (const std::bad_alloc& e) {
134 spdlog::critical("[WorkingImageCPU::getFullResImage]: Allocation failed: {}", e.what());
135 return std::unexpected(ErrorHandling::CoreError::AllocationFailed);
136 } catch (const std::exception& e) {
137 spdlog::critical("[WorkingImageCPU::getFullResImage]: Exception: {}", e.what());
138 return std::unexpected(ErrorHandling::CoreError::Unexpected);
139 }
140}
141
142
143} // namespace CaptureMoment::Core::ImageProcessing
ImageView m_view_data_image
The image view bound to this hardware worker.
std::expected< std::unique_ptr< Common::ImageRegion >, ErrorHandling::CoreError > getFullResImage() override
Exports current internal image data to a new CPU-based ImageRegion..
std::expected< std::unique_ptr< Common::ImageRegion >, ErrorHandling::CoreError > downsample(Common::ImageDim target_width, Common::ImageDim target_height) override
Exports a downscaled version of the image directly from GPU.
bool isValid() const override
Checks if the image data is valid.
Central error handling system for CaptureMoment Core library.
@ RGBA_F32
4-channel format: Red, Green, Blue, Alpha in 32-bit float.
std::size_t ImageDim
Type for image dimensions (width, height).
Definition image_types.h:20
CoreError
Enumeration of all error codes for CaptureMoment Core.
Definition core_error.h:36
@ InvalidImageRegion
The provided ImageRegion dimensions or data are invalid.
@ InvalidWorkingImage
The working image state is invalid or corrupted.
@ AllocationFailed
Memory allocation failed.
@ Unexpected
An unexpected error occurred.
std::span< float > working_data
Mutable span for processing.
Definition image_view.h:27
Image working buffers stored on the CPU.
CaptureMoment — footer