Skip to content

Commit 1d3bd32

Browse files
committed
Cleanup API for integer_sequence
1 parent 4858dda commit 1d3bd32

3 files changed

Lines changed: 98 additions & 51 deletions

File tree

Source/astcenc_integer_sequence.cpp

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
#include <array>
2525

26-
// unpacked quint triplets <low,middle,high> for each packed-quint value
26+
/** @brief Unpacked quint triplets <low,middle,high> for each packed value */
2727
static const uint8_t quints_of_integer[128][3] = {
2828
{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0},
2929
{4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4},
@@ -59,8 +59,7 @@ static const uint8_t quints_of_integer[128][3] = {
5959
{4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4}
6060
};
6161

62-
// packed quint-value for every unpacked quint-triplet
63-
// indexed by [high][middle][low]
62+
/** @brief Packed quint values for each unpacked value, indexed [hi][mid][lo]. */
6463
static const uint8_t integer_of_quints[5][5][5] = {
6564
{
6665
{0, 1, 2, 3, 4},
@@ -99,7 +98,7 @@ static const uint8_t integer_of_quints[5][5][5] = {
9998
}
10099
};
101100

102-
// unpacked trit quintuplets <low,_,_,_,high> for each packed-quint value
101+
/** @brief Unpacked trit quintuplets <low,...,high> for each packed value */
103102
static const uint8_t trits_of_integer[256][5] = {
104103
{0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0},
105104
{0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0},
@@ -167,8 +166,7 @@ static const uint8_t trits_of_integer[256][5] = {
167166
{0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2}
168167
};
169168

170-
// packed trit-value for every unpacked trit-quintuplet
171-
// indexed by [high][][][][low]
169+
/** @brief Packed trit values for each unpacked value, indexed [hi][][][][lo]. */
172170
static const uint8_t integer_of_trits[3][3][3][3][3] = {
173171
{
174172
{
@@ -424,26 +422,36 @@ static const std::array<ise_size, 21> ise_sizes = {{
424422

425423
/* See header for documentation. */
426424
int get_ise_sequence_bitcount(
427-
int items,
428-
quant_method quant
425+
int character_count,
426+
quant_method quant_level
429427
) {
430428
// Cope with out-of bounds values - input might be invalid
431-
if (static_cast<size_t>(quant) >= ise_sizes.size())
429+
if (static_cast<size_t>(quant_level) >= ise_sizes.size())
432430
{
433431
// Arbitrary large number that's more than an ASTC block can hold
434432
return 1024;
435433
}
436434

437-
auto& entry = ise_sizes[quant];
438-
return (entry.scale * items + entry.round) / entry.divisor;
435+
auto& entry = ise_sizes[quant_level];
436+
return (entry.scale * character_count + entry.round) / entry.divisor;
439437
}
440438

441-
// routine to write up to 8 bits
439+
/**
440+
* @brief Write up to 8 bits at an arbitrary bit offset.
441+
*
442+
* The stored value is at most 8 bits, but can be stored at an offset of
443+
* between 0 and 7 bits so may span two separate bytes in memory.
444+
*
445+
* @param value The value to write.
446+
* @param bitcount The number of bits to write, starting from LSB.
447+
* @param bitoffset The bit offset to store at, between 0 and 7.
448+
* @param[in,out] ptr The data pointer to write to.
449+
*/
442450
static inline void write_bits(
443451
int value,
444452
int bitcount,
445453
int bitoffset,
446-
uint8_t* ptr
454+
uint8_t ptr[2]
447455
) {
448456
int mask = (1 << bitcount) - 1;
449457
value &= mask;
@@ -459,7 +467,18 @@ static inline void write_bits(
459467
ptr[1] |= value >> 8;
460468
}
461469

462-
// routine to read up to 8 bits
470+
/**
471+
* @brief Read up to 8 bits at an arbitrary bit offset.
472+
*
473+
* The stored value is at most 8 bits, but can be stored at an offset of
474+
* between 0 and 7 bits so may span two separate bytes in memory.
475+
*
476+
* @param bitcount The number of bits to read.
477+
* @param bitoffset The bit offset to read from, between 0 and 7.
478+
* @param[in,out] ptr The data pointer to read from.
479+
*
480+
* @return The read value.
481+
*/
463482
static inline int read_bits(
464483
int bitcount,
465484
int bitoffset,
@@ -474,14 +493,15 @@ static inline int read_bits(
474493
return value;
475494
}
476495

496+
/* See header for details. */
477497
void encode_ise(
478-
int quant_level,
479-
int elements,
498+
quant_method quant_level,
499+
int character_count,
480500
const uint8_t* input_data,
481501
uint8_t* output_data,
482502
int bit_offset
483503
) {
484-
promise(elements > 0);
504+
promise(character_count > 0);
485505

486506
int bits = btq_counts[quant_level].bits;
487507
int trits = btq_counts[quant_level].trits;
@@ -492,7 +512,7 @@ void encode_ise(
492512
if (trits)
493513
{
494514
int i = 0;
495-
int full_trit_blocks = elements / 5;
515+
int full_trit_blocks = character_count / 5;
496516

497517
for (int j = 0; j < full_trit_blocks; j++)
498518
{
@@ -535,19 +555,19 @@ void encode_ise(
535555
}
536556

537557
// Loop tail for a partial block
538-
if (i != elements)
558+
if (i != character_count)
539559
{
540560
// i4 cannot be present - we know the block is partial
541561
// i0 must be present - we know the block isn't empty
542562
int i4 = 0;
543-
int i3 = i + 3 >= elements ? 0 : input_data[i + 3] >> bits;
544-
int i2 = i + 2 >= elements ? 0 : input_data[i + 2] >> bits;
545-
int i1 = i + 1 >= elements ? 0 : input_data[i + 1] >> bits;
563+
int i3 = i + 3 >= character_count ? 0 : input_data[i + 3] >> bits;
564+
int i2 = i + 2 >= character_count ? 0 : input_data[i + 2] >> bits;
565+
int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;
546566
int i0 = input_data[i + 0] >> bits;
547567

548568
uint8_t T = integer_of_trits[i4][i3][i2][i1][i0];
549569

550-
for (int j = 0; i < elements; i++, j++)
570+
for (int j = 0; i < character_count; i++, j++)
551571
{
552572
// Truncated table as this iteration is always partital
553573
static const uint8_t tbits[4] { 2, 2, 1, 2 };
@@ -565,7 +585,7 @@ void encode_ise(
565585
else if (quints)
566586
{
567587
int i = 0;
568-
int full_quint_blocks = elements / 3;
588+
int full_quint_blocks = character_count / 3;
569589

570590
for (int j = 0; j < full_quint_blocks; j++)
571591
{
@@ -596,17 +616,17 @@ void encode_ise(
596616
}
597617

598618
// Loop tail for a partial block
599-
if (i != elements)
619+
if (i != character_count)
600620
{
601621
// i2 cannot be present - we know the block is partial
602622
// i0 must be present - we know the block isn't empty
603623
int i2 = 0;
604-
int i1 = i + 1 >= elements ? 0 : input_data[i + 1] >> bits;
624+
int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;
605625
int i0 = input_data[i + 0] >> bits;
606626

607627
uint8_t T = integer_of_quints[i2][i1][i0];
608628

609-
for (int j = 0; i < elements; i++, j++)
629+
for (int j = 0; i < character_count; i++, j++)
610630
{
611631
// Truncated table as this iteration is always partital
612632
static const uint8_t tbits[2] { 3, 2 };
@@ -623,27 +643,28 @@ void encode_ise(
623643
// Write out just bits
624644
else
625645
{
626-
promise(elements > 0);
627-
for (int i = 0; i < elements; i++)
646+
promise(character_count > 0);
647+
for (int i = 0; i < character_count; i++)
628648
{
629649
write_bits(input_data[i], bits, bit_offset, output_data);
630650
bit_offset += bits;
631651
}
632652
}
633653
}
634654

655+
/* See header for details. */
635656
void decode_ise(
636-
int quant_level,
637-
int elements,
657+
quant_method quant_level,
658+
int character_count,
638659
const uint8_t* input_data,
639660
uint8_t* output_data,
640661
int bit_offset
641662
) {
642-
promise(elements > 0);
663+
promise(character_count > 0);
643664

644665
// note: due to how the trit/quint-block unpacking is done in this function,
645666
// we may write more temporary results than the number of outputs
646-
// The maximum actual number of results is 64 bit, but we keep 4 additional elements
667+
// The maximum actual number of results is 64 bit, but we keep 4 additional character_count
647668
// of padding.
648669
uint8_t results[68];
649670
uint8_t tq_blocks[22]; // trit-blocks or quint-blocks
@@ -662,7 +683,7 @@ void decode_ise(
662683
}
663684

664685
// collect bits for each element, as well as bits for any trit-blocks and quint-blocks.
665-
for (int i = 0; i < elements; i++)
686+
for (int i = 0; i < character_count; i++)
666687
{
667688
results[i] = read_bits(bits, bit_offset, input_data);
668689
bit_offset += bits;
@@ -697,7 +718,7 @@ void decode_ise(
697718
// unpack trit-blocks or quint-blocks as needed
698719
if (trits)
699720
{
700-
int trit_blocks = (elements + 4) / 5;
721+
int trit_blocks = (character_count + 4) / 5;
701722
for (int i = 0; i < trit_blocks; i++)
702723
{
703724
const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];
@@ -711,7 +732,7 @@ void decode_ise(
711732

712733
if (quints)
713734
{
714-
int quint_blocks = (elements + 2) / 3;
735+
int quint_blocks = (character_count + 2) / 3;
715736
for (int i = 0; i < quint_blocks; i++)
716737
{
717738
const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];
@@ -721,7 +742,7 @@ void decode_ise(
721742
}
722743
}
723744

724-
for (int i = 0; i < elements; i++)
745+
for (int i = 0; i < character_count; i++)
725746
{
726747
output_data[i] = results[i];
727748
}

Source/astcenc_internal.h

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -856,16 +856,41 @@ extern const uint8_t color_quant_tables[21][256];
856856
extern const uint8_t color_unquant_tables[21][256];
857857
extern int8_t quant_mode_table[17][128];
858858

859+
/**
860+
* @brief Encode a packed string using BISE.
861+
*
862+
* Note that BISE can return strings that are not a whole number of bytes
863+
* in length, and ASTC can start storing strings in a block at arbitrary bit
864+
* offsets in the encoded data.
865+
*
866+
* @param quant_level The BISE alphabet size.
867+
* @param character_count The number of characters in the string.
868+
* @param input_data The unpacked string, one byte per character.
869+
* @param[in,out] output_data The output packed string.
870+
* @param bit_offset The starting offset in the output storage.
871+
*/
859872
void encode_ise(
860-
int quant_level,
861-
int elements,
873+
quant_method quant_level,
874+
int character_count,
862875
const uint8_t* input_data,
863876
uint8_t* output_data,
864877
int bit_offset);
865878

879+
/**
880+
* @brief Decode a packed string using BISE.
881+
*
882+
* Note that BISE input strings are not a whole number of bytes in length, and
883+
* ASTC can start strings at arbitrary bit offsets in the encoded data.
884+
*
885+
* @param quant_level The BISE alphabet size.
886+
* @param character_count The number of characters in the string.
887+
* @param input_data The packed string.
888+
* @param[in,out] output_data The output storage, one byte per character.
889+
* @param bit_offset The starting offset in the output storage.
890+
*/
866891
void decode_ise(
867-
int quant_level,
868-
int elements,
892+
quant_method quant_level,
893+
int character_count,
869894
const uint8_t* input_data,
870895
uint8_t* output_data,
871896
int bit_offset);
@@ -877,12 +902,14 @@ void decode_ise(
877902
* may come from random data being decompressed, so we return an unencodable
878903
* size if that is the case.
879904
*
880-
* @param items The number of items in the sequence.
881-
* @param quant The desired quantization level.
905+
* @param character_count The number of items in the sequence.
906+
* @param quant_level The desired quantization level.
907+
*
908+
* @return The number of bits needed to encode the BISE string.
882909
*/
883910
int get_ise_sequence_bitcount(
884-
int items,
885-
quant_method quant);
911+
int character_count,
912+
quant_method quant_level);
886913

887914
void build_quant_mode_table(void);
888915

Source/astcenc_symbolic_physical.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void symbolic_to_physical(
131131
const block_mode& bm = bsd.block_modes[packed_index];
132132

133133
int weight_count = dts[bm.decimation_mode]->weight_count;
134-
int weight_quant_method = bm.quant_mode;
134+
quant_method weight_quant_method = (quant_method)bm.quant_mode;
135135
int is_dual_plane = bm.is_dual_plane;
136136

137137
int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
@@ -244,7 +244,7 @@ void symbolic_to_physical(
244244
}
245245

246246
// then, encode an ISE based on them.
247-
encode_ise(scb.color_quant_level, valuecount_to_encode, values_to_encode, pcb.data, (scb.partition_count == 1 ? 17 : 19 + PARTITION_BITS));
247+
encode_ise((quant_method)scb.color_quant_level, valuecount_to_encode, values_to_encode, pcb.data, (scb.partition_count == 1 ? 17 : 19 + PARTITION_BITS));
248248
}
249249

250250
void physical_to_symbolic(
@@ -334,7 +334,7 @@ void physical_to_symbolic(
334334
const struct block_mode& bm = bsd.block_modes[packed_index];
335335

336336
int weight_count = dts[bm.decimation_mode]->weight_count;
337-
int weight_quant_method = bm.quant_mode;
337+
quant_method weight_quant_method = (quant_method)bm.quant_mode;
338338
int is_dual_plane = bm.is_dual_plane;
339339

340340
int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
@@ -349,8 +349,7 @@ void physical_to_symbolic(
349349
bswapped[i] = bitrev8(pcb.data[15 - i]);
350350
}
351351

352-
int bits_for_weights = get_ise_sequence_bitcount(real_weight_count,
353-
(quant_method)weight_quant_method);
352+
int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method);
354353

355354
int below_weights_pos = 128 - bits_for_weights;
356355

@@ -461,7 +460,7 @@ void physical_to_symbolic(
461460

462461
// then unpack the integer-bits
463462
uint8_t values_to_decode[32];
464-
decode_ise(color_quant_level, color_integer_count, pcb.data, values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_BITS));
463+
decode_ise((quant_method)color_quant_level, color_integer_count, pcb.data, values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_BITS));
465464

466465
// and distribute them over the endpoint types
467466
int valuecount_to_decode = 0;

0 commit comments

Comments
 (0)