Coverage Report

Created: 2023-06-07 06:30

/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
}