• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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