See header for documentation. */
| 2597 | |
| 2598 | /* See header for documentation. */ |
| 2599 | int load_cimage( |
| 2600 | const char* filename, |
| 2601 | astc_compressed_image& img |
| 2602 | ) { |
| 2603 | std::ifstream file(filename, std::ios::in | std::ios::binary); |
| 2604 | if (!file) |
| 2605 | { |
| 2606 | print_error("ERROR: File open failed '%s'\n", filename); |
| 2607 | return 1; |
| 2608 | } |
| 2609 | |
| 2610 | astc_header hdr; |
| 2611 | file.read(reinterpret_cast<char*>(&hdr), sizeof(astc_header)); |
| 2612 | if (file.fail()) |
| 2613 | { |
| 2614 | print_error("ERROR: File read failed '%s'\n", filename); |
| 2615 | return 1; |
| 2616 | } |
| 2617 | |
| 2618 | unsigned int magicval = unpack_bytes(hdr.magic[0], hdr.magic[1], hdr.magic[2], hdr.magic[3]); |
| 2619 | if (magicval != ASTC_MAGIC_ID) |
| 2620 | { |
| 2621 | print_error("ERROR: Image header corrupt '%s'\n", filename); |
| 2622 | return 1; |
| 2623 | } |
| 2624 | |
| 2625 | // Ensure these are not zero to avoid div by zero |
| 2626 | size_t block_x = astc::max(static_cast<unsigned int>(hdr.block_x), 1u); |
| 2627 | size_t block_y = astc::max(static_cast<unsigned int>(hdr.block_y), 1u); |
| 2628 | size_t block_z = astc::max(static_cast<unsigned int>(hdr.block_z), 1u); |
| 2629 | |
| 2630 | size_t dim_x = unpack_bytes(hdr.dim_x[0], hdr.dim_x[1], hdr.dim_x[2], 0); |
| 2631 | size_t dim_y = unpack_bytes(hdr.dim_y[0], hdr.dim_y[1], hdr.dim_y[2], 0); |
| 2632 | size_t dim_z = unpack_bytes(hdr.dim_z[0], hdr.dim_z[1], hdr.dim_z[2], 0); |
| 2633 | |
| 2634 | if (dim_x == 0 || dim_y == 0 || dim_z == 0) |
| 2635 | { |
| 2636 | print_error("ERROR: Image header corrupt '%s'\n", filename); |
| 2637 | return 1; |
| 2638 | } |
| 2639 | |
| 2640 | // These cannot overflow as dim_* values are limited to 2^24 - 1 |
| 2641 | size_t blocks_x = (dim_x + block_x - 1) / block_x; |
| 2642 | size_t blocks_y = (dim_y + block_y - 1) / block_y; |
| 2643 | size_t blocks_z = (dim_z + block_z - 1) / block_z; |
| 2644 | |
| 2645 | // This can overflow if dim_* sizes are large |
| 2646 | bool overflow { false }; |
| 2647 | |
| 2648 | size_t data_size = astc::mul_safe(blocks_x, blocks_y, overflow); |
| 2649 | data_size = astc::mul_safe(data_size, blocks_z, overflow); |
| 2650 | data_size = astc::mul_safe(data_size, 16, overflow); |
| 2651 | |
| 2652 | if (overflow) |
| 2653 | { |
| 2654 | print_error("ERROR: Image header corrupt '%s'\n", filename); |
| 2655 | return 1; |
| 2656 | } |
no test coverage detected