• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. */
get_ise_sequence_bitcount(unsigned int character_count,quant_method quant_level)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  */
write_bits(unsigned int value,unsigned int bitcount,unsigned int bitoffset,uint8_t ptr[2])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  */
read_bits(unsigned int bitcount,unsigned int bitoffset,const uint8_t * ptr)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. */
encode_ise(quant_method quant_level,unsigned int character_count,const uint8_t * input_data,uint8_t * output_data,unsigned int bit_offset)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. */
decode_ise(quant_method quant_level,unsigned int character_count,const uint8_t * input_data,uint8_t * output_data,unsigned int bit_offset)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