/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 | 57.6k | { |
24 | 57.6k | int min_shifted_zeros = wps->float_min_shifted_zeros; |
25 | 57.6k | int max_shifted_ones = wps->float_max_shifted_ones; |
26 | 57.6k | uint32_t crc = wps->crc_x; |
27 | | |
28 | 57.6k | if (!bs_is_open (&wps->wvxbits)) { |
29 | 51.9k | float_values_nowvx (wps, values, num_values); |
30 | 51.9k | return; |
31 | 51.9k | } |
32 | | |
33 | 8.39M | while (num_values--) { |
34 | 8.38M | int shift_count = 0, exp = wps->float_max_exp; |
35 | 8.38M | f32 outval = 0; |
36 | 8.38M | uint32_t temp; |
37 | | |
38 | 8.38M | if (*values == 0) { |
39 | 2.30M | if (wps->float_flags & FLOAT_ZEROS_SENT) { |
40 | 1.51M | if (getbit (&wps->wvxbits)) { |
41 | 655k | getbits (&temp, 23, &wps->wvxbits); |
42 | 655k | set_mantissa (outval, temp); |
43 | | |
44 | 655k | if (exp >= 25) { |
45 | 318k | getbits (&temp, 8, &wps->wvxbits); |
46 | 318k | set_exponent (outval, temp); |
47 | 318k | } |
48 | | |
49 | 655k | set_sign (outval, getbit (&wps->wvxbits)); |
50 | 655k | } |
51 | 860k | else if (wps->float_flags & FLOAT_NEG_ZEROS) |
52 | 602k | set_sign (outval, getbit (&wps->wvxbits)); |
53 | 1.51M | } |
54 | 2.30M | } |
55 | 6.08M | else { |
56 | 6.08M | *(uint32_t*)values <<= (wps->float_shift & 0x1f); |
57 | | |
58 | 6.08M | if (*values < 0) { |
59 | 3.67M | *values = -*values; |
60 | 3.67M | set_sign (outval, 1); |
61 | 3.67M | } |
62 | | |
63 | 6.08M | if (*values == 0x1000000) { |
64 | 244k | if (getbit (&wps->wvxbits)) { |
65 | 104k | getbits (&temp, 23, &wps->wvxbits); |
66 | 104k | set_mantissa (outval, temp); |
67 | 104k | } |
68 | | |
69 | 244k | set_exponent (outval, 255); |
70 | 244k | } |
71 | 5.83M | else { |
72 | 5.83M | if (exp) |
73 | 35.0M | while (!(*values & 0x800000) && --exp) { |
74 | 30.5M | shift_count++; |
75 | 30.5M | *(uint32_t*)values <<= 1; |
76 | 30.5M | } |
77 | | |
78 | 5.83M | if (shift_count &= 0x1f) { |
79 | 3.17M | if ((wps->float_flags & FLOAT_SHIFT_ONES) || |
80 | 2.92M | ((wps->float_flags & FLOAT_SHIFT_SAME) && getbit (&wps->wvxbits))) |
81 | 1.37M | *values |= ((1U << shift_count) - 1); |
82 | 1.80M | else if (wps->float_flags & FLOAT_SHIFT_SENT) { |
83 | 1.51M | int32_t mask = (1U << shift_count) - 1; |
84 | 1.51M | int num_zeros = 0; |
85 | | |
86 | 1.51M | if (max_shifted_ones && shift_count > max_shifted_ones) |
87 | 160k | num_zeros = shift_count - max_shifted_ones; |
88 | | |
89 | 1.51M | if (min_shifted_zeros > num_zeros) |
90 | 300k | num_zeros = (min_shifted_zeros > shift_count) ? shift_count : min_shifted_zeros; |
91 | | |
92 | 1.51M | if ((shift_count -= num_zeros) > 0) { |
93 | 1.24M | getbits (&temp, shift_count, &wps->wvxbits); |
94 | 1.24M | *values |= (temp << num_zeros) & mask; |
95 | 1.24M | } |
96 | 1.51M | } |
97 | 3.17M | } |
98 | | |
99 | 5.83M | set_mantissa (outval, *values); |
100 | 5.83M | set_exponent (outval, exp); |
101 | 5.83M | } |
102 | 6.08M | } |
103 | | |
104 | 8.38M | crc = crc * 27 + get_mantissa (outval) * 9 + get_exponent (outval) * 3 + get_sign (outval); |
105 | 8.38M | * (f32 *) values++ = outval; |
106 | 8.38M | } |
107 | | |
108 | 5.70k | wps->crc_x = crc; |
109 | 5.70k | } |
110 | | |
111 | | static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values) |
112 | 51.9k | { |
113 | 93.9M | while (num_values--) { |
114 | 93.9M | int shift_count = 0, exp = wps->float_max_exp; |
115 | 93.9M | f32 outval = 0; |
116 | | |
117 | 93.9M | if (*values) { |
118 | 51.8M | *(uint32_t*)values <<= (wps->float_shift & 0x1f); |
119 | | |
120 | 51.8M | if (*values < 0) { |
121 | 31.7M | *values = -*values; |
122 | 31.7M | set_sign (outval, 1); |
123 | 31.7M | } |
124 | | |
125 | 51.8M | if (*values >= 0x1000000) { |
126 | 49.5M | while (*values & 0xf000000) { |
127 | 36.0M | *values >>= 1; |
128 | 36.0M | ++exp; |
129 | 36.0M | } |
130 | 13.5M | } |
131 | 38.3M | else if (exp) { |
132 | 25.0M | while (!(*values & 0x800000) && --exp) { |
133 | 24.0M | shift_count++; |
134 | 24.0M | *(uint32_t*)values <<= 1; |
135 | 24.0M | } |
136 | | |
137 | 993k | if ((shift_count &= 0x1f) && (wps->float_flags & FLOAT_SHIFT_ONES)) |
138 | 319k | *values |= ((1U << shift_count) - 1); |
139 | 993k | } |
140 | | |
141 | 51.8M | set_mantissa (outval, *values); |
142 | 51.8M | set_exponent (outval, exp); |
143 | 51.8M | } |
144 | | |
145 | 93.9M | * (f32 *) values++ = outval; |
146 | 93.9M | } |
147 | 51.9k | } |