2#include "../foray_logger.hpp"
3#include "../osi/foray_env.hpp"
5#include <tinyexr/tinyexr.h>
18 std::unordered_map<std::string, uint32_t>
Channels;
23 for(int32_t i = 0; i < 5; i++)
34 template <
typename FORMAT_TRAITS>
36 const EXRHeader& header,
37 const EXRImage& image,
44 using component_t =
typename FORMAT_TRAITS::COMPONENT_TRAITS::COMPONENT;
45 const uint32_t stride = FORMAT_TRAITS::COMPONENT_COUNT;
47 component_t* writeData =
reinterpret_cast<component_t*
>(out.data());
49 for(int32_t tile_index = 0; tile_index < (int32_t)numTiles; tile_index++)
51 const EXRTile& tile = tiles[tile_index];
55 const component_t* readStart_r =
nullptr;
56 const component_t* readStart_g =
nullptr;
57 const component_t* readStart_b =
nullptr;
58 const component_t* readStart_a =
nullptr;
62 readStart_r =
reinterpret_cast<const component_t*
>(tile.images[channels[(int)
EImageChannel::R]]);
66 readStart_g =
reinterpret_cast<const component_t*
>(tile.images[channels[(int)
EImageChannel::G]]);
70 readStart_b =
reinterpret_cast<const component_t*
>(tile.images[channels[(int)
EImageChannel::B]]);
74 readStart_a =
reinterpret_cast<const component_t*
>(tile.images[channels[(int)
EImageChannel::A]]);
77 component_t* writeStart = writeData + (tile.offset_y * tileHeight * image.width + tile.offset_x * tileWidth) * stride;
79 for(
int y = 0; y < th; y++)
81 const component_t* readRowPos_r =
nullptr;
82 const component_t* readRowPos_g =
nullptr;
83 const component_t* readRowPos_b =
nullptr;
84 const component_t* readRowPos_a =
nullptr;
87 readRowPos_r = readStart_r + y * tw;
91 readRowPos_g = readStart_g + y * tw;
95 readRowPos_b = readStart_b + y * tw;
99 readRowPos_a = readStart_a + y * tw;
102 component_t* writeRowPos = writeStart + (y * image.width * stride);
104 for(
int x = 0; x < tw; x++)
121 component_t a = FORMAT_TRAITS::COMPONENT_TRAITS::ALPHA_FALLBACK;
126 FORMAT_TRAITS::WriteColor(writeRowPos, r, g, b, a);
127 writeRowPos += stride;
137 template <VkFormat FORMAT>
140 const char* exrError =
nullptr;
141 using namespace impl;
143 mCustomLoaderInfo =
new ExrLoaderCache();
144 mCustomLoaderInfoDeleter = DeleteExrLoaderCache;
145 auto& loaderCache = *(
reinterpret_cast<ExrLoaderCache*
>(mCustomLoaderInfo));
150 success = success && ParseEXRVersionFromFile(&loaderCache.Version, mInfo.Utf8Path.GetPath().c_str()) == TINYEXR_SUCCESS;
151 success = success && ParseEXRHeaderFromFile(&loaderCache.Header, &loaderCache.Version, mInfo.Utf8Path.GetPath().c_str(), &exrError) == TINYEXR_SUCCESS;
156 logger()->warn(
"Failed to read image file \"{}\". Failed to read Exr header. TinyExr error: {}", mInfo.Utf8Path, exrError);
157 FreeEXRErrorMessage(exrError);
161 logger()->warn(
"Failed to read image file \"{}\". Failed to read Exr header.", mInfo.Utf8Path);
167 auto& header = loaderCache.Header;
169 auto stringToChannel = std::unordered_map<std::string_view, EImageChannel>({
180 if(header.num_channels > 0)
182 switch(header.pixel_types[0])
184 case TINYEXR_PIXELTYPE_UINT:
185 Assert(std::is_same_v<typename FORMAT_TRAITS::COMPONENT_TRAITS, ComponentTraits_UInt32>,
"EXR component type is Uint32, loader component type does not match!");
187 case TINYEXR_PIXELTYPE_HALF:
188 Assert(std::is_same_v<typename FORMAT_TRAITS::COMPONENT_TRAITS, ComponentTraits_Fp16>,
"EXR component type is Fp16, loader component type does not match!");
190 case TINYEXR_PIXELTYPE_FLOAT:
191 Assert(std::is_same_v<typename FORMAT_TRAITS::COMPONENT_TRAITS, ComponentTraits_Fp32>,
"EXR component type is Fp32, loader component type does not match!");
196 for(uint32_t channelIndex = 0; channelIndex < (uint32_t)header.num_channels; channelIndex++)
198 auto& channel = header.channels[channelIndex];
199 if(header.pixel_types[channelIndex] != header.pixel_types[0])
201 FORAY_THROWFMT(
"Image Loader: .EXR image \"{}\" has different pixel types per channel, which is not supported", mInfo.Name);
203 auto iter = stringToChannel.find(channel.name);
204 if(iter != stringToChannel.end())
207 mInfo.Channels.push_back(channel);
208 loaderCache.ChannelIndices[(int)channel] = channelIndex;
220 template <VkFormat FORMAT>
223 using namespace impl;
225 const char* exrError =
nullptr;
227 InitEXRImage(&image);
229 auto& loaderCache = *(
reinterpret_cast<ExrLoaderCache*
>(mCustomLoaderInfo));
230 auto& header = loaderCache.Header;
232 if(LoadEXRImageFromFile(&image, &header, mInfo.Utf8Path.GetPath().c_str(), &exrError) != TINYEXR_SUCCESS)
236 logger()->warn(
"Failed to read image file \"{}\". Failed to load file. TinyExr error: {}", mInfo.Utf8Path, exrError);
237 FreeEXRErrorMessage(exrError);
241 logger()->warn(
"Failed to read image file \"{}\". Failed to load file.", mInfo.Utf8Path);
246 mInfo.Extent.width = image.width;
247 mInfo.Extent.height = image.height;
252 mRawData.resize(FORMAT_TRAITS::BYTESTRIDE * mInfo.Extent.width * mInfo.Extent.height);
254 EXRTile single_image_tile;
259 const EXRTile* exr_tiles;
264 single_image_tile.images = image.images;
265 single_image_tile.width = image.width;
266 single_image_tile.height = image.height;
267 single_image_tile.level_x = image.width;
268 single_image_tile.level_y = image.height;
269 single_image_tile.offset_x = 0;
270 single_image_tile.offset_y = 0;
272 exr_tiles = &single_image_tile;
274 tile_width = image.width;
275 tile_height = image.height;
279 tile_width = header.tile_size_x;
280 tile_height = header.tile_size_y;
281 num_tiles = image.num_tiles;
282 exr_tiles = image.tiles;
285 lReadExr<FORMAT_TRAITS>(mRawData, header, image, exr_tiles, num_tiles, tile_height, tile_width, loaderCache.ChannelIndices);
bool PopulateImageInfo_TinyExr()
Definition foray_imageloader_exr.inl:138
bool Load_TinyExr()
Definition foray_imageloader_exr.inl:221
Definition foray_imageloader_exr.inl:13
~ExrLoaderCache()
Definition foray_imageloader_exr.inl:30
EXRVersion Version
Definition foray_imageloader_exr.inl:15
EXRHeader Header
Definition foray_imageloader_exr.inl:16
std::unordered_map< std::string, uint32_t > Channels
Definition foray_imageloader_exr.inl:18
ExrLoaderCache(EXRHeader &header)
Definition foray_imageloader_exr.inl:28
ExrLoaderCache()
Definition foray_imageloader_exr.inl:20
int32_t ChannelIndices[5]
Definition foray_imageloader_exr.inl:17
#define FORAY_THROWFMT(fmt,...)
Macro for throwing an exception with formatted error message argument.
Definition foray_exception.hpp:81
void lReadExr(std::vector< uint8_t > &out, const EXRHeader &header, const EXRImage &image, const EXRTile *tiles, uint32_t numTiles, uint32_t tileHeight, uint32_t tileWidth, int32_t channels[5])
Definition foray_imageloader_exr.inl:35
void DeleteExrLoaderCache(void *loaderCache)
Definition foray_dualbuffer.hpp:5
EImageChannel
Definition foray_imageloader.hpp:13
void Assert(bool condition, const source_location location=source_location::current())
Asserts condition. Throws a generic error message if conditition is false.
Definition foray_exception.hpp:52
spdlog::logger * logger()
Gives access to a global available logger object. The logger writes to console & to a file next to th...