Coverage Report

Created: 2023-06-07 06:30

/src/wavpack/src/entropy_utils.c
Line
Count
Source (jump to first uncovered line)
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
// entropy_utils.c
10
11
// This module contains the functions that process metadata blocks that are
12
// specific to the entropy decoder; these would be called any time a WavPack
13
// block was parsed. Additionally, it contains tables and functions that are
14
// common to both entropy coding and decoding. These are in a module separate
15
// from the actual entropy encoder (write_words.c) and decoder (read_words.c)
16
// so that if applications that just do a subset of the full WavPack reading
17
// and writing can link with a subset of the library.
18
19
#include <stdlib.h>
20
#include <string.h>
21
22
#include "wavpack_local.h"
23
24
///////////////////////////// local table storage ////////////////////////////
25
26
const uint32_t bitset [] = {
27
    1L << 0, 1L << 1, 1L << 2, 1L << 3,
28
    1L << 4, 1L << 5, 1L << 6, 1L << 7,
29
    1L << 8, 1L << 9, 1L << 10, 1L << 11,
30
    1L << 12, 1L << 13, 1L << 14, 1L << 15,
31
    1L << 16, 1L << 17, 1L << 18, 1L << 19,
32
    1L << 20, 1L << 21, 1L << 22, 1L << 23,
33
    1L << 24, 1L << 25, 1L << 26, 1L << 27,
34
    1L << 28, 1L << 29, 1L << 30, 1L << 31
35
};
36
37
const uint32_t bitmask [] = {
38
    (1L << 0) - 1, (1L << 1) - 1, (1L << 2) - 1, (1L << 3) - 1,
39
    (1L << 4) - 1, (1L << 5) - 1, (1L << 6) - 1, (1L << 7) - 1,
40
    (1L << 8) - 1, (1L << 9) - 1, (1L << 10) - 1, (1L << 11) - 1,
41
    (1L << 12) - 1, (1L << 13) - 1, (1L << 14) - 1, (1L << 15) - 1,
42
    (1L << 16) - 1, (1L << 17) - 1, (1L << 18) - 1, (1L << 19) - 1,
43
    (1L << 20) - 1, (1L << 21) - 1, (1L << 22) - 1, (1L << 23) - 1,
44
    (1L << 24) - 1, (1L << 25) - 1, (1L << 26) - 1, (1L << 27) - 1,
45
    (1L << 28) - 1, (1L << 29) - 1, (1L << 30) - 1, 0x7fffffff
46
};
47
48
const char nbits_table [] = {
49
    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,     // 0 - 15
50
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,     // 16 - 31
51
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,     // 32 - 47
52
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,     // 48 - 63
53
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,     // 64 - 79
54
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,     // 80 - 95
55
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,     // 96 - 111
56
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,     // 112 - 127
57
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 128 - 143
58
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 144 - 159
59
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 160 - 175
60
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 176 - 191
61
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 192 - 207
62
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 208 - 223
63
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // 224 - 239
64
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8      // 240 - 255
65
};
66
67
static const unsigned char log2_table [] = {
68
    0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
69
    0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
70
    0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
71
    0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
72
    0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
73
    0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
74
    0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
75
    0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
76
    0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
77
    0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
78
    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
79
    0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
80
    0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
81
    0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
82
    0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
83
    0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
84
};
85
86
static const unsigned char exp2_table [] = {
87
    0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
88
    0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
89
    0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
90
    0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
91
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
92
    0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
93
    0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
94
    0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
95
    0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
96
    0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
97
    0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
98
    0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
99
    0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
100
    0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
101
    0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
102
    0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
103
};
104
105
///////////////////////////// executable code ////////////////////////////////
106
107
// Read the median log2 values from the specified metadata structure, convert
108
// them back to 32-bit unsigned values and store them. If length is not
109
// exactly correct then we flag and return an error.
110
111
int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
112
1.35k
{
113
1.35k
    unsigned char *byteptr = (unsigned char *)wpmd->data;
114
115
1.35k
    if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12))
116
273
        return FALSE;
117
118
1.08k
    wps->w.c [0].median [0] = wp_exp2s (byteptr [0] + (byteptr [1] << 8));
119
1.08k
    wps->w.c [0].median [1] = wp_exp2s (byteptr [2] + (byteptr [3] << 8));
120
1.08k
    wps->w.c [0].median [2] = wp_exp2s (byteptr [4] + (byteptr [5] << 8));
121
122
1.08k
    if (!(wps->wphdr.flags & MONO_DATA)) {
123
412
        wps->w.c [1].median [0] = wp_exp2s (byteptr [6] + (byteptr [7] << 8));
124
412
        wps->w.c [1].median [1] = wp_exp2s (byteptr [8] + (byteptr [9] << 8));
125
412
        wps->w.c [1].median [2] = wp_exp2s (byteptr [10] + (byteptr [11] << 8));
126
412
    }
127
128
1.08k
    return TRUE;
