354{
355 if (!data || size == 0) {
357 "Invalid memory buffer for image loading");
358 return std::nullopt;
359 }
360
361 int width {}, height {}, channels {};
362
363 stbi_info_from_memory(
364 static_cast<const unsigned char*>(data),
365 static_cast<int>(size),
366 &width, &height, &channels);
367
368 int load_as = (channels == 3) ? 4 : 0;
369
370 unsigned char* pixels = stbi_load_from_memory(
371 static_cast<const unsigned char*>(data),
372 static_cast<int>(size),
373 &width, &height, &channels,
374 load_as);
375
376 if (!pixels) {
378 "Failed to decode image from memory: {}",
379 stbi_failure_reason());
380 return std::nullopt;
381 }
382
383 int result_channels = (load_as != 0) ? load_as : channels;
384
386 "Loaded image from memory ({}x{}, {} channels{})",
387 width, height, result_channels,
388 (channels == 3 && result_channels == 4) ? " [RGB→RGBA]" : "");
389
390 ImageData result;
391 size_t data_size = static_cast<size_t>(width) * height * result_channels;
392 result.pixels.resize(data_size);
393 std::memcpy(result.pixels.data(), pixels, data_size);
394
395 result.width = width;
396 result.height = height;
397 result.channels = result_channels;
398
399 switch (result_channels) {
400 case 1:
402 break;
403 case 2:
405 break;
406 case 4:
408 break;
409 default:
411 "Unsupported channel count: {}", result_channels);
412 stbi_image_free(pixels);
413 return std::nullopt;
414 }
415
416 stbi_image_free(pixels);
417 return result;
418}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.
@ RGBA8
Four channel 8-bit.
@ R8
Single channel 8-bit.