1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include <schroedinger/schro.h>
7 #include <schroedinger/schrounpack.h>
8 #include <schroedinger/schrotables.h>
9
10 #include <string.h>
11 #include <schroedinger/schroorc.h>
12
13 static void _schro_unpack_shift_in (SchroUnpack * unpack);
14 static unsigned int _schro_unpack_shift_out (SchroUnpack * unpack, int n);
15
16 void
schro_unpack_init_with_data(SchroUnpack * unpack,uint8_t * data,int n_bytes,unsigned int guard_bit)17 schro_unpack_init_with_data (SchroUnpack * unpack, uint8_t * data,
18 int n_bytes, unsigned int guard_bit)
19 {
20 memset (unpack, 0, sizeof (SchroUnpack));
21
22 unpack->data = data;
23 unpack->n_bits_left = 8 * n_bytes;
24 unpack->guard_bit = guard_bit;
25 }
26
27 void
schro_unpack_copy(SchroUnpack * dest,SchroUnpack * src)28 schro_unpack_copy (SchroUnpack * dest, SchroUnpack * src)
29 {
30 memcpy (dest, src, sizeof (SchroUnpack));
31 }
32
33 int
schro_unpack_get_bits_read(SchroUnpack * unpack)34 schro_unpack_get_bits_read (SchroUnpack * unpack)
35 {
36 return unpack->n_bits_read;
37 }
38
39 #ifdef unused
40 int
schro_unpack_get_bits_remaining(SchroUnpack * unpack)41 schro_unpack_get_bits_remaining (SchroUnpack * unpack)
42 {
43 if (unpack->overrun) {
44 return 0;
45 }
46 return unpack->n_bits_left + unpack->n_bits_in_shift_register;
47 }
48 #endif
49
50 void
schro_unpack_limit_bits_remaining(SchroUnpack * unpack,int n_bits)51 schro_unpack_limit_bits_remaining (SchroUnpack * unpack, int n_bits)
52 {
53 if (n_bits <= unpack->n_bits_in_shift_register) {
54 unpack->n_bits_in_shift_register = n_bits;
55 unpack->shift_register &= ~(0xffffffff >> n_bits);
56 unpack->n_bits_left = 0;
57 return;
58 }
59
60 unpack->n_bits_left = n_bits - unpack->n_bits_in_shift_register;
61 }
62
63 #if 0
64 void
65 schro_unpack_dumpbits (SchroUnpack * unpack)
66 {
67
68 }
69 #endif
70
71 static void
_schro_unpack_shift_in(SchroUnpack * unpack)72 _schro_unpack_shift_in (SchroUnpack * unpack)
73 {
74 if (unpack->n_bits_left >= 32) {
75 /* the fast path */
76 if (unpack->n_bits_in_shift_register == 0) {
77 unpack->shift_register =
78 (unpack->data[0] << 24) | (unpack->
79 data[1] << 16) | (unpack->data[2] << 8) | (unpack->data[3]);
80 unpack->data += 4;
81 unpack->n_bits_left -= 32;
82 unpack->n_bits_in_shift_register = 32;
83 } else {
84 while (unpack->n_bits_in_shift_register <= 24) {
85 unpack->shift_register |=
86 unpack->data[0] << (24 - unpack->n_bits_in_shift_register);
87 unpack->data++;
88 unpack->n_bits_left -= 8;
89 unpack->n_bits_in_shift_register += 8;
90 }
91 }
92 return;
93 }
94
95 if (unpack->n_bits_left == 0) {
96 unsigned int value = (unpack->guard_bit) ? 0xffffffff : 0;
97
98 unpack->overrun += 32 - unpack->n_bits_in_shift_register;
99 unpack->shift_register |= (value >> unpack->n_bits_in_shift_register);
100 unpack->n_bits_in_shift_register = 32;
101 return;
102 }
103
104 while (unpack->n_bits_left >= 8 && unpack->n_bits_in_shift_register <= 24) {
105 unpack->shift_register |=
106 unpack->data[0] << (24 - unpack->n_bits_in_shift_register);
107 unpack->data++;
108 unpack->n_bits_left -= 8;
109 unpack->n_bits_in_shift_register += 8;
110 }
111
112 if (unpack->n_bits_left > 0 &&
113 unpack->n_bits_in_shift_register + unpack->n_bits_left <= 32) {
114 unsigned int value;
115
116 value = unpack->data[0] >> (8 - unpack->n_bits_left);
117 unpack->shift_register |=
118 value << (32 - unpack->n_bits_in_shift_register - unpack->n_bits_left);
119 unpack->data++;
120 unpack->n_bits_in_shift_register += unpack->n_bits_left;
121 unpack->n_bits_left = 0;
122 }
123 }
124
125 static unsigned int
_schro_unpack_shift_out(SchroUnpack * unpack,int n)126 _schro_unpack_shift_out (SchroUnpack * unpack, int n)
127 {
128 unsigned int value;
129
130 if (n == 0)
131 return 0;
132
133 value = unpack->shift_register >> (32 - n);
134 unpack->shift_register <<= n;
135 unpack->n_bits_in_shift_register -= n;
136 unpack->n_bits_read += n;
137
138 return value;
139 }
140
141
142 void
schro_unpack_skip_bits(SchroUnpack * unpack,int n_bits)143 schro_unpack_skip_bits (SchroUnpack * unpack, int n_bits)
144 {
145 int n_bytes;
146
147 if (n_bits <= unpack->n_bits_in_shift_register) {
148 _schro_unpack_shift_out (unpack, n_bits);
149 return;
150 }
151
152 n_bits -= unpack->n_bits_in_shift_register;
153 _schro_unpack_shift_out (unpack, unpack->n_bits_in_shift_register);
154
155 n_bytes = MIN (n_bits >> 3, unpack->n_bits_left >> 3);
156 unpack->data += n_bytes;
157 unpack->n_bits_read += n_bytes * 8;
158 unpack->n_bits_left -= n_bytes * 8;
159 n_bits -= n_bytes * 8;
160
161 if (n_bits == 0)
162 return;
163
164 _schro_unpack_shift_in (unpack);
165
166 if (n_bits <= unpack->n_bits_in_shift_register) {
167 _schro_unpack_shift_out (unpack, n_bits);
168 return;
169 }
170
171 unpack->n_bits_in_shift_register = 0;
172 unpack->shift_register = 0;
173 unpack->overrun += n_bits;
174 unpack->n_bits_read += n_bits;
175 }
176
177 void
schro_unpack_byte_sync(SchroUnpack * unpack)178 schro_unpack_byte_sync (SchroUnpack * unpack)
179 {
180 if (unpack->n_bits_read & 7) {
181 schro_unpack_skip_bits (unpack, 8 - (unpack->n_bits_read & 7));
182 }
183 }
184
185 unsigned int
schro_unpack_decode_bit(SchroUnpack * unpack)186 schro_unpack_decode_bit (SchroUnpack * unpack)
187 {
188 if (unpack->n_bits_in_shift_register < 1) {
189 _schro_unpack_shift_in (unpack);
190 }
191
192 return _schro_unpack_shift_out (unpack, 1);
193 }
194
195 unsigned int
schro_unpack_decode_bits(SchroUnpack * unpack,int n)196 schro_unpack_decode_bits (SchroUnpack * unpack, int n)
197 {
198 unsigned int value;
199 int m;
200
201 m = MIN (n, unpack->n_bits_in_shift_register);
202 value = _schro_unpack_shift_out (unpack, m) << (n - m);
203 n -= m;
204
205 while (n > 0) {
206 _schro_unpack_shift_in (unpack);
207 m = MIN (n, unpack->n_bits_in_shift_register);
208 value |= _schro_unpack_shift_out (unpack, m) << (n - m);
209 n -= m;
210 }
211
212 return value;
213 }
214
215 unsigned int
schro_unpack_decode_uint(SchroUnpack * unpack)216 schro_unpack_decode_uint (SchroUnpack * unpack)
217 {
218 int count;
219 int value;
220
221 count = 0;
222 value = 0;
223 while (!schro_unpack_decode_bit (unpack)) {
224 count++;
225 value <<= 1;
226 value |= schro_unpack_decode_bit (unpack);
227 }
228
229 return (1 << count) - 1 + value;
230 }
231
232 int
schro_unpack_decode_sint_slow(SchroUnpack * unpack)233 schro_unpack_decode_sint_slow (SchroUnpack * unpack)
234 {
235 int value;
236
237 value = schro_unpack_decode_uint (unpack);
238 if (value) {
239 if (schro_unpack_decode_bit (unpack)) {
240 value = -value;
241 }
242 }
243
244 return value;
245 }
246
247 int
schro_unpack_decode_sint(SchroUnpack * unpack)248 schro_unpack_decode_sint (SchroUnpack * unpack)
249 {
250 int value;
251 int i;
252 const int16_t *table_entry;
253 int x;
254
255 if (unpack->n_bits_in_shift_register < SCHRO_UNPACK_TABLE_SHIFT) {
256 _schro_unpack_shift_in (unpack);
257 }
258 if (unpack->n_bits_in_shift_register >= SCHRO_UNPACK_TABLE_SHIFT) {
259 i = unpack->shift_register >> (32 - SCHRO_UNPACK_TABLE_SHIFT);
260 table_entry = schro_table_unpack_sint[i];
261 x = table_entry[0];
262 if (x & 0xf) {
263 value = x >> 4;
264 _schro_unpack_shift_out (unpack, x & 0xf);
265 return value;
266 }
267 }
268
269 return schro_unpack_decode_sint_slow (unpack);
270 }
271
272 typedef const int16_t SchroUnpackTableEntry[10];
273
274 void
schro_unpack_decode_sint_s16(int16_t * dest,SchroUnpack * unpack,int n)275 schro_unpack_decode_sint_s16 (int16_t * dest, SchroUnpack * unpack, int n)
276 {
277 int i;
278 int j;
279 const int16_t *table_entry;
280 int x;
281 int z;
282 SchroUnpackTableEntry *table = schro_table_unpack_sint;
283
284 while (n > 0) {
285 while (unpack->n_bits_in_shift_register < 8 + SCHRO_UNPACK_TABLE_SHIFT) {
286 _schro_unpack_shift_in (unpack);
287 }
288 i = unpack->shift_register >> (32 - SCHRO_UNPACK_TABLE_SHIFT);
289 table_entry = table[i];
290 x = table_entry[0];
291 if ((x & 0xf) == 0) {
292 int y = x >> 4;
293
294 i = (unpack->shift_register & 0xffffff) >> (24 -
295 SCHRO_UNPACK_TABLE_SHIFT);
296 table_entry = table[i];
297 x = table_entry[0];
298 if ((x & 0xf) == 0) {
299 dest[0] = schro_unpack_decode_sint_slow (unpack);
300 dest++;
301 n--;
302 } else {
303 int bits = ((x & 0xf) >> 1) - 1;
304
305 z = x >> 4;
306 if (z > 0) {
307 dest[0] = z + (y << bits);
308 } else {
309 dest[0] = z - (y << bits);
310 }
311 _schro_unpack_shift_out (unpack, (x & 0xf) + 8);
312 dest++;
313 n--;
314 }
315 } else {
316 j = 0;
317 do {
318 dest[j] = x >> 4;
319 j++;
320 n--;
321 x = table_entry[j];
322 } while (n > 0 && x & 0xf);
323 x = table_entry[j - 1];
324 _schro_unpack_shift_out (unpack, x & 0xf);
325 dest += j;
326 }
327 }
328 }
329
330 void
schro_unpack_decode_sint_s32(int32_t * dest,SchroUnpack * unpack,int n)331 schro_unpack_decode_sint_s32 (int32_t * dest, SchroUnpack * unpack, int n)
332 {
333 int i;
334 int j;
335 const int16_t *table_entry;
336 int x;
337 int z;
338 SchroUnpackTableEntry *table = schro_table_unpack_sint;
339
340 while (n > 0) {
341 while (unpack->n_bits_in_shift_register < 8 + SCHRO_UNPACK_TABLE_SHIFT) {
342 _schro_unpack_shift_in (unpack);
343 }
344 i = unpack->shift_register >> (32 - SCHRO_UNPACK_TABLE_SHIFT);
345 table_entry = table[i];
346 x = table_entry[0];
347 if ((x & 0xf) == 0) {
348 int y = x >> 4;
349
350 i = (unpack->shift_register & 0xffffff) >> (24 -
351 SCHRO_UNPACK_TABLE_SHIFT);
352 table_entry = table[i];
353 x = table_entry[0];
354 if ((x & 0xf) == 0) {
355 dest[0] = schro_unpack_decode_sint_slow (unpack);
356 dest++;
357 n--;
358 } else {
359 int bits = ((x & 0xf) >> 1) - 1;
360
361 z = x >> 4;
362 if (z > 0) {
363 dest[0] = z + (y << bits);
364 } else {
365 dest[0] = z - (y << bits);
366 }
367 _schro_unpack_shift_out (unpack, (x & 0xf) + 8);
368 dest++;
369 n--;
370 }
371 } else {
372 j = 0;
373 do {
374 dest[j] = x >> 4;
375 j++;
376 n--;
377 x = table_entry[j];
378 } while (n > 0 && x & 0xf);
379 x = table_entry[j - 1];
380 _schro_unpack_shift_out (unpack, x & 0xf);
381 dest += j;
382 }
383 }
384 }
385
386