14#include <lagrange/Logger.h>
15#include <lagrange/image/Array3D.h>
16#include <lagrange/image/View3D.h>
17#include <lagrange/image_io/exr.h>
18#include <lagrange/image_io/load_image.h>
19#include <lagrange/scene/Scene.h>
20#include <lagrange/utils/assert.h>
24using Array3Df = lagrange::image::experimental::Array3D<float>;
25using View3Df = lagrange::image::experimental::View3D<float>;
27template <
size_t NumChannels,
typename Precision>
30 size_t width = img.width;
31 size_t height = img.height;
36 std::conditional_t<NumChannels == 1, Precision, Eigen::Vector<Precision, NumChannels>>;
38 std::conditional_t<NumChannels == 1, float, Eigen::Vector<float, NumChannels>>;
42 img.storage->get_full_size()(0) /
sizeof(SourcePixel),
43 img.storage->get_full_size()(1),
52 for (
size_t x = 0; x < width; ++x) {
53 for (
size_t y = 0; y < height; ++y) {
54 auto pixel = target_view(x, y);
55 if constexpr (NumChannels == 1) {
56 result(x, y, 0) = pixel;
58 for (
size_t c = 0; c < NumChannels; ++c) {
59 result(x, y, c) = pixel[c];
68template <
size_t NumChannels>
71 switch (img.precision) {
72 case lagrange::image::ImagePrecision::float32:
return convert_from<NumChannels, float>(img);
73 case lagrange::image::ImagePrecision::float64:
return convert_from<NumChannels, double>(img);
74 case lagrange::image::ImagePrecision::uint8:
75 return convert_from<NumChannels, unsigned char>(img);
76 case lagrange::image::ImagePrecision::int8:
return convert_from<NumChannels, char>(img);
77 case lagrange::image::ImagePrecision::uint32:
return convert_from<NumChannels, uint32_t>(img);
78 case lagrange::image::ImagePrecision::int32:
return convert_from<NumChannels, int32_t>(img);
79 case lagrange::image::ImagePrecision::float16:
80 return convert_from<NumChannels, Eigen::half>(img);
81 default:
throw std::runtime_error(
"Unsupported precision");
85inline Array3Df load_image(
const lagrange::fs::path& path)
87 auto img = lagrange::image_io::load_image(path);
89 switch (img.channel) {
90 case lagrange::image::ImageChannel::one:
return convert_from<1>(img);
91 case lagrange::image::ImageChannel::three:
return convert_from<3>(img);
92 case lagrange::image::ImageChannel::four:
return convert_from<4>(img);
93 default:
throw std::runtime_error(
"Unsupported number of channels");
97inline void save_image(lagrange::fs::path path, View3Df image)
99 if (path.extension() !=
".exr") {
100 lagrange::logger().warn(
"Only .exr output files are supported. Saving as .exr.");
101 path = path.replace_extension(
".exr");
106 const size_t width =
image.extent(0);
107 const size_t height =
image.extent(1);
108 const size_t num_channels =
image.extent(2);
110 std::vector<float> scanline(width * height * num_channels);
111 for (
size_t x = 0; x < width; ++x) {
112 for (
size_t y = 0; y < height; ++y) {
113 for (
size_t c = 0; c < num_channels; ++c) {
114 scanline[y * width * num_channels + x * num_channels + c] =
image(x, y, c);
119 lagrange::image_io::save_image_exr(
121 static_cast<const void*
>(scanline.data()),
122 static_cast<int>(width),
123 static_cast<int>(height),
124 static_cast<int>(num_channels),
125 lagrange::image_io::TinyexrPixelType::float32);
128inline void sort_paths(std::vector<lagrange::fs::path>& paths)
130 auto original = paths;
131 std::sort(paths.begin(), paths.end());
132 if (!std::is_sorted(original.begin(), original.end())) {
133 lagrange::logger().warn(
"Input filenames were not sorted. Using sorted order.");
Definition ImageView.h:56
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
Array3D< T > create_image(size_t width, size_t height, size_t num_channels)
Create an image with the given dimensions and number of channels.
Definition Array3D.h:46
Basic image data structure.
Definition load_image.h:22