Another small bookmark.c revision, no functional change, saves bin size
[kugel-rb.git] / apps / codecs / libffmpegFLAC / shndec.c
blobfb11f77bfa574e2c49e0816987a9872e6b5d12ef
1 /*
2 * Shorten decoder
3 * Copyright (c) 2005 Jeff Muizelaar
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 /**
21 * @file shorten.c
22 * Shorten decoder
23 * @author Jeff Muizelaar
27 #include "bitstream.h"
28 #include "golomb.h"
29 #include "shndec.h"
30 #include "codeclib.h"
32 #define ULONGSIZE 2
34 #define WAVE_FORMAT_PCM 0x0001
36 #define TYPESIZE 4
37 #define CHANSIZE 0
38 #define LPCQSIZE 2
39 #define ENERGYSIZE 3
40 #define BITSHIFTSIZE 2
42 #define TYPE_S16HL 3 /* signed 16 bit shorts: high-low */
43 #define TYPE_S16LH 5 /* signed 16 bit shorts: low-high */
45 #define NWRAP 3
46 #define NSKIPSIZE 1
48 #define LPCQUANT 5
49 #define V2LPCQOFFSET (1 << LPCQUANT)
51 #define FNSIZE 2
53 #define VERBATIM_CKSIZE_SIZE 5
54 #define VERBATIM_BYTE_SIZE 8
55 #define CANONICAL_HEADER_SIZE 44
57 #define FFMAX(a,b) ((a) > (b) ? (a) : (b))
58 #define FFMIN(a,b) ((a) > (b) ? (b) : (a))
59 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
61 #define get_le16(gb) bswap_16(get_bits_long(gb, 16))
62 #define get_le32(gb) bswap_32(get_bits_long(gb, 32))
64 static uint32_t bswap_32(uint32_t x){
65 x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
66 return (x>>16) | (x<<16);
69 static uint16_t bswap_16(uint16_t x){
70 return (x>>8) | (x<<8);
73 /* converts fourcc string to int */
74 static int ff_get_fourcc(const char *s){
75 //assert( strlen(s)==4 );
76 return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24);
79 static unsigned int get_uint(ShortenContext *s, int k)
81 if (s->version != 0)
82 k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
83 return get_ur_golomb_shorten(&s->gb, k);
86 #if defined(CPU_COLDFIRE)
87 static void coldfire_lshift_samples(int n, int shift, int32_t *samples) ICODE_ATTR_FLAC;
88 static void coldfire_lshift_samples(int n, int shift, int32_t *samples)
91 for (i = 0; i < n; i++)
92 samples[i] =<< shift;
94 asm volatile (
95 "move.l %[n], %%d0 \n" /* d0 = loop counter */
96 "asr.l #2, %%d0 \n"
97 "beq l1_shift \n"
98 "l2_shift:" /* main loop (unroll by 4) */
99 "movem.l (%[x]), %%d4-%%d7 \n"
100 "asl.l %[s], %%d4 \n"
101 "asl.l %[s], %%d5 \n"
102 "asl.l %[s], %%d6 \n"
103 "asl.l %[s], %%d7 \n"
104 "movem.l %%d4-%%d7, (%[x]) \n"
105 "add.l #16, %[x] \n"
107 "subq.l #1, %%d0 \n"
108 "bne l2_shift \n"
109 "l1_shift:" /* any loops left? */
110 "and.l #3, %[n] \n"
111 "beq l4_shift \n"
112 "l3_shift:" /* remaining loops */
113 "move.l (%[x]), %%d4 \n"
114 "asl.l %[s], %%d4 \n"
115 "move.l %%d4, (%[x])+ \n"
117 "subq.l #1, %[n] \n"
118 "bne l3_shift \n"
119 "l4_shift:" /* exit */
120 : [n] "+d" (n), /* d1 */
121 [s] "+d" (shift), /* d2 */
122 [x] "+a" (samples) /* a0 */
124 : "%d0", "%d4", "%d5", "%d6", "%d7"
127 #endif
129 static inline void fix_bitshift(ShortenContext *s, int32_t *samples)
131 int i;
133 /* Wrapped samples don't get bitshifted, so we'll do them during
134 the next iteration. */
135 if (s->bitshift != 0) {
136 #if defined(CPU_COLDFIRE)
137 coldfire_lshift_samples(s->blocksize, s->bitshift, samples - s->nwrap);
138 #else
139 for (i = -s->nwrap; i < (s->blocksize - s->nwrap); i++)
140 samples[i] <<= s->bitshift;
141 #endif
144 /* Also, when we have to remember to fix the wrapped samples when
145 the bitshift changes.*/
146 if (s->bitshift != s->last_bitshift) {
147 if (s->last_bitshift != 0)
148 for (i = -s->nwrap; i < 0; i++)
149 samples[i] <<= s->last_bitshift;
151 s->last_bitshift = s->bitshift;
155 static inline void decode_subframe_lpc(ShortenContext *s, int32_t *decoded,
156 int residual_size, int pred_order)
158 int sum, i, j;
159 int coeffs[MAX_PRED_ORDER];
161 for (i=0; i<pred_order; i++) {
162 coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
165 for (i=0; i < s->blocksize; i++) {
166 sum = s->lpcqoffset;
167 for (j=0; j<pred_order; j++)
168 sum += coeffs[j] * decoded[i-j-1];
170 decoded[i] =
171 get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT);
175 static inline int shorten_decode_frame(ShortenContext *s, int32_t *decoded,
176 int32_t *offset)
178 int i;
179 int32_t sum;
181 int cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
182 switch (cmd) {
183 case FN_ZERO:
184 case FN_DIFF0:
185 case FN_DIFF1:
186 case FN_DIFF2:
187 case FN_DIFF3:
188 case FN_QLPC:
190 int residual_size = 0;
191 int32_t coffset;
192 if (cmd != FN_ZERO) {
193 residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
194 /* this is a hack as version 0 differed in defintion of
195 get_sr_golomb_shorten */
196 if (s->version == 0)
197 residual_size--;
200 if (s->nmean == 0) {
201 coffset = offset[0];
202 } else {
203 sum = (s->version < 2) ? 0 : s->nmean / 2;
204 for (i=0; i<s->nmean; i++)
205 sum += offset[i];
207 coffset = sum / s->nmean;
208 if (s->version >= 2)
209 coffset >>= FFMIN(1, s->bitshift);
212 switch (cmd) {
213 case FN_ZERO:
214 for (i=0; i<s->blocksize; i++)
215 decoded[i] = 0;
216 break;
218 case FN_DIFF0:
219 for (i=0; i<s->blocksize; i++)
220 decoded[i] =
221 get_sr_golomb_shorten(&s->gb, residual_size) +
222 coffset;
223 break;
225 case FN_DIFF1:
226 for (i=0; i<s->blocksize; i++)
227 decoded[i] =
228 get_sr_golomb_shorten(&s->gb, residual_size) +
229 decoded[i - 1];
230 break;
232 case FN_DIFF2:
233 for (i=0; i<s->blocksize; i++)
234 decoded[i] =
235 get_sr_golomb_shorten(&s->gb, residual_size) +
236 2*decoded[i-1] - decoded[i-2];
237 break;
239 case FN_DIFF3:
240 for (i=0; i<s->blocksize; i++)
241 decoded[i] =
242 get_sr_golomb_shorten(&s->gb, residual_size) +
243 3*decoded[i-1] - 3*decoded[i-2] + decoded[i-3];
244 break;
246 case FN_QLPC:
248 int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
249 for (i=0; i<pred_order; i++)
250 decoded[i - pred_order] -= coffset;
251 decode_subframe_lpc(s, decoded, residual_size, pred_order);
252 if (coffset != 0) {
253 for (i=0; i < s->blocksize; i++)
254 decoded[i] += coffset;
259 if (s->nmean > 0) {
260 sum = (s->version < 2) ? 0 : s->blocksize / 2;
261 for (i=0; i<s->blocksize; i++)
262 sum += decoded[i];
264 for (i=1; i<s->nmean; i++)
265 offset[i-1] = offset[i];
267 if (s->version < 2) {
268 offset[s->nmean - 1] = sum / s->blocksize;
269 } else {
270 offset[s->nmean - 1] =
271 (sum / s->blocksize) << s->bitshift;
275 fix_bitshift(s, decoded);
276 break;
279 case FN_VERBATIM:
280 i = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
281 while (i--)
282 get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
283 break;
285 case FN_BITSHIFT:
286 s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
287 break;
289 case FN_BLOCKSIZE:
290 s->blocksize = get_uint(s, av_log2(s->blocksize));
291 break;
293 case FN_QUIT:
294 break;
296 default:
297 return FN_ERROR;
298 break;
301 return cmd;
304 int shorten_decode_frames(ShortenContext *s, int *nsamples,
305 int32_t *decoded0, int32_t *decoded1,
306 int32_t *offset0, int32_t *offset1,
307 uint8_t *buf, int buf_size,
308 void (*yield)(void))
310 int32_t *decoded, *offset;
311 int cmd;
313 *nsamples = 0;
315 init_get_bits(&s->gb, buf, buf_size*8);
316 get_bits(&s->gb, s->bitindex);
318 int n = 0;
319 while (n < NUM_DEC_LOOPS) {
320 int chan = n%2;
321 if (chan == 0) {
322 decoded = decoded0 + s->nwrap + *nsamples;
323 offset = offset0;
324 } else {
325 decoded = decoded1 + s->nwrap + *nsamples;
326 offset = offset1;
329 yield();
331 cmd = shorten_decode_frame(s, decoded, offset);
333 if (cmd == FN_VERBATIM || cmd == FN_BITSHIFT || cmd == FN_BLOCKSIZE) {
334 continue;
335 } else if (cmd == FN_QUIT || cmd == FN_ERROR) {
336 break;
339 *nsamples += chan * s->blocksize;
340 n++;
343 if (*nsamples) {
344 /* Wrap the samples for the next loop */
345 int i;
346 for (i = 0; i < s->nwrap; i++) {
347 decoded0[i] = decoded0[*nsamples + i];
348 decoded1[i] = decoded1[*nsamples + i];
351 /* Scale the samples for the pcmbuf */
352 int scale = SHN_OUTPUT_DEPTH - s->bits_per_sample;
353 #if defined(CPU_COLDFIRE)
354 coldfire_lshift_samples(*nsamples, scale, decoded0 + s->nwrap);
355 coldfire_lshift_samples(*nsamples, scale, decoded1 + s->nwrap);
356 #else
357 for (i = 0; i < *nsamples; i++) {
358 decoded0[i + s->nwrap] <<= scale;
359 decoded1[i + s->nwrap] <<= scale;
361 #endif
364 return cmd;
367 static int decode_wave_header(ShortenContext *s,
368 uint8_t *header,
369 int header_size)
371 GetBitContext hb;
372 int len;
374 init_get_bits(&hb, header, header_size*8);
375 if (get_le32(&hb) != MKTAG('R','I','F','F')) {
376 return -8;
379 int chunk_size = get_le32(&hb);
381 if (get_le32(&hb) != MKTAG('W','A','V','E')) {
382 return -9;
385 while (get_le32(&hb) != MKTAG('f','m','t',' ')) {
386 len = get_le32(&hb);
387 skip_bits(&hb, 8*len);
390 len = get_le32(&hb);
391 if (len < 16) {
392 return -10;
395 if (get_le16(&hb) != WAVE_FORMAT_PCM ) {
396 return -11;
399 s->channels = get_le16(&hb);
400 if (s->channels > MAX_CHANNELS) {
401 return -3;
404 s->sample_rate = get_le32(&hb);
406 skip_bits(&hb, 32);
407 //s->bit_rate = 8*get_le32(&hb);
409 int block_align = get_le16(&hb);
410 s->totalsamples = (chunk_size - 36) / block_align;
412 s->bits_per_sample = get_le16(&hb);
413 if (s->bits_per_sample != 16) {
414 return -12;
417 len -= 16;
418 if (len > 0) {
419 return len;
422 return 0;
425 int shorten_init(ShortenContext* s, uint8_t *buf, int buf_size)
427 int i;
429 s->blocksize = DEFAULT_BLOCK_SIZE;
430 s->channels = 1;
431 s->nmean = -1;
433 init_get_bits(&s->gb, buf, buf_size*8);
434 get_bits(&s->gb, s->bitindex);
436 /* shorten signature */
437 if (get_bits_long(&s->gb, 32) != bswap_32(ff_get_fourcc("ajkg"))) {
438 return -1;
441 s->version = get_bits(&s->gb, 8);
443 int internal_ftype = get_uint(s, TYPESIZE);
444 if ((internal_ftype != TYPE_S16HL) && (internal_ftype != TYPE_S16LH)) {
445 return -2;
448 s->channels = get_uint(s, CHANSIZE);
449 if (s->channels > MAX_CHANNELS) {
450 return -3;
453 /* get blocksize if version > 0 */
454 int maxnlpc = 0;
455 if (s->version > 0) {
456 s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
457 maxnlpc = get_uint(s, LPCQSIZE);
458 s->nmean = get_uint(s, 0);
460 int skip_bytes = get_uint(s, NSKIPSIZE);
461 for (i=0; i<skip_bytes; i++) {
462 skip_bits(&s->gb, 8);
466 if (s->nmean > MAX_NMEAN) {
467 return -4;
470 s->nwrap = FFMAX(NWRAP, maxnlpc);
471 if (s->nwrap > MAX_NWRAP) {
472 return -5;
475 if (s->version > 1)
476 s->lpcqoffset = V2LPCQOFFSET;
478 if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
479 return -6;
482 uint8_t header[MAX_HEADER_SIZE];
483 int header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
484 if (header_size >= MAX_HEADER_SIZE || header_size < CANONICAL_HEADER_SIZE) {
485 return -7;
488 for (i=0; i<header_size; i++)
489 header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
491 s->header_bits = s->gb.index;
493 return decode_wave_header(s, header, header_size);