Lagrange
RawInputImage.h
1/*
2 * Copyright 2023 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/common.h>
15#include <lagrange/image/api.h>
16
17#include <cassert>
18#include <vector>
19
20namespace lagrange {
21namespace image {
22
36class LA_IMAGE_API RawInputImage
37{
38public:
39 enum class precision_semantic : uint32_t {
40 byte_p,
41 half_p,
42 single_p,
43 double_p
44 };
45
46 enum class color_space : uint32_t {
47 linear,
48 sRGB
49 };
50
51 enum class texture_format : uint32_t {
52 luminance = ((1) << 8) | 0x0,
53 luminance_alpha = ((2) << 8) | 0x1,
54 alpha_luminance = ((2) << 8) | 0x2,
55 rgb = ((3) << 8) | 0x4,
56 bgr = ((3) << 8) | 0x8,
57 rgba = ((4) << 8) | 0x10,
58 argb = ((4) << 8) | 0x12,
59 bgra = ((4) << 8) | 0x14,
60 max = ((4) << 8) | ((1 << 8) - 1)
61 };
62
65 enum class image_storage_format : uint32_t {
66 first_pixel_row_at_bottom,
67 first_pixel_row_at_top
68 };
69
70 enum class wrap_mode : uint32_t {
71 repeat,
72 clamp,
73 mirror
74 };
75
76 enum class texture_filtering : uint32_t {
77 nearest,
78 bilinear
79 };
80
81 template <typename Scalar, uint32_t NumChannels>
82 struct PixelTraits;
83
84public:
85 size_t get_width() const { return m_width; }
86 size_t get_height() const { return m_height; }
87 size_t get_row_byte_stride() const { return m_row_byte_stride; }
88 precision_semantic get_pixel_precision() const { return m_pixel_precision; }
89 color_space get_color_space() const { return m_color_space; }
90 texture_format get_tex_format() const { return m_tex_format; }
91 wrap_mode get_wrap_u() const { return m_wrap_u; }
92 wrap_mode get_wrap_v() const { return m_wrap_v; }
93 image_storage_format get_storage_format() const { return m_storage_format; }
94
95 size_t get_size_precision() const
96 {
97 return static_cast<size_t>(1llu << static_cast<uint32_t>(m_pixel_precision));
98 }
99
100 size_t get_num_channels() const
101 {
102 return static_cast<size_t>(static_cast<uint32_t>(m_tex_format) >> 8u);
103 }
104
105 size_t get_size_pixel() const { return get_size_precision() * get_num_channels(); }
106
107 size_t get_row_stride() const
108 {
109 return (0 == m_row_byte_stride ? get_size_pixel() * m_width : m_row_byte_stride);
110 }
111
112 size_t get_pixel_data_offset() const
113 {
114 return image_storage_format::first_pixel_row_at_top == m_storage_format
115 ? 0
116 : get_row_stride() * (m_height - 1);
117 }
118
119 const void* get_pixel_data() const;
120
121 void set_width(size_t x) { m_width = x; }
122 void set_height(size_t x) { m_height = x; }
123 void set_row_byte_stride(size_t x) { m_row_byte_stride = x; }
124 void set_pixel_precision(precision_semantic x) { m_pixel_precision = x; }
125 void set_color_space(color_space x) { m_color_space = x; }
126 void set_tex_format(texture_format x) { m_tex_format = x; }
127 void set_wrap_u(wrap_mode x) { m_wrap_u = x; }
128 void set_wrap_v(wrap_mode x) { m_wrap_v = x; }
129 void set_storage_format(image_storage_format x) { m_storage_format = x; }
130
138 void set_pixel_data(const void* pixel_data, const bool copy_to_local);
139
142 void set_pixel_data_buffer(std::vector<unsigned char> pixel_data_buffer);
143
144 bool operator==(const RawInputImage& other) const;
145 bool operator!=(const RawInputImage& other) const { return !(*this == other); }
146
160 template <typename TexcoordScalar, typename Scalar, uint32_t NumChannels>
161 typename PixelTraits<Scalar, NumChannels>::Pixel sample(
162 const TexcoordScalar u,
163 const TexcoordScalar v,
164 const texture_filtering filtering = texture_filtering::bilinear) const;
165
180 template <typename TexcoordScalar, typename Scalar, uint32_t NumChannels>
181 typename PixelTraits<Scalar, NumChannels>::Pixel sample_float(
182 const TexcoordScalar u,
183 const TexcoordScalar v,
184 const texture_filtering filtering = texture_filtering::bilinear) const;
185
188 template <typename Archive>
189 void serialize_impl(Archive& ar);
190
191protected:
192 template <
193 typename TexcoordScalar,
194 typename Scalar,
195 uint32_t NumChannels,
196 typename InternalScalar,
197 uint32_t InternalNumChannels>
198 typename PixelTraits<Scalar, NumChannels>::Pixel sample(
199 const TexcoordScalar u,
200 const TexcoordScalar v,
201 const texture_filtering filtering = texture_filtering::bilinear) const;
202
203protected:
204 size_t m_width = 0;
205 size_t m_height = 0;
206 size_t m_row_byte_stride = 0;
207 precision_semantic m_pixel_precision = precision_semantic::single_p;
208 color_space m_color_space = color_space::linear;
209 texture_format m_tex_format = texture_format::rgba;
210 wrap_mode m_wrap_u = wrap_mode::clamp;
211 wrap_mode m_wrap_v = wrap_mode::clamp;
212 image_storage_format m_storage_format = image_storage_format::first_pixel_row_at_top;
213
215 const void* m_pixel_data = nullptr;
216
217 std::vector<unsigned char> m_local_pixel_data;
218};
219
220template <typename Scalar, uint32_t NumChannels>
222{
223 static_assert(
224 0u < NumChannels && NumChannels <= (static_cast<uint32_t>(texture_format::max) >> 8u));
225 static_assert(
226 std::is_same<unsigned char, Scalar>::value || std::is_same<Eigen::half, Scalar>::value ||
227 std::is_same<float, Scalar>::value || std::is_same<double, Scalar>::value);
228
229 using Pixel = Eigen::Matrix<Scalar, NumChannels, 1>;
230
231 static Pixel zero() { return Pixel::Zero(); }
232
233 static Scalar coeff(const Pixel& p, const size_t i)
234 {
235 assert(i < NumChannels);
236 return p[i];
237 }
238
239 static Scalar& coeff(Pixel& p, const size_t i)
240 {
241 assert(i < NumChannels);
242 return p[i];
243 }
244};
245
246template <typename Scalar>
248{
249 static_assert(
250 std::is_same<unsigned char, Scalar>::value || std::is_same<Eigen::half, Scalar>::value ||
251 std::is_same<float, Scalar>::value || std::is_same<double, Scalar>::value);
252
253 using Pixel = Scalar;
254
255 static Pixel zero() { return static_cast<Scalar>(0); }
256
257 static Scalar coeff(const Pixel& p, [[maybe_unused]] const size_t i)
258 {
259 assert(0 == i);
260 return p;
261 }
262
263 static Scalar& coeff(Pixel& p, [[maybe_unused]] const size_t i)
264 {
265 assert(0 == i);
266 return p;
267 }
268};
269
271template <typename Archive>
273{
274 image.serialize_impl(ar);
275}
276
278LA_IMAGE_API RawInputImage
279make_default_rgba_image(std::size_t i_width, std::size_t i_height, const void* i_pixels);
280
282LA_IMAGE_API RawInputImage
283make_default_luminance_image(std::size_t i_width, std::size_t i_height, const void* i_pixels);
284
286template <typename T>
288{
290 return std::clamp(u, static_cast<T>(0), static_cast<T>(1));
291 } else if (RawInputImage::wrap_mode::repeat == m) {
292 return u - std::floor(u);
293 } else if (RawInputImage::wrap_mode::mirror == m) {
294 const auto f = static_cast<int>(std::floor(u));
295 auto _u = u - static_cast<T>(f);
296 if (f & 1) {
297 _u = static_cast<T>(1) - _u;
298 }
299 return _u;
300 }
301 assert(0);
302 return u;
303}
304
305} // namespace image
306} // namespace lagrange
307
308#include <lagrange/image/RawInputImage.impl.h>
RawInputImage holds the basic info and the raw pointer (without ownership) to the image pixels.
Definition: RawInputImage.h:37
image_storage_format
first_pixel_row_at_bottom: y is up (like OpenGL texcoords) first_pixel_row_at_top: y is down just lik...
Definition: RawInputImage.h:65
color_space
Definition: RawInputImage.h:46
wrap_mode
Definition: RawInputImage.h:70
@ clamp
clamp to the last pixel on the edge
@ mirror
tiles the texture, mirrored when the integer coord is odd
texture_filtering
Definition: RawInputImage.h:76
precision_semantic
Definition: RawInputImage.h:39
void serialize_impl(Archive &ar)
Serialization.
Definition: RawInputImage.impl.h:23
texture_format
Definition: RawInputImage.h:51
LA_IMAGE_API RawInputImage make_default_rgba_image(std::size_t i_width, std::size_t i_height, const void *i_pixels)
Wrap a void * data into a Linear 4-component image. Pixel memory ownership is not transferred.
Definition: RawInputImage.cpp:83
T wrap_uv(const T u, const RawInputImage::wrap_mode m)
wrap uv coordinate
Definition: RawInputImage.h:287
void serialize(lagrange::image::RawInputImage &image, Archive &ar)
Serialization of RawInputImage.
Definition: RawInputImage.h:272
LA_IMAGE_API RawInputImage make_default_luminance_image(std::size_t i_width, std::size_t i_height, const void *i_pixels)
Wrap a void * data into a Linear 1-component image. Pixel memory ownership is not transferred.
Definition: RawInputImage.cpp:101
bool operator==(const shared_ptr< T > &sp1, const shared_ptr< U > &sp2)
Operator == overloading.
Definition: shared_ptr.h:344
bool operator!=(const shared_ptr< T > &sp1, const shared_ptr< U > &sp2)
Operator != overloading.
Definition: shared_ptr.h:363
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: RawInputImage.h:222