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.c155
1 files changed, 154 insertions, 1 deletions
diff --git a/apps/codecs/demac/libdemac/entropy.c b/apps/codecs/demac/libdemac/entropy.c
index 86ea06d389..baddce07be 100644
--- a/apps/codecs/demac/libdemac/entropy.c
+++ b/apps/codecs/demac/libdemac/entropy.c
@@ -27,7 +27,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
27 27
28#include "parser.h" 28#include "parser.h"
29#include "entropy.h" 29#include "entropy.h"
30#include "rangecoding.h" /* Range-coding (static inline) functions */
31#include "demac_iram.h" 30#include "demac_iram.h"
32 31
33#define MODEL_ELEMENTS 64 32#define MODEL_ELEMENTS 64
@@ -91,6 +90,160 @@ static const int counts_diff_3980[64] ICONST_ATTR =
91}; 90};
92 91
93/* 92/*
93
94Range decoder adapted from rangecod.c included in:
95
96 http://www.compressconsult.com/rangecoder/rngcod13.zip
97
98 rangecod.c range encoding
99
100 (c) Michael Schindler
101 1997, 1998, 1999, 2000
102 http://www.compressconsult.com/
103 michael@compressconsult.com
104
105 This program is free software; you can redistribute it and/or modify
106 it under the terms of the GNU General Public License as published by
107 the Free Software Foundation; either version 2 of the License, or
108 (at your option) any later version.
109
110
111The encoding functions were removed, and functions turned into "static
112inline" functions. Some minor cosmetic changes were made (e.g. turning
113pre-processor symbols into upper-case, removing the rc parameter from
114each function (and the RNGC macro)).
115
116*/
117
118#ifdef ROCKBOX
119#include "../lib/codeclib.h"
120/* for UDIV32() */
121#endif
122
123#ifndef UDIV32
124#define UDIV32(a, b) (a / b)
125#endif
126
127/* BITSTREAM READING FUNCTIONS */
128
129/* We deal with the input data one byte at a time - to ensure
130 functionality on CPUs of any endianness regardless of any requirements
131 for aligned reads.
132*/
133
134static unsigned char* bytebuffer IBSS_ATTR;
135static int bytebufferoffset IBSS_ATTR;
136
137static inline void skip_byte(void)
138{
139 bytebufferoffset--;
140 bytebuffer += bytebufferoffset & 4;
141 bytebufferoffset &= 3;
142}
143
144static inline int read_byte(void)
145{
146 int ch = bytebuffer[bytebufferoffset];
147
148 skip_byte();
149
150 return ch;
151}
152
153/* RANGE DECODING FUNCTIONS */
154
155/* SIZE OF RANGE ENCODING CODE VALUES. */
156
157#define CODE_BITS 32
158#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1))
159#define SHIFT_BITS (CODE_BITS - 9)
160#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1)
161#define BOTTOM_VALUE (TOP_VALUE >> 8)
162
163struct rangecoder_t
164{
165 uint32_t low; /* low end of interval */
166 uint32_t range; /* length of interval */
167 uint32_t help; /* bytes_to_follow resp. intermediate value */
168 unsigned int buffer; /* buffer for input/output */
169};
170
171static struct rangecoder_t rc IBSS_ATTR;
172
173/* Start the decoder */
174static inline void range_start_decoding(void)
175{
176 rc.buffer = read_byte();
177 rc.low = rc.buffer >> (8 - EXTRA_BITS);
178 rc.range = (uint32_t) 1 << EXTRA_BITS;
179}
180
181static inline void range_dec_normalize(void)
182{
183 while (rc.range <= BOTTOM_VALUE)
184 {
185 rc.buffer = (rc.buffer << 8) | read_byte();
186 rc.low = (rc.low << 8) | ((rc.buffer >> 1) & 0xff);
187 rc.range <<= 8;
188 }
189}
190
191/* Calculate culmulative frequency for next symbol. Does NO update!*/
192/* tot_f is the total frequency */
193/* or: totf is (code_value)1<<shift */
194/* returns the culmulative frequency */
195static inline int range_decode_culfreq(int tot_f)
196{
197 range_dec_normalize();
198 rc.help = UDIV32(rc.range, tot_f);
199 return UDIV32(rc.low, rc.help);
200}
201
202static inline int range_decode_culshift(int shift)
203{
204 range_dec_normalize();
205 rc.help = rc.range >> shift;
206 return UDIV32(rc.low, rc.help);
207}
208
209
210/* Update decoding state */
211/* sy_f is the interval length (frequency of the symbol) */
212/* lt_f is the lower end (frequency sum of < symbols) */
213static inline void range_decode_update(int sy_f, int lt_f)
214{
215 rc.low -= rc.help * lt_f;
216 rc.range = rc.help * sy_f;
217}
218
219
220/* Decode a byte/short without modelling */
221static inline unsigned char decode_byte(void)
222{ int tmp = range_decode_culshift(8);
223 range_decode_update( 1,tmp);
224 return tmp;
225}
226
227static inline int short range_decode_short(void)
228{ int tmp = range_decode_culshift(16);
229 range_decode_update( 1,tmp);
230 return tmp;
231}
232
233/* Decode n bits (n <= 16) without modelling - based on range_decode_short */
234static inline int range_decode_bits(int n)
235{ int tmp = range_decode_culshift(n);
236 range_decode_update( 1,tmp);
237 return tmp;
238}
239
240
241/* Finish decoding */
242static inline void range_done_decoding(void)
243{ range_dec_normalize(); /* normalize to use up all bytes */
244}
245
246/*
94 range_get_symbol_* functions based on main decoding loop in simple_d.c from 247 range_get_symbol_* functions based on main decoding loop in simple_d.c from
95 http://www.compressconsult.com/rangecoder/rngcod13.zip 248 http://www.compressconsult.com/rangecoder/rngcod13.zip
96 (c) Michael Schindler 249 (c) Michael Schindler