summaryrefslogtreecommitdiff
path: root/apps/codecs/libwavpack/words.c
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2005-02-25 17:05:30 +0000
committerChristian Gmeiner <christian.gmeiner@gmail.com>2005-02-25 17:05:30 +0000
commite449d88b3e6b584998f8f38ed61467c35ca74466 (patch)
tree307e87242fd5fbf45d7424bb5afad17b9dd34429 /apps/codecs/libwavpack/words.c
parent234489a449e13d99b76daff61ff7774226d21a5b (diff)
downloadrockbox-e449d88b3e6b584998f8f38ed61467c35ca74466.tar.gz
rockbox-e449d88b3e6b584998f8f38ed61467c35ca74466.zip
Initial import of libwavpack
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6056 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwavpack/words.c')
-rw-r--r--apps/codecs/libwavpack/words.c503
1 files changed, 503 insertions, 0 deletions
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c
new file mode 100644
index 0000000000..35061b69a9
--- /dev/null
+++ b/apps/codecs/libwavpack/words.c
@@ -0,0 +1,503 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6////////////////////////////////////////////////////////////////////////////
7
8// words.c
9
10// This module provides entropy word encoding and decoding functions using
11// a variation on the Rice method. This was introduced in version 3.93
12// because it allows splitting the data into a "lossy" stream and a
13// "correction" stream in a very efficient manner and is therefore ideal
14// for the "hybrid" mode. For 4.0, the efficiency of this method was
15// significantly improved by moving away from the normal Rice restriction of
16// using powers of two for the modulus divisions and now the method can be
17// used for both hybrid and pure lossless encoding.
18
19// Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%),
20// and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the
21// previous. Using standard Rice coding on this data would result in 1.4
22// bits per sample average (not counting sign bit). However, there is a
23// very simple encoding that is over 99% efficient with this data and
24// results in about 1.22 bits per sample.
25
26#include "wavpack.h"
27
28#include <string.h>
29
30//////////////////////////////// local macros /////////////////////////////////
31
32#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data
33
34// these control the time constant "slow_level" which is used for hybrid mode
35// that controls bitrate as a function of residual level (HYBRID_BITRATE).
36#define SLS 8
37#define SLO ((1 << (SLS - 1)))
38
39// these control the time constant of the 3 median level breakpoints
40#define DIV0 128 // 5/7 of samples
41#define DIV1 64 // 10/49 of samples
42#define DIV2 32 // 20/343 of samples
43
44// this macro retrieves the specified median breakpoint (without frac; min = 1)
45#define GET_MED(med) (((wps->w.median [med] [chan]) >> 4) + 1)
46
47// These macros update the specified median breakpoints. Note that the median
48// is incremented when the sample is higher than the median, else decremented.
49// They are designed so that the median will never drop below 1 and the value
50// is essentially stationary if there are 2 increments for every 5 decrements.
51
52#define INC_MED0() (wps->w.median [0] [chan] += ((wps->w.median [0] [chan] + DIV0) / DIV0) * 5)
53#define DEC_MED0() (wps->w.median [0] [chan] -= ((wps->w.median [0] [chan] + (DIV0-2)) / DIV0) * 2)
54#define INC_MED1() (wps->w.median [1] [chan] += ((wps->w.median [1] [chan] + DIV1) / DIV1) * 5)
55#define DEC_MED1() (wps->w.median [1] [chan] -= ((wps->w.median [1] [chan] + (DIV1-2)) / DIV1) * 2)
56#define INC_MED2() (wps->w.median [2] [chan] += ((wps->w.median [2] [chan] + DIV2) / DIV2) * 5)
57#define DEC_MED2() (wps->w.median [2] [chan] -= ((wps->w.median [2] [chan] + (DIV2-2)) / DIV2) * 2)
58
59#define count_bits(av) ( \
60 (av) < (1 << 8) ? nbits_table [av] : \
61 ( \
62 (av) < (1L << 16) ? nbits_table [(av) >> 8] + 8 : \
63 ((av) < (1L << 24) ? nbits_table [(av) >> 16] + 16 : nbits_table [(av) >> 24] + 24) \
64 ) \
65)
66
67///////////////////////////// local table storage ////////////////////////////
68
69const char nbits_table [] = {
70 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15
71 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31
72 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 32 - 47
73 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 48 - 63
74 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 64 - 79
75 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 80 - 95
76 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 - 111
77 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 112 - 127
78 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 128 - 143
79 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 144 - 159
80 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 - 175
81 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 176 - 191
82 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 - 207
83 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 208 - 223
84 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 - 239
85 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255
86};
87
88static const uchar log2_table [] = {
89 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
90 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
91 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
92 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
93 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
94 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
95 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
96 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
97 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
98 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
99 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
100 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
101 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
102 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
103 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
104 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
105};
106
107static const uchar exp2_table [] = {
108 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
109 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
110 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
111 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
112 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
113 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
114 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
115 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
116 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
117 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
118 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
119 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
120 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
121 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
122 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
123 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
124};
125
126///////////////////////////// executable code ////////////////////////////////
127
128static int log2 (unsigned long avalue);
129
130// Read the median log2 values from the specifed metadata structure, convert
131// them back to 32-bit unsigned values and store them. If length is not
132// exactly correct then we flag and return an error.
133
134int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
135{
136 uchar *byteptr = wpmd->data;
137
138 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12))
139 return FALSE;
140
141 wps->w.median [0] [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
142 wps->w.median [1] [0] = exp2s (byteptr [2] + (byteptr [3] << 8));
143 wps->w.median [2] [0] = exp2s (byteptr [4] + (byteptr [5] << 8));
144
145 if (!(wps->wphdr.flags & MONO_FLAG)) {
146 wps->w.median [0] [1] = exp2s (byteptr [6] + (byteptr [7] << 8));
147 wps->w.median [1] [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
148 wps->w.median [2] [1] = exp2s (byteptr [10] + (byteptr [11] << 8));
149 }
150
151 return TRUE;
152}
153
154// Read the hybrid related values from the specifed metadata structure, convert
155// them back to their internal formats and store them. The extended profile
156// stuff is not implemented yet, so return an error if we get more data than
157// we know what to do with.
158
159int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
160{
161 uchar *byteptr = wpmd->data;
162 uchar *endptr = byteptr + wpmd->byte_length;
163
164 if (wps->wphdr.flags & HYBRID_BITRATE) {
165 wps->w.slow_level [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
166 byteptr += 2;
167
168 if (!(wps->wphdr.flags & MONO_FLAG)) {
169 wps->w.slow_level [1] = exp2s (byteptr [0] + (byteptr [1] << 8));
170 byteptr += 2;
171 }
172 }
173
174 wps->w.bitrate_acc [0] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16;
175 byteptr += 2;
176
177 if (!(wps->wphdr.flags & MONO_FLAG)) {
178 wps->w.bitrate_acc [1] = (long)(byteptr [0] + (byteptr [1] << 8)) << 16;
179 byteptr += 2;
180 }
181
182 if (byteptr < endptr) {
183 wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
184 byteptr += 2;
185
186 if (!(wps->wphdr.flags & MONO_FLAG)) {
187 wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
188 byteptr += 2;
189 }
190
191 if (byteptr < endptr)
192 return FALSE;
193 }
194 else
195 wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0;
196
197 return TRUE;
198}
199
200// This function is called during both encoding and decoding of hybrid data to
201// update the "error_limit" variable which determines the maximum sample error
202// allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only
203// currently implemented) this is calculated from the slow_level values and the
204// bitrate accumulators. Note that the bitrate accumulators can be changing.
205
206static void update_error_limit (WavpackStream *wps)
207{
208 int bitrate_0 = (wps->w.bitrate_acc [0] += wps->w.bitrate_delta [0]) >> 16;
209
210 if (wps->wphdr.flags & MONO_FLAG) {
211 if (wps->wphdr.flags & HYBRID_BITRATE) {
212 int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS;
213
214 if (slow_log_0 - bitrate_0 > -0x100)
215 wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100);
216 else
217 wps->w.error_limit [0] = 0;
218 }
219 else
220 wps->w.error_limit [0] = exp2s (bitrate_0);
221 }
222 else {
223 int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16;
224
225 if (wps->wphdr.flags & HYBRID_BITRATE) {
226 int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS;
227 int slow_log_1 = (wps->w.slow_level [1] + SLO) >> SLS;
228
229 if (wps->wphdr.flags & HYBRID_BALANCE) {
230 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
231
232 if (balance > bitrate_0) {
233 bitrate_1 = bitrate_0 * 2;
234 bitrate_0 = 0;
235 }
236 else if (-balance > bitrate_0) {
237 bitrate_0 = bitrate_0 * 2;
238 bitrate_1 = 0;
239 }
240 else {
241 bitrate_1 = bitrate_0 + balance;
242 bitrate_0 = bitrate_0 - balance;
243 }
244 }
245
246 if (slow_log_0 - bitrate_0 > -0x100)
247 wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100);
248 else
249 wps->w.error_limit [0] = 0;
250
251 if (slow_log_1 - bitrate_1 > -0x100)
252 wps->w.error_limit [1] = exp2s (slow_log_1 - bitrate_1 + 0x100);
253 else
254 wps->w.error_limit [1] = 0;
255 }
256 else {
257 wps->w.error_limit [0] = exp2s (bitrate_0);
258 wps->w.error_limit [1] = exp2s (bitrate_1);
259 }
260 }
261}
262
263static ulong read_code (Bitstream *bs, ulong maxcode);
264
265// Read the next word from the bitstream "wvbits" and return the value. This
266// function can be used for hybrid or lossless streams, but since an
267// optimized version is available for lossless this function would normally
268// be used for hybrid only. If a hybrid lossless stream is being read then
269// the "correction" offset is written at the specified pointer. A return value
270// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
271// some other error occurred.
272
273long get_word (WavpackStream *wps, int chan)
274{
275 ulong ones_count, low, mid, high;
276 int sign;
277
278 if (wps->w.zeros_acc) {
279 if (--wps->w.zeros_acc) {
280 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
281 return 0;
282 }
283 }
284 else if (!wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [0] & ~1) && !(wps->w.median [0] [1] & ~1)) {
285 ulong mask;
286 int cbits;
287
288 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits);
289
290 if (cbits == 33)
291 return WORD_EOF;
292
293 if (cbits < 2)
294 wps->w.zeros_acc = cbits;
295 else {
296 for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1)
297 if (getbit (&wps->wvbits))
298 wps->w.zeros_acc |= mask;
299
300 wps->w.zeros_acc |= mask;
301 }
302
303 if (wps->w.zeros_acc) {
304 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
305 CLEAR (wps->w.median);
306 return 0;
307 }
308 }
309
310 if (wps->w.holding_zero)
311 ones_count = wps->w.holding_zero = 0;
312 else {
313#ifdef LIMIT_ONES
314 for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count);
315
316 if (ones_count == (LIMIT_ONES + 1))
317 return WORD_EOF;
318
319 if (ones_count == LIMIT_ONES) {
320 ulong mask;
321 int cbits;
322
323 for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits);
324
325 if (cbits == 33)
326 return WORD_EOF;
327
328 if (cbits < 2)
329 ones_count = cbits;
330 else {
331 for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
332 if (getbit (&wps->wvbits))
333 ones_count |= mask;
334
335 ones_count |= mask;
336 }
337
338 ones_count += LIMIT_ONES;
339 }
340#else
341 for (ones_count = 0; getbit (&wps->wvbits); ++ones_count);
342#endif
343
344 if (wps->w.holding_one) {
345 wps->w.holding_one = ones_count & 1;
346 ones_count = (ones_count >> 1) + 1;
347 }
348 else {
349 wps->w.holding_one = ones_count & 1;
350 ones_count >>= 1;
351 }
352
353 wps->w.holding_zero = ~wps->w.holding_one & 1;
354 }
355
356 if ((wps->wphdr.flags & HYBRID_FLAG) && !chan)
357 update_error_limit (wps);
358
359 if (ones_count == 0) {
360 low = 0;
361 high = GET_MED (0) - 1;
362 DEC_MED0 ();
363 }
364 else {
365 low = GET_MED (0);
366 INC_MED0 ();
367
368 if (ones_count == 1) {
369 high = low + GET_MED (1) - 1;
370 DEC_MED1 ();
371 }
372 else {
373 low += GET_MED (1);
374 INC_MED1 ();
375
376 if (ones_count == 2) {
377 high = low + GET_MED (2) - 1;
378 DEC_MED2 ();
379 }
380 else {
381 low += (ones_count - 2) * GET_MED (2);
382 high = low + GET_MED (2) - 1;
383 INC_MED2 ();
384 }
385 }
386 }
387
388 mid = (high + low + 1) >> 1;
389
390 if (!wps->w.error_limit [chan])
391 mid = read_code (&wps->wvbits, high - low) + low;
392 else while (high - low > wps->w.error_limit [chan]) {
393 if (getbit (&wps->wvbits))
394 mid = (high + (low = mid) + 1) >> 1;
395 else
396 mid = ((high = mid - 1) + low + 1) >> 1;
397 }
398
399 sign = getbit (&wps->wvbits);
400
401 if (wps->wphdr.flags & HYBRID_BITRATE) {
402 wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS;
403 wps->w.slow_level [chan] += log2 (mid);
404 }
405
406 return sign ? ~mid : mid;
407}
408
409// Read a single unsigned value from the specified bitstream with a value
410// from 0 to maxcode. If there are exactly a power of two number of possible
411// codes then this will read a fixed number of bits; otherwise it reads the
412// minimum number of bits and then determines whether another bit is needed
413// to define the code.
414
415static ulong read_code (Bitstream *bs, ulong maxcode)
416{
417 int bitcount = count_bits (maxcode);
418 ulong extras = (1L << bitcount) - maxcode - 1, code;
419
420 if (!bitcount)
421 return 0;
422
423 getbits (&code, bitcount - 1, bs);
424 code &= (1L << (bitcount - 1)) - 1;
425
426 if (code >= extras) {
427 code = (code << 1) - extras;
428
429 if (getbit (bs))
430 ++code;
431 }
432
433 return code;
434}
435
436// The concept of a base 2 logarithm is used in many parts of WavPack. It is
437// a way of sufficiently accurately representing 32-bit signed and unsigned
438// values storing only 16 bits (actually fewer). It is also used in the hybrid
439// mode for quickly comparing the relative magnitude of large values (i.e.
440// division) and providing smooth exponentials using only addition.
441
442// These are not strict logarithms in that they become linear around zero and
443// can therefore represent both zero and negative values. They have 8 bits
444// of precision and in "roundtrip" conversions the total error never exceeds 1
445// part in 225 except for the cases of +/-115 and +/-195 (which error by 1).
446
447
448// This function returns the log2 for the specified 32-bit unsigned value.
449// The maximum value allowed is about 0xff800000 and returns 8447.
450
451static int log2 (unsigned long avalue)
452{
453 int dbits;
454
455 if ((avalue += avalue >> 9) < (1 << 8)) {
456 dbits = nbits_table [avalue];
457 return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
458 }
459 else {
460 if (avalue < (1L << 16))
461 dbits = nbits_table [avalue >> 8] + 8;
462 else if (avalue < (1L << 24))
463 dbits = nbits_table [avalue >> 16] + 16;
464 else
465 dbits = nbits_table [avalue >> 24] + 24;
466
467 return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
468 }
469}
470
471// This function returns the original integer represented by the supplied
472// logarithm (at least within the provided accuracy). The log is signed,
473// but since a full 32-bit value is returned this can be used for unsigned
474// conversions as well (i.e. the input range is -8192 to +8447).
475
476long exp2s (int log)
477{
478 ulong value;
479
480 if (log < 0)
481 return -exp2s (-log);
482
483 value = exp2_table [log & 0xff] | 0x100;
484
485 if ((log >>= 8) <= 9)
486 return value >> (9 - log);
487 else
488 return value << (log - 9);
489}
490
491// These two functions convert internal weights (which are normally +/-1024)
492// to and from an 8-bit signed character version for storage in metadata. The
493// weights are clipped here in the case that they are outside that range.
494
495int restore_weight (char weight)
496{
497 int result;
498
499 if ((result = (int) weight << 3) > 0)
500 result += (result + 64) >> 7;
501
502 return result;
503}