| 2615 | |
| 2616 | #ifndef TINYGLTF_NO_STB_IMAGE |
| 2617 | bool LoadImageData(Image *image, const int image_idx, std::string *err, |
| 2618 | std::string *warn, int req_width, int req_height, |
| 2619 | const unsigned char *bytes, int size, void *user_data) { |
| 2620 | (void)warn; |
| 2621 | |
| 2622 | LoadImageDataOption option; |
| 2623 | if (user_data) { |
| 2624 | option = *reinterpret_cast<LoadImageDataOption *>(user_data); |
| 2625 | } |
| 2626 | |
| 2627 | int w = 0, h = 0, comp = 0, req_comp = 0; |
| 2628 | |
| 2629 | // Try to decode image header |
| 2630 | if (!stbi_info_from_memory(bytes, size, &w, &h, &comp)) { |
| 2631 | // On failure, if we load images as is, we just warn. |
| 2632 | std::string* msgOut = option.as_is ? warn : err; |
| 2633 | if (msgOut) { |
| 2634 | (*msgOut) += |
| 2635 | "Unknown image format. STB cannot decode image header for image[" + |
| 2636 | std::to_string(image_idx) + "] name = \"" + image->name + "\".\n"; |
| 2637 | } |
| 2638 | if (!option.as_is) { |
| 2639 | // If we decode images, error out. |
| 2640 | return false; |
| 2641 | } else { |
| 2642 | // If we load images as is, we copy the image data, |
| 2643 | // set all image properties to invalid, and report success. |
| 2644 | image->width = image->height = image->component = -1; |
| 2645 | image->bits = image->pixel_type = -1; |
| 2646 | image->image.resize(static_cast<size_t>(size)); |
| 2647 | std::copy(bytes, bytes + size, image->image.begin()); |
| 2648 | return true; |
| 2649 | } |
| 2650 | } |
| 2651 | |
| 2652 | int bits = 8; |
| 2653 | int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE; |
| 2654 | |
| 2655 | if (stbi_is_16_bit_from_memory(bytes, size)) { |
| 2656 | bits = 16; |
| 2657 | pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT; |
| 2658 | } |
| 2659 | |
| 2660 | // preserve_channels true: Use channels stored in the image file. |
| 2661 | // false: force 32-bit textures for common Vulkan compatibility. It appears |
| 2662 | // that some GPU drivers do not support 24-bit images for Vulkan |
| 2663 | req_comp = (option.preserve_channels || option.as_is) ? 0 : 4; |
| 2664 | |
| 2665 | unsigned char* data = nullptr; |
| 2666 | // Perform image decoding if requested |
| 2667 | if (!option.as_is) { |
| 2668 | // If the image is marked as 16 bit per channel, attempt to decode it as such first. |
| 2669 | // If that fails, we are going to attempt to load it as 8 bit per channel image. |
| 2670 | if (bits == 16) { |
| 2671 | data = reinterpret_cast<unsigned char *>(stbi_load_16_from_memory(bytes, size, &w, &h, &comp, req_comp)); |
| 2672 | } |
| 2673 | // Load as 8 bit per channel data |
| 2674 | if (!data) { |
no test coverage detected