162 uint line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
163 uint line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]);
165 uint line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12);
167 uint line_3_2 = ((line_2_3 & 0x000fff) << 12) | ((line_2_3 & 0xfff000) >> 12);
169 block[2] = line_3_2 & 0xff;
170 block[3] = (line_3_2 & 0xff00) >> 8;
171 block[4] = (line_3_2 & 0xff0000) >> 16;
172 block[5] = line_1_0 & 0xff;
173 block[6] = (line_1_0 & 0xff00) >> 8;
174 block[7] = (line_1_0 & 0xff0000) >> 16;
207 *num_valid_levels = 0;
210 if (width == 0 || height == 0) {
223 uint block_bytes = 0;
245 *num_valid_levels = levels;
247 uint mip_width = width;
248 uint mip_height = height;
250 const uint8_t *data_end = data + data_size;
252 for (
uint level = 0; level < levels; level++) {
253 uint blocks_per_row = (mip_width + 3) / 4;
254 uint blocks_per_col = (mip_height + 3) / 4;
255 uint blocks = blocks_per_row * blocks_per_col;
257 if (data + block_bytes * blocks > data_end) {
260 *num_valid_levels = level;
264 if (mip_height == 1) {
268 if (mip_height == 2) {
270 for (
uint i = 0; i < blocks_per_row; i++) {
271 half_block_function(data + i * block_bytes);
276 for (
uint i = 0; i < blocks; i++) {
277 full_block_function(data + i * block_bytes);
283 uint row_bytes = block_bytes * blocks_per_row;
286 for (
uint y = 0; y < blocks_per_col / 2; y++) {
287 uint8_t *line1 = data + y * row_bytes;
288 uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes;
290 memcpy(temp_line, line1, row_bytes);
291 memcpy(line1, line2, row_bytes);
292 memcpy(line2, temp_line, row_bytes);
299 data += block_bytes * blocks;
300 mip_width = std::max(1U, mip_width >> 1);
301 mip_height = std::max(1U, mip_height >> 1);