1 
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 
6 #include <string.h>
7 
8 #include <schroedinger/schropack.h>
9 #include <schroedinger/schro.h>
10 #include <schroedinger/schroorc.h>
11 #include <orc/orc.h>
12 
13 
14 SchroPack *
schro_pack_new(void)15 schro_pack_new (void)
16 {
17   SchroPack *pack;
18 
19   pack = schro_malloc0 (sizeof (*pack));
20 
21   return pack;
22 }
23 
24 void
schro_pack_free(SchroPack * pack)25 schro_pack_free (SchroPack * pack)
26 {
27   schro_free (pack);
28 }
29 
30 #ifdef unused
31 void
schro_pack_copy(SchroPack * dest,SchroPack * src)32 schro_pack_copy (SchroPack * dest, SchroPack * src)
33 {
34   memcpy (dest, src, sizeof (SchroPack));
35 }
36 #endif
37 
38 static void
schro_pack_shift_out(SchroPack * pack)39 schro_pack_shift_out (SchroPack * pack)
40 {
41   if (pack->n < pack->buffer->length) {
42     pack->buffer->data[pack->n] = pack->value;
43     pack->n++;
44     pack->shift = 7;
45     pack->value = 0;
46     return;
47   }
48   if (pack->error == FALSE) {
49     SCHRO_ERROR ("buffer overrun");
50   }
51   pack->error = TRUE;
52   pack->shift = 7;
53   pack->value = 0;
54 }
55 
56 void
schro_pack_encode_init(SchroPack * pack,SchroBuffer * buffer)57 schro_pack_encode_init (SchroPack * pack, SchroBuffer * buffer)
58 {
59   pack->buffer = buffer;
60   pack->n = 0;
61 
62   pack->value = 0;
63   pack->shift = 7;
64 }
65 
66 int
schro_pack_get_offset(SchroPack * pack)67 schro_pack_get_offset (SchroPack * pack)
68 {
69   return pack->n;
70 }
71 
72 int
schro_pack_get_bit_offset(SchroPack * pack)73 schro_pack_get_bit_offset (SchroPack * pack)
74 {
75   return pack->n * 8 + (7 - pack->shift);
76 }
77 
78 void
schro_pack_flush(SchroPack * pack)79 schro_pack_flush (SchroPack * pack)
80 {
81   schro_pack_sync (pack);
82 }
83 
84 void
schro_pack_sync(SchroPack * pack)85 schro_pack_sync (SchroPack * pack)
86 {
87   if (pack->shift != 7) {
88     schro_pack_shift_out (pack);
89   }
90 }
91 
92 void
schro_pack_append(SchroPack * pack,const uint8_t * data,int len)93 schro_pack_append (SchroPack * pack, const uint8_t * data, int len)
94 {
95   if (pack->shift != 7) {
96     SCHRO_ERROR ("appending to unsyncronized pack");
97   }
98 
99   SCHRO_ASSERT (pack->n + len <= pack->buffer->length);
100 
101   orc_memcpy (pack->buffer->data + pack->n, (void *) data, len);
102   pack->n += len;
103 }
104 
105 void
schro_pack_append_zero(SchroPack * pack,int len)106 schro_pack_append_zero (SchroPack * pack, int len)
107 {
108   if (pack->shift != 7) {
109     SCHRO_ERROR ("appending to unsyncronized pack");
110   }
111 
112   SCHRO_ASSERT (pack->n + len <= pack->buffer->length);
113 
114   memset (pack->buffer->data + pack->n, 0, len);
115   pack->n += len;
116 }
117 
118 void
schro_pack_encode_bit(SchroPack * pack,int value)119 schro_pack_encode_bit (SchroPack * pack, int value)
120 {
121   value &= 1;
122   pack->value |= (value << pack->shift);
123   pack->shift--;
124   if (pack->shift < 0) {
125     schro_pack_shift_out (pack);
126   }
127 }
128 
129 void
schro_pack_encode_bits(SchroPack * pack,int n,unsigned int value)130 schro_pack_encode_bits (SchroPack * pack, int n, unsigned int value)
131 {
132   int i;
133   for (i = 0; i < n; i++) {
134     schro_pack_encode_bit (pack, (value >> (n - 1 - i)) & 1);
135   }
136 }
137 
138 static int
maxbit(unsigned int x)139 maxbit (unsigned int x)
140 {
141   int i;
142   for (i = 0; x; i++) {
143     x >>= 1;
144   }
145   return i;
146 }
147 
148 void
schro_pack_encode_uint(SchroPack * pack,int value)149 schro_pack_encode_uint (SchroPack * pack, int value)
150 {
151   int i;
152   int n_bits;
153 
154   value++;
155   n_bits = maxbit (value);
156   for (i = 0; i < n_bits - 1; i++) {
157     schro_pack_encode_bit (pack, 0);
158     schro_pack_encode_bit (pack, (value >> (n_bits - 2 - i)) & 1);
159   }
160   schro_pack_encode_bit (pack, 1);
161 }
162 
163 static void
__schro_pack_encode_sint(SchroPack * pack,int value)164 __schro_pack_encode_sint (SchroPack * pack, int value)
165 {
166   int sign;
167 
168   if (value < 0) {
169     sign = 1;
170     value = -value;
171   } else {
172     sign = 0;
173   }
174   schro_pack_encode_uint (pack, value);
175   if (value) {
176     schro_pack_encode_bit (pack, sign);
177   }
178 }
179 
180 void
schro_pack_encode_sint(SchroPack * pack,int value)181 schro_pack_encode_sint (SchroPack * pack, int value)
182 {
183   __schro_pack_encode_sint (pack, value);
184 }
185 
186 void
schro_pack_encode_sint_s16(SchroPack * pack,orc_int16 * values,int n)187 schro_pack_encode_sint_s16 (SchroPack * pack, orc_int16 *values, int n)
188 {
189   int i;
190   for(i=0;i<n;i++){
191     __schro_pack_encode_sint (pack, values[i]);
192   }
193 }
194 
195 void
schro_pack_encode_sint_s32(SchroPack * pack,orc_int32 * values,int n)196 schro_pack_encode_sint_s32 (SchroPack * pack, orc_int32 *values, int n)
197 {
198   int i;
199   for(i=0;i<n;i++){
200     __schro_pack_encode_sint (pack, values[i]);
201   }
202 }
203 
204 int
schro_pack_estimate_uint(int value)205 schro_pack_estimate_uint (int value)
206 {
207   int n_bits;
208 
209   value++;
210   n_bits = maxbit (value);
211   return n_bits + n_bits - 1;
212 }
213 
214 int
schro_pack_estimate_sint(int value)215 schro_pack_estimate_sint (int value)
216 {
217   int n_bits;
218 
219   if (value < 0) {
220     value = -value;
221   }
222   n_bits = schro_pack_estimate_uint (value);
223   if (value)
224     n_bits++;
225   return n_bits;
226 }
227