summaryrefslogtreecommitdiff
path: root/apps/codecs/demac/libdemac/entropy.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/demac/libdemac/entropy.c')
-rw-r--r--apps/codecs/demac/libdemac/entropy.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/apps/codecs/demac/libdemac/entropy.c b/apps/codecs/demac/libdemac/entropy.c
new file mode 100644
index 0000000000..2c60420250
--- /dev/null
+++ b/apps/codecs/demac/libdemac/entropy.c
@@ -0,0 +1,314 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27
28#include "parser.h"
29#include "entropy.h"
30#include "rangecoding.h" /* Range-coding (static inline) functions */
31
32#define MODEL_ELEMENTS 64
33
34/*
35 The following counts arrays for use with the range decoder are
36 hard-coded in the Monkey's Audio decoder.
37*/
38
39static const int counts_3970[65] ICONST_ATTR =
40{
41 0,14824,28224,39348,47855,53994,58171,60926,
42 62682,63786,64463,64878,65126,65276,65365,65419,
43 65450,65469,65480,65487,65491,65493,65494,65495,
44 65496,65497,65498,65499,65500,65501,65502,65503,
45 65504,65505,65506,65507,65508,65509,65510,65511,
46 65512,65513,65514,65515,65516,65517,65518,65519,
47 65520,65521,65522,65523,65524,65525,65526,65527,
48 65528,65529,65530,65531,65532,65533,65534,65535,
49 65536
50};
51
52/* counts_diff_3970[i] = counts_3970[i+1] - counts_3970[i] */
53static const int counts_diff_3970[64] ICONST_ATTR =
54{
55 14824,13400,11124,8507,6139,4177,2755,1756,
56 1104,677,415,248,150,89,54,31,
57 19,11,7,4,2,1,1,1,
58 1,1,1,1,1,1,1,1,
59 1,1,1,1,1,1,1,1,
60 1,1,1,1,1,1,1,1,
61 1,1,1,1,1,1,1,1,
62 1,1,1,1,1,1,1,1
63};
64
65static const int counts_3980[65] ICONST_ATTR =
66{
67 0,19578,36160,48417,56323,60899,63265,64435,
68 64971,65232,65351,65416,65447,65466,65476,65482,
69 65485,65488,65490,65491,65492,65493,65494,65495,
70 65496,65497,65498,65499,65500,65501,65502,65503,
71 65504,65505,65506,65507,65508,65509,65510,65511,
72 65512,65513,65514,65515,65516,65517,65518,65519,
73 65520,65521,65522,65523,65524,65525,65526,65527,
74 65528,65529,65530,65531,65532,65533,65534,65535,
75 65536
76};
77
78/* counts_diff_3980[i] = counts_3980[i+1] - counts_3980[i] */
79
80static const int counts_diff_3980[64] ICONST_ATTR =
81{
82 19578,16582,12257,7906,4576,2366,1170,536,
83 261,119,65,31,19,10,6,3,
84 3,2,1,1,1,1,1,1,
85 1,1,1,1,1,1,1,1,
86 1,1,1,1,1,1,1,1,
87 1,1,1,1,1,1,1,1,
88 1,1,1,1,1,1,1,1,
89 1,1,1,1,1,1,1,1
90};
91
92/*
93 range_get_symbol_* functions based on main decoding loop in simple_d.c from
94 http://www.compressconsult.com/rangecoder/rngcod13.zip
95 (c) Michael Schindler
96*/
97
98static inline int range_get_symbol_3980(void)
99{
100 int symbol, cf;
101
102 cf = range_decode_culshift(16);
103
104 /* figure out the symbol inefficiently; a binary search would be much better */
105 for (symbol = 0; counts_3980[symbol+1] <= cf; symbol++);
106
107 range_decode_update(counts_diff_3980[symbol],counts_3980[symbol]);
108
109 return symbol;
110}
111
112static inline int range_get_symbol_3970(void)
113{
114 int symbol, cf;
115
116 cf = range_decode_culshift(16);
117
118 /* figure out the symbol inefficiently; a binary search would be much better */
119 for (symbol = 0; counts_3970[symbol+1] <= cf; symbol++);
120
121 range_decode_update(counts_diff_3970[symbol],counts_3970[symbol]);
122
123 return symbol;
124}
125
126/* MAIN DECODING FUNCTIONS */
127
128struct rice_t
129{
130 uint32_t k;
131 uint32_t ksum;
132};
133
134static struct rice_t riceX IBSS_ATTR;
135static struct rice_t riceY IBSS_ATTR;
136
137static inline void update_rice(struct rice_t* rice, int x)
138{
139 rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
140
141 if (rice->k == 0) {
142 rice->k = 1;
143 } else if (rice->ksum < ((uint32_t)1 << (rice->k + 4))) {
144 rice->k--;
145 } else if (rice->ksum >= ((uint32_t)1 << (rice->k + 5))) {
146 rice->k++;
147 }
148}
149
150static inline int entropy_decode3980(struct rice_t* rice)
151{
152 int base, x, pivot, overflow;
153
154 pivot = rice->ksum >> 5;
155 if (pivot == 0) pivot=1;
156
157 overflow = range_get_symbol_3980();
158
159 if (overflow == (MODEL_ELEMENTS-1)) {
160 overflow = range_decode_short() << 16;
161 overflow |= range_decode_short();
162 }
163
164 if (pivot >= 0x10000) {
165 /* Codepath for 24-bit streams */
166 int nbits, lo_bits, base_hi, base_lo;
167
168 /* Count the number of bits in pivot */
169 nbits = 17; /* We know there must be at least 17 bits */
170 while ((pivot >> nbits) > 0) { nbits++; }
171
172 /* base_lo is the low (nbits-16) bits of base
173 base_hi is the high 16 bits of base
174 */
175 lo_bits = (nbits - 16);
176
177 base_hi = range_decode_culfreq((pivot >> lo_bits) + 1);
178 range_decode_update(1, base_hi);
179
180 base_lo = range_decode_culfreq(1 << lo_bits);
181 range_decode_update(1, base_lo);
182
183 base = (base_hi << lo_bits) + base_lo;
184 } else {
185 /* Codepath for 16-bit streams */
186 base = range_decode_culfreq(pivot);
187 range_decode_update(1, base);
188 }
189
190 x = base + (overflow * pivot);
191 update_rice(rice, x);
192
193 /* Convert to signed */
194 if (x & 1)
195 return (x >> 1) + 1;
196 else
197 return -(x >> 1);
198}
199
200
201static inline int entropy_decode3970(struct rice_t* rice)
202{
203 int x, tmpk;
204
205 int overflow = range_get_symbol_3970();
206
207 if (overflow == (MODEL_ELEMENTS - 1)) {
208 tmpk = range_decode_bits(5);
209 overflow = 0;
210 } else {
211 tmpk = (rice->k < 1) ? 0 : rice->k - 1;
212 }
213
214 if (tmpk <= 16) {
215 x = range_decode_bits(tmpk);
216 } else {
217 x = range_decode_short();
218 x |= (range_decode_bits(tmpk - 16) << 16);
219 }
220 x += (overflow << tmpk);
221
222 update_rice(rice, x);
223
224 /* Convert to signed */
225 if (x & 1)
226 return (x >> 1) + 1;
227 else
228 return -(x >> 1);
229}
230
231void init_entropy_decoder(struct ape_ctx_t* ape_ctx,
232 unsigned char* inbuffer, int* firstbyte,
233 int* bytesconsumed)
234{
235 bytebuffer = inbuffer;
236 bytebufferoffset = *firstbyte;
237
238 /* Read the CRC */
239 ape_ctx->CRC = read_byte();
240 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
241 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
242 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
243
244 /* Read the frame flags if they exist */
245 ape_ctx->frameflags = 0;
246 if ((ape_ctx->fileversion > 3820) && (ape_ctx->CRC & 0x80000000)) {
247 ape_ctx->CRC &= ~0x80000000;
248
249 ape_ctx->frameflags = read_byte();
250 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
251 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
252 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
253 }
254 /* Keep a count of the blocks decoded in this frame */
255 ape_ctx->blocksdecoded = 0;
256
257 /* Initialise the rice structs */
258 riceX.k = 10;
259 riceX.ksum = (1 << riceX.k) * 16;
260 riceY.k = 10;
261 riceY.ksum = (1 << riceY.k) * 16;
262
263 /* The first 8 bits of input are ignored. */
264 skip_byte();
265
266 range_start_decoding();
267
268 /* Return the new state of the buffer */
269 *bytesconsumed = (intptr_t)bytebuffer - (intptr_t)inbuffer;
270 *firstbyte = bytebufferoffset;
271}
272
273int entropy_decode(struct ape_ctx_t* ape_ctx,
274 unsigned char* inbuffer, int* firstbyte,
275 int* bytesconsumed,
276 int32_t* decoded0, int32_t* decoded1,
277 int blockstodecode)
278{
279 bytebuffer = inbuffer;
280 bytebufferoffset = *firstbyte;
281
282 ape_ctx->blocksdecoded += blockstodecode;
283
284 if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
285 /* We are pure silence, just memset the output buffer. */
286 memset(decoded0, 0, blockstodecode * sizeof(int32_t));
287 memset(decoded1, 0, blockstodecode * sizeof(int32_t));
288 } else {
289 if (ape_ctx->fileversion > 3970) {
290 while (blockstodecode--) {
291 *(decoded0++) = entropy_decode3980(&riceY);
292 if (decoded1 != NULL)
293 *(decoded1++) = entropy_decode3980(&riceX);
294 }
295 } else {
296 while (blockstodecode--) {
297 *(decoded0++) = entropy_decode3970(&riceY);
298 if (decoded1 != NULL)
299 *(decoded1++) = entropy_decode3970(&riceX);
300 }
301 }
302 }
303
304 if (ape_ctx->blocksdecoded == ape_ctx->currentframeblocks)
305 {
306 range_done_decoding();
307 }
308
309 /* Return the new state of the buffer */
310 *bytesconsumed = bytebuffer - inbuffer;
311 *firstbyte = bytebufferoffset;
312
313 return(0);
314}