/*
 * Siren Encoder/Decoder library
 *
 *   @author: Youness Alaoui <kakaroto@kakaroto.homelinux.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */


#include "siren7.h"
#include "huffman_consts.h"


static short current_word = 0;
static int bit_idx = 0;
static int *bitstream_ptr = NULL;

int
next_bit (void)
{
  if (bitstream_ptr == NULL)
    return -1;

  if (bit_idx == 0) {
    current_word = *bitstream_ptr++;
    bit_idx = 16;
  }

  return (current_word >> --bit_idx) & 1;
}

void
set_bitstream (int *stream)
{
  bitstream_ptr = stream;
  current_word = *bitstream_ptr;
  bit_idx = 0;
}


int
compute_region_powers (int number_of_regions, float *coefs, int *drp_num_bits,
    int *drp_code_bits, int *absolute_region_power_index, int esf_adjustment)
{
  float region_power = 0;
  int num_bits;
  int idx;
  int max_idx, min_idx;
  int region, i;

  for (region = 0; region < number_of_regions; region++) {
    region_power = 0.0f;
    for (i = 0; i < region_size; i++) {
      region_power +=
          coefs[(region * region_size) + i] * coefs[(region * region_size) + i];
    }
    region_power *= region_size_inverse;

    min_idx = 0;
    max_idx = 64;
    for (i = 0; i < 6; i++) {
      idx = (min_idx + max_idx) / 2;
      if (region_power_table_boundary[idx - 1] <= region_power) {
        min_idx = idx;
      } else {
        max_idx = idx;
      }
    }
    absolute_region_power_index[region] = min_idx - 24;

  }

  for (region = number_of_regions - 2; region >= 0; region--) {
    if (absolute_region_power_index[region] <
        absolute_region_power_index[region + 1] - 11)
      absolute_region_power_index[region] =
          absolute_region_power_index[region + 1] - 11;
  }

  if (absolute_region_power_index[0] < (1 - esf_adjustment))
    absolute_region_power_index[0] = (1 - esf_adjustment);

  if (absolute_region_power_index[0] > (31 - esf_adjustment))
    absolute_region_power_index[0] = (31 - esf_adjustment);

  drp_num_bits[0] = 5;
  drp_code_bits[0] = absolute_region_power_index[0] + esf_adjustment;


  for (region = 1; region < number_of_regions; region++) {
    if (absolute_region_power_index[region] < (-8 - esf_adjustment))
      absolute_region_power_index[region] = (-8 - esf_adjustment);
    if (absolute_region_power_index[region] > (31 - esf_adjustment))
      absolute_region_power_index[region] = (31 - esf_adjustment);
  }

  num_bits = 5;

  for (region = 0; region < number_of_regions - 1; region++) {
    idx =
        absolute_region_power_index[region + 1] -
        absolute_region_power_index[region] + 12;
    if (idx < 0)
      idx = 0;

    absolute_region_power_index[region + 1] =
        absolute_region_power_index[region] + idx - 12;
    drp_num_bits[region + 1] = differential_region_power_bits[region][idx];
    drp_code_bits[region + 1] = differential_region_power_codes[region][idx];
    num_bits += drp_num_bits[region + 1];
  }

  return num_bits;
}


int
decode_envelope (int number_of_regions, float *decoder_standard_deviation,
    int *absolute_region_power_index, int esf_adjustment)
{
  int index;
  int i;
  int envelope_bits = 0;

  index = 0;
  for (i = 0; i < 5; i++)
    index = (index << 1) | next_bit ();
  envelope_bits = 5;

  absolute_region_power_index[0] = index - esf_adjustment;
  decoder_standard_deviation[0] =
      standard_deviation[absolute_region_power_index[0] + 24];

  for (i = 1; i < number_of_regions; i++) {
    index = 0;
    do {
      index = differential_decoder_tree[i - 1][index][next_bit ()];
      envelope_bits++;
    } while (index > 0);

    absolute_region_power_index[i] =
        absolute_region_power_index[i - 1] - index - 12;
    decoder_standard_deviation[i] =
        standard_deviation[absolute_region_power_index[i] + 24];
  }

  return envelope_bits;
}



static int
huffman_vector (int category, int power_idx, float *mlts, int *out)
{
  int i, j;
  float temp_value = deviation_inverse[power_idx] * step_size_inverse[category];
  int sign_idx, idx, non_zeroes, max, bits_available;
  int current_word = 0;
  int region_bits = 0;

  bits_available = 32;
  for (i = 0; i < number_of_vectors[category]; i++) {
    sign_idx = idx = non_zeroes = 0;
    for (j = 0; j < vector_dimension[category]; j++) {
      max = (int) ((fabs (*mlts) * temp_value) + dead_zone[category]);
      if (max != 0) {
        sign_idx <<= 1;
        non_zeroes++;
        if (*mlts > 0)
          sign_idx++;
        if (max > max_bin[category] || max < 0)
          max = max_bin[category];

      }
      mlts++;
      idx = (idx * (max_bin[category] + 1)) + max;
    }

    region_bits += bitcount_tables[category][idx] + non_zeroes;
    bits_available -= bitcount_tables[category][idx] + non_zeroes;
    if (bits_available < 0) {
      *out++ =
          current_word + (((code_tables[category][idx] << non_zeroes) +
              sign_idx) >> -bits_available);
      bits_available += 32;
      current_word =
          ((code_tables[category][idx] << non_zeroes) +
          sign_idx) << bits_available;
    } else {
      current_word +=
          ((code_tables[category][idx] << non_zeroes) +
          sign_idx) << bits_available;
    }

  }

  *out = current_word;
  return region_bits;
}

