/src/astc-encoder/Source/astcenc_symbolic_physical.cpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // ---------------------------------------------------------------------------- |
3 | | // Copyright 2011-2026 Arm Limited |
4 | | // |
5 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
6 | | // use this file except in compliance with the License. You may obtain a copy |
7 | | // of the License at: |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, software |
12 | | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 | | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 | | // License for the specific language governing permissions and limitations |
15 | | // under the License. |
16 | | // ---------------------------------------------------------------------------- |
17 | | |
18 | | /** |
19 | | * @brief Functions for converting between symbolic and physical encodings. |
20 | | */ |
21 | | |
22 | | #include "astcenc_internal.h" |
23 | | |
24 | | #include <cassert> |
25 | | |
26 | | /** |
27 | | * @brief Reverse bits in a byte. |
28 | | * |
29 | | * @param p The value to reverse. |
30 | | * |
31 | | * @return The reversed result. |
32 | | */ |
33 | | static inline int bitrev8(int p) |
34 | 76.0k | { |
35 | 76.0k | p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F); |
36 | 76.0k | p = ((p & 0x33) << 2) | ((p >> 2) & 0x33); |
37 | 76.0k | p = ((p & 0x55) << 1) | ((p >> 1) & 0x55); |
38 | 76.0k | return p; |
39 | 76.0k | } |
40 | | |
41 | | |
42 | | /** |
43 | | * @brief Read up to 8 bits at an arbitrary bit offset. |
44 | | * |
45 | | * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may |
46 | | * span two separate bytes in memory. |
47 | | * |
48 | | * @param bitcount The number of bits to read. |
49 | | * @param bitoffset The bit offset to read from, between 0 and 7. |
50 | | * @param[in,out] ptr The data pointer to read from. |
51 | | * |
52 | | * @return The read value. |
53 | | */ |
54 | | static inline int read_bits( |
55 | | int bitcount, |
56 | | int bitoffset, |
57 | | const uint8_t* ptr |
58 | 20.4k | ) { |
59 | 20.4k | int mask = (1 << bitcount) - 1; |
60 | 20.4k | ptr += bitoffset >> 3; |
61 | 20.4k | bitoffset &= 7; |
62 | 20.4k | int value = ptr[0] | (ptr[1] << 8); |
63 | 20.4k | value >>= bitoffset; |
64 | 20.4k | value &= mask; |
65 | 20.4k | return value; |
66 | 20.4k | } |
67 | | |
68 | | #if !defined(ASTCENC_DECOMPRESS_ONLY) |
69 | | |
70 | | /** |
71 | | * @brief Write up to 8 bits at an arbitrary bit offset. |
72 | | * |
73 | | * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so |
74 | | * may span two separate bytes in memory. |
75 | | * |
76 | | * @param value The value to write. |
77 | | * @param bitcount The number of bits to write, starting from LSB. |
78 | | * @param bitoffset The bit offset to store at, between 0 and 7. |
79 | | * @param[in,out] ptr The data pointer to write to. |
80 | | */ |
81 | | static inline void write_bits( |
82 | | int value, |
83 | | int bitcount, |
84 | | int bitoffset, |
85 | | uint8_t* ptr |
86 | 9.46k | ) { |
87 | 9.46k | int mask = (1 << bitcount) - 1; |
88 | 9.46k | value &= mask; |
89 | 9.46k | ptr += bitoffset >> 3; |
90 | 9.46k | bitoffset &= 7; |
91 | 9.46k | value <<= bitoffset; |
92 | 9.46k | mask <<= bitoffset; |
93 | 9.46k | mask = ~mask; |
94 | | |
95 | 9.46k | ptr[0] &= mask; |
96 | 9.46k | ptr[0] |= value; |
97 | 9.46k | ptr[1] &= mask >> 8; |
98 | 9.46k | ptr[1] |= value >> 8; |
99 | 9.46k | } |
100 | | |
101 | | /* See header for documentation. */ |
102 | | void symbolic_to_physical( |
103 | | const block_size_descriptor& bsd, |
104 | | const symbolic_compressed_block& scb, |
105 | | uint8_t pcb[16] |
106 | 2.10k | ) { |
107 | 2.10k | assert(scb.block_type != SYM_BTYPE_ERROR); |
108 | | |
109 | | // Constant color block using UNORM16 colors |
110 | 2.10k | if (scb.block_type == SYM_BTYPE_CONST_U16) |
111 | 137 | { |
112 | | // There is currently no attempt to coalesce larger void-extents |
113 | 137 | static const uint8_t cbytes[8] { 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
114 | 1.23k | for (unsigned int i = 0; i < 8; i++) |
115 | 1.09k | { |
116 | 1.09k | pcb[i] = cbytes[i]; |
117 | 1.09k | } |
118 | | |
119 | 685 | for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) |
120 | 548 | { |
121 | 548 | pcb[2 * i + 8] = scb.constant_color[i] & 0xFF; |
122 | 548 | pcb[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; |
123 | 548 | } |
124 | | |
125 | 137 | return; |
126 | 137 | } |
127 | | |
128 | | // Constant color block using FP16 colors |
129 | 1.96k | if (scb.block_type == SYM_BTYPE_CONST_F16) |
130 | 5 | { |
131 | | // There is currently no attempt to coalesce larger void-extents |
132 | 5 | static const uint8_t cbytes[8] { 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
133 | 45 | for (unsigned int i = 0; i < 8; i++) |
134 | 40 | { |
135 | 40 | pcb[i] = cbytes[i]; |
136 | 40 | } |
137 | | |
138 | 25 | for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) |
139 | 20 | { |
140 | 20 | pcb[2 * i + 8] = scb.constant_color[i] & 0xFF; |
141 | 20 | pcb[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; |
142 | 20 | } |
143 | | |
144 | 5 | return; |
145 | 5 | } |
146 | | |
147 | 1.96k | unsigned int partition_count = scb.partition_count; |
148 | | |
149 | | // Compress the weights. |
150 | | // They are encoded as an ordinary integer-sequence, then bit-reversed |
151 | 1.96k | uint8_t weightbuf[16] { 0 }; |
152 | | |
153 | 1.96k | const auto& bm = bsd.get_block_mode(scb.block_mode); |
154 | 1.96k | const auto& di = bsd.get_decimation_info(bm.decimation_mode); |
155 | 1.96k | int weight_count = di.weight_count; |
156 | 1.96k | quant_method weight_quant_method = bm.get_weight_quant_mode(); |
157 | 1.96k | float weight_quant_levels = static_cast<float>(get_quant_level(weight_quant_method)); |
158 | 1.96k | int is_dual_plane = bm.is_dual_plane; |
159 | | |
160 | 1.96k | const auto& qat = quant_and_xfer_tables[weight_quant_method]; |
161 | | |
162 | 1.96k | int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; |
163 | | |
164 | 1.96k | int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); |
165 | | |
166 | 1.96k | uint8_t weights[64]; |
167 | 1.96k | if (is_dual_plane) |
168 | 591 | { |
169 | 10.2k | for (int i = 0; i < weight_count; i++) |
170 | 9.69k | { |
171 | 9.69k | float uqw = static_cast<float>(scb.weights[i]); |
172 | 9.69k | float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
173 | 9.69k | int qwi = static_cast<int>(qw + 0.5f); |
174 | 9.69k | weights[2 * i] = qat.scramble_map[qwi]; |
175 | | |
176 | 9.69k | uqw = static_cast<float>(scb.weights[i + WEIGHTS_PLANE2_OFFSET]); |
177 | 9.69k | qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
178 | 9.69k | qwi = static_cast<int>(qw + 0.5f); |
179 | 9.69k | weights[2 * i + 1] = qat.scramble_map[qwi]; |
180 | 9.69k | } |
181 | 591 | } |
182 | 1.37k | else |
183 | 1.37k | { |
184 | 32.4k | for (int i = 0; i < weight_count; i++) |
185 | 31.0k | { |
186 | 31.0k | float uqw = static_cast<float>(scb.weights[i]); |
187 | 31.0k | float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
188 | 31.0k | int qwi = static_cast<int>(qw + 0.5f); |
189 | 31.0k | weights[i] = qat.scramble_map[qwi]; |
190 | 31.0k | } |
191 | 1.37k | } |
192 | | |
193 | 1.96k | encode_ise(weight_quant_method, real_weight_count, weights, weightbuf, 0); |
194 | | |
195 | 33.3k | for (int i = 0; i < 16; i++) |
196 | 31.3k | { |
197 | 31.3k | pcb[i] = static_cast<uint8_t>(bitrev8(weightbuf[15 - i])); |
198 | 31.3k | } |
199 | | |
200 | 1.96k | write_bits(scb.block_mode, 11, 0, pcb); |
201 | 1.96k | write_bits(partition_count - 1, 2, 11, pcb); |
202 | | |
203 | 1.96k | int below_weights_pos = 128 - bits_for_weights; |
204 | | |
205 | | // Encode partition index and color endpoint types for blocks with 2+ partitions |
206 | 1.96k | if (partition_count > 1) |
207 | 1.09k | { |
208 | 1.09k | write_bits(scb.partition_index, 6, 13, pcb); |
209 | 1.09k | write_bits(scb.partition_index >> 6, PARTITION_INDEX_BITS - 6, 19, pcb); |
210 | | |
211 | 1.09k | if (scb.color_formats_matched) |
212 | 305 | { |
213 | 305 | write_bits(scb.color_formats[0] << 2, 6, 13 + PARTITION_INDEX_BITS, pcb); |
214 | 305 | } |
215 | 794 | else |
216 | 794 | { |
217 | | // Check endpoint types for each partition to determine the lowest class present |
218 | 794 | int low_class = 4; |
219 | | |
220 | 2.85k | for (unsigned int i = 0; i < partition_count; i++) |
221 | 2.05k | { |
222 | 2.05k | int class_of_format = scb.color_formats[i] >> 2; |
223 | 2.05k | low_class = astc::min(class_of_format, low_class); |
224 | 2.05k | } |
225 | | |
226 | 794 | if (low_class == 3) |
227 | 176 | { |
228 | 176 | low_class = 2; |
229 | 176 | } |
230 | | |
231 | 794 | int encoded_type = low_class + 1; |
232 | 794 | int bitpos = 2; |
233 | | |
234 | 2.85k | for (unsigned int i = 0; i < partition_count; i++) |
235 | 2.05k | { |
236 | 2.05k | int classbit_of_format = (scb.color_formats[i] >> 2) - low_class; |
237 | 2.05k | encoded_type |= classbit_of_format << bitpos; |
238 | 2.05k | bitpos++; |
239 | 2.05k | } |
240 | | |
241 | 2.85k | for (unsigned int i = 0; i < partition_count; i++) |
242 | 2.05k | { |
243 | 2.05k | int lowbits_of_format = scb.color_formats[i] & 3; |
244 | 2.05k | encoded_type |= lowbits_of_format << bitpos; |
245 | 2.05k | bitpos += 2; |
246 | 2.05k | } |
247 | | |
248 | 794 | int encoded_type_lowpart = encoded_type & 0x3F; |
249 | 794 | int encoded_type_highpart = encoded_type >> 6; |
250 | 794 | int encoded_type_highpart_size = (3 * partition_count) - 4; |
251 | 794 | int encoded_type_highpart_pos = 128 - bits_for_weights - encoded_type_highpart_size; |
252 | 794 | write_bits(encoded_type_lowpart, 6, 13 + PARTITION_INDEX_BITS, pcb); |
253 | 794 | write_bits(encoded_type_highpart, encoded_type_highpart_size, encoded_type_highpart_pos, pcb); |
254 | 794 | below_weights_pos -= encoded_type_highpart_size; |
255 | 794 | } |
256 | 1.09k | } |
257 | 862 | else |
258 | 862 | { |
259 | 862 | write_bits(scb.color_formats[0], 4, 13, pcb); |
260 | 862 | } |
261 | | |
262 | | // In dual-plane mode, encode the color component of the second plane of weights |
263 | 1.96k | if (is_dual_plane) |
264 | 591 | { |
265 | 591 | write_bits(scb.plane2_component, 2, below_weights_pos - 2, pcb); |
266 | 591 | } |
267 | | |
268 | | // Encode the color components |
269 | 1.96k | uint8_t values_to_encode[32]; |
270 | 1.96k | int valuecount_to_encode = 0; |
271 | | |
272 | 1.96k | const uint8_t* pack_table = color_uquant_to_scrambled_pquant_tables[scb.quant_mode - QUANT_6]; |
273 | 5.77k | for (unsigned int i = 0; i < scb.partition_count; i++) |
274 | 3.81k | { |
275 | 3.81k | int vals = 2 * (scb.color_formats[i] >> 2) + 2; |
276 | 3.81k | assert(vals <= 8); |
277 | 23.5k | for (int j = 0; j < vals; j++) |
278 | 19.7k | { |
279 | 19.7k | values_to_encode[j + valuecount_to_encode] = pack_table[scb.color_values[i][j]]; |
280 | 19.7k | } |
281 | 3.81k | valuecount_to_encode += vals; |
282 | 3.81k | } |
283 | | |
284 | 1.96k | encode_ise(scb.get_color_quant_mode(), valuecount_to_encode, values_to_encode, pcb, |
285 | 1.96k | scb.partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS); |
286 | 1.96k | } |
287 | | |
288 | | #endif |
289 | | |
290 | | /* See header for documentation. */ |
291 | | void physical_to_symbolic( |
292 | | const block_size_descriptor& bsd, |
293 | | const uint8_t pcb[16], |
294 | | symbolic_compressed_block& scb |
295 | 4.12k | ) { |
296 | 4.12k | uint8_t bswapped[16]; |
297 | | |
298 | 4.12k | scb.block_type = SYM_BTYPE_NONCONST; |
299 | | |
300 | | // Extract header fields |
301 | 4.12k | int block_mode = read_bits(11, 0, pcb); |
302 | 4.12k | if ((block_mode & 0x1FF) == 0x1FC) |
303 | 814 | { |
304 | | // Constant color block |
305 | | |
306 | | // Check what format the data has |
307 | 814 | if (block_mode & 0x200) |
308 | 489 | { |
309 | 489 | scb.block_type = SYM_BTYPE_CONST_F16; |
310 | 489 | } |
311 | 325 | else |
312 | 325 | { |
313 | 325 | scb.block_type = SYM_BTYPE_CONST_U16; |
314 | 325 | } |
315 | | |
316 | 814 | scb.partition_count = 0; |
317 | 4.07k | for (int i = 0; i < 4; i++) |
318 | 3.25k | { |
319 | 3.25k | scb.constant_color[i] = pcb[2 * i + 8] | (pcb[2 * i + 9] << 8); |
320 | 3.25k | } |
321 | | |
322 | | // Additionally, check that the void-extent |
323 | 814 | if (bsd.dim_z == 1) |
324 | 711 | { |
325 | | // 2D void-extent |
326 | 711 | int rsvbits = read_bits(2, 10, pcb); |
327 | 711 | if (rsvbits != 3) |
328 | 43 | { |
329 | 43 | scb.block_type = SYM_BTYPE_ERROR; |
330 | 43 | return; |
331 | 43 | } |
332 | | |
333 | | // Low values span 3 bytes so need two read_bits calls |
334 | 668 | int vx_low_s = read_bits(8, 12, pcb) | (read_bits(5, 12 + 8, pcb) << 8); |
335 | 668 | int vx_high_s = read_bits(13, 25, pcb); |
336 | 668 | int vx_low_t = read_bits(8, 38, pcb) | (read_bits(5, 38 + 8, pcb) << 8); |
337 | 668 | int vx_high_t = read_bits(13, 51, pcb); |
338 | | |
339 | 668 | int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && |
340 | 126 | vx_low_t == 0x1FFF && vx_high_t == 0x1FFF; |
341 | | |
342 | 668 | if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones) |
343 | 291 | { |
344 | 291 | scb.block_type = SYM_BTYPE_ERROR; |
345 | 291 | return; |
346 | 291 | } |
347 | 668 | } |
348 | 103 | else |
349 | 103 | { |
350 | | // 3D void-extent |
351 | 103 | int vx_low_s = read_bits(9, 10, pcb); |
352 | 103 | int vx_high_s = read_bits(9, 19, pcb); |
353 | 103 | int vx_low_t = read_bits(9, 28, pcb); |
354 | 103 | int vx_high_t = read_bits(9, 37, pcb); |
355 | 103 | int vx_low_r = read_bits(9, 46, pcb); |
356 | 103 | int vx_high_r = read_bits(9, 55, pcb); |
357 | | |
358 | 103 | int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && |
359 | 53 | vx_low_t == 0x1FF && vx_high_t == 0x1FF && |
360 | 26 | vx_low_r == 0x1FF && vx_high_r == 0x1FF; |
361 | | |
362 | 103 | if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_r >= vx_high_r) && !all_ones) |
363 | 98 | { |
364 | 98 | scb.block_type = SYM_BTYPE_ERROR; |
365 | 98 | return; |
366 | 98 | } |
367 | 103 | } |
368 | | |
369 | 382 | return; |
370 | 814 | } |
371 | | |
372 | 3.30k | unsigned int packed_index = bsd.block_mode_packed_index[block_mode]; |
373 | 3.30k | if (packed_index == BLOCK_BAD_BLOCK_MODE) |
374 | 517 | { |
375 | 517 | scb.block_type = SYM_BTYPE_ERROR; |
376 | 517 | return; |
377 | 517 | } |
378 | | |
379 | 2.79k | const auto& bm = bsd.get_block_mode(block_mode); |
380 | 2.79k | const auto& di = bsd.get_decimation_info(bm.decimation_mode); |
381 | | |
382 | 2.79k | int weight_count = di.weight_count; |
383 | 2.79k | promise(weight_count > 0); |
384 | | |
385 | 2.79k | quant_method weight_quant_method = static_cast<quant_method>(bm.quant_mode); |
386 | 2.79k | int is_dual_plane = bm.is_dual_plane; |
387 | | |
388 | 2.79k | int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; |
389 | | |
390 | 2.79k | int partition_count = read_bits(2, 11, pcb) + 1; |
391 | 2.79k | promise(partition_count > 0); |
392 | | |
393 | 2.79k | scb.block_mode = static_cast<uint16_t>(block_mode); |
394 | 2.79k | scb.partition_count = static_cast<uint8_t>(partition_count); |
395 | | |
396 | 47.4k | for (int i = 0; i < 16; i++) |
397 | 44.6k | { |
398 | 44.6k | bswapped[i] = static_cast<uint8_t>(bitrev8(pcb[15 - i])); |
399 | 44.6k | } |
400 | | |
401 | 2.79k | int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); |
402 | | |
403 | 2.79k | int below_weights_pos = 128 - bits_for_weights; |
404 | | |
405 | 2.79k | uint8_t indices[64]; |
406 | 2.79k | const auto& qat = quant_and_xfer_tables[weight_quant_method]; |
407 | | |
408 | 2.79k | decode_ise(weight_quant_method, real_weight_count, bswapped, indices, 0); |
409 | | |
410 | 2.79k | if (is_dual_plane) |
411 | 837 | { |
412 | 13.1k | for (int i = 0; i < weight_count; i++) |
413 | 12.2k | { |
414 | 12.2k | scb.weights[i] = qat.unscramble_and_unquant_map[indices[2 * i]]; |
415 | 12.2k | scb.weights[i + WEIGHTS_PLANE2_OFFSET] = qat.unscramble_and_unquant_map[indices[2 * i + 1]]; |
416 | 12.2k | } |
417 | 837 | } |
418 | 1.95k | else |
419 | 1.95k | { |
420 | 37.8k | for (int i = 0; i < weight_count; i++) |
421 | 35.8k | { |
422 | 35.8k | scb.weights[i] = qat.unscramble_and_unquant_map[indices[i]]; |
423 | 35.8k | } |
424 | 1.95k | } |
425 | | |
426 | 2.79k | if (is_dual_plane && partition_count == 4) |
427 | 81 | { |
428 | 81 | scb.block_type = SYM_BTYPE_ERROR; |
429 | 81 | return; |
430 | 81 | } |
431 | | |
432 | 2.71k | scb.color_formats_matched = 0; |
433 | | |
434 | | // Determine the format of each endpoint pair |
435 | 2.71k | int color_formats[BLOCK_MAX_PARTITIONS]; |
436 | 2.71k | int encoded_type_highpart_size = 0; |
437 | 2.71k | if (partition_count == 1) |
438 | 307 | { |
439 | 307 | color_formats[0] = read_bits(4, 13, pcb); |
440 | 307 | scb.partition_index = 0; |
441 | 307 | } |
442 | 2.40k | else |
443 | 2.40k | { |
444 | 2.40k | encoded_type_highpart_size = (3 * partition_count) - 4; |
445 | 2.40k | below_weights_pos -= encoded_type_highpart_size; |
446 | 2.40k | int encoded_type = read_bits(6, 13 + PARTITION_INDEX_BITS, pcb) | |
447 | 2.40k | (read_bits(encoded_type_highpart_size, below_weights_pos, pcb) << 6); |
448 | 2.40k | int baseclass = encoded_type & 0x3; |
449 | 2.40k | if (baseclass == 0) |
450 | 1.46k | { |
451 | 6.26k | for (int i = 0; i < partition_count; i++) |
452 | 4.80k | { |
453 | 4.80k | color_formats[i] = (encoded_type >> 2) & 0xF; |
454 | 4.80k | } |
455 | | |
456 | 1.46k | below_weights_pos += encoded_type_highpart_size; |
457 | 1.46k | scb.color_formats_matched = 1; |
458 | 1.46k | encoded_type_highpart_size = 0; |
459 | 1.46k | } |
460 | 941 | else |
461 | 941 | { |
462 | 941 | int bitpos = 2; |
463 | 941 | baseclass--; |
464 | | |
465 | 3.46k | for (int i = 0; i < partition_count; i++) |
466 | 2.52k | { |
467 | 2.52k | color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2; |
468 | 2.52k | bitpos++; |
469 | 2.52k | } |
470 | | |
471 | 3.46k | for (int i = 0; i < partition_count; i++) |
472 | 2.52k | { |
473 | 2.52k | color_formats[i] |= (encoded_type >> bitpos) & 3; |
474 | 2.52k | bitpos += 2; |
475 | 2.52k | } |
476 | 941 | } |
477 | 2.40k | scb.partition_index = static_cast<uint16_t>(read_bits(10, 13, pcb)); |
478 | | |
479 | | // Reject blocks selecting a partitioning that is not present in this |
480 | | // block size descriptor. A SELF_DECOMPRESS_ONLY context drops the |
481 | | // partitionings its compressor never emits, so a texture compressed |
482 | | // with a different context can reference an inactive entry. This is an |
483 | | // API contract break from the application, and should not happen in |
484 | | // valid usage. |
485 | 2.40k | if (bsd.partitioning_packed_index[partition_count - 2][scb.partition_index] == BLOCK_BAD_PARTITIONING) |
486 | 0 | { |
487 | 0 | scb.block_type = SYM_BTYPE_ERROR; |
488 | 0 | return; |
489 | 0 | } |
490 | 2.40k | } |
491 | | |
492 | 10.3k | for (int i = 0; i < partition_count; i++) |
493 | 7.63k | { |
494 | 7.63k | scb.color_formats[i] = static_cast<uint8_t>(color_formats[i]); |
495 | 7.63k | } |
496 | | |
497 | | // Determine number of color endpoint integers |
498 | 2.71k | int color_integer_count = 0; |
499 | 10.3k | for (int i = 0; i < partition_count; i++) |
500 | 7.63k | { |
501 | 7.63k | int endpoint_class = color_formats[i] >> 2; |
502 | 7.63k | color_integer_count += (endpoint_class + 1) * 2; |
503 | 7.63k | } |
504 | | |
505 | 2.71k | if (color_integer_count > 18) |
506 | 120 | { |
507 | 120 | scb.block_type = SYM_BTYPE_ERROR; |
508 | 120 | return; |
509 | 120 | } |
510 | | |
511 | | // Determine the color endpoint format to use |
512 | 2.59k | static const int color_bits_arr[5] { -1, 115 - 4, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS }; |
513 | 2.59k | int color_bits = color_bits_arr[partition_count] - bits_for_weights - encoded_type_highpart_size; |
514 | 2.59k | if (is_dual_plane) |
515 | 748 | { |
516 | 748 | color_bits -= 2; |
517 | 748 | } |
518 | | |
519 | 2.59k | if (color_bits < 0) |
520 | 78 | { |
521 | 78 | color_bits = 0; |
522 | 78 | } |
523 | | |
524 | 2.59k | int color_quant_level = quant_mode_table[color_integer_count >> 1][color_bits]; |
525 | 2.59k | if (color_quant_level < QUANT_6) |
526 | 128 | { |
527 | 128 | scb.block_type = SYM_BTYPE_ERROR; |
528 | 128 | return; |
529 | 128 | } |
530 | | |
531 | | // Unpack the integer color values and assign to endpoints |
532 | 2.46k | scb.quant_mode = static_cast<quant_method>(color_quant_level); |
533 | | |
534 | 2.46k | uint8_t values_to_decode[32]; |
535 | 2.46k | decode_ise(static_cast<quant_method>(color_quant_level), color_integer_count, pcb, |
536 | 2.46k | values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS)); |
537 | | |
538 | 2.46k | int valuecount_to_decode = 0; |
539 | 2.46k | const uint8_t* unpack_table = color_scrambled_pquant_to_uquant_tables[scb.quant_mode - QUANT_6]; |
540 | 9.27k | for (int i = 0; i < partition_count; i++) |
541 | 6.81k | { |
542 | 6.81k | int vals = 2 * (color_formats[i] >> 2) + 2; |
543 | 40.2k | for (int j = 0; j < vals; j++) |
544 | 33.4k | { |
545 | 33.4k | scb.color_values[i][j] = unpack_table[values_to_decode[j + valuecount_to_decode]]; |
546 | 33.4k | } |
547 | 6.81k | valuecount_to_decode += vals; |
548 | 6.81k | } |
549 | | |
550 | | // Fetch component for second-plane in the case of dual plane of weights. |
551 | 2.46k | scb.plane2_component = -1; |
552 | 2.46k | if (is_dual_plane) |
553 | 648 | { |
554 | 648 | scb.plane2_component = static_cast<int8_t>(read_bits(2, below_weights_pos - 2, pcb)); |
555 | 648 | } |
556 | 2.46k | } |