Skip to content

Commit 3a65a0d

Browse files
committed
Use a table-driven approach for computing ISE sizes
1 parent e8e4e88 commit 3a65a0d

6 files changed

Lines changed: 107 additions & 76 deletions

Source/astcenc_block_sizes2.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static int decode_block_mode_2d(
117117
int weight_count = N * M * (D + 1);
118118
int qmode = (base_quant_mode - 2) + 6 * H;
119119

120-
int weightbits = compute_ise_bitcount(weight_count, (quantization_method)qmode);
120+
int weightbits = get_ise_sequence_bitcount(weight_count, (quantization_method)qmode);
121121
if (weight_count > MAX_WEIGHTS_PER_BLOCK ||
122122
weightbits < MIN_WEIGHT_BITS_PER_BLOCK ||
123123
weightbits > MAX_WEIGHT_BITS_PER_BLOCK)
@@ -213,7 +213,7 @@ static int decode_block_mode_3d(
213213
int weight_count = N * M * Q * (D + 1);
214214
int qmode = (base_quant_mode - 2) + 6 * H;
215215

216-
int weightbits = compute_ise_bitcount(weight_count, (quantization_method)qmode);
216+
int weightbits = get_ise_sequence_bitcount(weight_count, (quantization_method)qmode);
217217
if (weight_count > MAX_WEIGHTS_PER_BLOCK ||
218218
weightbits < MIN_WEIGHT_BITS_PER_BLOCK ||
219219
weightbits > MAX_WEIGHT_BITS_PER_BLOCK)
@@ -670,15 +670,15 @@ static int construct_dt_entry_2d(
670670
int maxprec_2planes = -1;
671671
for (int i = 0; i < 12; i++)
672672
{
673-
int bits_1plane = compute_ise_bitcount(weight_count, (quantization_method) i);
673+
int bits_1plane = get_ise_sequence_bitcount(weight_count, (quantization_method) i);
674674
if (bits_1plane >= MIN_WEIGHT_BITS_PER_BLOCK && bits_1plane <= MAX_WEIGHT_BITS_PER_BLOCK)
675675
{
676676
maxprec_1plane = i;
677677
}
678678

679679
if (try_2planes)
680680
{
681-
int bits_2planes = compute_ise_bitcount(2 * weight_count, (quantization_method) i);
681+
int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, (quantization_method) i);
682682
if (bits_2planes >= MIN_WEIGHT_BITS_PER_BLOCK && bits_2planes <= MAX_WEIGHT_BITS_PER_BLOCK)
683683
{
684684
maxprec_2planes = i;
@@ -865,8 +865,8 @@ static void construct_block_size_descriptor_3d(
865865
int maxprec_2planes = -1;
866866
for (int i = 0; i < 12; i++)
867867
{
868-
int bits_1plane = compute_ise_bitcount(weight_count, (quantization_method) i);
869-
int bits_2planes = compute_ise_bitcount(2 * weight_count, (quantization_method) i);
868+
int bits_1plane = get_ise_sequence_bitcount(weight_count, (quantization_method) i);
869+
int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, (quantization_method) i);
870870

871871
if (bits_1plane >= MIN_WEIGHT_BITS_PER_BLOCK && bits_1plane <= MAX_WEIGHT_BITS_PER_BLOCK)
872872
{

Source/astcenc_compress_symbolic.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static float compress_symbolic_block_fixed_partition_1_plane(
339339
int decimation_mode = bm.decimation_mode;
340340

341341
// compute weight bitcount for the mode
342-
int bits_used_by_weights = compute_ise_bitcount(
342+
int bits_used_by_weights = get_ise_sequence_bitcount(
343343
ixtab2[decimation_mode]->weight_count,
344344
(quantization_method)bm.quantization_mode);
345345
int bitcount = free_bits_for_partition_count[partition_count] - bits_used_by_weights;
@@ -776,7 +776,7 @@ static float compress_symbolic_block_fixed_partition_2_planes(
776776
}
777777

778778
// compute weight bitcount for the mode
779-
int bits_used_by_weights = compute_ise_bitcount(
779+
int bits_used_by_weights = get_ise_sequence_bitcount(
780780
2 * ixtab2[decimation_mode]->weight_count,
781781
(quantization_method)bm.quantization_mode);
782782
int bitcount = free_bits_for_partition_count[partition_count] - bits_used_by_weights;

Source/astcenc_integer_sequence.cpp

Lines changed: 85 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,27 @@ static const uint8_t integer_of_trits[3][3][3][3][3] = {
331331
}
332332
};
333333

334+
/**
335+
* @brief The number of bits, trits, and quints needed for a quant level.
336+
*/
334337
struct btq_count {
338+
/**< The quantization level. */
335339
uint8_t quant;
340+
341+
/**< The number of bits. */
336342
uint8_t bits;
343+
344+
/**< The number of trits. */
337345
uint8_t trits;
346+
347+
/**< The number of quints. */
338348
uint8_t quints;
339349
};
340350

341-
static std::array<btq_count, 21> btq_counts = {{
351+
/**
352+
* @brief The table of bits, trits, and quints needed for a quant encode.
353+
*/
354+
static const std::array<btq_count, 21> btq_counts = {{
342355
{ QUANT_2, 1, 0, 0 },
343356
{ QUANT_3, 0, 1, 0 },
344357
{ QUANT_4, 2, 0, 0 },
@@ -362,6 +375,69 @@ static std::array<btq_count, 21> btq_counts = {{
362375
{ QUANT_256, 8, 0, 0 }
363376
}};
364377

378+
/**
379+
* @brief The sequence scale, round, and divisors needed to compute sizing.
380+
*
381+
* The length of a quantized sequence in bits is:
382+
* (scale * <sequence_len> + round) / divisor
383+
*/
384+
struct ise_size {
385+
/**< The quantization level. */
386+
uint8_t quant;
387+
388+
/**< The scaling parameter. */
389+
uint8_t scale;
390+
391+
/**< The rounding parameter. */
392+
uint8_t round;
393+
394+
/**< The divisor parameter. */
395+
uint8_t divisor;
396+
};
397+
398+
/**
399+
* @brief The table of scale, round, and divisors needed for quant sizing.
400+
*/
401+
static const std::array<ise_size, 21> ise_sizes = {{
402+
{ QUANT_2, 1, 0, 1 },
403+
{ QUANT_3, 8, 4, 5 },
404+
{ QUANT_4, 2, 0, 1 },
405+
{ QUANT_5, 7, 2, 3 },
406+
{ QUANT_6, 13, 4, 5 },
407+
{ QUANT_8, 3, 0, 1 },
408+
{ QUANT_10, 10, 2, 3 },
409+
{ QUANT_12, 18, 4, 5 },
410+
{ QUANT_16, 4, 0, 1 },
411+
{ QUANT_20, 13, 2, 3 },
412+
{ QUANT_24, 23, 4, 5 },
413+
{ QUANT_32, 5, 0, 1 },
414+
{ QUANT_40, 16, 2, 3 },
415+
{ QUANT_48, 28, 4, 5 },
416+
{ QUANT_64, 6, 0, 1 },
417+
{ QUANT_80, 19, 2, 3 },
418+
{ QUANT_96, 33, 4, 5 },
419+
{ QUANT_128, 7, 0, 1 },
420+
{ QUANT_160, 22, 2, 3 },
421+
{ QUANT_192, 38, 4, 5 },
422+
{ QUANT_256, 8, 0, 1 }
423+
}};
424+
425+
/* See header for documentation. */
426+
int get_ise_sequence_bitcount(
427+
int items,
428+
quantization_method quant
429+
) {
430+
// Cope with out-of bounds values - input might be invalid
431+
if (static_cast<size_t>(quant) >= ise_sizes.size())
432+
{
433+
// Arbitrary large number that's more than an ASTC block can hold
434+
return 1024;
435+
}
436+
437+
auto& entry = ise_sizes[quant];
438+
return (entry.scale * items + entry.round) / entry.divisor;
439+
}
440+
365441
// routine to write up to 8 bits
366442
static inline void write_bits(
367443
int value,
@@ -455,7 +531,7 @@ void encode_ise(
455531
if (trits)
456532
{
457533
static const int bits_to_write[5] = { 2, 2, 1, 2, 1 };
458-
static const int block_shift[5] = { 0, 2, 4, 5, 7 };
534+
static const int block_shift[5] = { 0, 2, 4, 5, 7 };
459535
static const int next_lcounter[5] = { 1, 2, 3, 4, 0 };
460536
static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 };
461537
write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data);
@@ -467,7 +543,7 @@ void encode_ise(
467543
if (quints)
468544
{
469545
static const int bits_to_write[3] = { 3, 2, 2 };
470-
static const int block_shift[3] = { 0, 3, 5 };
546+
static const int block_shift[3] = { 0, 3, 5 };
471547
static const int next_lcounter[3] = { 1, 2, 0 };
472548
static const int hcounter_incr[3] = { 0, 0, 1 };
473549
write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data);
@@ -513,8 +589,8 @@ void decode_ise(
513589

514590
if (trits)
515591
{
516-
static const int bits_to_read[5] = { 2, 2, 1, 2, 1 };
517-
static const int block_shift[5] = { 0, 2, 4, 5, 7 };
592+
static const int bits_to_read[5] = { 2, 2, 1, 2, 1 };
593+
static const int block_shift[5] = { 0, 2, 4, 5, 7 };
518594
static const int next_lcounter[5] = { 1, 2, 3, 4, 0 };
519595
static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 };
520596
int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
@@ -526,8 +602,8 @@ void decode_ise(
526602

527603
if (quints)
528604
{
529-
static const int bits_to_read[3] = { 3, 2, 2 };
530-
static const int block_shift[3] = { 0, 3, 5 };
605+
static const int bits_to_read[3] = { 3, 2, 2 };
606+
static const int block_shift[3] = { 0, 3, 5 };
531607
static const int next_lcounter[3] = { 1, 2, 0 };
532608
static const int hcounter_incr[3] = { 0, 0, 1 };
533609
int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
@@ -545,7 +621,7 @@ void decode_ise(
545621
for (int i = 0; i < trit_blocks; i++)
546622
{
547623
const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];
548-
results[5 * i] |= tritptr[0] << bits;
624+
results[5 * i ] |= tritptr[0] << bits;
549625
results[5 * i + 1] |= tritptr[1] << bits;
550626
results[5 * i + 2] |= tritptr[2] << bits;
551627
results[5 * i + 3] |= tritptr[3] << bits;
@@ -559,7 +635,7 @@ void decode_ise(
559635
for (int i = 0; i < quint_blocks; i++)
560636
{
561637
const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];
562-
results[3 * i] |= quintptr[0] << bits;
638+
results[3 * i ] |= quintptr[0] << bits;
563639
results[3 * i + 1] |= quintptr[1] << bits;
564640
results[3 * i + 2] |= quintptr[2] << bits;
565641
}
@@ -570,58 +646,3 @@ void decode_ise(
570646
output_data[i] = results[i];
571647
}
572648
}
573-
574-
int compute_ise_bitcount(
575-
int items,
576-
quantization_method quant
577-
) {
578-
// Values in this enum are from an external data source, so not guaranteed
579-
// to be bounded to the enum values for invalid block encodings
580-
switch (static_cast<int>(quant))
581-
{
582-
case QUANT_2:
583-
return items;
584-
case QUANT_3:
585-
return (8 * items + 4) / 5;
586-
case QUANT_4:
587-
return 2 * items;
588-
case QUANT_5:
589-
return (7 * items + 2) / 3;
590-
case QUANT_6:
591-
return (13 * items + 4) / 5;
592-
case QUANT_8:
593-
return 3 * items;
594-
case QUANT_10:
595-
return (10 * items + 2) / 3;
596-
case QUANT_12:
597-
return (18 * items + 4) / 5;
598-
case QUANT_16:
599-
return items * 4;
600-
case QUANT_20:
601-
return (13 * items + 2) / 3;
602-
case QUANT_24:
603-
return (23 * items + 4) / 5;
604-
case QUANT_32:
605-
return 5 * items;
606-
case QUANT_40:
607-
return (16 * items + 2) / 3;
608-
case QUANT_48:
609-
return (28 * items + 4) / 5;
610-
case QUANT_64:
611-
return 6 * items;
612-
case QUANT_80:
613-
return (19 * items + 2) / 3;
614-
case QUANT_96:
615-
return (33 * items + 4) / 5;
616-
case QUANT_128:
617-
return 7 * items;
618-
case QUANT_160:
619-
return (22 * items + 2) / 3;
620-
case QUANT_192:
621-
return (38 * items + 4) / 5;
622-
case QUANT_256:
623-
return 8 * items;
624-
default:
625-
return 100000;
626-
}
627-
}

Source/astcenc_internal.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,17 @@ void decode_ise(
813813
uint8_t* output_data,
814814
int bit_offset);
815815

816-
int compute_ise_bitcount(
816+
/**
817+
* @brief Return the number of bits needed to encode an ISE sequence.
818+
*
819+
* This implementation assumes that the @c quant level is untrusted, given it
820+
* may come from random data being decompressed, so we return an unencodable
821+
* size if that is the case.
822+
*
823+
* @param items The number of items in the sequence.
824+
* @param quant The desired quantization level.
825+
*/
826+
int get_ise_sequence_bitcount(
817827
int items,
818828
quantization_method quant);
819829

Source/astcenc_quantization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void build_quantization_mode_table()
552552
{
553553
for (int j = 1; j <= 16; j++)
554554
{
555-
int p = compute_ise_bitcount(2 * j, (quantization_method)i);
555+
int p = get_ise_sequence_bitcount(2 * j, (quantization_method)i);
556556
if (p < 128)
557557
{
558558
quantization_mode_table[j][p] = i;

Source/astcenc_symbolic_physical.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void symbolic_to_physical(
136136

137137
int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
138138

139-
int bits_for_weights = compute_ise_bitcount(real_weight_count,
139+
int bits_for_weights = get_ise_sequence_bitcount(real_weight_count,
140140
(quantization_method) weight_quantization_method);
141141

142142
if (is_dual_plane)
@@ -349,7 +349,7 @@ void physical_to_symbolic(
349349
bswapped[i] = bitrev8(pcb.data[15 - i]);
350350
}
351351

352-
int bits_for_weights = compute_ise_bitcount(real_weight_count,
352+
int bits_for_weights = get_ise_sequence_bitcount(real_weight_count,
353353
(quantization_method) weight_quantization_method);
354354

355355
int below_weights_pos = 128 - bits_for_weights;

0 commit comments

Comments
 (0)