579{
580 if (!data ||
size == 0) {
582 "Invalid memory buffer for image loading");
583 return std::nullopt;
584 }
585
586 const auto* bytes = static_cast<const unsigned char*>(data);
587
589 && bytes[0] == 0x76 && bytes[1] == 0x2F
590 && bytes[2] == 0x31 && bytes[3] == 0x01) {
591 return load_exr_from_memory(bytes,
size);
592 }
593
595
596 stbi_info_from_memory(bytes,
static_cast<int>(
size),
598
599 int load_as = (
channels == 3) ? 4 : 0;
600
601 unsigned char*
pixels = stbi_load_from_memory(
602 bytes,
603 static_cast<int>(
size),
605 load_as);
606
609 "Failed to decode image from memory: {}",
610 stbi_failure_reason());
611 return std::nullopt;
612 }
613
614 int result_channels = (load_as != 0) ? load_as :
channels;
615
617 "Loaded image from memory ({}x{}, {} channels{})",
619 (
channels == 3 && result_channels == 4) ?
" [RGB→RGBA]" :
"");
620
622 auto& buf = result.
pixels.emplace<std::vector<uint8_t>>();
623 size_t data_size =
static_cast<size_t>(
width) *
height * result_channels;
624 buf.resize(data_size);
625 std::memcpy(buf.data(),
pixels, data_size);
626
627 result.width =
width;
629 result.channels = result_channels;
630
631 switch (result_channels) {
632 case 1:
633 result.format = Portal::Graphics::ImageFormat::R8;
634 break;
635 case 2:
636 result.format = Portal::Graphics::ImageFormat::RG8;
637 break;
638 case 4:
639 result.format = Portal::Graphics::ImageFormat::RGBA8;
640 break;
641 default:
643 "Unsupported channel count: {}", result_channels);
645 return std::nullopt;
646 }
647
649 return result;
650}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
const std::vector< float > * pixels
Kakshya::ImageData ImageData
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.