/src/astc-encoder/Source/astcenc_symbolic_physical.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // ---------------------------------------------------------------------------- |
3 | | // Copyright 2011-2023 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 | 800 | { |
35 | 800 | p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F); |
36 | 800 | p = ((p & 0x33) << 2) | ((p >> 2) & 0x33); |
37 | 800 | p = ((p & 0x55) << 1) | ((p >> 1) & 0x55); |
38 | 800 | return p; |
39 | 800 | } |
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 | 1.93k | ) { |
59 | 1.93k | int mask = (1 << bitcount) - 1; |
60 | 1.93k | ptr += bitoffset >> 3; |
61 | 1.93k | bitoffset &= 7; |
62 | 1.93k | int value = ptr[0] | (ptr[1] << 8); |
63 | 1.93k | value >>= bitoffset; |
64 | 1.93k | value &= mask; |
65 | 1.93k | return value; |
66 | 1.93k | } |
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 | 0 | ) { |
87 | 0 | int mask = (1 << bitcount) - 1; |
88 | 0 | value &= mask; |
89 | 0 | ptr += bitoffset >> 3; |
90 | 0 | bitoffset &= 7; |
91 | 0 | value <<= bitoffset; |
92 | 0 | mask <<= bitoffset; |
93 | 0 | mask = ~mask; |
94 | |
|
95 | 0 | ptr[0] &= mask; |
96 | 0 | ptr[0] |= value; |
97 | 0 | ptr[1] &= mask >> 8; |
98 | 0 | ptr[1] |= value >> 8; |
99 | 0 | } |
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 | 0 | ) { |
107 | 0 | assert(scb.block_type != SYM_BTYPE_ERROR); |
108 | | |
109 | | // Constant color block using UNORM16 colors |
110 | 0 | if (scb.block_type == SYM_BTYPE_CONST_U16) |
111 | 0 | { |
112 | | // There is currently no attempt to coalesce larger void-extents |
113 | 0 | static const uint8_t cbytes[8] { 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
114 | 0 | for (unsigned int i = 0; i < 8; i++) |
115 | 0 | { |
116 | 0 | pcb[i] = cbytes[i]; |
117 | 0 | } |
118 | |
|
119 | 0 | for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) |
120 | 0 | { |
121 | 0 | pcb[2 * i + 8] = scb.constant_color[i] & 0xFF; |
122 | 0 | pcb[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; |
123 | 0 | } |
124 | |
|
125 | 0 | return; |
126 | 0 | } |
127 | | |
128 | | // Constant color block using FP16 colors |
129 | 0 | if (scb.block_type == SYM_BTYPE_CONST_F16) |
130 | 0 | { |
131 | | // There is currently no attempt to coalesce larger void-extents |
132 | 0 | static const uint8_t cbytes[8] { 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
133 | 0 | for (unsigned int i = 0; i < 8; i++) |
134 | 0 | { |
135 | 0 | pcb[i] = cbytes[i]; |
136 | 0 | } |
137 | |
|
138 | 0 | for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++) |
139 | 0 | { |
140 | 0 | pcb[2 * i + 8] = scb.constant_color[i] & 0xFF; |
141 | 0 | pcb[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF; |
142 | 0 | } |
143 | |
|
144 | 0 | return; |
145 | 0 | } |
146 | | |
147 | 0 | 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 | 0 | uint8_t weightbuf[16] { 0 }; |
152 | |
|
153 | 0 | const auto& bm = bsd.get_block_mode(scb.block_mode); |
154 | 0 | const auto& di = bsd.get_decimation_info(bm.decimation_mode); |
155 | 0 | int weight_count = di.weight_count; |
156 | 0 | quant_method weight_quant_method = bm.get_weight_quant_mode(); |
157 | 0 | float weight_quant_levels = static_cast<float>(get_quant_level(weight_quant_method)); |
158 | 0 | int is_dual_plane = bm.is_dual_plane; |
159 | |
|
160 | 0 | const auto& qat = quant_and_xfer_tables[weight_quant_method]; |
161 | |
|
162 | 0 | int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; |
163 | |
|
164 | 0 | int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); |
165 | |
|
166 | 0 | uint8_t weights[64]; |
167 | 0 | if (is_dual_plane) |
168 | 0 | { |
169 | 0 | for (int i = 0; i < weight_count; i++) |
170 | 0 | { |
171 | 0 | float uqw = static_cast<float>(scb.weights[i]); |
172 | 0 | float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
173 | 0 | int qwi = static_cast<int>(qw + 0.5f); |
174 | 0 | weights[2 * i] = qat.scramble_map[qwi]; |
175 | |
|
176 | 0 | uqw = static_cast<float>(scb.weights[i + WEIGHTS_PLANE2_OFFSET]); |
177 | 0 | qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
178 | 0 | qwi = static_cast<int>(qw + 0.5f); |
179 | 0 | weights[2 * i + 1] = qat.scramble_map[qwi]; |
180 | 0 | } |
181 | 0 | } |
182 | 0 | else |
183 | 0 | { |
184 | 0 | for (int i = 0; i < weight_count; i++) |
185 | 0 | { |
186 | 0 | float uqw = static_cast<float>(scb.weights[i]); |
187 | 0 | float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f); |
188 | 0 | int qwi = static_cast<int>(qw + 0.5f); |
189 | 0 | weights[i] = qat.scramble_map[qwi]; |
190 | 0 | } |
191 | 0 | } |
192 | |
|
193 | 0 | encode_ise(weight_quant_method, real_weight_count, weights, weightbuf, 0); |
194 | |
|
195 | 0 | for (int i = 0; i < 16; i++) |
196 | 0 | { |
197 | 0 | pcb[i] = static_cast<uint8_t>(bitrev8(weightbuf[15 - i])); |
198 | 0 | } |
199 | |
|
200 | 0 | write_bits(scb.block_mode, 11, 0, pcb); |
201 | 0 | write_bits(partition_count - 1, 2, 11, pcb); |
202 | |
|
203 | 0 | int below_weights_pos = 128 - bits_for_weights; |
204 | | |
205 | | // Encode partition index and color endpoint types for blocks with 2+ partitions |
206 | 0 | if (partition_count > 1) |
207 | 0 | { |
208 | 0 | write_bits(scb.partition_index, 6, 13, pcb); |
209 | 0 | write_bits(scb.partition_index >> 6, PARTITION_INDEX_BITS - 6, 19, pcb); |
210 | |
|
211 | 0 | if (scb.color_formats_matched) |
212 | 0 | { |
213 | 0 | write_bits(scb.color_formats[0] << 2, 6, 13 + PARTITION_INDEX_BITS, pcb); |
214 | 0 | } |
215 | 0 | else |
216 | 0 | { |
217 | | // Check endpoint types for each partition to determine the lowest class present |
218 | 0 | int low_class = 4; |
219 | |
|
220 | 0 | for (unsigned int i = 0; i < partition_count; i++) |
221 | 0 | { |
222 | 0 | int class_of_format = scb.color_formats[i] >> 2; |
223 | 0 | low_class = astc::min(class_of_format, low_class); |
224 | 0 | } |
225 | |
|
226 | 0 | if (low_class == 3) |
227 | 0 | { |
228 | 0 | low_class = 2; |
229 | 0 | } |
230 | |
|
231 | 0 | int encoded_type = low_class + 1; |
232 | 0 | int bitpos = 2; |
233 | |
|
234 | 0 | for (unsigned int i = 0; i < partition_count; i++) |
235 | 0 | { |
236 | 0 | int classbit_of_format = (scb.color_formats[i] >> 2) - low_class; |
237 | 0 | encoded_type |= classbit_of_format << bitpos; |
238 | 0 | bitpos++; |
239 | 0 | } |
240 | |
|
241 | 0 | for (unsigned int i = 0; i < partition_count; i++) |
242 | 0 | { |
243 | 0 | int lowbits_of_format = scb.color_formats[i] & 3; |
244 | 0 | encoded_type |= lowbits_of_format << bitpos; |
245 | 0 | bitpos += 2; |
246 | 0 | } |
247 | |
|
248 | 0 | int encoded_type_lowpart = encoded_type & 0x3F; |
249 | 0 | int encoded_type_highpart = encoded_type >> 6; |
250 | 0 | int encoded_type_highpart_size = (3 * partition_count) - 4; |
251 | 0 | int encoded_type_highpart_pos = 128 - bits_for_weights - encoded_type_highpart_size; |
252 | 0 | write_bits(encoded_type_lowpart, 6, 13 + PARTITION_INDEX_BITS, pcb); |
253 | 0 | write_bits(encoded_type_highpart, encoded_type_highpart_size, encoded_type_highpart_pos, pcb); |
254 | 0 | below_weights_pos -= encoded_type_highpart_size; |
255 | 0 | } |
256 | 0 | } |
257 | 0 | else |
258 | 0 | { |
259 | 0 | write_bits(scb.color_formats[0], 4, 13, pcb); |
260 | 0 | } |
261 | | |
262 | | // In dual-plane mode, encode the color component of the second plane of weights |
263 | 0 | if (is_dual_plane) |
264 | 0 | { |
265 | 0 | write_bits(scb.plane2_component, 2, below_weights_pos - 2, pcb); |
266 | 0 | } |
267 | | |
268 | | // Encode the color components |
269 | 0 | uint8_t values_to_encode[32]; |
270 | 0 | int valuecount_to_encode = 0; |
271 | |
|
272 | 0 | const uint8_t* pack_table = color_uquant_to_scrambled_pquant_tables[scb.quant_mode - QUANT_6]; |
273 | 0 | for (unsigned int i = 0; i < scb.partition_count; i++) |
274 | 0 | { |
275 | 0 | int vals = 2 * (scb.color_formats[i] >> 2) + 2; |
276 | 0 | assert(vals <= 8); |
277 | 0 | for (int j = 0; j < vals; j++) |
278 | 0 | { |
279 | 0 | values_to_encode[j + valuecount_to_encode] = pack_table[scb.color_values[i][j]]; |
280 | 0 | } |
281 | 0 | valuecount_to_encode += vals; |
282 | 0 | } |
283 | | |
284 | 0 | encode_ise(scb.get_color_quant_mode(), valuecount_to_encode, values_to_encode, pcb, |
285 | 0 | scb.partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS); |
286 | 0 | } |
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 | 306 | ) { |
296 | 306 | uint8_t bswapped[16]; |
297 | | |
298 | 306 | scb.block_type = SYM_BTYPE_NONCONST; |
299 | | |
300 | | // Extract header fields |
301 | 306 | int block_mode = read_bits(11, 0, pcb); |
302 | 306 | if ((block_mode & 0x1FF) == 0x1FC) |
303 | 233 | { |
304 | | // Constant color block |
305 | | |
306 | | // Check what format the data has |
307 | 233 | if (block_mode & 0x200) |
308 | 205 | { |
309 | 205 | scb.block_type = SYM_BTYPE_CONST_F16; |
310 | 205 | } |
311 | 28 | else |
312 | 28 | { |
313 | 28 | scb.block_type = SYM_BTYPE_CONST_U16; |
314 | 28 | } |
315 | | |
316 | 233 | scb.partition_count = 0; |
317 | 1.16k | for (int i = 0; i < 4; i++) |
318 | 932 | { |
319 | 932 | scb.constant_color[i] = pcb[2 * i + 8] | (pcb[2 * i + 9] << 8); |
320 | 932 | } |
321 | | |
322 | | // Additionally, check that the void-extent |
323 | 233 | if (bsd.zdim == 1) |
324 | 131 | { |
325 | | // 2D void-extent |
326 | 131 | int rsvbits = read_bits(2, 10, pcb); |
327 | 131 | if (rsvbits != 3) |
328 | 7 | { |
329 | 7 | scb.block_type = SYM_BTYPE_ERROR; |
330 | 7 | return; |
331 | 7 | } |
332 | | |
333 | | // Low values span 3 bytes so need two read_bits calls |
334 | 124 | int vx_low_s = read_bits(8, 12, pcb) | (read_bits(5, 12 + 8, pcb) << 8); |
335 | 124 | int vx_high_s = read_bits(13, 25, pcb); |
336 | 124 | int vx_low_t = read_bits(8, 38, pcb) | (read_bits(5, 38 + 8, pcb) << 8); |
337 | 124 | int vx_high_t = read_bits(13, 51, pcb); |
338 | | |
339 | 124 | int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && |
340 | 124 | vx_low_t == 0x1FFF && vx_high_t == 0x1FFF; |
341 | | |
342 | 124 | if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones) |
343 | 115 | { |
344 | 115 | scb.block_type = SYM_BTYPE_ERROR; |
345 | 115 | return; |
346 | 115 | } |
347 | 124 | } |
348 | 102 | else |
349 | 102 | { |
350 | | // 3D void-extent |
351 | 102 | int vx_low_s = read_bits(9, 10, pcb); |
352 | 102 | int vx_high_s = read_bits(9, 19, pcb); |
353 | 102 | int vx_low_t = read_bits(9, 28, pcb); |
354 | 102 | int vx_high_t = read_bits(9, 37, pcb); |
355 | 102 | int vx_low_r = read_bits(9, 46, pcb); |
356 | 102 | int vx_high_r = read_bits(9, 55, pcb); |
357 | | |
358 | 102 | int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && |
359 | 102 | vx_low_t == 0x1FF && vx_high_t == 0x1FF && |
360 | 102 | vx_low_r == 0x1FF && vx_high_r == 0x1FF; |
361 | | |
362 | 102 | if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_r >= vx_high_r) && !all_ones) |
363 | 99 | { |
364 | 99 | scb.block_type = SYM_BTYPE_ERROR; |
365 | 99 | return; |
366 | 99 | } |
367 | 102 | } |
368 | | |
369 | 12 | return; |
370 | 233 | } |
371 | | |
372 | 73 | unsigned int packed_index = bsd.block_mode_packed_index[block_mode]; |
373 | 73 | if (packed_index == BLOCK_BAD_BLOCK_MODE) |
374 | 23 | { |
375 | 23 | scb.block_type = SYM_BTYPE_ERROR; |
376 | 23 | return; |
377 | 23 | } |
378 | | |
379 | 50 | const auto& bm = bsd.get_block_mode(block_mode); |
380 | 50 | const auto& di = bsd.get_decimation_info(bm.decimation_mode); |
381 | | |
382 | 50 | int weight_count = di.weight_count; |
383 | 50 | promise(weight_count > 0); |
384 | | |
385 | 50 | quant_method weight_quant_method = static_cast<quant_method>(bm.quant_mode); |
386 | 50 | int is_dual_plane = bm.is_dual_plane; |
387 | | |
388 | 50 | int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; |
389 | | |
390 | 50 | int partition_count = read_bits(2, 11, pcb) + 1; |
391 | 50 | promise(partition_count > 0); |
392 | | |
393 | 50 | scb.block_mode = static_cast<uint16_t>(block_mode); |
394 | 50 | scb.partition_count = static_cast<uint8_t>(partition_count); |
395 | | |
396 | 850 | for (int i = 0; i < 16; i++) |
397 | 800 | { |
398 | 800 | bswapped[i] = static_cast<uint8_t>(bitrev8(pcb[15 - i])); |
399 | 800 | } |
400 | | |
401 | 50 | int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method); |
402 | | |
403 | 50 | int below_weights_pos = 128 - bits_for_weights; |
404 | | |
405 | 50 | uint8_t indices[64]; |
406 | 50 | const auto& qat = quant_and_xfer_tables[weight_quant_method]; |
407 | | |
408 | 50 | decode_ise(weight_quant_method, real_weight_count, bswapped, indices, 0); |
409 | | |
410 | 50 | if (is_dual_plane) |
411 | 20 | { |
412 | 332 | for (int i = 0; i < weight_count; i++) |
413 | 312 | { |
414 | 312 | scb.weights[i] = qat.unscramble_and_unquant_map[indices[2 * i]]; |
415 | 312 | scb.weights[i + WEIGHTS_PLANE2_OFFSET] = qat.unscramble_and_unquant_map[indices[2 * i + 1]]; |
416 | 312 | } |
417 | 20 | } |
418 | 30 | else |
419 | 30 | { |
420 | 1.09k | for (int i = 0; i < weight_count; i++) |
421 | 1.06k | { |
422 | 1.06k | scb.weights[i] = qat.unscramble_and_unquant_map[indices[i]]; |
423 | 1.06k | } |
424 | 30 | } |
425 | | |
426 | 50 | if (is_dual_plane && partition_count == 4) |
427 | 10 | { |
428 | 10 | scb.block_type = SYM_BTYPE_ERROR; |
429 | 10 | return; |
430 | 10 | } |
431 | | |
432 | 40 | scb.color_formats_matched = 0; |
433 | | |
434 | | // Determine the format of each endpoint pair |
435 | 40 | int color_formats[BLOCK_MAX_PARTITIONS]; |
436 | 40 | int encoded_type_highpart_size = 0; |
437 | 40 | if (partition_count == 1) |
438 | 16 | { |
439 | 16 | color_formats[0] = read_bits(4, 13, pcb); |
440 | 16 | scb.partition_index = 0; |
441 | 16 | } |
442 | 24 | else |
443 | 24 | { |
444 | 24 | encoded_type_highpart_size = (3 * partition_count) - 4; |
445 | 24 | below_weights_pos -= encoded_type_highpart_size; |
446 | 24 | int encoded_type = read_bits(6, 13 + PARTITION_INDEX_BITS, pcb) | |
447 | 24 | (read_bits(encoded_type_highpart_size, below_weights_pos, pcb) << 6); |
448 | 24 | int baseclass = encoded_type & 0x3; |
449 | 24 | if (baseclass == 0) |
450 | 8 | { |
451 | 34 | for (int i = 0; i < partition_count; i++) |
452 | 26 | { |
453 | 26 | color_formats[i] = (encoded_type >> 2) & 0xF; |
454 | 26 | } |
455 | | |
456 | 8 | below_weights_pos += encoded_type_highpart_size; |
457 | 8 | scb.color_formats_matched = 1; |
458 | 8 | encoded_type_highpart_size = 0; |
459 | 8 | } |
460 | 16 | else |
461 | 16 | { |
462 | 16 | int bitpos = 2; |
463 | 16 | baseclass--; |
464 | | |
465 | 65 | for (int i = 0; i < partition_count; i++) |
466 | 49 | { |
467 | 49 | color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2; |
468 | 49 | bitpos++; |
469 | 49 | } |
470 | | |
471 | 65 | for (int i = 0; i < partition_count; i++) |
472 | 49 | { |
473 | 49 | color_formats[i] |= (encoded_type >> bitpos) & 3; |
474 | 49 | bitpos += 2; |
475 | 49 | } |
476 | 16 | } |
477 | 24 | scb.partition_index = static_cast<uint16_t>(read_bits(10, 13, pcb)); |
478 | 24 | } |
479 | | |
480 | 131 | for (int i = 0; i < partition_count; i++) |
481 | 91 | { |
482 | 91 | scb.color_formats[i] = static_cast<uint8_t>(color_formats[i]); |
483 | 91 | } |
484 | | |
485 | | // Determine number of color endpoint integers |
486 | 40 | int color_integer_count = 0; |
487 | 131 | for (int i = 0; i < partition_count; i++) |
488 | 91 | { |
489 | 91 | int endpoint_class = color_formats[i] >> 2; |
490 | 91 | color_integer_count += (endpoint_class + 1) * 2; |
491 | 91 | } |
492 | | |
493 | 40 | if (color_integer_count > 18) |
494 | 6 | { |
495 | 6 | scb.block_type = SYM_BTYPE_ERROR; |
496 | 6 | return; |
497 | 6 | } |
498 | | |
499 | | // Determine the color endpoint format to use |
500 | 34 | 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 }; |
501 | 34 | int color_bits = color_bits_arr[partition_count] - bits_for_weights - encoded_type_highpart_size; |
502 | 34 | if (is_dual_plane) |
503 | 10 | { |
504 | 10 | color_bits -= 2; |
505 | 10 | } |
506 | | |
507 | 34 | if (color_bits < 0) |
508 | 6 | { |
509 | 6 | color_bits = 0; |
510 | 6 | } |
511 | | |
512 | 34 | int color_quant_level = quant_mode_table[color_integer_count >> 1][color_bits]; |
513 | 34 | if (color_quant_level < QUANT_6) |
514 | 10 | { |
515 | 10 | scb.block_type = SYM_BTYPE_ERROR; |
516 | 10 | return; |
517 | 10 | } |
518 | | |
519 | | // Unpack the integer color values and assign to endpoints |
520 | 24 | scb.quant_mode = static_cast<quant_method>(color_quant_level); |
521 | | |
522 | 24 | uint8_t values_to_decode[32]; |
523 | 24 | decode_ise(static_cast<quant_method>(color_quant_level), color_integer_count, pcb, |
524 | 24 | values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS)); |
525 | | |
526 | 24 | int valuecount_to_decode = 0; |
527 | 24 | const uint8_t* unpack_table = color_scrambled_pquant_to_uquant_tables[scb.quant_mode - QUANT_6]; |
528 | 64 | for (int i = 0; i < partition_count; i++) |
529 | 40 | { |
530 | 40 | int vals = 2 * (color_formats[i] >> 2) + 2; |
531 | 192 | for (int j = 0; j < vals; j++) |
532 | 152 | { |
533 | 152 | scb.color_values[i][j] = unpack_table[values_to_decode[j + valuecount_to_decode]]; |
534 | 152 | } |
535 | 40 | valuecount_to_decode += vals; |
536 | 40 | } |
537 | | |
538 | | // Fetch component for second-plane in the case of dual plane of weights. |
539 | 24 | scb.plane2_component = -1; |
540 | 24 | if (is_dual_plane) |
541 | 6 | { |
542 | 6 | scb.plane2_component = static_cast<int8_t>(read_bits(2, below_weights_pos - 2, pcb)); |
543 | 6 | } |
544 | 24 | } |