Path: blob/master/thirdparty/astcenc/astcenc_integer_sequence.cpp
9903 views
// SPDX-License-Identifier: Apache-2.01// ----------------------------------------------------------------------------2// Copyright 2011-2024 Arm Limited3//4// Licensed under the Apache License, Version 2.0 (the "License"); you may not5// use this file except in compliance with the License. You may obtain a copy6// of the License at:7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT12// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the13// License for the specific language governing permissions and limitations14// under the License.15// ----------------------------------------------------------------------------1617/**18* @brief Functions for encoding/decoding Bounded Integer Sequence Encoding.19*/2021#include "astcenc_internal.h"2223#include <array>2425/** @brief Unpacked quint triplets <low,middle,high> for each packed value */26// TODO: Bitpack these into a uint16_t?27static const uint8_t quints_of_integer[128][3] {28{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0},29{4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4},30{0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0},31{4, 1, 0}, {1, 4, 0}, {4, 4, 1}, {4, 4, 4},32{0, 2, 0}, {1, 2, 0}, {2, 2, 0}, {3, 2, 0},33{4, 2, 0}, {2, 4, 0}, {4, 4, 2}, {4, 4, 4},34{0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {3, 3, 0},35{4, 3, 0}, {3, 4, 0}, {4, 4, 3}, {4, 4, 4},36{0, 0, 1}, {1, 0, 1}, {2, 0, 1}, {3, 0, 1},37{4, 0, 1}, {0, 4, 1}, {4, 0, 4}, {0, 4, 4},38{0, 1, 1}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1},39{4, 1, 1}, {1, 4, 1}, {4, 1, 4}, {1, 4, 4},40{0, 2, 1}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1},41{4, 2, 1}, {2, 4, 1}, {4, 2, 4}, {2, 4, 4},42{0, 3, 1}, {1, 3, 1}, {2, 3, 1}, {3, 3, 1},43{4, 3, 1}, {3, 4, 1}, {4, 3, 4}, {3, 4, 4},44{0, 0, 2}, {1, 0, 2}, {2, 0, 2}, {3, 0, 2},45{4, 0, 2}, {0, 4, 2}, {2, 0, 4}, {3, 0, 4},46{0, 1, 2}, {1, 1, 2}, {2, 1, 2}, {3, 1, 2},47{4, 1, 2}, {1, 4, 2}, {2, 1, 4}, {3, 1, 4},48{0, 2, 2}, {1, 2, 2}, {2, 2, 2}, {3, 2, 2},49{4, 2, 2}, {2, 4, 2}, {2, 2, 4}, {3, 2, 4},50{0, 3, 2}, {1, 3, 2}, {2, 3, 2}, {3, 3, 2},51{4, 3, 2}, {3, 4, 2}, {2, 3, 4}, {3, 3, 4},52{0, 0, 3}, {1, 0, 3}, {2, 0, 3}, {3, 0, 3},53{4, 0, 3}, {0, 4, 3}, {0, 0, 4}, {1, 0, 4},54{0, 1, 3}, {1, 1, 3}, {2, 1, 3}, {3, 1, 3},55{4, 1, 3}, {1, 4, 3}, {0, 1, 4}, {1, 1, 4},56{0, 2, 3}, {1, 2, 3}, {2, 2, 3}, {3, 2, 3},57{4, 2, 3}, {2, 4, 3}, {0, 2, 4}, {1, 2, 4},58{0, 3, 3}, {1, 3, 3}, {2, 3, 3}, {3, 3, 3},59{4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4}60};6162/** @brief Packed quint values for each unpacked value, indexed [hi][mid][lo]. */63static const uint8_t integer_of_quints[5][5][5] {64{65{0, 1, 2, 3, 4},66{8, 9, 10, 11, 12},67{16, 17, 18, 19, 20},68{24, 25, 26, 27, 28},69{5, 13, 21, 29, 6}70},71{72{32, 33, 34, 35, 36},73{40, 41, 42, 43, 44},74{48, 49, 50, 51, 52},75{56, 57, 58, 59, 60},76{37, 45, 53, 61, 14}77},78{79{64, 65, 66, 67, 68},80{72, 73, 74, 75, 76},81{80, 81, 82, 83, 84},82{88, 89, 90, 91, 92},83{69, 77, 85, 93, 22}84},85{86{96, 97, 98, 99, 100},87{104, 105, 106, 107, 108},88{112, 113, 114, 115, 116},89{120, 121, 122, 123, 124},90{101, 109, 117, 125, 30}91},92{93{102, 103, 70, 71, 38},94{110, 111, 78, 79, 46},95{118, 119, 86, 87, 54},96{126, 127, 94, 95, 62},97{39, 47, 55, 63, 31}98}99};100101/** @brief Unpacked trit quintuplets <low,...,high> for each packed value */102// TODO: Bitpack these into a uint16_t?103static const uint8_t trits_of_integer[256][5] {104{0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0},105{0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0},106{0, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {2, 2, 0, 0, 0}, {2, 0, 2, 0, 0},107{0, 2, 2, 0, 0}, {1, 2, 2, 0, 0}, {2, 2, 2, 0, 0}, {2, 0, 2, 0, 0},108{0, 0, 1, 0, 0}, {1, 0, 1, 0, 0}, {2, 0, 1, 0, 0}, {0, 1, 2, 0, 0},109{0, 1, 1, 0, 0}, {1, 1, 1, 0, 0}, {2, 1, 1, 0, 0}, {1, 1, 2, 0, 0},110{0, 2, 1, 0, 0}, {1, 2, 1, 0, 0}, {2, 2, 1, 0, 0}, {2, 1, 2, 0, 0},111{0, 0, 0, 2, 2}, {1, 0, 0, 2, 2}, {2, 0, 0, 2, 2}, {0, 0, 2, 2, 2},112{0, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, {2, 0, 0, 1, 0}, {0, 0, 2, 1, 0},113{0, 1, 0, 1, 0}, {1, 1, 0, 1, 0}, {2, 1, 0, 1, 0}, {1, 0, 2, 1, 0},114{0, 2, 0, 1, 0}, {1, 2, 0, 1, 0}, {2, 2, 0, 1, 0}, {2, 0, 2, 1, 0},115{0, 2, 2, 1, 0}, {1, 2, 2, 1, 0}, {2, 2, 2, 1, 0}, {2, 0, 2, 1, 0},116{0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {2, 0, 1, 1, 0}, {0, 1, 2, 1, 0},117{0, 1, 1, 1, 0}, {1, 1, 1, 1, 0}, {2, 1, 1, 1, 0}, {1, 1, 2, 1, 0},118{0, 2, 1, 1, 0}, {1, 2, 1, 1, 0}, {2, 2, 1, 1, 0}, {2, 1, 2, 1, 0},119{0, 1, 0, 2, 2}, {1, 1, 0, 2, 2}, {2, 1, 0, 2, 2}, {1, 0, 2, 2, 2},120{0, 0, 0, 2, 0}, {1, 0, 0, 2, 0}, {2, 0, 0, 2, 0}, {0, 0, 2, 2, 0},121{0, 1, 0, 2, 0}, {1, 1, 0, 2, 0}, {2, 1, 0, 2, 0}, {1, 0, 2, 2, 0},122{0, 2, 0, 2, 0}, {1, 2, 0, 2, 0}, {2, 2, 0, 2, 0}, {2, 0, 2, 2, 0},123{0, 2, 2, 2, 0}, {1, 2, 2, 2, 0}, {2, 2, 2, 2, 0}, {2, 0, 2, 2, 0},124{0, 0, 1, 2, 0}, {1, 0, 1, 2, 0}, {2, 0, 1, 2, 0}, {0, 1, 2, 2, 0},125{0, 1, 1, 2, 0}, {1, 1, 1, 2, 0}, {2, 1, 1, 2, 0}, {1, 1, 2, 2, 0},126{0, 2, 1, 2, 0}, {1, 2, 1, 2, 0}, {2, 2, 1, 2, 0}, {2, 1, 2, 2, 0},127{0, 2, 0, 2, 2}, {1, 2, 0, 2, 2}, {2, 2, 0, 2, 2}, {2, 0, 2, 2, 2},128{0, 0, 0, 0, 2}, {1, 0, 0, 0, 2}, {2, 0, 0, 0, 2}, {0, 0, 2, 0, 2},129{0, 1, 0, 0, 2}, {1, 1, 0, 0, 2}, {2, 1, 0, 0, 2}, {1, 0, 2, 0, 2},130{0, 2, 0, 0, 2}, {1, 2, 0, 0, 2}, {2, 2, 0, 0, 2}, {2, 0, 2, 0, 2},131{0, 2, 2, 0, 2}, {1, 2, 2, 0, 2}, {2, 2, 2, 0, 2}, {2, 0, 2, 0, 2},132{0, 0, 1, 0, 2}, {1, 0, 1, 0, 2}, {2, 0, 1, 0, 2}, {0, 1, 2, 0, 2},133{0, 1, 1, 0, 2}, {1, 1, 1, 0, 2}, {2, 1, 1, 0, 2}, {1, 1, 2, 0, 2},134{0, 2, 1, 0, 2}, {1, 2, 1, 0, 2}, {2, 2, 1, 0, 2}, {2, 1, 2, 0, 2},135{0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 0, 2, 2, 2},136{0, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {2, 0, 0, 0, 1}, {0, 0, 2, 0, 1},137{0, 1, 0, 0, 1}, {1, 1, 0, 0, 1}, {2, 1, 0, 0, 1}, {1, 0, 2, 0, 1},138{0, 2, 0, 0, 1}, {1, 2, 0, 0, 1}, {2, 2, 0, 0, 1}, {2, 0, 2, 0, 1},139{0, 2, 2, 0, 1}, {1, 2, 2, 0, 1}, {2, 2, 2, 0, 1}, {2, 0, 2, 0, 1},140{0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {2, 0, 1, 0, 1}, {0, 1, 2, 0, 1},141{0, 1, 1, 0, 1}, {1, 1, 1, 0, 1}, {2, 1, 1, 0, 1}, {1, 1, 2, 0, 1},142{0, 2, 1, 0, 1}, {1, 2, 1, 0, 1}, {2, 2, 1, 0, 1}, {2, 1, 2, 0, 1},143{0, 0, 1, 2, 2}, {1, 0, 1, 2, 2}, {2, 0, 1, 2, 2}, {0, 1, 2, 2, 2},144{0, 0, 0, 1, 1}, {1, 0, 0, 1, 1}, {2, 0, 0, 1, 1}, {0, 0, 2, 1, 1},145{0, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 0, 1, 1}, {1, 0, 2, 1, 1},146{0, 2, 0, 1, 1}, {1, 2, 0, 1, 1}, {2, 2, 0, 1, 1}, {2, 0, 2, 1, 1},147{0, 2, 2, 1, 1}, {1, 2, 2, 1, 1}, {2, 2, 2, 1, 1}, {2, 0, 2, 1, 1},148{0, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {2, 0, 1, 1, 1}, {0, 1, 2, 1, 1},149{0, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {2, 1, 1, 1, 1}, {1, 1, 2, 1, 1},150{0, 2, 1, 1, 1}, {1, 2, 1, 1, 1}, {2, 2, 1, 1, 1}, {2, 1, 2, 1, 1},151{0, 1, 1, 2, 2}, {1, 1, 1, 2, 2}, {2, 1, 1, 2, 2}, {1, 1, 2, 2, 2},152{0, 0, 0, 2, 1}, {1, 0, 0, 2, 1}, {2, 0, 0, 2, 1}, {0, 0, 2, 2, 1},153{0, 1, 0, 2, 1}, {1, 1, 0, 2, 1}, {2, 1, 0, 2, 1}, {1, 0, 2, 2, 1},154{0, 2, 0, 2, 1}, {1, 2, 0, 2, 1}, {2, 2, 0, 2, 1}, {2, 0, 2, 2, 1},155{0, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {2, 2, 2, 2, 1}, {2, 0, 2, 2, 1},156{0, 0, 1, 2, 1}, {1, 0, 1, 2, 1}, {2, 0, 1, 2, 1}, {0, 1, 2, 2, 1},157{0, 1, 1, 2, 1}, {1, 1, 1, 2, 1}, {2, 1, 1, 2, 1}, {1, 1, 2, 2, 1},158{0, 2, 1, 2, 1}, {1, 2, 1, 2, 1}, {2, 2, 1, 2, 1}, {2, 1, 2, 2, 1},159{0, 2, 1, 2, 2}, {1, 2, 1, 2, 2}, {2, 2, 1, 2, 2}, {2, 1, 2, 2, 2},160{0, 0, 0, 1, 2}, {1, 0, 0, 1, 2}, {2, 0, 0, 1, 2}, {0, 0, 2, 1, 2},161{0, 1, 0, 1, 2}, {1, 1, 0, 1, 2}, {2, 1, 0, 1, 2}, {1, 0, 2, 1, 2},162{0, 2, 0, 1, 2}, {1, 2, 0, 1, 2}, {2, 2, 0, 1, 2}, {2, 0, 2, 1, 2},163{0, 2, 2, 1, 2}, {1, 2, 2, 1, 2}, {2, 2, 2, 1, 2}, {2, 0, 2, 1, 2},164{0, 0, 1, 1, 2}, {1, 0, 1, 1, 2}, {2, 0, 1, 1, 2}, {0, 1, 2, 1, 2},165{0, 1, 1, 1, 2}, {1, 1, 1, 1, 2}, {2, 1, 1, 1, 2}, {1, 1, 2, 1, 2},166{0, 2, 1, 1, 2}, {1, 2, 1, 1, 2}, {2, 2, 1, 1, 2}, {2, 1, 2, 1, 2},167{0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2}168};169170/** @brief Packed trit values for each unpacked value, indexed [hi][][][][lo]. */171static const uint8_t integer_of_trits[3][3][3][3][3] {172{173{174{175{0, 1, 2},176{4, 5, 6},177{8, 9, 10}178},179{180{16, 17, 18},181{20, 21, 22},182{24, 25, 26}183},184{185{3, 7, 15},186{19, 23, 27},187{12, 13, 14}188}189},190{191{192{32, 33, 34},193{36, 37, 38},194{40, 41, 42}195},196{197{48, 49, 50},198{52, 53, 54},199{56, 57, 58}200},201{202{35, 39, 47},203{51, 55, 59},204{44, 45, 46}205}206},207{208{209{64, 65, 66},210{68, 69, 70},211{72, 73, 74}212},213{214{80, 81, 82},215{84, 85, 86},216{88, 89, 90}217},218{219{67, 71, 79},220{83, 87, 91},221{76, 77, 78}222}223}224},225{226{227{228{128, 129, 130},229{132, 133, 134},230{136, 137, 138}231},232{233{144, 145, 146},234{148, 149, 150},235{152, 153, 154}236},237{238{131, 135, 143},239{147, 151, 155},240{140, 141, 142}241}242},243{244{245{160, 161, 162},246{164, 165, 166},247{168, 169, 170}248},249{250{176, 177, 178},251{180, 181, 182},252{184, 185, 186}253},254{255{163, 167, 175},256{179, 183, 187},257{172, 173, 174}258}259},260{261{262{192, 193, 194},263{196, 197, 198},264{200, 201, 202}265},266{267{208, 209, 210},268{212, 213, 214},269{216, 217, 218}270},271{272{195, 199, 207},273{211, 215, 219},274{204, 205, 206}275}276}277},278{279{280{281{96, 97, 98},282{100, 101, 102},283{104, 105, 106}284},285{286{112, 113, 114},287{116, 117, 118},288{120, 121, 122}289},290{291{99, 103, 111},292{115, 119, 123},293{108, 109, 110}294}295},296{297{298{224, 225, 226},299{228, 229, 230},300{232, 233, 234}301},302{303{240, 241, 242},304{244, 245, 246},305{248, 249, 250}306},307{308{227, 231, 239},309{243, 247, 251},310{236, 237, 238}311}312},313{314{315{28, 29, 30},316{60, 61, 62},317{92, 93, 94}318},319{320{156, 157, 158},321{188, 189, 190},322{220, 221, 222}323},324{325{31, 63, 127},326{159, 191, 255},327{252, 253, 254}328}329}330}331};332333/**334* @brief The number of bits, trits, and quints needed for a quant level.335*/336struct btq_count337{338/** @brief The number of bits. */339uint8_t bits:6;340341/** @brief The number of trits. */342uint8_t trits:1;343344/** @brief The number of quints. */345uint8_t quints:1;346};347348/**349* @brief The table of bits, trits, and quints needed for a quant encode.350*/351static const std::array<btq_count, 21> btq_counts {{352{ 1, 0, 0 }, // QUANT_2353{ 0, 1, 0 }, // QUANT_3354{ 2, 0, 0 }, // QUANT_4355{ 0, 0, 1 }, // QUANT_5356{ 1, 1, 0 }, // QUANT_6357{ 3, 0, 0 }, // QUANT_8358{ 1, 0, 1 }, // QUANT_10359{ 2, 1, 0 }, // QUANT_12360{ 4, 0, 0 }, // QUANT_16361{ 2, 0, 1 }, // QUANT_20362{ 3, 1, 0 }, // QUANT_24363{ 5, 0, 0 }, // QUANT_32364{ 3, 0, 1 }, // QUANT_40365{ 4, 1, 0 }, // QUANT_48366{ 6, 0, 0 }, // QUANT_64367{ 4, 0, 1 }, // QUANT_80368{ 5, 1, 0 }, // QUANT_96369{ 7, 0, 0 }, // QUANT_128370{ 5, 0, 1 }, // QUANT_160371{ 6, 1, 0 }, // QUANT_192372{ 8, 0, 0 } // QUANT_256373}};374375/**376* @brief The sequence scale, round, and divisors needed to compute sizing.377*378* The length of a quantized sequence in bits is:379* (scale * <sequence_len> + round) / divisor380*/381struct ise_size382{383/** @brief The scaling parameter. */384uint8_t scale:6;385386/** @brief The divisor parameter. */387uint8_t divisor:2;388};389390/**391* @brief The table of scale, round, and divisors needed for quant sizing.392*/393static const std::array<ise_size, 21> ise_sizes {{394{ 1, 0 }, // QUANT_2395{ 8, 2 }, // QUANT_3396{ 2, 0 }, // QUANT_4397{ 7, 1 }, // QUANT_5398{ 13, 2 }, // QUANT_6399{ 3, 0 }, // QUANT_8400{ 10, 1 }, // QUANT_10401{ 18, 2 }, // QUANT_12402{ 4, 0 }, // QUANT_16403{ 13, 1 }, // QUANT_20404{ 23, 2 }, // QUANT_24405{ 5, 0 }, // QUANT_32406{ 16, 1 }, // QUANT_40407{ 28, 2 }, // QUANT_48408{ 6, 0 }, // QUANT_64409{ 19, 1 }, // QUANT_80410{ 33, 2 }, // QUANT_96411{ 7, 0 }, // QUANT_128412{ 22, 1 }, // QUANT_160413{ 38, 2 }, // QUANT_192414{ 8, 0 } // QUANT_256415}};416417/* See header for documentation. */418unsigned int get_ise_sequence_bitcount(419unsigned int character_count,420quant_method quant_level421) {422// Cope with out-of bounds values - input might be invalid423if (static_cast<size_t>(quant_level) >= ise_sizes.size())424{425// Arbitrary large number that's more than an ASTC block can hold426return 1024;427}428429auto& entry = ise_sizes[quant_level];430unsigned int divisor = (entry.divisor << 1) + 1;431return (entry.scale * character_count + divisor - 1) / divisor;432}433434/**435* @brief Write up to 8 bits at an arbitrary bit offset.436*437* The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may438* span two separate bytes in memory.439*440* @param value The value to write.441* @param bitcount The number of bits to write, starting from LSB.442* @param bitoffset The bit offset to store at, between 0 and 7.443* @param[in,out] ptr The data pointer to write to.444*/445static inline void write_bits(446unsigned int value,447unsigned int bitcount,448unsigned int bitoffset,449uint8_t ptr[2]450) {451unsigned int mask = (1 << bitcount) - 1;452value &= mask;453ptr += bitoffset >> 3;454bitoffset &= 7;455value <<= bitoffset;456mask <<= bitoffset;457mask = ~mask;458459ptr[0] &= mask;460ptr[0] |= value;461ptr[1] &= mask >> 8;462ptr[1] |= value >> 8;463}464465/**466* @brief Read up to 16 bits from two bytes.467*468* This function reads a packed N-bit field from two bytes in memory. The stored value must exist469* within the two bytes, but can start at an arbitary bit offset and span the two bytes in memory.470*471* @param bitcount The number of bits to read.472* @param bitoffset The bit offset to read from, between 0 and 7.473* @param[in,out] ptr The data pointer to read from.474*475* @return The read value.476*/477static inline unsigned int read_bits(478unsigned int bitcount,479unsigned int bitoffset,480const uint8_t* ptr481) {482unsigned int mask = (1 << bitcount) - 1;483ptr += bitoffset >> 3;484bitoffset &= 7;485unsigned int value = ptr[0] | (ptr[1] << 8);486value >>= bitoffset;487value &= mask;488return value;489}490491/* See header for documentation. */492void encode_ise(493quant_method quant_level,494unsigned int character_count,495const uint8_t* input_data,496uint8_t* output_data,497unsigned int bit_offset498) {499promise(character_count > 0);500501unsigned int bits = btq_counts[quant_level].bits;502unsigned int trits = btq_counts[quant_level].trits;503unsigned int quints = btq_counts[quant_level].quints;504unsigned int mask = (1 << bits) - 1;505506// Write out trits and bits507if (trits)508{509unsigned int i = 0;510unsigned int full_trit_blocks = character_count / 5;511512for (unsigned int j = 0; j < full_trit_blocks; j++)513{514unsigned int i4 = input_data[i + 4] >> bits;515unsigned int i3 = input_data[i + 3] >> bits;516unsigned int i2 = input_data[i + 2] >> bits;517unsigned int i1 = input_data[i + 1] >> bits;518unsigned int i0 = input_data[i + 0] >> bits;519520uint8_t T = integer_of_trits[i4][i3][i2][i1][i0];521522// The max size of a trit bit count is 6, so we can always safely523// pack a single MX value with the following 1 or 2 T bits.524uint8_t pack;525526// Element 0 + T0 + T1527pack = (input_data[i++] & mask) | (((T >> 0) & 0x3) << bits);528write_bits(pack, bits + 2, bit_offset, output_data);529bit_offset += bits + 2;530531// Element 1 + T2 + T3532pack = (input_data[i++] & mask) | (((T >> 2) & 0x3) << bits);533write_bits(pack, bits + 2, bit_offset, output_data);534bit_offset += bits + 2;535536// Element 2 + T4537pack = (input_data[i++] & mask) | (((T >> 4) & 0x1) << bits);538write_bits(pack, bits + 1, bit_offset, output_data);539bit_offset += bits + 1;540541// Element 3 + T5 + T6542pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits);543write_bits(pack, bits + 2, bit_offset, output_data);544bit_offset += bits + 2;545546// Element 4 + T7547pack = (input_data[i++] & mask) | (((T >> 7) & 0x1) << bits);548write_bits(pack, bits + 1, bit_offset, output_data);549bit_offset += bits + 1;550}551552// Loop tail for a partial block553if (i != character_count)554{555// i4 cannot be present - we know the block is partial556// i0 must be present - we know the block isn't empty557unsigned int i4 = 0;558unsigned int i3 = i + 3 >= character_count ? 0 : input_data[i + 3] >> bits;559unsigned int i2 = i + 2 >= character_count ? 0 : input_data[i + 2] >> bits;560unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;561unsigned int i0 = input_data[i + 0] >> bits;562563uint8_t T = integer_of_trits[i4][i3][i2][i1][i0];564565for (unsigned int j = 0; i < character_count; i++, j++)566{567// Truncated table as this iteration is always partital568static const uint8_t tbits[4] { 2, 2, 1, 2 };569static const uint8_t tshift[4] { 0, 2, 4, 5 };570571uint8_t pack = (input_data[i] & mask) |572(((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits);573574write_bits(pack, bits + tbits[j], bit_offset, output_data);575bit_offset += bits + tbits[j];576}577}578}579// Write out quints and bits580else if (quints)581{582unsigned int i = 0;583unsigned int full_quint_blocks = character_count / 3;584585for (unsigned int j = 0; j < full_quint_blocks; j++)586{587unsigned int i2 = input_data[i + 2] >> bits;588unsigned int i1 = input_data[i + 1] >> bits;589unsigned int i0 = input_data[i + 0] >> bits;590591uint8_t T = integer_of_quints[i2][i1][i0];592593// The max size of a quint bit count is 5, so we can always safely594// pack a single M value with the following 2 or 3 T bits.595uint8_t pack;596597// Element 0598pack = (input_data[i++] & mask) | (((T >> 0) & 0x7) << bits);599write_bits(pack, bits + 3, bit_offset, output_data);600bit_offset += bits + 3;601602// Element 1603pack = (input_data[i++] & mask) | (((T >> 3) & 0x3) << bits);604write_bits(pack, bits + 2, bit_offset, output_data);605bit_offset += bits + 2;606607// Element 2608pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits);609write_bits(pack, bits + 2, bit_offset, output_data);610bit_offset += bits + 2;611}612613// Loop tail for a partial block614if (i != character_count)615{616// i2 cannot be present - we know the block is partial617// i0 must be present - we know the block isn't empty618unsigned int i2 = 0;619unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;620unsigned int i0 = input_data[i + 0] >> bits;621622uint8_t T = integer_of_quints[i2][i1][i0];623624for (unsigned int j = 0; i < character_count; i++, j++)625{626// Truncated table as this iteration is always partital627static const uint8_t tbits[2] { 3, 2 };628static const uint8_t tshift[2] { 0, 3 };629630uint8_t pack = (input_data[i] & mask) |631(((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits);632633write_bits(pack, bits + tbits[j], bit_offset, output_data);634bit_offset += bits + tbits[j];635}636}637}638// Write out just bits639else640{641for (unsigned int i = 0; i < character_count; i++)642{643write_bits(input_data[i], bits, bit_offset, output_data);644bit_offset += bits;645}646}647}648649/* See header for documentation. */650void decode_ise(651quant_method quant_level,652unsigned int character_count,653const uint8_t* input_data,654uint8_t* output_data,655unsigned int bit_offset656) {657promise(character_count > 0);658659// Note: due to how the trit/quint-block unpacking is done in this function, we may write more660// temporary results than the number of outputs. The maximum actual number of results is 64 bit,661// but we keep 4 additional character_count of padding.662uint8_t results[68];663uint8_t tq_blocks[22] { 0 }; // Trit-blocks or quint-blocks, must be zeroed664665unsigned int bits = btq_counts[quant_level].bits;666unsigned int trits = btq_counts[quant_level].trits;667unsigned int quints = btq_counts[quant_level].quints;668669unsigned int lcounter = 0;670unsigned int hcounter = 0;671672// Collect bits for each element, as well as bits for any trit-blocks and quint-blocks.673for (unsigned int i = 0; i < character_count; i++)674{675results[i] = static_cast<uint8_t>(read_bits(bits, bit_offset, input_data));676bit_offset += bits;677678if (trits)679{680static const uint8_t bits_to_read[5] { 2, 2, 1, 2, 1 };681static const uint8_t block_shift[5] { 0, 2, 4, 5, 7 };682static const uint8_t next_lcounter[5] { 1, 2, 3, 4, 0 };683static const uint8_t hcounter_incr[5] { 0, 0, 0, 0, 1 };684unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);685bit_offset += bits_to_read[lcounter];686tq_blocks[hcounter] |= tdata << block_shift[lcounter];687hcounter += hcounter_incr[lcounter];688lcounter = next_lcounter[lcounter];689}690691if (quints)692{693static const uint8_t bits_to_read[3] { 3, 2, 2 };694static const uint8_t block_shift[3] { 0, 3, 5 };695static const uint8_t next_lcounter[3] { 1, 2, 0 };696static const uint8_t hcounter_incr[3] { 0, 0, 1 };697unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);698bit_offset += bits_to_read[lcounter];699tq_blocks[hcounter] |= tdata << block_shift[lcounter];700hcounter += hcounter_incr[lcounter];701lcounter = next_lcounter[lcounter];702}703}704705// Unpack trit-blocks or quint-blocks as needed706if (trits)707{708unsigned int trit_blocks = (character_count + 4) / 5;709promise(trit_blocks > 0);710for (unsigned int i = 0; i < trit_blocks; i++)711{712const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];713results[5 * i ] |= tritptr[0] << bits;714results[5 * i + 1] |= tritptr[1] << bits;715results[5 * i + 2] |= tritptr[2] << bits;716results[5 * i + 3] |= tritptr[3] << bits;717results[5 * i + 4] |= tritptr[4] << bits;718}719}720721if (quints)722{723unsigned int quint_blocks = (character_count + 2) / 3;724promise(quint_blocks > 0);725for (unsigned int i = 0; i < quint_blocks; i++)726{727const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];728results[3 * i ] |= quintptr[0] << bits;729results[3 * i + 1] |= quintptr[1] << bits;730results[3 * i + 2] |= quintptr[2] << bits;731}732}733734for (unsigned int i = 0; i < character_count; i++)735{736output_data[i] = results[i];737}738}739740741