int
quantize_mlt (int number_of_regions, int rate_control_possibilities,
    int number_of_available_bits, float *coefs,
    int *absolute_region_power_index, int *power_categories,
    int *category_balance, int *region_mlt_bit_counts, int *region_mlt_bits)
{
  int region;
  int mlt_bits = 0;
  int rate_control;

  for (rate_control = 0; rate_control < ((rate_control_possibilities >> 1) - 1);
      rate_control++)
    power_categories[category_balance[rate_control]]++;

  for (region = 0; region < number_of_regions; region++) {
    if (power_categories[region] > 6)
      region_mlt_bit_counts[region] = 0;
    else
      region_mlt_bit_counts[region] =
          huffman_vector (power_categories[region],
          absolute_region_power_index[region], coefs + (region_size * region),
          region_mlt_bits + (4 * region));
    mlt_bits += region_mlt_bit_counts[region];
  }

  while (mlt_bits < number_of_available_bits && rate_control > 0) {
    rate_control--;
    region = category_balance[rate_control];
    power_categories[region]--;

    if (power_categories[region] < 0)
      power_categories[region] = 0;

    mlt_bits -= region_mlt_bit_counts[region];

    if (power_categories[region] > 6)
      region_mlt_bit_counts[region] = 0;
    else
      region_mlt_bit_counts[region] =
          huffman_vector (power_categories[region],
          absolute_region_power_index[region], coefs + (region_size * region),
          region_mlt_bits + (4 * region));

    mlt_bits += region_mlt_bit_counts[region];
  }

  while (mlt_bits > number_of_available_bits
      && rate_control < rate_control_possibilities) {
    region = category_balance[rate_control];
    power_categories[region]++;
    mlt_bits -= region_mlt_bit_counts[region];

    if (power_categories[region] > 6)
      region_mlt_bit_counts[region] = 0;
    else
      region_mlt_bit_counts[region] =
          huffman_vector (power_categories[region],
          absolute_region_power_index[region], coefs + (region_size * region),
          region_mlt_bits + (4 * region));

    mlt_bits += region_mlt_bit_counts[region];

    rate_control++;
  }

  return rate_control;
}

static int
get_dw (SirenDecoder decoder)
{
  int ret = decoder->dw1 + decoder->dw4;

  if ((ret & 0x8000) != 0)
    ret++;

  decoder->dw1 = decoder->dw2;
  decoder->dw2 = decoder->dw3;
  decoder->dw3 = decoder->dw4;
  decoder->dw4 = ret;

  return ret;
}




int
decode_vector (SirenDecoder decoder, int number_of_regions,
    int number_of_available_bits, float *decoder_standard_deviation,
    int *power_categories, float *coefs, int scale_factor)
{
  float *coefs_ptr;
  float decoded_value;
  float noise;
  int *decoder_tree;

  int region;
  int category;
  int i, j;
  int index;
  int error;
  int dw1;
  int dw2;

  error = 0;
  for (region = 0; region < number_of_regions; region++) {
    category = power_categories[region];
    coefs_ptr = coefs + (region * region_size);

    if (category < 7) {
      decoder_tree = decoder_tables[category];

      for (i = 0; i < number_of_vectors[category]; i++) {
        index = 0;
        do {
          if (number_of_available_bits <= 0) {
            error = 1;
            break;
          }

          index = decoder_tree[index + next_bit ()];
          number_of_available_bits--;
        } while ((index & 1) == 0);

        index >>= 1;

        if (error == 0 && number_of_available_bits >= 0) {
          for (j = 0; j < vector_dimension[category]; j++) {
            decoded_value =
                mlt_quant[category][index & ((1 << index_table[category]) - 1)];
            index >>= index_table[category];

            if (decoded_value != 0) {
              if (next_bit () == 0)
                decoded_value *= -decoder_standard_deviation[region];
              else
                decoded_value *= decoder_standard_deviation[region];
              number_of_available_bits--;
            }

            *coefs_ptr++ = decoded_value * scale_factor;
          }
        } else {
          error = 1;
          break;
        }
      }

      if (error == 1) {
        for (j = region + 1; j < number_of_regions; j++)
          power_categories[j] = 7;
        category = 7;
      }
    }


    coefs_ptr = coefs + (region * region_size);

    if (category == 5) {
      i = 0;
      for (j = 0; j < region_size; j++) {
        if (*coefs_ptr != 0) {
          i++;
          if (fabs (*coefs_ptr) > 2.0 * decoder_standard_deviation[region]) {
            i += 3;
          }
        }
        coefs_ptr++;
      }

      noise = decoder_standard_deviation[region] * noise_category5[i];
    } else if (category == 6) {
      i = 0;
      for (j = 0; j < region_size; j++) {
        if (*coefs_ptr++ != 0)
          i++;
      }

      noise = decoder_standard_deviation[region] * noise_category6[i];
    } else if (category == 7) {
      noise = decoder_standard_deviation[region] * noise_category7;
    } else {
      noise = 0;
    }

    coefs_ptr = coefs + (region * region_size);

    if (category == 5 || category == 6 || category == 7) {
      dw1 = get_dw (decoder);
      dw2 = get_dw (decoder);

      for (j = 0; j < 10; j++) {
        if (category == 7 || *coefs_ptr == 0) {
          if ((dw1 & 1))
            *coefs_ptr = noise;
          else
            *coefs_ptr = -noise;
        }
        coefs_ptr++;
        dw1 >>= 1;

        if (category == 7 || *coefs_ptr == 0) {
          if ((dw2 & 1))
            *coefs_ptr = noise;
          else
            *coefs_ptr = -noise;
        }
        coefs_ptr++;
        dw2 >>= 1;
      }
    }
  }

  return error == 1 ? -1 : number_of_available_bits;
}
