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