1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2020 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 "astc_codec_internals.h"
23
24 // unpacked quint triplets <low,middle,high> for each packed-quint value
25 static const uint8_t quints_of_integer[128][3] = {
26 {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0},
27 {4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4},
28 {0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0},
29 {4, 1, 0}, {1, 4, 0}, {4, 4, 1}, {4, 4, 4},
30 {0, 2, 0}, {1, 2, 0}, {2, 2, 0}, {3, 2, 0},
31 {4, 2, 0}, {2, 4, 0}, {4, 4, 2}, {4, 4, 4},
32 {0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {3, 3, 0},
33 {4, 3, 0}, {3, 4, 0}, {4, 4, 3}, {4, 4, 4},
34 {0, 0, 1}, {1, 0, 1}, {2, 0, 1}, {3, 0, 1},
35 {4, 0, 1}, {0, 4, 1}, {4, 0, 4}, {0, 4, 4},
36 {0, 1, 1}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1},
37 {4, 1, 1}, {1, 4, 1}, {4, 1, 4}, {1, 4, 4},
38 {0, 2, 1}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1},
39 {4, 2, 1}, {2, 4, 1}, {4, 2, 4}, {2, 4, 4},
40 {0, 3, 1}, {1, 3, 1}, {2, 3, 1}, {3, 3, 1},
41 {4, 3, 1}, {3, 4, 1}, {4, 3, 4}, {3, 4, 4},
42 {0, 0, 2}, {1, 0, 2}, {2, 0, 2}, {3, 0, 2},
43 {4, 0, 2}, {0, 4, 2}, {2, 0, 4}, {3, 0, 4},
44 {0, 1, 2}, {1, 1, 2}, {2, 1, 2}, {3, 1, 2},
45 {4, 1, 2}, {1, 4, 2}, {2, 1, 4}, {3, 1, 4},
46 {0, 2, 2}, {1, 2, 2}, {2, 2, 2}, {3, 2, 2},
47 {4, 2, 2}, {2, 4, 2}, {2, 2, 4}, {3, 2, 4},
48 {0, 3, 2}, {1, 3, 2}, {2, 3, 2}, {3, 3, 2},
49 {4, 3, 2}, {3, 4, 2}, {2, 3, 4}, {3, 3, 4},
50 {0, 0, 3}, {1, 0, 3}, {2, 0, 3}, {3, 0, 3},
51 {4, 0, 3}, {0, 4, 3}, {0, 0, 4}, {1, 0, 4},
52 {0, 1, 3}, {1, 1, 3}, {2, 1, 3}, {3, 1, 3},
53 {4, 1, 3}, {1, 4, 3}, {0, 1, 4}, {1, 1, 4},
54 {0, 2, 3}, {1, 2, 3}, {2, 2, 3}, {3, 2, 3},
55 {4, 2, 3}, {2, 4, 3}, {0, 2, 4}, {1, 2, 4},
56 {0, 3, 3}, {1, 3, 3}, {2, 3, 3}, {3, 3, 3},
57 {4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4}
58 };
59
60 // unpacked trit quintuplets <low,_,_,_,high> for each packed-quint value
61 static const uint8_t trits_of_integer[256][5] = {
62 {0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0},
63 {0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0},
64 {0, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {2, 2, 0, 0, 0}, {2, 0, 2, 0, 0},
65 {0, 2, 2, 0, 0}, {1, 2, 2, 0, 0}, {2, 2, 2, 0, 0}, {2, 0, 2, 0, 0},
66 {0, 0, 1, 0, 0}, {1, 0, 1, 0, 0}, {2, 0, 1, 0, 0}, {0, 1, 2, 0, 0},
67 {0, 1, 1, 0, 0}, {1, 1, 1, 0, 0}, {2, 1, 1, 0, 0}, {1, 1, 2, 0, 0},
68 {0, 2, 1, 0, 0}, {1, 2, 1, 0, 0}, {2, 2, 1, 0, 0}, {2, 1, 2, 0, 0},
69 {0, 0, 0, 2, 2}, {1, 0, 0, 2, 2}, {2, 0, 0, 2, 2}, {0, 0, 2, 2, 2},
70 {0, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, {2, 0, 0, 1, 0}, {0, 0, 2, 1, 0},
71 {0, 1, 0, 1, 0}, {1, 1, 0, 1, 0}, {2, 1, 0, 1, 0}, {1, 0, 2, 1, 0},
72 {0, 2, 0, 1, 0}, {1, 2, 0, 1, 0}, {2, 2, 0, 1, 0}, {2, 0, 2, 1, 0},
73 {0, 2, 2, 1, 0}, {1, 2, 2, 1, 0}, {2, 2, 2, 1, 0}, {2, 0, 2, 1, 0},
74 {0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {2, 0, 1, 1, 0}, {0, 1, 2, 1, 0},
75 {0, 1, 1, 1, 0}, {1, 1, 1, 1, 0}, {2, 1, 1, 1, 0}, {1, 1, 2, 1, 0},
76 {0, 2, 1, 1, 0}, {1, 2, 1, 1, 0}, {2, 2, 1, 1, 0}, {2, 1, 2, 1, 0},
77 {0, 1, 0, 2, 2}, {1, 1, 0, 2, 2}, {2, 1, 0, 2, 2}, {1, 0, 2, 2, 2},
78 {0, 0, 0, 2, 0}, {1, 0, 0, 2, 0}, {2, 0, 0, 2, 0}, {0, 0, 2, 2, 0},
79 {0, 1, 0, 2, 0}, {1, 1, 0, 2, 0}, {2, 1, 0, 2, 0}, {1, 0, 2, 2, 0},
80 {0, 2, 0, 2, 0}, {1, 2, 0, 2, 0}, {2, 2, 0, 2, 0}, {2, 0, 2, 2, 0},
81 {0, 2, 2, 2, 0}, {1, 2, 2, 2, 0}, {2, 2, 2, 2, 0}, {2, 0, 2, 2, 0},
82 {0, 0, 1, 2, 0}, {1, 0, 1, 2, 0}, {2, 0, 1, 2, 0}, {0, 1, 2, 2, 0},
83 {0, 1, 1, 2, 0}, {1, 1, 1, 2, 0}, {2, 1, 1, 2, 0}, {1, 1, 2, 2, 0},
84 {0, 2, 1, 2, 0}, {1, 2, 1, 2, 0}, {2, 2, 1, 2, 0}, {2, 1, 2, 2, 0},
85 {0, 2, 0, 2, 2}, {1, 2, 0, 2, 2}, {2, 2, 0, 2, 2}, {2, 0, 2, 2, 2},
86 {0, 0, 0, 0, 2}, {1, 0, 0, 0, 2}, {2, 0, 0, 0, 2}, {0, 0, 2, 0, 2},
87 {0, 1, 0, 0, 2}, {1, 1, 0, 0, 2}, {2, 1, 0, 0, 2}, {1, 0, 2, 0, 2},
88 {0, 2, 0, 0, 2}, {1, 2, 0, 0, 2}, {2, 2, 0, 0, 2}, {2, 0, 2, 0, 2},
89 {0, 2, 2, 0, 2}, {1, 2, 2, 0, 2}, {2, 2, 2, 0, 2}, {2, 0, 2, 0, 2},
90 {0, 0, 1, 0, 2}, {1, 0, 1, 0, 2}, {2, 0, 1, 0, 2}, {0, 1, 2, 0, 2},
91 {0, 1, 1, 0, 2}, {1, 1, 1, 0, 2}, {2, 1, 1, 0, 2}, {1, 1, 2, 0, 2},
92 {0, 2, 1, 0, 2}, {1, 2, 1, 0, 2}, {2, 2, 1, 0, 2}, {2, 1, 2, 0, 2},
93 {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 0, 2, 2, 2},
94 {0, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {2, 0, 0, 0, 1}, {0, 0, 2, 0, 1},
95 {0, 1, 0, 0, 1}, {1, 1, 0, 0, 1}, {2, 1, 0, 0, 1}, {1, 0, 2, 0, 1},
96 {0, 2, 0, 0, 1}, {1, 2, 0, 0, 1}, {2, 2, 0, 0, 1}, {2, 0, 2, 0, 1},
97 {0, 2, 2, 0, 1}, {1, 2, 2, 0, 1}, {2, 2, 2, 0, 1}, {2, 0, 2, 0, 1},
98 {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {2, 0, 1, 0, 1}, {0, 1, 2, 0, 1},
99 {0, 1, 1, 0, 1}, {1, 1, 1, 0, 1}, {2, 1, 1, 0, 1}, {1, 1, 2, 0, 1},
100 {0, 2, 1, 0, 1}, {1, 2, 1, 0, 1}, {2, 2, 1, 0, 1}, {2, 1, 2, 0, 1},
101 {0, 0, 1, 2, 2}, {1, 0, 1, 2, 2}, {2, 0, 1, 2, 2}, {0, 1, 2, 2, 2},
102 {0, 0, 0, 1, 1}, {1, 0, 0, 1, 1}, {2, 0, 0, 1, 1}, {0, 0, 2, 1, 1},
103 {0, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 0, 1, 1}, {1, 0, 2, 1, 1},
104 {0, 2, 0, 1, 1}, {1, 2, 0, 1, 1}, {2, 2, 0, 1, 1}, {2, 0, 2, 1, 1},
105 {0, 2, 2, 1, 1}, {1, 2, 2, 1, 1}, {2, 2, 2, 1, 1}, {2, 0, 2, 1, 1},
106 {0, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {2, 0, 1, 1, 1}, {0, 1, 2, 1, 1},
107 {0, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {2, 1, 1, 1, 1}, {1, 1, 2, 1, 1},
108 {0, 2, 1, 1, 1}, {1, 2, 1, 1, 1}, {2, 2, 1, 1, 1}, {2, 1, 2, 1, 1},
109 {0, 1, 1, 2, 2}, {1, 1, 1, 2, 2}, {2, 1, 1, 2, 2}, {1, 1, 2, 2, 2},
110 {0, 0, 0, 2, 1}, {1, 0, 0, 2, 1}, {2, 0, 0, 2, 1}, {0, 0, 2, 2, 1},
111 {0, 1, 0, 2, 1}, {1, 1, 0, 2, 1}, {2, 1, 0, 2, 1}, {1, 0, 2, 2, 1},
112 {0, 2, 0, 2, 1}, {1, 2, 0, 2, 1}, {2, 2, 0, 2, 1}, {2, 0, 2, 2, 1},
113 {0, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {2, 2, 2, 2, 1}, {2, 0, 2, 2, 1},
114 {0, 0, 1, 2, 1}, {1, 0, 1, 2, 1}, {2, 0, 1, 2, 1}, {0, 1, 2, 2, 1},
115 {0, 1, 1, 2, 1}, {1, 1, 1, 2, 1}, {2, 1, 1, 2, 1}, {1, 1, 2, 2, 1},
116 {0, 2, 1, 2, 1}, {1, 2, 1, 2, 1}, {2, 2, 1, 2, 1}, {2, 1, 2, 2, 1},
117 {0, 2, 1, 2, 2}, {1, 2, 1, 2, 2}, {2, 2, 1, 2, 2}, {2, 1, 2, 2, 2},
118 {0, 0, 0, 1, 2}, {1, 0, 0, 1, 2}, {2, 0, 0, 1, 2}, {0, 0, 2, 1, 2},
119 {0, 1, 0, 1, 2}, {1, 1, 0, 1, 2}, {2, 1, 0, 1, 2}, {1, 0, 2, 1, 2},
120 {0, 2, 0, 1, 2}, {1, 2, 0, 1, 2}, {2, 2, 0, 1, 2}, {2, 0, 2, 1, 2},
121 {0, 2, 2, 1, 2}, {1, 2, 2, 1, 2}, {2, 2, 2, 1, 2}, {2, 0, 2, 1, 2},
122 {0, 0, 1, 1, 2}, {1, 0, 1, 1, 2}, {2, 0, 1, 1, 2}, {0, 1, 2, 1, 2},
123 {0, 1, 1, 1, 2}, {1, 1, 1, 1, 2}, {2, 1, 1, 1, 2}, {1, 1, 2, 1, 2},
124 {0, 2, 1, 1, 2}, {1, 2, 1, 1, 2}, {2, 2, 1, 1, 2}, {2, 1, 2, 1, 2},
125 {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2}
126 };
127
find_number_of_bits_trits_quints(int quantization_level,int * bits,int * trits,int * quints)128 void find_number_of_bits_trits_quints(
129 int quantization_level,
130 int* bits,
131 int* trits,
132 int* quints
133 ) {
134 *bits = 0;
135 *trits = 0;
136 *quints = 0;
137 switch (quantization_level)
138 {
139 case QUANT_2:
140 *bits = 1;
141 break;
142 case QUANT_3:
143 *bits = 0;
144 *trits = 1;
145 break;
146 case QUANT_4:
147 *bits = 2;
148 break;
149 case QUANT_5:
150 *bits = 0;
151 *quints = 1;
152 break;
153 case QUANT_6:
154 *bits = 1;
155 *trits = 1;
156 break;
157 case QUANT_8:
158 *bits = 3;
159 break;
160 case QUANT_10:
161 *bits = 1;
162 *quints = 1;
163 break;
164 case QUANT_12:
165 *bits = 2;
166 *trits = 1;
167 break;
168 case QUANT_16:
169 *bits = 4;
170 break;
171 case QUANT_20:
172 *bits = 2;
173 *quints = 1;
174 break;
175 case QUANT_24:
176 *bits = 3;
177 *trits = 1;
178 break;
179 case QUANT_32:
180 *bits = 5;
181 break;
182 case QUANT_40:
183 *bits = 3;
184 *quints = 1;
185 break;
186 case QUANT_48:
187 *bits = 4;
188 *trits = 1;
189 break;
190 case QUANT_64:
191 *bits = 6;
192 break;
193 case QUANT_80:
194 *bits = 4;
195 *quints = 1;
196 break;
197 case QUANT_96:
198 *bits = 5;
199 *trits = 1;
200 break;
201 case QUANT_128:
202 *bits = 7;
203 break;
204 case QUANT_160:
205 *bits = 5;
206 *quints = 1;
207 break;
208 case QUANT_192:
209 *bits = 6;
210 *trits = 1;
211 break;
212 case QUANT_256:
213 *bits = 8;
214 break;
215 }
216 }
217
218 // routine to read up to 8 bits
read_bits(int bitcount,int bitoffset,const uint8_t * ptr)219 static inline int read_bits(
220 int bitcount,
221 int bitoffset,
222 const uint8_t* ptr
223 ) {
224 int mask = (1 << bitcount) - 1;
225 ptr += bitoffset >> 3;
226 bitoffset &= 7;
227 int value = ptr[0] | (ptr[1] << 8);
228 value >>= bitoffset;
229 value &= mask;
230 return value;
231 }
232
decode_ise(int quantization_level,int elements,const uint8_t * input_data,uint8_t * output_data,int bit_offset)233 void decode_ise(
234 int quantization_level,
235 int elements,
236 const uint8_t* input_data,
237 uint8_t* output_data,
238 int bit_offset
239 ) {
240 int i;
241 // note: due to how the trit/quint-block unpacking is done in this function,
242 // we may write more temporary results than the number of outputs
243 // The maximum actual number of results is 64 bit, but we keep 4 additional elements
244 // of padding.
245 uint8_t results[68];
246 uint8_t tq_blocks[22]; // trit-blocks or quint-blocks
247
248 int bits, trits, quints;
249 find_number_of_bits_trits_quints(quantization_level, &bits, &trits, &quints);
250
251 int lcounter = 0;
252 int hcounter = 0;
253
254 // trit-blocks or quint-blocks must be zeroed out before we collect them in the loop below.
255 for (i = 0; i < 22; i++)
256 tq_blocks[i] = 0;
257
258 // collect bits for each element, as well as bits for any trit-blocks and quint-blocks.
259 for (i = 0; i < elements; i++)
260 {
261 results[i] = read_bits(bits, bit_offset, input_data);
262 bit_offset += bits;
263
264 if (trits)
265 {
266 static const int bits_to_read[5] = { 2, 2, 1, 2, 1 };
267 static const int block_shift[5] = { 0, 2, 4, 5, 7 };
268 static const int next_lcounter[5] = { 1, 2, 3, 4, 0 };
269 static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 };
270 int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
271 bit_offset += bits_to_read[lcounter];
272 tq_blocks[hcounter] |= tdata << block_shift[lcounter];
273 hcounter += hcounter_incr[lcounter];
274 lcounter = next_lcounter[lcounter];
275 }
276
277 if (quints)
278 {
279 static const int bits_to_read[3] = { 3, 2, 2 };
280 static const int block_shift[3] = { 0, 3, 5 };
281 static const int next_lcounter[3] = { 1, 2, 0 };
282 static const int hcounter_incr[3] = { 0, 0, 1 };
283 int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
284 bit_offset += bits_to_read[lcounter];
285 tq_blocks[hcounter] |= tdata << block_shift[lcounter];
286 hcounter += hcounter_incr[lcounter];
287 lcounter = next_lcounter[lcounter];
288 }
289 }
290
291 // unpack trit-blocks or quint-blocks as needed
292 if (trits)
293 {
294 int trit_blocks = (elements + 4) / 5;
295 for (i = 0; i < trit_blocks; i++)
296 {
297 const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];
298 results[5 * i] |= tritptr[0] << bits;
299 results[5 * i + 1] |= tritptr[1] << bits;
300 results[5 * i + 2] |= tritptr[2] << bits;
301 results[5 * i + 3] |= tritptr[3] << bits;
302 results[5 * i + 4] |= tritptr[4] << bits;
303 }
304 }
305
306 if (quints)
307 {
308 int quint_blocks = (elements + 2) / 3;
309 for (i = 0; i < quint_blocks; i++)
310 {
311 const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];
312 results[3 * i] |= quintptr[0] << bits;
313 results[3 * i + 1] |= quintptr[1] << bits;
314 results[3 * i + 2] |= quintptr[2] << bits;
315 }
316 }
317
318 for (i = 0; i < elements; i++)
319 output_data[i] = results[i];
320 }
321
compute_ise_bitcount(int items,quantization_method quant)322 int compute_ise_bitcount(
323 int items,
324 quantization_method quant
325 ) {
326 switch (quant)
327 {
328 case QUANT_2:
329 return items;
330 case QUANT_3:
331 return (8 * items + 4) / 5;
332 case QUANT_4:
333 return 2 * items;
334 case QUANT_5:
335 return (7 * items + 2) / 3;
336 case QUANT_6:
337 return (13 * items + 4) / 5;
338 case QUANT_8:
339 return 3 * items;
340 case QUANT_10:
341 return (10 * items + 2) / 3;
342 case QUANT_12:
343 return (18 * items + 4) / 5;
344 case QUANT_16:
345 return items * 4;
346 case QUANT_20:
347 return (13 * items + 2) / 3;
348 case QUANT_24:
349 return (23 * items + 4) / 5;
350 case QUANT_32:
351 return 5 * items;
352 case QUANT_40:
353 return (16 * items + 2) / 3;
354 case QUANT_48:
355 return (28 * items + 4) / 5;
356 case QUANT_64:
357 return 6 * items;
358 case QUANT_80:
359 return (19 * items + 2) / 3;
360 case QUANT_96:
361 return (33 * items + 4) / 5;
362 case QUANT_128:
363 return 7 * items;
364 case QUANT_160:
365 return (22 * items + 2) / 3;
366 case QUANT_192:
367 return (38 * items + 4) / 5;
368 case QUANT_256:
369 return 8 * items;
370 default:
371 return 100000;
372 }
373 }
374