$OpenBSD: patch-libdca_parse_c,v 1.1 2012/05/15 16:17:27 ajacoutot Exp $

- Mark tables as static constants.
- Change output normalisation factor from 3/2 to sqrt(2).
- Sanity check for subframes and prim_channels to avoid crashes with invalid streams.
- Avoid crashing with invalid frames setting a bitalloc_huffman component to 7.

--- libdca/parse.c.orig	Mon May 14 22:44:48 2012
+++ libdca/parse.c	Mon May 14 22:44:53 2012
@@ -59,12 +59,11 @@ void * memalign (size_t align, size_t size);
 static int decode_blockcode (int code, int levels, int *values);
 
 static void qmf_32_subbands (dca_state_t * state, int chans,
-                             double samples_in[32][8], sample_t *samples_out,
-                             double rScale, sample_t bias);
+                             double samples_in[32][8], sample_t *samples_out);
 
 static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
                                    double *samples_in, sample_t *samples_out,
-                                   double rScale, sample_t bias );
+                                   sample_t bias);
 
 static void pre_calc_cosmod( dca_state_t * state );
 
@@ -123,7 +122,9 @@ static int syncinfo (dca_state_t * state, int * flags,
     bitstream_get (state, 1);
 
     *frame_length = (bitstream_get (state, 7) + 1) * 32;
+    if (*frame_length < 6 * 32) return 0;
     frame_size = bitstream_get (state, 14) + 1;
+    if (frame_size < 96) return 0;
     if (!state->word_mode) frame_size = frame_size * 8 / 14 * 2;
 
     /* Audio channel arrangement */
@@ -304,8 +305,15 @@ int dca_frame (dca_state_t * state, uint8_t * buf, int
 
     /* Primary audio coding header */
     state->subframes = bitstream_get (state, 4) + 1;
+
+    if (state->subframes > DCA_SUBFRAMES_MAX)
+        state->subframes = DCA_SUBFRAMES_MAX;
+
     state->prim_channels = bitstream_get (state, 3) + 1;
 
+    if (state->prim_channels > DCA_PRIM_CHANNELS_MAX)
+        state->prim_channels = DCA_PRIM_CHANNELS_MAX;
+
 #ifdef DEBUG
     fprintf (stderr, "subframes: %i\n", state->subframes);
     fprintf (stderr, "prim channels: %i\n", state->prim_channels);
@@ -356,7 +364,10 @@ int dca_frame (dca_state_t * state, uint8_t * buf, int
     for (i = 0; i < state->prim_channels; i++)
     {
         state->bitalloc_huffman[i] = bitstream_get (state, 3);
-        /* if (state->bitalloc_huffman[i] == 7) bailout */
+        /* There might be a way not to trash the whole frame, but for
+         * now we must bail out or we will buffer overflow later. */
+        if (state->bitalloc_huffman[i] == 7)
+            return 1;
 #ifdef DEBUG
         fprintf (stderr, "bit allocation quantizer: %i\n",
                  state->bitalloc_huffman[i]);
@@ -533,6 +544,7 @@ static int dca_subframe_header (dca_state_t * state)
                 k < state->vq_start_subband[j] &&
                 state->bitalloc[j][k] > 0)
             {
+                /* tmode cannot overflow since transient_huffman[j] < 4 */
                 state->transition_mode[j][k] = InverseQ (state,
                     tmode[state->transient_huffman[j]]);
             }
@@ -548,7 +560,7 @@ static int dca_subframe_header (dca_state_t * state)
     /* Scale factors */
     for (j = 0; j < state->prim_channels; j++)
     {
-        int *scale_table;
+        const int *scale_table;
         int scale_sum;
 
         for (k = 0; k < state->subband_activity[j]; k++)
@@ -761,7 +773,7 @@ static int dca_subsubframe (dca_state_t * state)
     int k, l;
     int subsubframe = state->current_subsubframe;
 
-    double *quant_step_table;
+    const double *quant_step_table;
 
     /* FIXME */
     double subband_samples[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
@@ -981,14 +993,7 @@ static int dca_subsubframe (dca_state_t * state)
     /* 32 subbands QMF */
     for (k = 0; k < state->prim_channels; k++)
     {
-        /*static double pcm_to_float[8] =
-            {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
-
-        qmf_32_subbands (state, k,
-                         subband_samples[k],
-                         &state->samples[256*k],
-          /*WTF ???*/    32768.0*3/2/*pcm_to_float[state->source_pcm_res]*/,
-                         0/*state->bias*/);
+        qmf_32_subbands (state, k, subband_samples[k], &state->samples[256*k]);
     }
 
     /* Down/Up mixing */
@@ -1000,6 +1005,10 @@ static int dca_subsubframe (dca_state_t * state)
     {
         dca_downmix (state->samples, state->amode, state->output, state->bias,
                      state->clev, state->slev);
+    } else if (state->bias)
+    {
+        for ( k = 0; k < 256*state->prim_channels; k++ )
+            state->samples[k] += state->bias;
     }
 
     /* Generate LFE samples for this subsubframe FIXME!!! */
@@ -1011,8 +1020,7 @@ static int dca_subsubframe (dca_state_t * state)
         lfe_interpolation_fir (state->lfe, 2 * state->lfe,
                                state->lfe_data + lfe_samples +
                                2 * state->lfe * subsubframe,
-                               &state->samples[256*i_channels],
-                               8388608.0, state->bias);
+                               &state->samples[256*i_channels], state->bias);
         /* Outputs 20bits pcm samples */
     }
 
@@ -1142,10 +1150,10 @@ static void pre_calc_cosmod( dca_state_t * state )
 }
 
 static void qmf_32_subbands (dca_state_t * state, int chans,
-                             double samples_in[32][8], sample_t *samples_out,
-                             double scale, sample_t bias)
+                             double samples_in[32][8], sample_t *samples_out)
 {
-    double *prCoeff;
+    static const double scale = 1.4142135623730951 /* sqrt(2) */ * 32768.0;
+    const double *prCoeff;
     int i, j, k;
     double raXin[32];
 
@@ -1211,7 +1219,7 @@ static void qmf_32_subbands (dca_state_t * state, int 
 
         /* Create 32 PCM output samples */
         for (i=0;i<32;i++)
-            samples_out[nChIndex++] = subband_fir_hist2[i] / scale + bias;
+            samples_out[nChIndex++] = subband_fir_hist2[i] / scale;
 
         /* Update working arrays */
         for (i=511;i>=32;i--)
@@ -1225,7 +1233,7 @@ static void qmf_32_subbands (dca_state_t * state, int 
 
 static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
                                    double *samples_in, sample_t *samples_out,
-                                   double scale, sample_t bias)
+                                   sample_t bias)
 {
     /* samples_in: An array holding decimated samples.
      *   Samples in current subframe starts from samples_in[0],
@@ -1235,8 +1243,9 @@ static void lfe_interpolation_fir (int nDecimationSele
      * samples_out: An array holding interpolated samples
      */
 
+    static const double scale = 8388608.0;
     int nDeciFactor, k, J;
-    double *prCoeff;
+    const double *prCoeff;
 
     int NumFIRCoef = 512; /* Number of FIR coefficients */
     int nInterpIndex = 0; /* Index to the interpolated samples */
