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