annotate celp_filters.c @ 10311:943b63f364ca libavcodec

Make sure all the bits are written to output in fax data decoder. This fixes decoding TIFF images with fax compression and width being not multiple of eight (and issue 1429).
author kostya
date Tue, 29 Sep 2009 05:55:14 +0000
parents d35904b4fe3f
children 8d536f190e6e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
1 /*
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
2 * various filters for ACELP-based codecs
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
3 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
4 * Copyright (c) 2008 Vladimir Voroshilov
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
5 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
6 * This file is part of FFmpeg.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
7 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
12 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
16 * Lesser General Public License for more details.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
17 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
21 */
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
22
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
23 #include <inttypes.h>
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
24
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
25 #include "avcodec.h"
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
26 #include "celp_filters.h"
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
27
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
28 void ff_celp_convolve_circ(int16_t* fc_out,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
29 const int16_t* fc_in,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
30 const int16_t* filter,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
31 int len)
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
32 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
33 int i, k;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
34
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
35 memset(fc_out, 0, len * sizeof(int16_t));
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
36
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
37 /* Since there are few pulses over an entire subframe (i.e. almost
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
38 all fc_in[i] are zero) it is faster to loop over fc_in first. */
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
39 for (i = 0; i < len; i++) {
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
40 if (fc_in[i]) {
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
41 for (k = 0; k < i; k++)
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
42 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
43
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
44 for (k = i; k < len; k++)
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
45 fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
46 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
47 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
48 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
49
10045
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
50 void ff_celp_circ_addf(float *out, const float *in,
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
51 const float *lagged, int lag, float fac, int n)
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
52 {
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
53 int k;
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
54 for (k = 0; k < lag; k++)
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
55 out[k] = in[k] + fac * lagged[n + k - lag];
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
56 for (; k < n; k++)
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
57 out[k] = in[k] + fac * lagged[ k - lag];
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
58 }
d35904b4fe3f Add ff_celp_circ_addf() function to be used for sparse vector circular
superdump
parents: 10013
diff changeset
59
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
60 int ff_celp_lp_synthesis_filter(int16_t *out,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
61 const int16_t* filter_coeffs,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
62 const int16_t* in,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
63 int buffer_length,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
64 int filter_length,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
65 int stop_on_overflow,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
66 int rounder)
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
67 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
68 int i,n;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
69
9447
d7554a5e3fd7 [COSMETIC] Correct a minor nit. Should be clearer now.
reynaldo
parents: 9446
diff changeset
70 // Avoids a +1 in the inner loop.
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
71 filter_length++;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
72
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
73 for (n = 0; n < buffer_length; n++) {
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
74 int sum = rounder;
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
75 for (i = 1; i < filter_length; i++)
9446
1a3865d1b049 Fix possibly harmful outbound addressing. Patch by Kenan Gillet.
reynaldo
parents: 9017
diff changeset
76 sum -= filter_coeffs[i-1] * out[n-i];
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
77
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
78 sum = (sum >> 12) + in[n];
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
79
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
80 if (sum + 0x8000 > 0xFFFFU) {
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
81 if (stop_on_overflow)
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
82 return 1;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
83 sum = (sum >> 31) ^ 32767;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
84 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
85 out[n] = sum;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
86 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
87
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
88 return 0;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
89 }
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
90
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
91 void ff_celp_lp_synthesis_filterf(float *out,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
92 const float* filter_coeffs,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
93 const float* in,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
94 int buffer_length,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
95 int filter_length)
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
96 {
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
97 int i,n;
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
98
9447
d7554a5e3fd7 [COSMETIC] Correct a minor nit. Should be clearer now.
reynaldo
parents: 9446
diff changeset
99 // Avoids a +1 in the inner loop.
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
100 filter_length++;
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
101
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
102 for (n = 0; n < buffer_length; n++) {
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
103 out[n] = in[n];
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
104 for (i = 1; i < filter_length; i++)
9446
1a3865d1b049 Fix possibly harmful outbound addressing. Patch by Kenan Gillet.
reynaldo
parents: 9017
diff changeset
105 out[n] -= filter_coeffs[i-1] * out[n-i];
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
106 }
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
107 }
9509
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
108
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
109 void ff_celp_lp_zero_synthesis_filterf(float *out,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
110 const float* filter_coeffs,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
111 const float* in,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
112 int buffer_length,
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
113 int filter_length)
9509
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
114 {
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
115 int i,n;
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
116
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
117 // Avoids a +1 in the inner loop.
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
118 filter_length++;
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
119
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
120 for (n = 0; n < buffer_length; n++) {
9509
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
121 out[n] = in[n];
10003
24952f1a8979 cosmetics: K&R coding style
diego
parents: 9509
diff changeset
122 for (i = 1; i < filter_length; i++)
10013
454cb6aa43a3 Correct the sign of the arithmetic in ff_celp_lp_zero_synthesis_filterf()
superdump
parents: 10003
diff changeset
123 out[n] += filter_coeffs[i-1] * in[n-i];
9509
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
124 }
2838045383c5 Add LP zero synthesis filter. Patch by Kenan Gillet.
reynaldo
parents: 9447
diff changeset
125 }