diff options
Diffstat (limited to 'apps/codecs/libwavpack/float.c')
-rw-r--r-- | apps/codecs/libwavpack/float.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/apps/codecs/libwavpack/float.c b/apps/codecs/libwavpack/float.c new file mode 100644 index 0000000000..3e678e824d --- /dev/null +++ b/apps/codecs/libwavpack/float.c | |||
@@ -0,0 +1,83 @@ | |||
1 | //////////////////////////////////////////////////////////////////////////// | ||
2 | // **** WAVPACK **** // | ||
3 | // Hybrid Lossless Wavefile Compressor // | ||
4 | // Copyright (c) 1998 - 2004 Conifer Software. // | ||
5 | // All Rights Reserved. // | ||
6 | // Distributed under the BSD Software License (see license.txt) // | ||
7 | //////////////////////////////////////////////////////////////////////////// | ||
8 | |||
9 | // float.c | ||
10 | |||
11 | #include "wavpack.h" | ||
12 | |||
13 | int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd) | ||
14 | { | ||
15 | int bytecnt = wpmd->byte_length; | ||
16 | char *byteptr = wpmd->data; | ||
17 | |||
18 | if (bytecnt != 4) | ||
19 | return FALSE; | ||
20 | |||
21 | wps->float_flags = *byteptr++; | ||
22 | wps->float_shift = *byteptr++; | ||
23 | wps->float_max_exp = *byteptr++; | ||
24 | wps->float_norm_exp = *byteptr; | ||
25 | return TRUE; | ||
26 | } | ||
27 | |||
28 | void float_values (WavpackStream *wps, long *values, long num_values) | ||
29 | { | ||
30 | while (num_values--) { | ||
31 | int shift_count = 0, exp = wps->float_max_exp; | ||
32 | f32 outval = { 0, 0, 0 }; | ||
33 | |||
34 | if (*values) { | ||
35 | *values <<= wps->float_shift; | ||
36 | |||
37 | if (*values < 0) { | ||
38 | *values = -*values; | ||
39 | outval.sign = 1; | ||
40 | } | ||
41 | |||
42 | if (*values == 0x1000000) | ||
43 | outval.exponent = 255; | ||
44 | else { | ||
45 | if (exp) | ||
46 | while (!(*values & 0x800000) && --exp) { | ||
47 | shift_count++; | ||
48 | *values <<= 1; | ||
49 | } | ||
50 | |||
51 | if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES)) | ||
52 | *values |= ((1 << shift_count) - 1); | ||
53 | |||
54 | outval.mantissa = *values; | ||
55 | outval.exponent = exp; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | * (f32 *) values++ = outval; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | void float_normalize (long *values, long num_values, int delta_exp) | ||
64 | { | ||
65 | f32 *fvalues = (f32 *) values, fzero = { 0, 0, 0 }; | ||
66 | int exp; | ||
67 | |||
68 | if (!delta_exp) | ||
69 | return; | ||
70 | |||
71 | while (num_values--) { | ||
72 | if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0) | ||
73 | *fvalues = fzero; | ||
74 | else if (exp == 255 || (exp += delta_exp) >= 255) { | ||
75 | fvalues->exponent = 255; | ||
76 | fvalues->mantissa = 0; | ||
77 | } | ||
78 | else | ||
79 | fvalues->exponent = exp; | ||
80 | |||
81 | fvalues++; | ||
82 | } | ||
83 | } | ||