MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ImageReader.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Buffers {
7class VKBuffer;
8class TextureBuffer;
9}
10
11namespace MayaFlux::IO {
12
13/**
14 * @struct ImageData
15 * @brief Raw image data loaded from file.
16 *
17 * Pixel storage is a variant over uint8, uint16, and float, chosen by the
18 * loader based on the source format. 8-bit formats (PNG, JPG, BMP, TGA)
19 * populate the uint8 variant. 16-bit PNG populates the uint16 variant.
20 * Floating-point formats (EXR, HDR) populate the float variant.
21 *
22 * The declared ImageFormat must match the active variant. Accessors below
23 * enforce this; direct member access is permitted but callers are
24 * responsible for consistency.
25 */
26struct ImageData {
27 using PixelStorage = std::variant<
28 std::vector<uint8_t>,
29 std::vector<uint16_t>,
30 std::vector<float>>;
31
33 uint32_t width { 0 };
34 uint32_t height { 0 };
35 uint32_t channels { 0 };
37
38 /**
39 * @brief Total byte size of pixel storage, dispatched on variant.
40 */
41 [[nodiscard]] size_t byte_size() const
42 {
43 return std::visit(
44 [](const auto& vec) { return vec.size() * sizeof(typename std::decay_t<decltype(vec)>::value_type); },
45 pixels);
46 }
47
48 /**
49 * @brief Raw data pointer, dispatched on variant. For upload paths.
50 */
51 [[nodiscard]] const void* data() const
52 {
53 return std::visit(
54 [](const auto& vec) -> const void* { return vec.data(); },
55 pixels);
56 }
57
58 /**
59 * @brief Number of pixel elements (not bytes), dispatched on variant.
60 */
61 [[nodiscard]] size_t element_count() const
62 {
63 return std::visit(
64 [](const auto& vec) { return vec.size(); },
65 pixels);
66 }
67
68 /**
69 * @brief Check that the active variant matches the declared format.
70 *
71 * Callers producing ImageData should invoke this to validate before
72 * handing the data to downstream consumers.
73 */
74 [[nodiscard]] bool is_consistent() const;
75
76 /**
77 * @brief Typed accessors. Return nullptr if variant does not match.
78 */
79 [[nodiscard]] const std::vector<uint8_t>* as_uint8() const { return std::get_if<std::vector<uint8_t>>(&pixels); }
80 [[nodiscard]] const std::vector<uint16_t>* as_uint16() const { return std::get_if<std::vector<uint16_t>>(&pixels); }
81 [[nodiscard]] const std::vector<float>* as_float() const { return std::get_if<std::vector<float>>(&pixels); }
82
83 [[nodiscard]] std::vector<uint8_t>* as_uint8() { return std::get_if<std::vector<uint8_t>>(&pixels); }
84 [[nodiscard]] std::vector<uint16_t>* as_uint16() { return std::get_if<std::vector<uint16_t>>(&pixels); }
85 [[nodiscard]] std::vector<float>* as_float() { return std::get_if<std::vector<float>>(&pixels); }
86};
87
88/**
89 * @class ImageReader
90 * @brief File reader for image formats (PNG, JPG, BMP, TGA, etc.)
91 *
92 * Uses STB Image library for decoding. Supports:
93 * - PNG, JPG, BMP, TGA, PSD, GIF, HDR, PIC, PNM
94 * - Automatic format detection
95 * - Channel conversion (force RGBA, etc.)
96 * - Direct GPU texture creation
97 *
98 * Implements the FileReader interface for consistency with other readers.
99 */
100class MAYAFLUX_API ImageReader : public FileReader {
101public:
102 ImageReader();
103 ~ImageReader() override;
104
105 // FileReader interface implementation
106 [[nodiscard]] bool can_read(const std::string& filepath) const override;
107 bool open(const std::string& filepath, FileReadOptions options = FileReadOptions::ALL) override;
108 void close() override;
109 [[nodiscard]] bool is_open() const override;
110 [[nodiscard]] std::optional<FileMetadata> get_metadata() const override;
111 [[nodiscard]] std::vector<FileRegion> get_regions() const override;
112 std::vector<Kakshya::DataVariant> read_all() override;
113 std::vector<Kakshya::DataVariant> read_region(const FileRegion& region) override;
114 std::shared_ptr<Kakshya::SignalSourceContainer> create_container() override;
115 bool load_into_container(std::shared_ptr<Kakshya::SignalSourceContainer> container) override;
116 [[nodiscard]] std::vector<uint64_t> get_read_position() const override;
117 bool seek(const std::vector<uint64_t>& position) override;
118 [[nodiscard]] std::vector<std::string> get_supported_extensions() const override;
119 [[nodiscard]] std::type_index get_data_type() const override;
120 [[nodiscard]] std::type_index get_container_type() const override;
121 [[nodiscard]] std::string get_last_error() const override;
122 [[nodiscard]] bool supports_streaming() const override;
123 [[nodiscard]] uint64_t get_preferred_chunk_size() const override;
124 [[nodiscard]] size_t get_num_dimensions() const override;
125 [[nodiscard]] std::vector<uint64_t> get_dimension_sizes() const override;
126
127 /**
128 * @brief Load image from memory (static utility)
129 * @param data Pointer to image data in memory
130 * @param size Size of the image data in bytes
131 * @return Image data or nullopt on failure
132 */
133 static std::optional<ImageData> load_from_memory(const void* data, size_t size);
134
135 /**
136 * @brief Load image from file (static utility)
137 * @param path Image file path
138 * @param desired_channels Force channel count (0 = keep original, 4 = RGBA)
139 * @return Image data or nullopt on failure
140 */
141 static std::optional<ImageData> load(
142 const std::string& path, int desired_channels = 4);
143
144 /**
145 * @brief Load image from file (static utility)
146 * @param path Image file path
147 * @param desired_channels Force channel count (0 = keep original, 4 = RGBA)
148 * @return Image data or nullopt on failure
149 */
150 static std::optional<ImageData> load(
151 const std::filesystem::path& path, int desired_channels = 4);
152
153 /**
154 * @brief Load image directly into GPU texture (static utility)
155 * @param path Image file path
156 * @return Initialized VKImage or nullptr on failure
157 */
158 static std::shared_ptr<Core::VKImage> load_texture(
159 const std::string& path);
160
161 /**
162 * @brief Get the loaded image data
163 * @return Image data or nullopt if no file open
164 */
165 [[nodiscard]] std::optional<ImageData> get_image_data() const;
166
167 /**
168 * @brief Create a VKBuffer containing the loaded image pixel data
169 * @return VKBuffer with pixel data ready for GPU processing
170 *
171 * Creates a buffer suitable for:
172 * - Transfer operations (upload to VKImage)
173 * - Direct compute shader processing
174 * - Buffer processor chains (treat pixels as samples)
175 */
176 std::shared_ptr<Buffers::TextureBuffer> create_texture_buffer();
177
178 /**
179 * @brief Load image directly into an existing VKBuffer
180 * @param buffer Target buffer (must be large enough)
181 * @return True if load succeeded
182 */
183 bool load_into_buffer(const std::shared_ptr<Buffers::VKBuffer>& buffer);
184
185private:
186 std::string m_filepath;
187 std::optional<ImageData> m_image_data;
188 std::string m_last_error;
190};
191
192} // namespace MayaFlux::IO
Range size
glm::vec3 position
Abstract interface for reading various file formats into containers.
std::optional< ImageData > m_image_data
File reader for image formats (PNG, JPG, BMP, TGA, etc.)
FileReadOptions
Generic options for file reading behavior.
ImageFormat
User-friendly image format enum.
auto create_container(Args &&... args) -> std::shared_ptr< ContainerType >
creates a new container of the specified type
Definition Depot.hpp:41
Generic region descriptor for any file type.
std::vector< float > * as_float()
bool is_consistent() const
Check that the active variant matches the declared format.
const std::vector< float > * as_float() const
Portal::Graphics::ImageFormat format
size_t byte_size() const
Total byte size of pixel storage, dispatched on variant.
std::vector< uint8_t > * as_uint8()
std::vector< uint16_t > * as_uint16()
const std::vector< uint16_t > * as_uint16() const
const std::vector< uint8_t > * as_uint8() const
Typed accessors.
std::variant< std::vector< uint8_t >, std::vector< uint16_t >, std::vector< float > > PixelStorage
const void * data() const
Raw data pointer, dispatched on variant.
size_t element_count() const
Number of pixel elements (not bytes), dispatched on variant.
Raw image data loaded from file.