129
1.35k
}
130
131
// Read the hybrid related values from the specified metadata structure, convert
132
// them back to their internal formats and store them. The extended profile
133
// stuff is not implemented yet, so return an error if we get more data than
134
// we know what to do with.
135
136
int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
137
2.00k
{
138
2.00k
    unsigned char *byteptr = (unsigned char *)wpmd->data;
139
2.00k
    unsigned char *endptr = byteptr + wpmd->byte_length;
140
141
2.00k
    if (wps->wphdr.flags & HYBRID_BITRATE) {
142
1.00k
        if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr)
143
367
            return FALSE;
144
145
633
        wps->w.c [0].slow_level = wp_exp2s (byteptr [0] + (byteptr [1] << 8));
146
633
        byteptr += 2;
147
148
633
        if (!(wps->wphdr.flags & MONO_DATA)) {
149
263
            wps->w.c [1].slow_level = wp_exp2s (byteptr [0] + (byteptr [1] << 8));
150
263
            byteptr += 2;
151
263
        }
152
633
    }
153
154
1.63k
    if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr)
155
202
        return FALSE;
156
157
1.43k
    wps->w.bitrate_acc [0] = (uint32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
158
1.43k
    byteptr += 2;
159
160
1.43k
    if (!(wps->wphdr.flags & MONO_DATA)) {
161
591
        wps->w.bitrate_acc [1] = (uint32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
162
591
        byteptr += 2;
163
591
    }
164
165
1.43k
    if (byteptr < endptr) {
166
931
        if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr)
167
206
            return FALSE;
168
169
725
        wps->w.bitrate_delta [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8)));
170
725
        byteptr += 2;
171
172
725
        if (!(wps->wphdr.flags & MONO_DATA)) {
173
214
            wps->w.bitrate_delta [1] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8)));
174
214
            byteptr += 2;
175
214
        }
176
177
725
        if (byteptr < endptr)
178
353
            return FALSE;
179
725
    }
180
500
    else
181
500
        wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0;
182
183
872
    return TRUE;
