jpegdec: be less picky on padding
[ffmpeg.git] / libavcodec / ra144.c
index 9c23e43..1ec1e10 100644 (file)
 
 #include <stdint.h>
 #include "avcodec.h"
+#include "celp_filters.h"
+#include "mathops.h"
 #include "ra144.h"
 
-const int16_t gain_val_tab[256][3] = {
+const int16_t ff_gain_val_tab[256][3] = {
     { 541, 956,  768}, { 877, 581,  568}, { 675,1574,  635}, {1248,1464,  668},
     {1246, 839, 1394}, {2560,1386,  991}, { 925, 687,  608}, {2208, 797, 1144},
     { 535, 832,  799}, { 762, 605, 1154}, { 832,1122, 1003}, {1180, 687, 1176},
@@ -90,7 +92,7 @@ const int16_t gain_val_tab[256][3] = {
     {9216,1020, 2028}, {9968, 924, 1188}, {5424, 909, 1206}, {6512, 744, 1086}
 };
 
-const uint8_t gain_exp_tab[256] = {
+const uint8_t ff_gain_exp_tab[256] = {
    15, 15, 15, 15, 15, 16, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14,
    14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13,
    13, 13, 13, 13, 14, 13, 12, 12, 13, 13, 13, 12, 13, 13, 13, 13,
@@ -109,7 +111,7 @@ const uint8_t gain_exp_tab[256] = {
    12, 12, 11, 12, 12, 12, 12, 13, 11, 12, 12, 12, 13, 13, 12, 12
 };
 
-const int8_t cb1_vects[128][40]={
+const int8_t ff_cb1_vects[128][40]={
     {
      38,  -4,  15,  -4,  14, -13,  12, -11,  -2,  -6,
      -6, -11, -45, -16, -11, -13,  -7,   6, -12,   4,
@@ -753,7 +755,7 @@ const int8_t cb1_vects[128][40]={
     }
 };
 
-const int8_t cb2_vects[128][40]={
+const int8_t ff_cb2_vects[128][40]={
     {
      73, -32, -60, -15, -26,  59,   2, -33,  30, -10,
      -3, -17,   8,  30,  -1, -26,  -4, -22,  10,  16,
@@ -1397,7 +1399,7 @@ const int8_t cb2_vects[128][40]={
     }
 };
 
-const uint16_t cb1_base[128]={
+const uint16_t ff_cb1_base[128]={
     19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671,
     20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411,
     20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387,
@@ -1416,7 +1418,7 @@ const uint16_t cb1_base[128]={
     16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657,
 };
 
-const uint16_t cb2_base[128]={
+const uint16_t ff_cb2_base[128]={
     12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053,
     12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268,
     11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109,
@@ -1435,7 +1437,7 @@ const uint16_t cb2_base[128]={
     12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174,
 };
 
-const int16_t energy_tab[32]={
+const int16_t ff_energy_tab[32]={
         0,    16,    20,    25,    32,    41,    51,    65,
        81,   103,   129,   163,   205,   259,   326,   410,
       516,   650,   819,  1031,  1298,  1634,  2057,  2590,
@@ -1497,20 +1499,20 @@ static const int16_t lpc_refl_cb10[4]={
      -617,   190,   802,  1483
 };
 
-const int16_t * const lpc_refl_cb[10]={
+const int16_t * const ff_lpc_refl_cb[10]={
     lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5,
     lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
 };
 
-void add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
-             const int8_t *s2, const int8_t *s3)
+static void ff_add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
+                       const int8_t *s2, const int8_t *s3)
 {
     int i;
     int v[3];
 
     v[0] = 0;
     for (i=!skip_first; i<3; i++)
-        v[i] = (gain_val_tab[n][i] * m[i]) >> gain_exp_tab[n];
+        v[i] = (ff_gain_val_tab[n][i] * m[i]) >> ff_gain_exp_tab[n];
 
     if (v[0]) {
         for (i=0; i < BLOCKSIZE; i++)
@@ -1525,7 +1527,7 @@ void add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
  * Copy the last offset values of *source to *target. If those values are not
  * enough to fill the target buffer, fill it with another copy of those values.
  */
-void copy_and_dup(int16_t *target, const int16_t *source, int offset)
+void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
 {
     source += BUFFERSIZE - offset;
 
@@ -1540,32 +1542,39 @@ void copy_and_dup(int16_t *target, const int16_t *source, int offset)
  * @return 1 if one of the reflection coefficients is greater than
  *         4095, 0 if not.
  */
-int eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
+int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
 {
     int b, i, j;
-    int buffer1[10];
-    int buffer2[10];
+    int buffer1[LPC_ORDER];
+    int buffer2[LPC_ORDER];
     int *bp1 = buffer1;
     int *bp2 = buffer2;
 
-    for (i=0; i < 10; i++)
+    for (i=0; i < LPC_ORDER; i++)
         buffer2[i] = coefs[i];
 
-    refl[9] = bp2[9];
+    refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
 
-    if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {
+    if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
         av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
         return 1;
     }
 
-    for (i=8; i >= 0; i--) {
+    for (i = LPC_ORDER-2; i >= 0; i--) {
         b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
 
         if (!b)
             b = -2;
 
-        for (j=0; j <= i; j++)
-            bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12;
+        b = 0x1000000 / b;
+        for (j=0; j <= i; j++) {
+#if CONFIG_FTRAPV
+            int a = bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12);
+            if((int)(a*(unsigned)b) != a*(int64_t)b)
+                return 1;
+#endif
+            bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * b) >> 12;
+        }
 
         if ((unsigned) bp1[i] + 0x1000 > 0x1fff)
             return 1;
@@ -1579,16 +1588,16 @@ int eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
 
 /**
  * Evaluate the LPC filter coefficients from the reflection coefficients.
- * Does the inverse of the eval_refl() function.
+ * Does the inverse of the ff_eval_refl() function.
  */
-void eval_coefs(int *coefs, const int *refl)
+void ff_eval_coefs(int *coefs, const int *refl)
 {
-    int buffer[10];
+    int buffer[LPC_ORDER];
     int *b1 = buffer;
     int *b2 = coefs;
     int i, j;
 
-    for (i=0; i < 10; i++) {
+    for (i=0; i < LPC_ORDER; i++) {
         b1[i] = refl[i] << 4;
 
         for (j=0; j < i; j++)
@@ -1597,15 +1606,15 @@ void eval_coefs(int *coefs, const int *refl)
         FFSWAP(int *, b1, b2);
     }
 
-    for (i=0; i < 10; i++)
+    for (i=0; i < LPC_ORDER; i++)
         coefs[i] >>= 4;
 }
 
-void int_to_int16(int16_t *out, const int *inp)
+void ff_int_to_int16(int16_t *out, const int *inp)
 {
     int i;
 
-    for (i=0; i < 10; i++)
+    for (i = 0; i < LPC_ORDER; i++)
         *out++ = *inp++;
 }
 
@@ -1613,7 +1622,7 @@ void int_to_int16(int16_t *out, const int *inp)
  * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
  * odd way to make the output identical to the binary decoder.
  */
-int t_sqrt(unsigned int x)
+int ff_t_sqrt(unsigned int x)
 {
     int s = 2;
     while (x > 0xfff) {
@@ -1624,13 +1633,13 @@ int t_sqrt(unsigned int x)
     return ff_sqrt(x << 20) << s;
 }
 
-unsigned int rms(const int *data)
+unsigned int ff_rms(const int *data)
 {
     int i;
     unsigned int res = 0x10000;
-    int b = 10;
+    int b = LPC_ORDER;
 
-    for (i=0; i < 10; i++) {
+    for (i = 0; i < LPC_ORDER; i++) {
         res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
 
         if (res == 0)
@@ -1642,37 +1651,37 @@ unsigned int rms(const int *data)
         }
     }
 
-    return t_sqrt(res) >> b;
+    return ff_t_sqrt(res) >> b;
 }
 
-int interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
+int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
 {
-    int work[10];
+    int work[LPC_ORDER];
     int b = NBLOCKS - a;
     int i;
 
     // Interpolate block coefficients from the this frame's forth block and
     // last frame's forth block.
-    for (i=0; i<10; i++)
+    for (i = 0; i < LPC_ORDER; i++)
         out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
 
-    if (eval_refl(work, out, ractx->avctx)) {
+    if (ff_eval_refl(work, out, ractx->avctx)) {
         // The interpolated coefficients are unstable, copy either new or old
         // coefficients.
-        int_to_int16(out, ractx->lpc_coef[copyold]);
-        return rescale_rms(ractx->lpc_refl_rms[copyold], energy);
+        ff_int_to_int16(out, ractx->lpc_coef[copyold]);
+        return ff_rescale_rms(ractx->lpc_refl_rms[copyold], energy);
     } else {
-        return rescale_rms(rms(work), energy);
+        return ff_rescale_rms(ff_rms(work), energy);
     }
 }
 
-unsigned int rescale_rms(unsigned int rms, unsigned int energy)
+unsigned int ff_rescale_rms(unsigned int rms, unsigned int energy)
 {
     return (rms * energy) >> 10;
 }
 
 /** inverse root mean square */
-int irms(const int16_t *data)
+int ff_irms(const int16_t *data)
 {
     unsigned int i, sum = 0;
 
@@ -1682,5 +1691,38 @@ int irms(const int16_t *data)
     if (sum == 0)
         return 0; /* OOPS - division by zero */
 
-    return 0x20000000 / (t_sqrt(sum) >> 8);
+    return 0x20000000 / (ff_t_sqrt(sum) >> 8);
+}
+
+void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
+                           int cba_idx, int cb1_idx, int cb2_idx,
+                           int gval, int gain)
+{
+    uint16_t buffer_a[BLOCKSIZE];
+    uint16_t *block;
+    int m[3];
+
+    if (cba_idx) {
+        cba_idx += BLOCKSIZE/2 - 1;
+        ff_copy_and_dup(buffer_a, ractx->adapt_cb, cba_idx);
+        m[0] = (ff_irms(buffer_a) * gval) >> 12;
+    } else {
+        m[0] = 0;
+    }
+    m[1] = (ff_cb1_base[cb1_idx] * gval) >> 8;
+    m[2] = (ff_cb2_base[cb2_idx] * gval) >> 8;
+    memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,
+            (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));
+
+    block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
+
+    ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
+               ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
+
+    memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
+           LPC_ORDER*sizeof(*ractx->curr_sblock));
+
+    if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
+                                    block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))
+        memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
 }