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