| 820 | } |
| 821 | |
| 822 | bool LoadUncompressedBMP(u32* pixels, const u8* src, const u8* data, u32 width, u32 height, const BMPInfoHeader& info_header, const std::vector<u32>& palette, bool flip_vertical, u32 red_mask = 0, u32 green_mask = 0, u32 blue_mask = 0, u32 alpha_mask = 0, bool use_alpha = false) |
| 823 | { |
| 824 | const u32 row_size = ((width * info_header.bit_count + 31) / 32) * 4; |
| 825 | |
| 826 | for (u32 y = 0; y < height; y++) |
| 827 | { |
| 828 | u32 dst_y = flip_vertical ? (height - 1 - y) : y; |
| 829 | const u8* row_src = src + (y * row_size); |
| 830 | u32* row_dst = pixels + (dst_y * width); |
| 831 | |
| 832 | u32 bit_offset = 0; |
| 833 | |
| 834 | for (u32 x = 0; x < width; x++) |
| 835 | { |
| 836 | u32 pixel_value = 0; |
| 837 | |
| 838 | switch (info_header.bit_count) |
| 839 | { |
| 840 | case 1: |
| 841 | { |
| 842 | const u32 byte_index = bit_offset / 8; |
| 843 | const u32 bit_index = 7 - (bit_offset % 8); |
| 844 | pixel_value = (row_src[byte_index] >> bit_index) & 1; |
| 845 | bit_offset += 1; |
| 846 | break; |
| 847 | } |
| 848 | case 4: |
| 849 | { |
| 850 | const u32 byte_index = bit_offset / 8; |
| 851 | const u32 nibble_index = (bit_offset % 8) / 4; |
| 852 | pixel_value = (row_src[byte_index] >> (nibble_index * 4)) & 0xF; |
| 853 | bit_offset += 4; |
| 854 | break; |
| 855 | } |
| 856 | case 8: |
| 857 | { |
| 858 | pixel_value = row_src[bit_offset / 8]; |
| 859 | bit_offset += 8; |
| 860 | break; |
| 861 | } |
| 862 | case 16: |
| 863 | { |
| 864 | const u32 byte_index = bit_offset / 8; |
| 865 | pixel_value = row_src[byte_index] | (row_src[byte_index + 1] << 8); |
| 866 | bit_offset += 16; |
| 867 | |
| 868 | if (info_header.compression == 3) |
| 869 | { |
| 870 | const u8* bitfields = data + sizeof(BMPFileHeader) + info_header.size; |
| 871 | const u32 r_mask = *reinterpret_cast<const u32*>(bitfields); |
| 872 | const u32 g_mask = *reinterpret_cast<const u32*>(bitfields + 4); |
| 873 | const u32 b_mask = *reinterpret_cast<const u32*>(bitfields + 8); |
| 874 | |
| 875 | u32 r_shift = 0, g_shift = 0, b_shift = 0; |
| 876 | u32 temp = r_mask; |
| 877 | while (temp >>= 1) |
| 878 | r_shift++; |
| 879 | temp = g_mask; |
no test coverage detected