184
1.43k
}
185
186
// This function is called during both encoding and decoding of hybrid data to
187
// update the "error_limit" variable which determines the maximum sample error
188
// allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only
189
// currently implemented) this is calculated from the slow_level values and the
190
// bitrate accumulators. Note that the bitrate accumulators can be changing.
191
192
void update_error_limit (WavpackStream *wps)
193
63.0M
{
194
63.0M
    int bitrate_0 = (wps->w.bitrate_acc [0] += wps->w.bitrate_delta [0]) >> 16;
195
196
63.0M
    if (wps->wphdr.flags & MONO_DATA) {
197
24.7M
        if (wps->wphdr.flags & HYBRID_BITRATE) {
198
13.0M
            int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS;
199
200
13.0M
            if (slow_log_0 - bitrate_0 > -0x100)
201
12.6M
                wps->w.c [0].error_limit = wp_exp2s (slow_log_0 - bitrate_0 + 0x100);
202
392k
            else
203
392k
                wps->w.c [0].error_limit = 0;
204
13.0M
        }
205
11.7M
        else
206
11.7M
            wps->w.c [0].error_limit = wp_exp2s (bitrate_0);
207
24.7M
    }
208
38.2M
    else {
209
38.2M
        int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16;
210
211
38.2M
        if (wps->wphdr.flags & HYBRID_BITRATE) {
212
23.8M
            int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS;
213
23.8M
            int slow_log_1 = (wps->w.c [1].slow_level + SLO) >> SLS;
214
215
23.8M
            if (wps->wphdr.flags & HYBRID_BALANCE) {
216
17.3M
                int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
217
218
17.3M
                if (balance > bitrate_0) {
219
7.20M
                    bitrate_1 = bitrate_0 * 2;
220
7.20M
                    bitrate_0 = 0;
221
7.20M
                }
222
10.1M
                else if (-balance > bitrate_0) {
223
6.48M
                    bitrate_0 = bitrate_0 * 2;
224
6.48M
                    bitrate_1 = 0;
225
6.48M
                }
226
3.65M
                else {
227
3.65M
                    bitrate_1 = bitrate_0 + balance;
228
3.65M
                    bitrate_0 = bitrate_0 - balance;
229
3.65M
                }
230
17.3M
            }
231
232
23.8M
            if (slow_log_0 - bitrate_0 > -0x100)
233
22.5M
                wps->w.c [0].error_limit = wp_exp2s (slow_log_0 - bitrate_0 + 0x100);
234
1.30M
            else
235
1.30M
                wps->w.c [0].error_limit = 0;
236
237
23.8M
            if (slow_log_1 - bitrate_1 > -0x100)
238
22.5M
                wps->w.c [1].error_limit = wp_exp2s (slow_log_1 - bitrate_1 + 0x100);
239
1.30M
            else
240
1.30M
                wps->w.c [1].error_limit = 0;
241
23.8M
        }
242
14.4M
        else {
243
14.4M
            wps->w.c [0].error_limit = wp_exp2s (bitrate_0);
244
14.4M
            wps->w.c [1].error_limit = wp_exp2s (bitrate_1);
245
14.4M
        }
246
38.2M
    }
247
63.0M
}
248
249
// The concept of a base 2 logarithm is used in many parts of WavPack. It is
250
// a way of sufficiently accurately representing 32-bit signed and unsigned
251
// values storing only 16 bits (actually fewer). It is also used in the hybrid
252
// mode for quickly comparing the relative magnitude of large values (i.e.
253
// division) and providing smooth exponentials using only addition.
254
255
// These are not strict logarithms in that they become linear around zero and
256
// can therefore represent both zero and negative values. They have 8 bits
257
// of precision and in "roundtrip" conversions the total error never exceeds 1
258
// part in 225 except for the cases of +/-115 and +/-195 (which error by 1).
259
260
261
// This function returns the log2 for the specified 32-bit unsigned value.
262
// The maximum value allowed is about 0xff800000 and returns 8447.
263
264
int FASTCALL wp_log2 (uint32_t avalue)
265
60.9M
{
266
60.9M
    int dbits;
267
268
60.9M
    if ((avalue += avalue >> 9) < (1 << 8)) {
269
32.8M
        dbits = nbits_table [avalue];
270
32.8M
        return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
271
32.8M
    }
272
28.1M
    else {
273
28.1M
        if (avalue < (1L << 16))
274
2.96M
            dbits = nbits_table [avalue >> 8] + 8;
275
25.2M
        else if (avalue < (1L << 24))
276
10.5M
            dbits = nbits_table [avalue >> 16] + 16;
277
14.6M
        else
278
14.6M
            dbits = nbits_table [avalue >> 24] + 24;
279
280
28.1M
        return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
281
28.1M
    }
282
60.9M
}
283
284
// This function scans a buffer of longs and accumulates the total log2 value
285
// of all the samples. This is useful for determining maximum compression
286
// because the bitstream storage required for entropy coding is proportional
287
// to the base 2 log of the samples. On some platforms there is an assembly
288
// version of this.
289
290
#if !defined(OPT_ASM_X86) && !defined(OPT_ASM_X64)
291
292
uint32_t log2buffer (int32_t *samples, uint32_t num_samples, int limit)
293
{
294
    uint32_t result = 0, avalue;
295
    int dbits;
296
297
    while (num_samples--) {
298
        avalue = abs (*samples++);
299
300
        if ((avalue += avalue >> 9) < (1 << 8)) {
301
            dbits = nbits_table [avalue];
302
            result += (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
303
        }
304
        else {
305
            if (avalue < (1L << 16))
306
                dbits = nbits_table [avalue >> 8] + 8;
307
            else if (avalue < (1L << 24))
308
                dbits = nbits_table [avalue >> 16] + 16;
309
            else
310
                dbits = nbits_table [avalue >> 24] + 24;
311
312
            result += dbits = (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
313
314
            if (limit && dbits >= limit)
315
                return (uint32_t) -1;
316
        }
317
    }
318
319
    return result;
320
}
321
322
#endif
323
324
// This function returns the log2 for the specified 32-bit signed value.
325
// All input values are valid and the return values are in the range of
326
// +/- 8192.
327
328
int wp_log2s (int32_t value)
329
0
{
330
0
    return (value < 0) ? -wp_log2 (-value) : wp_log2 (value);
331
0
}
332
333
// This function returns the original integer represented by the supplied
334
// logarithm (at least within the provided accuracy). The log is signed,
335
// but since a full 32-bit value is returned this can be used for unsigned
336
// conversions as well (i.e. the input range is -8192 to +8447).
337
338
int32_t wp_exp2s (int log)
339
98.3M
{
340
98.3M
    uint32_t value;
341
342
98.3M
    if (log < 0)
343
2.83k
        return -wp_exp2s (-log);
344
345
98.3M
    value = exp2_table [log & 0xff] | 0x100;
346
347
98.3M
    if ((log >>= 8) <= 9)
348
69.6M
        return value >> (9 - log);
349
28.7M
    else
350
28.7M
        return value << ((log - 9) & 0x1f);
351
98.3M
}
352
353
// These two functions convert internal weights (which are normally +/-1024)
354
// to and from an 8-bit signed character version for storage in metadata. The
355
// weights are clipped here in the case that they are outside that range.
356
357
signed char store_weight (int weight)
358
0
{
359
0
    if (weight > 1024)
360
0
        weight = 1024;
361
0
    else if (weight < -1024)
362
0
        weight = -1024;
363
364
0
    if (weight > 0)
365
0
        weight -= (weight + 64) >> 7;
366
367
0
    return (weight + 4) >> 3;
368
0
}
369
370
int restore_weight (signed char weight)
371
6.86k
{
372
6.86k
    int result;
373
374
6.86k
    if ((result = (int) weight * 8) > 0)
375
4.94k
        result += (result + 64) >> 7;
376
377
6.86k
    return result;
378
6.86k
}