/src/wavpack/src/unpack_floats.c
Line | Count | Source |
1 | | //////////////////////////////////////////////////////////////////////////// |
2 | | // **** WAVPACK **** // |
3 | | // Hybrid Lossless Wavefile Compressor // |
4 | | // Copyright (c) 1998 - 2013 Conifer Software. // |
5 | | // All Rights Reserved. // |
6 | | // Distributed under the BSD Software License (see license.txt) // |
7 | | //////////////////////////////////////////////////////////////////////////// |
8 | | |
9 | | // unpack_floats.c |
10 | | |
11 | | // This module deals with the restoration of floating-point data. Note that no |
12 | | // floating point math is involved here...the values are only processed with |
13 | | // the macros that directly access the mantissa, exponent, and sign fields. |
14 | | // That's why we use the f32 type instead of the built-in float type. |
15 | | |
16 | | #include <stdlib.h> |
17 | | |
18 | | #include "wavpack_local.h" |
19 | | |
20 | | static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values); |
21 | | |
22 | | void float_values (WavpackStream *wps, int32_t *values, int32_t num_values) |
23 | 48.3k | { |
24 | 48.3k | int min_shifted_zeros = wps->float_min_shifted_zeros; |
25 | 48.3k | int max_shifted_ones = wps->float_max_shifted_ones; |
26 | 48.3k | uint32_t crc = wps->crc_x; |
27 | | |
28 | 48.3k | if (!bs_is_open (&wps->wvxbits)) { |
29 | 41.4k | float_values_nowvx (wps, values, num_values); |
30 | 41.4k | return; |
31 | 41.4k | } |
32 | | |
33 | 9.17M | while (num_values--) { |
34 | 9.17M | int shift_count = 0, exp = wps->float_max_exp; |
35 | 9.17M | f32 outval = 0; |
36 | 9.17M | uint32_t temp; |
37 | | |
38 | 9.17M | if (*values == 0) { |
39 | 3.06M | if (wps->float_flags & FLOAT_ZEROS_SENT) { |
40 | 2.59M | if (getbit (&wps->wvxbits)) { |
41 | 919k | getbits (&temp, 23, &wps->wvxbits); |
42 | 919k | set_mantissa (outval, temp); |
43 | | |
44 | 919k | if (exp >= 25) { |
45 | 738k | getbits (&temp, 8, &wps->wvxbits); |
46 | 738k | set_exponent (outval, temp); |
47 | 738k | } |
48 | | |
49 | 919k | set_sign (outval, getbit (&wps->wvxbits)); |
50 | 919k | } |
51 | 1.67M | else if (wps->float_flags & FLOAT_NEG_ZEROS) |
52 | 1.39M | set_sign (outval, getbit (&wps->wvxbits)); |
53 | 2.59M | } |
54 | 3.06M | } |
55 | 6.10M | else { |
56 | 6.10M | *(uint32_t*)values <<= (wps->float_shift & 0x1f); |
57 | | |
58 | 6.10M | if (*values < 0) { |
59 | 3.83M | *values = -*values; |
60 | 3.83M | set_sign (outval, 1); |
61 | 3.83M | } |
62 | | |
63 | 6.10M | if (*values == 0x1000000) { |
64 | 878k | if (getbit (&wps->wvxbits)) { |
65 | 281k | getbits (&temp, 23, &wps->wvxbits); |
66 | 281k | set_mantissa (outval, temp); |
67 | 281k | } |
68 | | |
69 | 878k | set_exponent (outval, 255); |
70 | 878k | } |
71 | 5.22M | else { |
72 | 5.22M | if (exp) |
73 | 125M | while (!(*values & 0x800000) && --exp) { |
74 | 121M | shift_count++; |
75 | 121M | *(uint32_t*)values <<= 1; |
76 | 121M | } |
77 | | |
78 | 5.22M | if (shift_count &= 0x1f) { |
79 | 2.92M | if ((wps->float_flags & FLOAT_SHIFT_ONES) || |
80 | 2.92M | ((wps->float_flags & FLOAT_SHIFT_SAME) && getbit (&wps->wvxbits))) |
81 | 1.07M | *values |= ((1U << shift_count) - 1); |
82 | 1.85M | else if (wps->float_flags & FLOAT_SHIFT_SENT) { |
83 | 1.47M | int32_t mask = (1U << shift_count) - 1; |
84 | 1.47M | int num_zeros = 0; |
85 | | |
86 | 1.47M | if (max_shifted_ones && shift_count > max_shifted_ones) |
87 | 567k | num_zeros = shift_count - max_shifted_ones; |
88 | | |
89 | 1.47M | if (min_shifted_zeros > num_zeros) |
90 | 243k | num_zeros = (min_shifted_zeros > shift_count) ? shift_count : min_shifted_zeros; |
91 | | |
92 | 1.47M | if ((shift_count -= num_zeros) > 0) { |
93 | 1.33M | getbits (&temp, shift_count, &wps->wvxbits); |
94 | 1.33M | *values |= (temp << num_zeros) & mask; |
95 | 1.33M | } |
96 | 1.47M | } |
97 | 2.92M | } |
98 | | |
99 | 5.22M | set_mantissa (outval, *values); |
100 | 5.22M | set_exponent (outval, exp); |
101 | 5.22M | } |
102 | 6.10M | } |
103 | | |
104 | 9.17M | crc = crc * 27 + get_mantissa (outval) * 9 + get_exponent (outval) * 3 + get_sign (outval); |
105 | 9.17M | * (f32 *) values++ = outval; |
106 | 9.17M | } |
107 | | |
108 | 6.97k | wps->crc_x = crc; |
109 | 6.97k | } |
110 | | |
111 | | static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values) |
112 | 41.4k | { |
113 | 72.5M | while (num_values--) { |
114 | 72.5M | int shift_count = 0, exp = wps->float_max_exp; |
115 | 72.5M | f32 outval = 0; |
116 | | |
117 | 72.5M | if (*values) { |
118 | 38.0M | *(uint32_t*)values <<= (wps->float_shift & 0x1f); |
119 | | |
120 | 38.0M | if (*values < 0) { |
121 | 23.9M | *values = -*values; |
122 | 23.9M | set_sign (outval, 1); |
123 | 23.9M | } |
124 | | |
125 | 38.0M | if (*values >= 0x1000000) { |
126 | 45.0M | while (*values & 0xf000000) { |
127 | 32.1M | *values >>= 1; |
128 | 32.1M | ++exp; |
129 | 32.1M | } |
130 | 12.8M | } |
131 | 25.2M | else if (exp) { |
132 | 23.8M | while (!(*values & 0x800000) && --exp) { |
133 | 22.7M | shift_count++; |
134 | 22.7M | *(uint32_t*)values <<= 1; |
135 | 22.7M | } |
136 | | |
137 | 1.02M | if ((shift_count &= 0x1f) && (wps->float_flags & FLOAT_SHIFT_ONES)) |
138 | 546k | *values |= ((1U << shift_count) - 1); |
139 | 1.02M | } |
140 | | |
141 | 38.0M | set_mantissa (outval, *values); |
142 | 38.0M | set_exponent (outval, exp); |
143 | 38.0M | } |
144 | | |
145 | 72.5M | * (f32 *) values++ = outval; |
146 | 72.5M | } |
147 | 41.4k | } |