| 1 | // SPDX-License-Identifier: Apache-2.0 |
| 2 | // ---------------------------------------------------------------------------- |
| 3 | // Copyright 2011-2021 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 encoding/decoding Bounded Integer Sequence Encoding. |
| 20 | */ |
| 21 | |
| 22 | #include "astcenc_internal.h" |
| 23 | |
| 24 | #include <array> |
| 25 | |
| 26 | /** @brief Unpacked quint triplets <low,middle,high> for each packed value */ |
| 27 | // TODO: Bitpack these into a uint16_t? |
| 28 | static const uint8_t quints_of_integer[128][3] { |
| 29 | {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, |
| 30 | {4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4}, |
| 31 | {0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0}, |
| 32 | {4, 1, 0}, {1, 4, 0}, {4, 4, 1}, {4, 4, 4}, |
| 33 | {0, 2, 0}, {1, 2, 0}, {2, 2, 0}, {3, 2, 0}, |
| 34 | {4, 2, 0}, {2, 4, 0}, {4, 4, 2}, {4, 4, 4}, |
| 35 | {0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {3, 3, 0}, |
| 36 | {4, 3, 0}, {3, 4, 0}, {4, 4, 3}, {4, 4, 4}, |
| 37 | {0, 0, 1}, {1, 0, 1}, {2, 0, 1}, {3, 0, 1}, |
| 38 | {4, 0, 1}, {0, 4, 1}, {4, 0, 4}, {0, 4, 4}, |
| 39 | {0, 1, 1}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1}, |
| 40 | {4, 1, 1}, {1, 4, 1}, {4, 1, 4}, {1, 4, 4}, |
| 41 | {0, 2, 1}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1}, |
| 42 | {4, 2, 1}, {2, 4, 1}, {4, 2, 4}, {2, 4, 4}, |
| 43 | {0, 3, 1}, {1, 3, 1}, {2, 3, 1}, {3, 3, 1}, |
| 44 | {4, 3, 1}, {3, 4, 1}, {4, 3, 4}, {3, 4, 4}, |
| 45 | {0, 0, 2}, {1, 0, 2}, {2, 0, 2}, {3, 0, 2}, |
| 46 | {4, 0, 2}, {0, 4, 2}, {2, 0, 4}, {3, 0, 4}, |
| 47 | {0, 1, 2}, {1, 1, 2}, {2, 1, 2}, {3, 1, 2}, |
| 48 | {4, 1, 2}, {1, 4, 2}, {2, 1, 4}, {3, 1, 4}, |
| 49 | {0, 2, 2}, {1, 2, 2}, {2, 2, 2}, {3, 2, 2}, |
| 50 | {4, 2, 2}, {2, 4, 2}, {2, 2, 4}, {3, 2, 4}, |
| 51 | {0, 3, 2}, {1, 3, 2}, {2, 3, 2}, {3, 3, 2}, |
| 52 | {4, 3, 2}, {3, 4, 2}, {2, 3, 4}, {3, 3, 4}, |
| 53 | {0, 0, 3}, {1, 0, 3}, {2, 0, 3}, {3, 0, 3}, |
| 54 | {4, 0, 3}, {0, 4, 3}, {0, 0, 4}, {1, 0, 4}, |
| 55 | {0, 1, 3}, {1, 1, 3}, {2, 1, 3}, {3, 1, 3}, |
| 56 | {4, 1, 3}, {1, 4, 3}, {0, 1, 4}, {1, 1, 4}, |
| 57 | {0, 2, 3}, {1, 2, 3}, {2, 2, 3}, {3, 2, 3}, |
| 58 | {4, 2, 3}, {2, 4, 3}, {0, 2, 4}, {1, 2, 4}, |
| 59 | {0, 3, 3}, {1, 3, 3}, {2, 3, 3}, {3, 3, 3}, |
| 60 | {4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4} |
| 61 | }; |
| 62 | |
| 63 | /** @brief Packed quint values for each unpacked value, indexed [hi][mid][lo]. */ |
| 64 | static const uint8_t integer_of_quints[5][5][5] { |
| 65 | { |
| 66 | {0, 1, 2, 3, 4}, |
| 67 | {8, 9, 10, 11, 12}, |
| 68 | {16, 17, 18, 19, 20}, |
| 69 | {24, 25, 26, 27, 28}, |
| 70 | {5, 13, 21, 29, 6} |
| 71 | }, |
| 72 | { |
| 73 | {32, 33, 34, 35, 36}, |
| 74 | {40, 41, 42, 43, 44}, |
| 75 | {48, 49, 50, 51, 52}, |
| 76 | {56, 57, 58, 59, 60}, |
| 77 | {37, 45, 53, 61, 14} |
| 78 | }, |
| 79 | { |
| 80 | {64, 65, 66, 67, 68}, |
| 81 | {72, 73, 74, 75, 76}, |
| 82 | {80, 81, 82, 83, 84}, |
| 83 | {88, 89, 90, 91, 92}, |
| 84 | {69, 77, 85, 93, 22} |
| 85 | }, |
| 86 | { |
| 87 | {96, 97, 98, 99, 100}, |
| 88 | {104, 105, 106, 107, 108}, |
| 89 | {112, 113, 114, 115, 116}, |
| 90 | {120, 121, 122, 123, 124}, |
| 91 | {101, 109, 117, 125, 30} |
| 92 | }, |
| 93 | { |
| 94 | {102, 103, 70, 71, 38}, |
| 95 | {110, 111, 78, 79, 46}, |
| 96 | {118, 119, 86, 87, 54}, |
| 97 | {126, 127, 94, 95, 62}, |
| 98 | {39, 47, 55, 63, 31} |
| 99 | } |
| 100 | }; |
| 101 | |
| 102 | /** @brief Unpacked trit quintuplets <low,...,high> for each packed value */ |
| 103 | // TODO: Bitpack these into a uint16_t? |
| 104 | static const uint8_t trits_of_integer[256][5] { |
| 105 | {0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0}, |
| 106 | {0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0}, |
| 107 | {0, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {2, 2, 0, 0, 0}, {2, 0, 2, 0, 0}, |
| 108 | {0, 2, 2, 0, 0}, {1, 2, 2, 0, 0}, {2, 2, 2, 0, 0}, {2, 0, 2, 0, 0}, |
| 109 | {0, 0, 1, 0, 0}, {1, 0, 1, 0, 0}, {2, 0, 1, 0, 0}, {0, 1, 2, 0, 0}, |
| 110 | {0, 1, 1, 0, 0}, {1, 1, 1, 0, 0}, {2, 1, 1, 0, 0}, {1, 1, 2, 0, 0}, |
| 111 | {0, 2, 1, 0, 0}, {1, 2, 1, 0, 0}, {2, 2, 1, 0, 0}, {2, 1, 2, 0, 0}, |
| 112 | {0, 0, 0, 2, 2}, {1, 0, 0, 2, 2}, {2, 0, 0, 2, 2}, {0, 0, 2, 2, 2}, |
| 113 | {0, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, {2, 0, 0, 1, 0}, {0, 0, 2, 1, 0}, |
| 114 | {0, 1, 0, 1, 0}, {1, 1, 0, 1, 0}, {2, 1, 0, 1, 0}, {1, 0, 2, 1, 0}, |
| 115 | {0, 2, 0, 1, 0}, {1, 2, 0, 1, 0}, {2, 2, 0, 1, 0}, {2, 0, 2, 1, 0}, |
| 116 | {0, 2, 2, 1, 0}, {1, 2, 2, 1, 0}, {2, 2, 2, 1, 0}, {2, 0, 2, 1, 0}, |
| 117 | {0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {2, 0, 1, 1, 0}, {0, 1, 2, 1, 0}, |
| 118 | {0, 1, 1, 1, 0}, {1, 1, 1, 1, 0}, {2, 1, 1, 1, 0}, {1, 1, 2, 1, 0}, |
| 119 | {0, 2, 1, 1, 0}, {1, 2, 1, 1, 0}, {2, 2, 1, 1, 0}, {2, 1, 2, 1, 0}, |
| 120 | {0, 1, 0, 2, 2}, {1, 1, 0, 2, 2}, {2, 1, 0, 2, 2}, {1, 0, 2, 2, 2}, |
| 121 | {0, 0, 0, 2, 0}, {1, 0, 0, 2, 0}, {2, 0, 0, 2, 0}, {0, 0, 2, 2, 0}, |
| 122 | {0, 1, 0, 2, 0}, {1, 1, 0, 2, 0}, {2, 1, 0, 2, 0}, {1, 0, 2, 2, 0}, |
| 123 | {0, 2, 0, 2, 0}, {1, 2, 0, 2, 0}, {2, 2, 0, 2, 0}, {2, 0, 2, 2, 0}, |
| 124 | {0, 2, 2, 2, 0}, {1, 2, 2, 2, 0}, {2, 2, 2, 2, 0}, {2, 0, 2, 2, 0}, |
| 125 | {0, 0, 1, 2, 0}, {1, 0, 1, 2, 0}, {2, 0, 1, 2, 0}, {0, 1, 2, 2, 0}, |
| 126 | {0, 1, 1, 2, 0}, {1, 1, 1, 2, 0}, {2, 1, 1, 2, 0}, {1, 1, 2, 2, 0}, |
| 127 | {0, 2, 1, 2, 0}, {1, 2, 1, 2, 0}, {2, 2, 1, 2, 0}, {2, 1, 2, 2, 0}, |
| 128 | {0, 2, 0, 2, 2}, {1, 2, 0, 2, 2}, {2, 2, 0, 2, 2}, {2, 0, 2, 2, 2}, |
| 129 | {0, 0, 0, 0, 2}, {1, 0, 0, 0, 2}, {2, 0, 0, 0, 2}, {0, 0, 2, 0, 2}, |
| 130 | {0, 1, 0, 0, 2}, {1, 1, 0, 0, 2}, {2, 1, 0, 0, 2}, {1, 0, 2, 0, 2}, |
| 131 | {0, 2, 0, 0, 2}, {1, 2, 0, 0, 2}, {2, 2, 0, 0, 2}, {2, 0, 2, 0, 2}, |
| 132 | {0, 2, 2, 0, 2}, {1, 2, 2, 0, 2}, {2, 2, 2, 0, 2}, {2, 0, 2, 0, 2}, |
| 133 | {0, 0, 1, 0, 2}, {1, 0, 1, 0, 2}, {2, 0, 1, 0, 2}, {0, 1, 2, 0, 2}, |
| 134 | {0, 1, 1, 0, 2}, {1, 1, 1, 0, 2}, {2, 1, 1, 0, 2}, {1, 1, 2, 0, 2}, |
| 135 | {0, 2, 1, 0, 2}, {1, 2, 1, 0, 2}, {2, 2, 1, 0, 2}, {2, 1, 2, 0, 2}, |
| 136 | {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 0, 2, 2, 2}, |
| 137 | {0, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {2, 0, 0, 0, 1}, {0, 0, 2, 0, 1}, |
| 138 | {0, 1, 0, 0, 1}, {1, 1, 0, 0, 1}, {2, 1, 0, 0, 1}, {1, 0, 2, 0, 1}, |
| 139 | {0, 2, 0, 0, 1}, {1, 2, 0, 0, 1}, {2, 2, 0, 0, 1}, {2, 0, 2, 0, 1}, |
| 140 | {0, 2, 2, 0, 1}, {1, 2, 2, 0, 1}, {2, 2, 2, 0, 1}, {2, 0, 2, 0, 1}, |
| 141 | {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {2, 0, 1, 0, 1}, {0, 1, 2, 0, 1}, |
| 142 | {0, 1, 1, 0, 1}, {1, 1, 1, 0, 1}, {2, 1, 1, 0, 1}, {1, 1, 2, 0, 1}, |
| 143 | {0, 2, 1, 0, 1}, {1, 2, 1, 0, 1}, {2, 2, 1, 0, 1}, {2, 1, 2, 0, 1}, |
| 144 | {0, 0, 1, 2, 2}, {1, 0, 1, 2, 2}, {2, 0, 1, 2, 2}, {0, 1, 2, 2, 2}, |
| 145 | {0, 0, 0, 1, 1}, {1, 0, 0, 1, 1}, {2, 0, 0, 1, 1}, {0, 0, 2, 1, 1}, |
| 146 | {0, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 0, 1, 1}, {1, 0, 2, 1, 1}, |
| 147 | {0, 2, 0, 1, 1}, {1, 2, 0, 1, 1}, {2, 2, 0, 1, 1}, {2, 0, 2, 1, 1}, |
| 148 | {0, 2, 2, 1, 1}, {1, 2, 2, 1, 1}, {2, 2, 2, 1, 1}, {2, 0, 2, 1, 1}, |
| 149 | {0, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {2, 0, 1, 1, 1}, {0, 1, 2, 1, 1}, |
| 150 | {0, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {2, 1, 1, 1, 1}, {1, 1, 2, 1, 1}, |
| 151 | {0, 2, 1, 1, 1}, {1, 2, 1, 1, 1}, {2, 2, 1, 1, 1}, {2, 1, 2, 1, 1}, |
| 152 | {0, 1, 1, 2, 2}, {1, 1, 1, 2, 2}, {2, 1, 1, 2, 2}, {1, 1, 2, 2, 2}, |
| 153 | {0, 0, 0, 2, 1}, {1, 0, 0, 2, 1}, {2, 0, 0, 2, 1}, {0, 0, 2, 2, 1}, |
| 154 | {0, 1, 0, 2, 1}, {1, 1, 0, 2, 1}, {2, 1, 0, 2, 1}, {1, 0, 2, 2, 1}, |
| 155 | {0, 2, 0, 2, 1}, {1, 2, 0, 2, 1}, {2, 2, 0, 2, 1}, {2, 0, 2, 2, 1}, |
| 156 | {0, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {2, 2, 2, 2, 1}, {2, 0, 2, 2, 1}, |
| 157 | {0, 0, 1, 2, 1}, {1, 0, 1, 2, 1}, {2, 0, 1, 2, 1}, {0, 1, 2, 2, 1}, |
| 158 | {0, 1, 1, 2, 1}, {1, 1, 1, 2, 1}, {2, 1, 1, 2, 1}, {1, 1, 2, 2, 1}, |
| 159 | {0, 2, 1, 2, 1}, {1, 2, 1, 2, 1}, {2, 2, 1, 2, 1}, {2, 1, 2, 2, 1}, |
| 160 | {0, 2, 1, 2, 2}, {1, 2, 1, 2, 2}, {2, 2, 1, 2, 2}, {2, 1, 2, 2, 2}, |
| 161 | {0, 0, 0, 1, 2}, {1, 0, 0, 1, 2}, {2, 0, 0, 1, 2}, {0, 0, 2, 1, 2}, |
| 162 | {0, 1, 0, 1, 2}, {1, 1, 0, 1, 2}, {2, 1, 0, 1, 2}, {1, 0, 2, 1, 2}, |
| 163 | {0, 2, 0, 1, 2}, {1, 2, 0, 1, 2}, {2, 2, 0, 1, 2}, {2, 0, 2, 1, 2}, |
| 164 | {0, 2, 2, 1, 2}, {1, 2, 2, 1, 2}, {2, 2, 2, 1, 2}, {2, 0, 2, 1, 2}, |
| 165 | {0, 0, 1, 1, 2}, {1, 0, 1, 1, 2}, {2, 0, 1, 1, 2}, {0, 1, 2, 1, 2}, |
| 166 | {0, 1, 1, 1, 2}, {1, 1, 1, 1, 2}, {2, 1, 1, 1, 2}, {1, 1, 2, 1, 2}, |
| 167 | {0, 2, 1, 1, 2}, {1, 2, 1, 1, 2}, {2, 2, 1, 1, 2}, {2, 1, 2, 1, 2}, |
| 168 | {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2} |
| 169 | }; |
| 170 | |
| 171 | /** @brief Packed trit values for each unpacked value, indexed [hi][][][][lo]. */ |
| 172 | static const uint8_t integer_of_trits[3][3][3][3][3] { |
| 173 | { |
| 174 | { |
| 175 | { |
| 176 | {0, 1, 2}, |
| 177 | {4, 5, 6}, |
| 178 | {8, 9, 10} |
| 179 | }, |
| 180 | { |
| 181 | {16, 17, 18}, |
| 182 | {20, 21, 22}, |
| 183 | {24, 25, 26} |
| 184 | }, |
| 185 | { |
| 186 | {3, 7, 15}, |
| 187 | {19, 23, 27}, |
| 188 | {12, 13, 14} |
| 189 | } |
| 190 | }, |
| 191 | { |
| 192 | { |
| 193 | {32, 33, 34}, |
| 194 | {36, 37, 38}, |
| 195 | {40, 41, 42} |
| 196 | }, |
| 197 | { |
| 198 | {48, 49, 50}, |
| 199 | {52, 53, 54}, |
| 200 | {56, 57, 58} |
| 201 | }, |
| 202 | { |
| 203 | {35, 39, 47}, |
| 204 | {51, 55, 59}, |
| 205 | {44, 45, 46} |
| 206 | } |
| 207 | }, |
| 208 | { |
| 209 | { |
| 210 | {64, 65, 66}, |
| 211 | {68, 69, 70}, |
| 212 | {72, 73, 74} |
| 213 | }, |
| 214 | { |
| 215 | {80, 81, 82}, |
| 216 | {84, 85, 86}, |
| 217 | {88, 89, 90} |
| 218 | }, |
| 219 | { |
| 220 | {67, 71, 79}, |
| 221 | {83, 87, 91}, |
| 222 | {76, 77, 78} |
| 223 | } |
| 224 | } |
| 225 | }, |
| 226 | { |
| 227 | { |
| 228 | { |
| 229 | {128, 129, 130}, |
| 230 | {132, 133, 134}, |
| 231 | {136, 137, 138} |
| 232 | }, |
| 233 | { |
| 234 | {144, 145, 146}, |
| 235 | {148, 149, 150}, |
| 236 | {152, 153, 154} |
| 237 | }, |
| 238 | { |
| 239 | {131, 135, 143}, |
| 240 | {147, 151, 155}, |
| 241 | {140, 141, 142} |
| 242 | } |
| 243 | }, |
| 244 | { |
| 245 | { |
| 246 | {160, 161, 162}, |
| 247 | {164, 165, 166}, |
| 248 | {168, 169, 170} |
| 249 | }, |
| 250 | { |
| 251 | {176, 177, 178}, |
| 252 | {180, 181, 182}, |
| 253 | {184, 185, 186} |
| 254 | }, |
| 255 | { |
| 256 | {163, 167, 175}, |
| 257 | {179, 183, 187}, |
| 258 | {172, 173, 174} |
| 259 | } |
| 260 | }, |
| 261 | { |
| 262 | { |
| 263 | {192, 193, 194}, |
| 264 | {196, 197, 198}, |
| 265 | {200, 201, 202} |
| 266 | }, |
| 267 | { |
| 268 | {208, 209, 210}, |
| 269 | {212, 213, 214}, |
| 270 | {216, 217, 218} |
| 271 | }, |
| 272 | { |
| 273 | {195, 199, 207}, |
| 274 | {211, 215, 219}, |
| 275 | {204, 205, 206} |
| 276 | } |
| 277 | } |
| 278 | }, |
| 279 | { |
| 280 | { |
| 281 | { |
| 282 | {96, 97, 98}, |
| 283 | {100, 101, 102}, |
| 284 | {104, 105, 106} |
| 285 | }, |
| 286 | { |
| 287 | {112, 113, 114}, |
| 288 | {116, 117, 118}, |
| 289 | {120, 121, 122} |
| 290 | }, |
| 291 | { |
| 292 | {99, 103, 111}, |
| 293 | {115, 119, 123}, |
| 294 | {108, 109, 110} |
| 295 | } |
| 296 | }, |
| 297 | { |
| 298 | { |
| 299 | {224, 225, 226}, |
| 300 | {228, 229, 230}, |
| 301 | {232, 233, 234} |
| 302 | }, |
| 303 | { |
| 304 | {240, 241, 242}, |
| 305 | {244, 245, 246}, |
| 306 | {248, 249, 250} |
| 307 | }, |
| 308 | { |
| 309 | {227, 231, 239}, |
| 310 | {243, 247, 251}, |
| 311 | {236, 237, 238} |
| 312 | } |
| 313 | }, |
| 314 | { |
| 315 | { |
| 316 | {28, 29, 30}, |
| 317 | {60, 61, 62}, |
| 318 | {92, 93, 94} |
| 319 | }, |
| 320 | { |
| 321 | {156, 157, 158}, |
| 322 | {188, 189, 190}, |
| 323 | {220, 221, 222} |
| 324 | }, |
| 325 | { |
| 326 | {31, 63, 127}, |
| 327 | {159, 191, 255}, |
| 328 | {252, 253, 254} |
| 329 | } |
| 330 | } |
| 331 | } |
| 332 | }; |
| 333 | |
| 334 | /** |
| 335 | * @brief The number of bits, trits, and quints needed for a quant level. |
| 336 | */ |
| 337 | struct btq_count |
| 338 | { |
| 339 | /** @brief The number of bits. */ |
| 340 | uint8_t bits:6; |
| 341 | |
| 342 | /** @brief The number of trits. */ |
| 343 | uint8_t trits:1; |
| 344 | |
| 345 | /** @brief The number of quints. */ |
| 346 | uint8_t quints:1; |
| 347 | }; |
| 348 | |
| 349 | /** |
| 350 | * @brief The table of bits, trits, and quints needed for a quant encode. |
| 351 | */ |
| 352 | static const std::array<btq_count, 21> btq_counts {{ |
| 353 | { 1, 0, 0 }, // QUANT_2 |
| 354 | { 0, 1, 0 }, // QUANT_3 |
| 355 | { 2, 0, 0 }, // QUANT_4 |
| 356 | { 0, 0, 1 }, // QUANT_5 |
| 357 | { 1, 1, 0 }, // QUANT_6 |
| 358 | { 3, 0, 0 }, // QUANT_8 |
| 359 | { 1, 0, 1 }, // QUANT_10 |
| 360 | { 2, 1, 0 }, // QUANT_12 |
| 361 | { 4, 0, 0 }, // QUANT_16 |
| 362 | { 2, 0, 1 }, // QUANT_20 |
| 363 | { 3, 1, 0 }, // QUANT_24 |
| 364 | { 5, 0, 0 }, // QUANT_32 |
| 365 | { 3, 0, 1 }, // QUANT_40 |
| 366 | { 4, 1, 0 }, // QUANT_48 |
| 367 | { 6, 0, 0 }, // QUANT_64 |
| 368 | { 4, 0, 1 }, // QUANT_80 |
| 369 | { 5, 1, 0 }, // QUANT_96 |
| 370 | { 7, 0, 0 }, // QUANT_128 |
| 371 | { 5, 0, 1 }, // QUANT_160 |
| 372 | { 6, 1, 0 }, // QUANT_192 |
| 373 | { 8, 0, 0 } // QUANT_256 |
| 374 | }}; |
| 375 | |
| 376 | /** |
| 377 | * @brief The sequence scale, round, and divisors needed to compute sizing. |
| 378 | * |
| 379 | * The length of a quantized sequence in bits is: |
| 380 | * (scale * <sequence_len> + round) / divisor |
| 381 | */ |
| 382 | struct ise_size |
| 383 | { |
| 384 | /** @brief The scaling parameter. */ |
| 385 | uint8_t scale:6; |
| 386 | |
| 387 | /** @brief The divisor parameter. */ |
| 388 | uint8_t divisor:2; |
| 389 | }; |
| 390 | |
| 391 | /** |
| 392 | * @brief The table of scale, round, and divisors needed for quant sizing. |
| 393 | */ |
| 394 | static const std::array<ise_size, 21> ise_sizes {{ |
| 395 | { 1, 0 }, // QUANT_2 |
| 396 | { 8, 2 }, // QUANT_3 |
| 397 | { 2, 0 }, // QUANT_4 |
| 398 | { 7, 1 }, // QUANT_5 |
| 399 | { 13, 2 }, // QUANT_6 |
| 400 | { 3, 0 }, // QUANT_8 |
| 401 | { 10, 1 }, // QUANT_10 |
| 402 | { 18, 2 }, // QUANT_12 |
| 403 | { 4, 0 }, // QUANT_16 |
| 404 | { 13, 1 }, // QUANT_20 |
| 405 | { 23, 2 }, // QUANT_24 |
| 406 | { 5, 0 }, // QUANT_32 |
| 407 | { 16, 1 }, // QUANT_40 |
| 408 | { 28, 2 }, // QUANT_48 |
| 409 | { 6, 0 }, // QUANT_64 |
| 410 | { 19, 1 }, // QUANT_80 |
| 411 | { 33, 2 }, // QUANT_96 |
| 412 | { 7, 0 }, // QUANT_128 |
| 413 | { 22, 1 }, // QUANT_160 |
| 414 | { 38, 2 }, // QUANT_192 |
| 415 | { 8, 0 } // QUANT_256 |
| 416 | }}; |
| 417 | |
| 418 | /* See header for documentation. */ |
| 419 | unsigned int get_ise_sequence_bitcount( |
| 420 | unsigned int character_count, |
| 421 | quant_method quant_level |
| 422 | ) { |
| 423 | // Cope with out-of bounds values - input might be invalid |
| 424 | if (static_cast<size_t>(quant_level) >= ise_sizes.size()) |
| 425 | { |
| 426 | // Arbitrary large number that's more than an ASTC block can hold |
| 427 | return 1024; |
| 428 | } |
| 429 | |
| 430 | auto& entry = ise_sizes[quant_level]; |
| 431 | unsigned int divisor = (entry.divisor << 1) + 1; |
| 432 | return (entry.scale * character_count + divisor - 1) / divisor; |
| 433 | } |
| 434 | |
| 435 | /** |
| 436 | * @brief Write up to 8 bits at an arbitrary bit offset. |
| 437 | * |
| 438 | * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may |
| 439 | * span two separate bytes in memory. |
| 440 | * |
| 441 | * @param value The value to write. |
| 442 | * @param bitcount The number of bits to write, starting from LSB. |
| 443 | * @param bitoffset The bit offset to store at, between 0 and 7. |
| 444 | * @param[in,out] ptr The data pointer to write to. |
| 445 | */ |
| 446 | static inline void write_bits( |
| 447 | unsigned int value, |
| 448 | unsigned int bitcount, |
| 449 | unsigned int bitoffset, |
| 450 | uint8_t ptr[2] |
| 451 | ) { |
| 452 | unsigned int mask = (1 << bitcount) - 1; |
| 453 | value &= mask; |
| 454 | ptr += bitoffset >> 3; |
| 455 | bitoffset &= 7; |
| 456 | value <<= bitoffset; |
| 457 | mask <<= bitoffset; |
| 458 | mask = ~mask; |
| 459 | |
| 460 | ptr[0] &= mask; |
| 461 | ptr[0] |= value; |
| 462 | ptr[1] &= mask >> 8; |
| 463 | ptr[1] |= value >> 8; |
| 464 | } |
| 465 | |
| 466 | /** |
| 467 | * @brief Read up to 8 bits at an arbitrary bit offset. |
| 468 | * |
| 469 | * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may |
| 470 | * span two separate bytes in memory. |
| 471 | * |
| 472 | * @param bitcount The number of bits to read. |
| 473 | * @param bitoffset The bit offset to read from, between 0 and 7. |
| 474 | * @param[in,out] ptr The data pointer to read from. |
| 475 | * |
| 476 | * @return The read value. |
| 477 | */ |
| 478 | static inline unsigned int read_bits( |
| 479 | unsigned int bitcount, |
| 480 | unsigned int bitoffset, |
| 481 | const uint8_t* ptr |
| 482 | ) { |
| 483 | unsigned int mask = (1 << bitcount) - 1; |
| 484 | ptr += bitoffset >> 3; |
| 485 | bitoffset &= 7; |
| 486 | unsigned int value = ptr[0] | (ptr[1] << 8); |
| 487 | value >>= bitoffset; |
| 488 | value &= mask; |
| 489 | return value; |
| 490 | } |
| 491 | |
| 492 | /* See header for documentation. */ |
| 493 | void encode_ise( |
| 494 | quant_method quant_level, |
| 495 | unsigned int character_count, |
| 496 | const uint8_t* input_data, |
| 497 | uint8_t* output_data, |
| 498 | unsigned int bit_offset |
| 499 | ) { |
| 500 | promise(character_count > 0); |
| 501 | |
| 502 | unsigned int bits = btq_counts[quant_level].bits; |
| 503 | unsigned int trits = btq_counts[quant_level].trits; |
| 504 | unsigned int quints = btq_counts[quant_level].quints; |
| 505 | unsigned int mask = (1 << bits) - 1; |
| 506 | |
| 507 | // Write out trits and bits |
| 508 | if (trits) |
| 509 | { |
| 510 | unsigned int i = 0; |
| 511 | unsigned int full_trit_blocks = character_count / 5; |
| 512 | |
| 513 | for (unsigned int j = 0; j < full_trit_blocks; j++) |
| 514 | { |
| 515 | unsigned int i4 = input_data[i + 4] >> bits; |
| 516 | unsigned int i3 = input_data[i + 3] >> bits; |
| 517 | unsigned int i2 = input_data[i + 2] >> bits; |
| 518 | unsigned int i1 = input_data[i + 1] >> bits; |
| 519 | unsigned int i0 = input_data[i + 0] >> bits; |
| 520 | |
| 521 | uint8_t T = integer_of_trits[i4][i3][i2][i1][i0]; |
| 522 | |
| 523 | // The max size of a trit bit count is 6, so we can always safely |
| 524 | // pack a single MX value with the following 1 or 2 T bits. |
| 525 | uint8_t pack; |
| 526 | |
| 527 | // Element 0 + T0 + T1 |
| 528 | pack = (input_data[i++] & mask) | (((T >> 0) & 0x3) << bits); |
| 529 | write_bits(pack, bits + 2, bit_offset, output_data); |
| 530 | bit_offset += bits + 2; |
| 531 | |
| 532 | // Element 1 + T2 + T3 |
| 533 | pack = (input_data[i++] & mask) | (((T >> 2) & 0x3) << bits); |
| 534 | write_bits(pack, bits + 2, bit_offset, output_data); |
| 535 | bit_offset += bits + 2; |
| 536 | |
| 537 | // Element 2 + T4 |
| 538 | pack = (input_data[i++] & mask) | (((T >> 4) & 0x1) << bits); |
| 539 | write_bits(pack, bits + 1, bit_offset, output_data); |
| 540 | bit_offset += bits + 1; |
| 541 | |
| 542 | // Element 3 + T5 + T6 |
| 543 | pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits); |
| 544 | write_bits(pack, bits + 2, bit_offset, output_data); |
| 545 | bit_offset += bits + 2; |
| 546 | |
| 547 | // Element 4 + T7 |
| 548 | pack = (input_data[i++] & mask) | (((T >> 7) & 0x1) << bits); |
| 549 | write_bits(pack, bits + 1, bit_offset, output_data); |
| 550 | bit_offset += bits + 1; |
| 551 | } |
| 552 | |
| 553 | // Loop tail for a partial block |
| 554 | if (i != character_count) |
| 555 | { |
| 556 | // i4 cannot be present - we know the block is partial |
| 557 | // i0 must be present - we know the block isn't empty |
| 558 | unsigned int i4 = 0; |
| 559 | unsigned int i3 = i + 3 >= character_count ? 0 : input_data[i + 3] >> bits; |
| 560 | unsigned int i2 = i + 2 >= character_count ? 0 : input_data[i + 2] >> bits; |
| 561 | unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits; |
| 562 | unsigned int i0 = input_data[i + 0] >> bits; |
| 563 | |
| 564 | uint8_t T = integer_of_trits[i4][i3][i2][i1][i0]; |
| 565 | |
| 566 | for (unsigned int j = 0; i < character_count; i++, j++) |
| 567 | { |
| 568 | // Truncated table as this iteration is always partital |
| 569 | static const uint8_t tbits[4] { 2, 2, 1, 2 }; |
| 570 | static const uint8_t tshift[4] { 0, 2, 4, 5 }; |
| 571 | |
| 572 | uint8_t pack = (input_data[i] & mask) | |
| 573 | (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits); |
| 574 | |
| 575 | write_bits(pack, bits + tbits[j], bit_offset, output_data); |
| 576 | bit_offset += bits + tbits[j]; |
| 577 | } |
| 578 | } |
| 579 | } |
| 580 | // Write out quints and bits |
| 581 | else if (quints) |
| 582 | { |
| 583 | unsigned int i = 0; |
| 584 | unsigned int full_quint_blocks = character_count / 3; |
| 585 | |
| 586 | for (unsigned int j = 0; j < full_quint_blocks; j++) |
| 587 | { |
| 588 | unsigned int i2 = input_data[i + 2] >> bits; |
| 589 | unsigned int i1 = input_data[i + 1] >> bits; |
| 590 | unsigned int i0 = input_data[i + 0] >> bits; |
| 591 | |
| 592 | uint8_t T = integer_of_quints[i2][i1][i0]; |
| 593 | |
| 594 | // The max size of a quint bit count is 5, so we can always safely |
| 595 | // pack a single M value with the following 2 or 3 T bits. |
| 596 | uint8_t pack; |
| 597 | |
| 598 | // Element 0 |
| 599 | pack = (input_data[i++] & mask) | (((T >> 0) & 0x7) << bits); |
| 600 | write_bits(pack, bits + 3, bit_offset, output_data); |
| 601 | bit_offset += bits + 3; |
| 602 | |
| 603 | // Element 1 |
| 604 | pack = (input_data[i++] & mask) | (((T >> 3) & 0x3) << bits); |
| 605 | write_bits(pack, bits + 2, bit_offset, output_data); |
| 606 | bit_offset += bits + 2; |
| 607 | |
| 608 | // Element 2 |
| 609 | pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits); |
| 610 | write_bits(pack, bits + 2, bit_offset, output_data); |
| 611 | bit_offset += bits + 2; |
| 612 | } |
| 613 | |
| 614 | // Loop tail for a partial block |
| 615 | if (i != character_count) |
| 616 | { |
| 617 | // i2 cannot be present - we know the block is partial |
| 618 | // i0 must be present - we know the block isn't empty |
| 619 | unsigned int i2 = 0; |
| 620 | unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits; |
| 621 | unsigned int i0 = input_data[i + 0] >> bits; |
| 622 | |
| 623 | uint8_t T = integer_of_quints[i2][i1][i0]; |
| 624 | |
| 625 | for (unsigned int j = 0; i < character_count; i++, j++) |
| 626 | { |
| 627 | // Truncated table as this iteration is always partital |
| 628 | static const uint8_t tbits[2] { 3, 2 }; |
| 629 | static const uint8_t tshift[2] { 0, 3 }; |
| 630 | |
| 631 | uint8_t pack = (input_data[i] & mask) | |
| 632 | (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits); |
| 633 | |
| 634 | write_bits(pack, bits + tbits[j], bit_offset, output_data); |
| 635 | bit_offset += bits + tbits[j]; |
| 636 | } |
| 637 | } |
| 638 | } |
| 639 | // Write out just bits |
| 640 | else |
| 641 | { |
| 642 | for (unsigned int i = 0; i < character_count; i++) |
| 643 | { |
| 644 | write_bits(input_data[i], bits, bit_offset, output_data); |
| 645 | bit_offset += bits; |
| 646 | } |
| 647 | } |
| 648 | } |
| 649 | |
| 650 | /* See header for documentation. */ |
| 651 | void decode_ise( |
| 652 | quant_method quant_level, |
| 653 | unsigned int character_count, |
| 654 | const uint8_t* input_data, |
| 655 | uint8_t* output_data, |
| 656 | unsigned int bit_offset |
| 657 | ) { |
| 658 | promise(character_count > 0); |
| 659 | |
| 660 | // Note: due to how the trit/quint-block unpacking is done in this function, we may write more |
| 661 | // temporary results than the number of outputs. The maximum actual number of results is 64 bit, |
| 662 | // but we keep 4 additional character_count of padding. |
| 663 | uint8_t results[68]; |
| 664 | uint8_t tq_blocks[22] { 0 }; // Trit-blocks or quint-blocks, must be zeroed |
| 665 | |
| 666 | unsigned int bits = btq_counts[quant_level].bits; |
| 667 | unsigned int trits = btq_counts[quant_level].trits; |
| 668 | unsigned int quints = btq_counts[quant_level].quints; |
| 669 | |
| 670 | unsigned int lcounter = 0; |
| 671 | unsigned int hcounter = 0; |
| 672 | |
| 673 | // Collect bits for each element, as well as bits for any trit-blocks and quint-blocks. |
| 674 | for (unsigned int i = 0; i < character_count; i++) |
| 675 | { |
| 676 | results[i] = static_cast<uint8_t>(read_bits(bits, bit_offset, input_data)); |
| 677 | bit_offset += bits; |
| 678 | |
| 679 | if (trits) |
| 680 | { |
| 681 | static const uint8_t bits_to_read[5] { 2, 2, 1, 2, 1 }; |
| 682 | static const uint8_t block_shift[5] { 0, 2, 4, 5, 7 }; |
| 683 | static const uint8_t next_lcounter[5] { 1, 2, 3, 4, 0 }; |
| 684 | static const uint8_t hcounter_incr[5] { 0, 0, 0, 0, 1 }; |
| 685 | unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data); |
| 686 | bit_offset += bits_to_read[lcounter]; |
| 687 | tq_blocks[hcounter] |= tdata << block_shift[lcounter]; |
| 688 | hcounter += hcounter_incr[lcounter]; |
| 689 | lcounter = next_lcounter[lcounter]; |
| 690 | } |
| 691 | |
| 692 | if (quints) |
| 693 | { |
| 694 | static const uint8_t bits_to_read[3] { 3, 2, 2 }; |
| 695 | static const uint8_t block_shift[3] { 0, 3, 5 }; |
| 696 | static const uint8_t next_lcounter[3] { 1, 2, 0 }; |
| 697 | static const uint8_t hcounter_incr[3] { 0, 0, 1 }; |
| 698 | unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data); |
| 699 | bit_offset += bits_to_read[lcounter]; |
| 700 | tq_blocks[hcounter] |= tdata << block_shift[lcounter]; |
| 701 | hcounter += hcounter_incr[lcounter]; |
| 702 | lcounter = next_lcounter[lcounter]; |
| 703 | } |
| 704 | } |
| 705 | |
| 706 | // Unpack trit-blocks or quint-blocks as needed |
| 707 | if (trits) |
| 708 | { |
| 709 | unsigned int trit_blocks = (character_count + 4) / 5; |
| 710 | promise(trit_blocks > 0); |
| 711 | for (unsigned int i = 0; i < trit_blocks; i++) |
| 712 | { |
| 713 | const uint8_t *tritptr = trits_of_integer[tq_blocks[i]]; |
| 714 | results[5 * i ] |= tritptr[0] << bits; |
| 715 | results[5 * i + 1] |= tritptr[1] << bits; |
| 716 | results[5 * i + 2] |= tritptr[2] << bits; |
| 717 | results[5 * i + 3] |= tritptr[3] << bits; |
| 718 | results[5 * i + 4] |= tritptr[4] << bits; |
| 719 | } |
| 720 | } |
| 721 | |
| 722 | if (quints) |
| 723 | { |
| 724 | unsigned int quint_blocks = (character_count + 2) / 3; |
| 725 | promise(quint_blocks > 0); |
| 726 | for (unsigned int i = 0; i < quint_blocks; i++) |
| 727 | { |
| 728 | const uint8_t *quintptr = quints_of_integer[tq_blocks[i]]; |
| 729 | results[3 * i ] |= quintptr[0] << bits; |
| 730 | results[3 * i + 1] |= quintptr[1] << bits; |
| 731 | results[3 * i + 2] |= quintptr[2] << bits; |
| 732 | } |
| 733 | } |
| 734 | |
| 735 | for (unsigned int i = 0; i < character_count; i++) |
| 736 | { |
| 737 | output_data[i] = results[i]; |
| 738 | } |
| 739 | } |
| 740 | |