Coverage Report

Created: 2025-12-14 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}