1 /*----------------------------------------------------------------------------*/
2 /**
3  *	This confidential and proprietary software may be used only as
4  *	authorised by a licensing agreement from ARM Limited
5  *	(C) COPYRIGHT 2011-2012 ARM Limited
6  *	ALL RIGHTS RESERVED
7  *
8  *	The entire notice above must be reproduced on all authorised
9  *	copies and copies may only be made to the extent permitted
10  *	by a licensing agreement from ARM Limited.
11  *
12  *	@brief	Functions to encode/decode data using Bounded Integer Sequence
13  *			Encoding.
14  */
15 /*----------------------------------------------------------------------------*/
16 #include "astc_codec_internals.h"
17 	// unpacked quint triplets <low,middle,high> for each packed-quint value
18 static const uint8_t quints_of_integer[128][3] = {
19 	{0, 0, 0},	{1, 0, 0},	{2, 0, 0},	{3, 0, 0},
20 	{4, 0, 0},	{0, 4, 0},	{4, 4, 0},	{4, 4, 4},
21 	{0, 1, 0},	{1, 1, 0},	{2, 1, 0},	{3, 1, 0},
22 	{4, 1, 0},	{1, 4, 0},	{4, 4, 1},	{4, 4, 4},
23 	{0, 2, 0},	{1, 2, 0},	{2, 2, 0},	{3, 2, 0},
24 	{4, 2, 0},	{2, 4, 0},	{4, 4, 2},	{4, 4, 4},
25 	{0, 3, 0},	{1, 3, 0},	{2, 3, 0},	{3, 3, 0},
26 	{4, 3, 0},	{3, 4, 0},	{4, 4, 3},	{4, 4, 4},
27 	{0, 0, 1},	{1, 0, 1},	{2, 0, 1},	{3, 0, 1},
28 	{4, 0, 1},	{0, 4, 1},	{4, 0, 4},	{0, 4, 4},
29 	{0, 1, 1},	{1, 1, 1},	{2, 1, 1},	{3, 1, 1},
30 	{4, 1, 1},	{1, 4, 1},	{4, 1, 4},	{1, 4, 4},
31 	{0, 2, 1},	{1, 2, 1},	{2, 2, 1},	{3, 2, 1},
32 	{4, 2, 1},	{2, 4, 1},	{4, 2, 4},	{2, 4, 4},
33 	{0, 3, 1},	{1, 3, 1},	{2, 3, 1},	{3, 3, 1},
34 	{4, 3, 1},	{3, 4, 1},	{4, 3, 4},	{3, 4, 4},
35 	{0, 0, 2},	{1, 0, 2},	{2, 0, 2},	{3, 0, 2},
36 	{4, 0, 2},	{0, 4, 2},	{2, 0, 4},	{3, 0, 4},
37 	{0, 1, 2},	{1, 1, 2},	{2, 1, 2},	{3, 1, 2},
38 	{4, 1, 2},	{1, 4, 2},	{2, 1, 4},	{3, 1, 4},
39 	{0, 2, 2},	{1, 2, 2},	{2, 2, 2},	{3, 2, 2},
40 	{4, 2, 2},	{2, 4, 2},	{2, 2, 4},	{3, 2, 4},
41 	{0, 3, 2},	{1, 3, 2},	{2, 3, 2},	{3, 3, 2},
42 	{4, 3, 2},	{3, 4, 2},	{2, 3, 4},	{3, 3, 4},
43 	{0, 0, 3},	{1, 0, 3},	{2, 0, 3},	{3, 0, 3},
44 	{4, 0, 3},	{0, 4, 3},	{0, 0, 4},	{1, 0, 4},
45 	{0, 1, 3},	{1, 1, 3},	{2, 1, 3},	{3, 1, 3},
46 	{4, 1, 3},	{1, 4, 3},	{0, 1, 4},	{1, 1, 4},
47 	{0, 2, 3},	{1, 2, 3},	{2, 2, 3},	{3, 2, 3},
48 	{4, 2, 3},	{2, 4, 3},	{0, 2, 4},	{1, 2, 4},
49 	{0, 3, 3},	{1, 3, 3},	{2, 3, 3},	{3, 3, 3},
50 	{4, 3, 3},	{3, 4, 3},	{0, 3, 4},	{1, 3, 4},
51 };
52 
53 // packed quint-value for every unpacked quint-triplet
54 // indexed by [high][middle][low]
55 static const uint8_t integer_of_quints[5][5][5] = {
56 	{
57 	 {0, 1, 2, 3, 4,},
58 	 {8, 9, 10, 11, 12,},
59 	 {16, 17, 18, 19, 20,},
60 	 {24, 25, 26, 27, 28,},
61 	 {5, 13, 21, 29, 6,},
62 	 },
63 	{
64 	 {32, 33, 34, 35, 36,},
65 	 {40, 41, 42, 43, 44,},
66 	 {48, 49, 50, 51, 52,},
67 	 {56, 57, 58, 59, 60,},
68 	 {37, 45, 53, 61, 14,},
69 	 },
70 	{
71 	 {64, 65, 66, 67, 68,},
72 	 {72, 73, 74, 75, 76,},
73 	 {80, 81, 82, 83, 84,},
74 	 {88, 89, 90, 91, 92,},
75 	 {69, 77, 85, 93, 22,},
76 	 },
77 	{
78 	 {96, 97, 98, 99, 100,},
79 	 {104, 105, 106, 107, 108,},
80 	 {112, 113, 114, 115, 116,},
81 	 {120, 121, 122, 123, 124,},
82 	 {101, 109, 117, 125, 30,},
83 	 },
84 	{
85 	 {102, 103, 70, 71, 38,},
86 	 {110, 111, 78, 79, 46,},
87 	 {118, 119, 86, 87, 54,},
88 	 {126, 127, 94, 95, 62,},
89 	 {39, 47, 55, 63, 31,},
90 	 },
91 };
92 
93 // unpacked trit quintuplets <low,_,_,_,high> for each packed-quint value
94 static const uint8_t trits_of_integer[256][5] = {
95 	{0, 0, 0, 0, 0},	{1, 0, 0, 0, 0},	{2, 0, 0, 0, 0},	{0, 0, 2, 0, 0},
96 	{0, 1, 0, 0, 0},	{1, 1, 0, 0, 0},	{2, 1, 0, 0, 0},	{1, 0, 2, 0, 0},
97 	{0, 2, 0, 0, 0},	{1, 2, 0, 0, 0},	{2, 2, 0, 0, 0},	{2, 0, 2, 0, 0},
98 	{0, 2, 2, 0, 0},	{1, 2, 2, 0, 0},	{2, 2, 2, 0, 0},	{2, 0, 2, 0, 0},
99 	{0, 0, 1, 0, 0},	{1, 0, 1, 0, 0},	{2, 0, 1, 0, 0},	{0, 1, 2, 0, 0},
100 	{0, 1, 1, 0, 0},	{1, 1, 1, 0, 0},	{2, 1, 1, 0, 0},	{1, 1, 2, 0, 0},
101 	{0, 2, 1, 0, 0},	{1, 2, 1, 0, 0},	{2, 2, 1, 0, 0},	{2, 1, 2, 0, 0},
102 	{0, 0, 0, 2, 2},	{1, 0, 0, 2, 2},	{2, 0, 0, 2, 2},	{0, 0, 2, 2, 2},
103 	{0, 0, 0, 1, 0},	{1, 0, 0, 1, 0},	{2, 0, 0, 1, 0},	{0, 0, 2, 1, 0},
104 	{0, 1, 0, 1, 0},	{1, 1, 0, 1, 0},	{2, 1, 0, 1, 0},	{1, 0, 2, 1, 0},
105 	{0, 2, 0, 1, 0},	{1, 2, 0, 1, 0},	{2, 2, 0, 1, 0},	{2, 0, 2, 1, 0},
106 	{0, 2, 2, 1, 0},	{1, 2, 2, 1, 0},	{2, 2, 2, 1, 0},	{2, 0, 2, 1, 0},
107 	{0, 0, 1, 1, 0},	{1, 0, 1, 1, 0},	{2, 0, 1, 1, 0},	{0, 1, 2, 1, 0},
108 	{0, 1, 1, 1, 0},	{1, 1, 1, 1, 0},	{2, 1, 1, 1, 0},	{1, 1, 2, 1, 0},
109 	{0, 2, 1, 1, 0},	{1, 2, 1, 1, 0},	{2, 2, 1, 1, 0},	{2, 1, 2, 1, 0},
110 	{0, 1, 0, 2, 2},	{1, 1, 0, 2, 2},	{2, 1, 0, 2, 2},	{1, 0, 2, 2, 2},
111 	{0, 0, 0, 2, 0},	{1, 0, 0, 2, 0},	{2, 0, 0, 2, 0},	{0, 0, 2, 2, 0},
112 	{0, 1, 0, 2, 0},	{1, 1, 0, 2, 0},	{2, 1, 0, 2, 0},	{1, 0, 2, 2, 0},
113 	{0, 2, 0, 2, 0},	{1, 2, 0, 2, 0},	{2, 2, 0, 2, 0},	{2, 0, 2, 2, 0},
114 	{0, 2, 2, 2, 0},	{1, 2, 2, 2, 0},	{2, 2, 2, 2, 0},	{2, 0, 2, 2, 0},
115 	{0, 0, 1, 2, 0},	{1, 0, 1, 2, 0},	{2, 0, 1, 2, 0},	{0, 1, 2, 2, 0},
116 	{0, 1, 1, 2, 0},	{1, 1, 1, 2, 0},	{2, 1, 1, 2, 0},	{1, 1, 2, 2, 0},
117 	{0, 2, 1, 2, 0},	{1, 2, 1, 2, 0},	{2, 2, 1, 2, 0},	{2, 1, 2, 2, 0},
118 	{0, 2, 0, 2, 2},	{1, 2, 0, 2, 2},	{2, 2, 0, 2, 2},	{2, 0, 2, 2, 2},
119 	{0, 0, 0, 0, 2},	{1, 0, 0, 0, 2},	{2, 0, 0, 0, 2},	{0, 0, 2, 0, 2},
120 	{0, 1, 0, 0, 2},	{1, 1, 0, 0, 2},	{2, 1, 0, 0, 2},	{1, 0, 2, 0, 2},
121 	{0, 2, 0, 0, 2},	{1, 2, 0, 0, 2},	{2, 2, 0, 0, 2},	{2, 0, 2, 0, 2},
122 	{0, 2, 2, 0, 2},	{1, 2, 2, 0, 2},	{2, 2, 2, 0, 2},	{2, 0, 2, 0, 2},
123 	{0, 0, 1, 0, 2},	{1, 0, 1, 0, 2},	{2, 0, 1, 0, 2},	{0, 1, 2, 0, 2},
124 	{0, 1, 1, 0, 2},	{1, 1, 1, 0, 2},	{2, 1, 1, 0, 2},	{1, 1, 2, 0, 2},
125 	{0, 2, 1, 0, 2},	{1, 2, 1, 0, 2},	{2, 2, 1, 0, 2},	{2, 1, 2, 0, 2},
126 	{0, 2, 2, 2, 2},	{1, 2, 2, 2, 2},	{2, 2, 2, 2, 2},	{2, 0, 2, 2, 2},
127 	{0, 0, 0, 0, 1},	{1, 0, 0, 0, 1},	{2, 0, 0, 0, 1},	{0, 0, 2, 0, 1},
128 	{0, 1, 0, 0, 1},	{1, 1, 0, 0, 1},	{2, 1, 0, 0, 1},	{1, 0, 2, 0, 1},
129 	{0, 2, 0, 0, 1},	{1, 2, 0, 0, 1},	{2, 2, 0, 0, 1},	{2, 0, 2, 0, 1},
130 	{0, 2, 2, 0, 1},	{1, 2, 2, 0, 1},	{2, 2, 2, 0, 1},	{2, 0, 2, 0, 1},
131 	{0, 0, 1, 0, 1},	{1, 0, 1, 0, 1},	{2, 0, 1, 0, 1},	{0, 1, 2, 0, 1},
132 	{0, 1, 1, 0, 1},	{1, 1, 1, 0, 1},	{2, 1, 1, 0, 1},	{1, 1, 2, 0, 1},
133 	{0, 2, 1, 0, 1},	{1, 2, 1, 0, 1},	{2, 2, 1, 0, 1},	{2, 1, 2, 0, 1},
134 	{0, 0, 1, 2, 2},	{1, 0, 1, 2, 2},	{2, 0, 1, 2, 2},	{0, 1, 2, 2, 2},
135 	{0, 0, 0, 1, 1},	{1, 0, 0, 1, 1},	{2, 0, 0, 1, 1},	{0, 0, 2, 1, 1},
136 	{0, 1, 0, 1, 1},	{1, 1, 0, 1, 1},	{2, 1, 0, 1, 1},	{1, 0, 2, 1, 1},
137 	{0, 2, 0, 1, 1},	{1, 2, 0, 1, 1},	{2, 2, 0, 1, 1},	{2, 0, 2, 1, 1},
138 	{0, 2, 2, 1, 1},	{1, 2, 2, 1, 1},	{2, 2, 2, 1, 1},	{2, 0, 2, 1, 1},
139 	{0, 0, 1, 1, 1},	{1, 0, 1, 1, 1},	{2, 0, 1, 1, 1},	{0, 1, 2, 1, 1},
140 	{0, 1, 1, 1, 1},	{1, 1, 1, 1, 1},	{2, 1, 1, 1, 1},	{1, 1, 2, 1, 1},
141 	{0, 2, 1, 1, 1},	{1, 2, 1, 1, 1},	{2, 2, 1, 1, 1},	{2, 1, 2, 1, 1},
142 	{0, 1, 1, 2, 2},	{1, 1, 1, 2, 2},	{2, 1, 1, 2, 2},	{1, 1, 2, 2, 2},
143 	{0, 0, 0, 2, 1},	{1, 0, 0, 2, 1},	{2, 0, 0, 2, 1},	{0, 0, 2, 2, 1},
144 	{0, 1, 0, 2, 1},	{1, 1, 0, 2, 1},	{2, 1, 0, 2, 1},	{1, 0, 2, 2, 1},
145 	{0, 2, 0, 2, 1},	{1, 2, 0, 2, 1},	{2, 2, 0, 2, 1},	{2, 0, 2, 2, 1},
146 	{0, 2, 2, 2, 1},	{1, 2, 2, 2, 1},	{2, 2, 2, 2, 1},	{2, 0, 2, 2, 1},
147 	{0, 0, 1, 2, 1},	{1, 0, 1, 2, 1},	{2, 0, 1, 2, 1},	{0, 1, 2, 2, 1},
148 	{0, 1, 1, 2, 1},	{1, 1, 1, 2, 1},	{2, 1, 1, 2, 1},	{1, 1, 2, 2, 1},
149 	{0, 2, 1, 2, 1},	{1, 2, 1, 2, 1},	{2, 2, 1, 2, 1},	{2, 1, 2, 2, 1},
150 	{0, 2, 1, 2, 2},	{1, 2, 1, 2, 2},	{2, 2, 1, 2, 2},	{2, 1, 2, 2, 2},
151 	{0, 0, 0, 1, 2},	{1, 0, 0, 1, 2},	{2, 0, 0, 1, 2},	{0, 0, 2, 1, 2},
152 	{0, 1, 0, 1, 2},	{1, 1, 0, 1, 2},	{2, 1, 0, 1, 2},	{1, 0, 2, 1, 2},
153 	{0, 2, 0, 1, 2},	{1, 2, 0, 1, 2},	{2, 2, 0, 1, 2},	{2, 0, 2, 1, 2},
154 	{0, 2, 2, 1, 2},	{1, 2, 2, 1, 2},	{2, 2, 2, 1, 2},	{2, 0, 2, 1, 2},
155 	{0, 0, 1, 1, 2},	{1, 0, 1, 1, 2},	{2, 0, 1, 1, 2},	{0, 1, 2, 1, 2},
156 	{0, 1, 1, 1, 2},	{1, 1, 1, 1, 2},	{2, 1, 1, 1, 2},	{1, 1, 2, 1, 2},
157 	{0, 2, 1, 1, 2},	{1, 2, 1, 1, 2},	{2, 2, 1, 1, 2},	{2, 1, 2, 1, 2},
158 	{0, 2, 2, 2, 2},	{1, 2, 2, 2, 2},	{2, 2, 2, 2, 2},	{2, 1, 2, 2, 2},
159 };
160 
161 // packed trit-value for every unpacked trit-quintuplet
162 // indexed by [high][][][][low]
163 static const uint8_t integer_of_trits[3][3][3][3][3] = {
164 	{
165 	 {
166 	  {
167 	   {0, 1, 2,},
168 	   {4, 5, 6,},
169 	   {8, 9, 10,},
170 	   },
171 	  {
172 	   {16, 17, 18,},
173 	   {20, 21, 22,},
174 	   {24, 25, 26,},
175 	   },
176 	  {
177 	   {3, 7, 15,},
178 	   {19, 23, 27,},
179 	   {12, 13, 14,},
180 	   },
181 	  },
182 	 {
183 	  {
184 	   {32, 33, 34,},
185 	   {36, 37, 38,},
186 	   {40, 41, 42,},
187 	   },
188 	  {
189 	   {48, 49, 50,},
190 	   {52, 53, 54,},
191 	   {56, 57, 58,},
192 	   },
193 	  {
194 	   {35, 39, 47,},
195 	   {51, 55, 59,},
196 	   {44, 45, 46,},
197 	   },
198 	  },
199 	 {
200 	  {
201 	   {64, 65, 66,},
202 	   {68, 69, 70,},
203 	   {72, 73, 74,},
204 	   },
205 	  {
206 	   {80, 81, 82,},
207 	   {84, 85, 86,},
208 	   {88, 89, 90,},
209 	   },
210 	  {
211 	   {67, 71, 79,},
212 	   {83, 87, 91,},
213 	   {76, 77, 78,},
214 	   },
215 	  },
216 	 },
217 	{
218 	 {
219 	  {
220 	   {128, 129, 130,},
221 	   {132, 133, 134,},
222 	   {136, 137, 138,},
223 	   },
224 	  {
225 	   {144, 145, 146,},
226 	   {148, 149, 150,},
227 	   {152, 153, 154,},
228 	   },
229 	  {
230 	   {131, 135, 143,},
231 	   {147, 151, 155,},
232 	   {140, 141, 142,},
233 	   },
234 	  },
235 	 {
236 	  {
237 	   {160, 161, 162,},
238 	   {164, 165, 166,},
239 	   {168, 169, 170,},
240 	   },
241 	  {
242 	   {176, 177, 178,},
243 	   {180, 181, 182,},
244 	   {184, 185, 186,},
245 	   },
246 	  {
247 	   {163, 167, 175,},
248 	   {179, 183, 187,},
249 	   {172, 173, 174,},
250 	   },
251 	  },
252 	 {
253 	  {
254 	   {192, 193, 194,},
255 	   {196, 197, 198,},
256 	   {200, 201, 202,},
257 	   },
258 	  {
259 	   {208, 209, 210,},
260 	   {212, 213, 214,},
261 	   {216, 217, 218,},
262 	   },
263 	  {
264 	   {195, 199, 207,},
265 	   {211, 215, 219,},
266 	   {204, 205, 206,},
267 	   },
268 	  },
269 	 },
270 	{
271 	 {
272 	  {
273 	   {96, 97, 98,},
274 	   {100, 101, 102,},
275 	   {104, 105, 106,},
276 	   },
277 	  {
278 	   {112, 113, 114,},
279 	   {116, 117, 118,},
280 	   {120, 121, 122,},
281 	   },
282 	  {
283 	   {99, 103, 111,},
284 	   {115, 119, 123,},
285 	   {108, 109, 110,},
286 	   },
287 	  },
288 	 {
289 	  {
290 	   {224, 225, 226,},
291 	   {228, 229, 230,},
292 	   {232, 233, 234,},
293 	   },
294 	  {
295 	   {240, 241, 242,},
296 	   {244, 245, 246,},
297 	   {248, 249, 250,},
298 	   },
299 	  {
300 	   {227, 231, 239,},
301 	   {243, 247, 251,},
302 	   {236, 237, 238,},
303 	   },
304 	  },
305 	 {
306 	  {
307 	   {28, 29, 30,},
308 	   {60, 61, 62,},
309 	   {92, 93, 94,},
310 	   },
311 	  {
312 	   {156, 157, 158,},
313 	   {188, 189, 190,},
314 	   {220, 221, 222,},
315 	   },
316 	  {
317 	   {31, 63, 127,},
318 	   {159, 191, 255,},
319 	   {252, 253, 254,},
320 	   },
321 	  },
322 	 },
323 };
324 
325 
326 
find_number_of_bits_trits_quints(int quantization_level,int * bits,int * trits,int * quints)327 void find_number_of_bits_trits_quints(int quantization_level, int *bits, int *trits, int *quints)
328 {
329 	*bits = 0;
330 	*trits = 0;
331 	*quints = 0;
332 	switch (quantization_level)
333 	{
334 	case QUANT_2:
335 		*bits = 1;
336 		break;
337 	case QUANT_3:
338 		*bits = 0;
339 		*trits = 1;
340 		break;
341 	case QUANT_4:
342 		*bits = 2;
343 		break;
344 	case QUANT_5:
345 		*bits = 0;
346 		*quints = 1;
347 		break;
348 	case QUANT_6:
349 		*bits = 1;
350 		*trits = 1;
351 		break;
352 	case QUANT_8:
353 		*bits = 3;
354 		break;
355 	case QUANT_10:
356 		*bits = 1;
357 		*quints = 1;
358 		break;
359 	case QUANT_12:
360 		*bits = 2;
361 		*trits = 1;
362 		break;
363 	case QUANT_16:
364 		*bits = 4;
365 		break;
366 	case QUANT_20:
367 		*bits = 2;
368 		*quints = 1;
369 		break;
370 	case QUANT_24:
371 		*bits = 3;
372 		*trits = 1;
373 		break;
374 	case QUANT_32:
375 		*bits = 5;
376 		break;
377 	case QUANT_40:
378 		*bits = 3;
379 		*quints = 1;
380 		break;
381 	case QUANT_48:
382 		*bits = 4;
383 		*trits = 1;
384 		break;
385 	case QUANT_64:
386 		*bits = 6;
387 		break;
388 	case QUANT_80:
389 		*bits = 4;
390 		*quints = 1;
391 		break;
392 	case QUANT_96:
393 		*bits = 5;
394 		*trits = 1;
395 		break;
396 	case QUANT_128:
397 		*bits = 7;
398 		break;
399 	case QUANT_160:
400 		*bits = 5;
401 		*quints = 1;
402 		break;
403 	case QUANT_192:
404 		*bits = 6;
405 		*trits = 1;
406 		break;
407 	case QUANT_256:
408 		*bits = 8;
409 		break;
410 	}
411 }
412 
413 
414 // routine to write up to 8 bits
write_bits(int value,int bitcount,int bitoffset,uint8_t * ptr)415 static inline void write_bits(int value, int bitcount, int bitoffset, uint8_t * ptr)
416 {
417 	int mask = (1 << bitcount) - 1;
418 	value &= mask;
419 	ptr += bitoffset >> 3;
420 	bitoffset &= 7;
421 	value <<= bitoffset;
422 	mask <<= bitoffset;
423 	mask = ~mask;
424 
425 	ptr[0] &= mask;
426 	ptr[0] |= value;
427 	ptr[1] &= mask >> 8;
428 	ptr[1] |= value >> 8;
429 }
430 
431 
432 // routine to read up to 8 bits
read_bits(int bitcount,int bitoffset,const uint8_t * ptr)433 static inline int read_bits(int bitcount, int bitoffset, const uint8_t * ptr)
434 {
435 	int mask = (1 << bitcount) - 1;
436 	ptr += bitoffset >> 3;
437 	bitoffset &= 7;
438 	int value = ptr[0] | (ptr[1] << 8);
439 	value >>= bitoffset;
440 	value &= mask;
441 	return value;
442 }
443 
444 
445 
446 
encode_ise(int quantization_level,int elements,const uint8_t * input_data,uint8_t * output_data,int bit_offset)447 void encode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset)
448 {
449 	int i;
450 	uint8_t lowparts[64];
451 	uint8_t highparts[69];		// 64 elements + 5 elements for padding
452 	uint8_t tq_blocks[22];		// trit-blocks or quint-blocks
453 
454 	int bits, trits, quints;
455 	find_number_of_bits_trits_quints(quantization_level, &bits, &trits, &quints);
456 
457 	for (i = 0; i < elements; i++)
458 	{
459 		lowparts[i] = input_data[i] & ((1 << bits) - 1);
460 		highparts[i] = input_data[i] >> bits;
461 	}
462 	for (i = elements; i < elements + 5; i++)
463 		highparts[i] = 0;		// padding before we start constructing trit-blocks or quint-blocks
464 
465 	// construct trit-blocks or quint-blocks as necessary
466 	if (trits)
467 	{
468 		int trit_blocks = (elements + 4) / 5;
469 		for (i = 0; i < trit_blocks; i++)
470 			tq_blocks[i] = integer_of_trits[highparts[5 * i + 4]][highparts[5 * i + 3]][highparts[5 * i + 2]][highparts[5 * i + 1]][highparts[5 * i]];
471 	}
472 	if (quints)
473 	{
474 		int quint_blocks = (elements + 2) / 3;
475 		for (i = 0; i < quint_blocks; i++)
476 			tq_blocks[i] = integer_of_quints[highparts[3 * i + 2]][highparts[3 * i + 1]][highparts[3 * i]];
477 	}
478 
479 	// then, write out the actual bits.
480 	int lcounter = 0;
481 	int hcounter = 0;
482 	for (i = 0; i < elements; i++)
483 	{
484 		write_bits(lowparts[i], bits, bit_offset, output_data);
485 		bit_offset += bits;
486 		if (trits)
487 		{
488 			static const int bits_to_write[5] = { 2, 2, 1, 2, 1 };
489 			static const int block_shift[5] = { 0, 2, 4, 5, 7 };
490 			static const int next_lcounter[5] = { 1, 2, 3, 4, 0 };
491 			static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 };
492 			write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data);
493 			bit_offset += bits_to_write[lcounter];
494 			hcounter += hcounter_incr[lcounter];
495 			lcounter = next_lcounter[lcounter];
496 		}
497 		if (quints)
498 		{
499 			static const int bits_to_write[3] = { 3, 2, 2 };
500 			static const int block_shift[3] = { 0, 3, 5 };
501 			static const int next_lcounter[3] = { 1, 2, 0 };
502 			static const int hcounter_incr[3] = { 0, 0, 1 };
503 			write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data);
504 			bit_offset += bits_to_write[lcounter];
505 			hcounter += hcounter_incr[lcounter];
506 			lcounter = next_lcounter[lcounter];
507 		}
508 	}
509 }
510 
511 
512 
513 
decode_ise(int quantization_level,int elements,const uint8_t * input_data,uint8_t * output_data,int bit_offset)514 void decode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset)
515 {
516 	int i;
517 	// note: due to how the trit/quint-block unpacking is done in this function,
518 	// we may write more temporary results than the number of outputs
519 	// The maximum actual number of results is 64 bit, but we keep 4 additional elements
520 	// of padding.
521 	uint8_t results[68];
522 	uint8_t tq_blocks[22];		// trit-blocks or quint-blocks
523 
524 	int bits, trits, quints;
525 	find_number_of_bits_trits_quints(quantization_level, &bits, &trits, &quints);
526 
527 	int lcounter = 0;
528 	int hcounter = 0;
529 
530 	// trit-blocks or quint-blocks must be zeroed out before we collect them in the loop below.
531 	for (i = 0; i < 22; i++)
532 		tq_blocks[i] = 0;
533 
534 	// collect bits for each element, as well as bits for any trit-blocks and quint-blocks.
535 	for (i = 0; i < elements; i++)
536 	{
537 		results[i] = read_bits(bits, bit_offset, input_data);
538 		bit_offset += bits;
539 		if (trits)
540 		{
541 			static const int bits_to_read[5] = { 2, 2, 1, 2, 1 };
542 			static const int block_shift[5] = { 0, 2, 4, 5, 7 };
543 			static const int next_lcounter[5] = { 1, 2, 3, 4, 0 };
544 			static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 };
545 			int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
546 			bit_offset += bits_to_read[lcounter];
547 			tq_blocks[hcounter] |= tdata << block_shift[lcounter];
548 			hcounter += hcounter_incr[lcounter];
549 			lcounter = next_lcounter[lcounter];
550 		}
551 		if (quints)
552 		{
553 			static const int bits_to_read[3] = { 3, 2, 2 };
554 			static const int block_shift[3] = { 0, 3, 5 };
555 			static const int next_lcounter[3] = { 1, 2, 0 };
556 			static const int hcounter_incr[3] = { 0, 0, 1 };
557 			int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
558 			bit_offset += bits_to_read[lcounter];
559 			tq_blocks[hcounter] |= tdata << block_shift[lcounter];
560 			hcounter += hcounter_incr[lcounter];
561 			lcounter = next_lcounter[lcounter];
562 		}
563 	}
564 
565 
566 	// unpack trit-blocks or quint-blocks as needed
567 	if (trits)
568 	{
569 		int trit_blocks = (elements + 4) / 5;
570 		for (i = 0; i < trit_blocks; i++)
571 		{
572 			const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];
573 			results[5 * i] |= tritptr[0] << bits;
574 			results[5 * i + 1] |= tritptr[1] << bits;
575 			results[5 * i + 2] |= tritptr[2] << bits;
576 			results[5 * i + 3] |= tritptr[3] << bits;
577 			results[5 * i + 4] |= tritptr[4] << bits;
578 		}
579 	}
580 
581 	if (quints)
582 	{
583 		int quint_blocks = (elements + 2) / 3;
584 		for (i = 0; i < quint_blocks; i++)
585 		{
586 			const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];
587 			results[3 * i] |= quintptr[0] << bits;
588 			results[3 * i + 1] |= quintptr[1] << bits;
589 			results[3 * i + 2] |= quintptr[2] << bits;
590 		}
591 	}
592 
593 	for (i = 0; i < elements; i++)
594 		output_data[i] = results[i];
595 }
596 
597 
598 
599 
compute_ise_bitcount(int items,quantization_method quant)600 int compute_ise_bitcount(int items, quantization_method quant)
601 {
602 	switch (quant)
603 	{
604 	case QUANT_2:
605 		return items;
606 	case QUANT_3:
607 		return (8 * items + 4) / 5;
608 	case QUANT_4:
609 		return 2 * items;
610 	case QUANT_5:
611 		return (7 * items + 2) / 3;
612 	case QUANT_6:
613 		return (13 * items + 4) / 5;
614 	case QUANT_8:
615 		return 3 * items;
616 	case QUANT_10:
617 		return (10 * items + 2) / 3;
618 	case QUANT_12:
619 		return (18 * items + 4) / 5;
620 	case QUANT_16:
621 		return items * 4;
622 	case QUANT_20:
623 		return (13 * items + 2) / 3;
624 	case QUANT_24:
625 		return (23 * items + 4) / 5;
626 	case QUANT_32:
627 		return 5 * items;
628 	case QUANT_40:
629 		return (16 * items + 2) / 3;
630 	case QUANT_48:
631 		return (28 * items + 4) / 5;
632 	case QUANT_64:
633 		return 6 * items;
634 	case QUANT_80:
635 		return (19 * items + 2) / 3;
636 	case QUANT_96:
637 		return (33 * items + 4) / 5;
638 	case QUANT_128:
639 		return 7 * items;
640 	case QUANT_160:
641 		return (22 * items + 2) / 3;
642 	case QUANT_192:
643 		return (38 * items + 4) / 5;
644 	case QUANT_256:
645 		return 8 * items;
646 	default:
647 		return 100000;
648 	}
649 }
650