/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / BIFS codec sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "quant.h"

#ifdef GPAC_ENABLE_BIFS_PMF

/*
	Adaptive Arithmethic Decoder from Annex G (Normative)

	 Original code:
		   sac.c, part of tmndecode (H.263 decoder)

	Copyright (C) 1996  Telenor R&D, Norway
         Karl Olav Lillevold <Karl.Lillevold@nta.no>

	Karl Olav Lillevold               <Karl.Lillevold@nta.no>
		Telenor Research and Development
		P.O.Box 83                        tel.:   +47 63 84 84 00
		N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76

    Robert Danielsen                  e-mail: Robert.Danielsen@nta.no
		Telenor Research and Development  www:    http://www.nta.no/brukere/DVC/
		P.O.Box 83                        tel.:   +47 63 84 84 00
		N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76

	 Original license: GNU Lesser General Public License

	This is basically the code from IM1 (the spec is not up-to-date with ref soft)
*/




#define AAM_Q1 16384
#define AAM_Q2 32768
#define AAM_Q3 49152
#define AAM_TOP 65535
#define AAM_ZEROMAX 22
#define AAM_MAX_FREQ 16383

struct _aamodel
{
	s32 nb_symb;
	s32	*cumul_freq;
	s32 *freq;
};

struct _aadecoder
{
	u32 low, high, code_value;
	s32 zero_run;
	Bool Bit;
	GF_BitStream *bs;
	Bool needs_flush;
	u32 read_bits, used_bits;
	/*amount of fake bits (bit read after end of stream)*/
	u32 skip_bits;
};



GF_AAModel *gp_bifs_aa_model_new()
{
	GF_AAModel *tmp;
	GF_SAFEALLOC(tmp, GF_AAModel);
	return tmp;
}

void gp_bifs_aa_model_del(GF_AAModel *model)
{
	if (model->cumul_freq) gf_free(model->cumul_freq);
	if (model->freq) gf_free(model->freq);
	gf_free(model);
}

void gp_bifs_aa_model_init(GF_AAModel *model, u32 nbBits)
{
	s32 i;
	model->nb_symb = 1<<nbBits;
	if (model->cumul_freq) gf_free(model->cumul_freq);
	if (model->freq) gf_free(model->freq);
	model->freq = (s32*)gf_malloc(sizeof(s32) * model->nb_symb);
	model->cumul_freq = (s32*)gf_malloc(sizeof(s32) * (model->nb_symb+1));

	for(i=0; i<model->nb_symb; i++) {
		model->freq[i]=1;
		model->cumul_freq[i] = model->nb_symb - i;
	}
	model->cumul_freq[model->nb_symb] = 0;
}

void UpdateAAModel(GF_AAModel *model, s32 symbol)
{
	s32 sum, i;

	/*The model is rescaled to avoid overflow*/
	if (model->cumul_freq[0] == AAM_MAX_FREQ) {
		sum = 0;
		for (i=model->nb_symb-1; i>=0; i--) {
			model->freq[i] = (model->freq[i]+1)/2;
			sum += model->freq[i];
			model->cumul_freq[i] = sum;
		}
		model->cumul_freq[model->nb_symb] = 0;
	}
	model->freq[symbol] ++;
	model->cumul_freq[symbol] ++;
	while (symbol>0) model->cumul_freq[--symbol] ++;
}


void gf_bs_rewind_bits(GF_BitStream *bs, u64 nbBits);

GF_AADecoder *gp_bifs_aa_dec_new(GF_BitStream *bs)
{
	GF_AADecoder *tmp;
	GF_SAFEALLOC(tmp, GF_AADecoder);
	if (tmp)
		tmp->bs = bs;
	return tmp;
}
void gp_bifs_aa_dec_del(GF_AADecoder *dec)
{
	gf_free(dec);
}

static Bool bit_out_psc_layer(GF_AADecoder *dec)
{
	s32 v;
	if (gf_bs_bits_available(dec->bs) ) {
		v = gf_bs_read_int(dec->bs, 1) ? 1 : 0;
		dec->read_bits++;
	} else {
		v = (dec->zero_run == AAM_MAX_FREQ) ? 1 : 0;
		dec->skip_bits++;
	}

	if (dec->zero_run == AAM_ZEROMAX) {
		if (!v) return 0;
		v = gf_bs_read_int(dec->bs, 1) ? 1 : 0;
		dec->zero_run = 0;
		dec->read_bits++;
		dec->used_bits++;
	}
	dec->Bit = v;
	dec->needs_flush = 1;

	if (!dec->Bit)
		dec->zero_run++;
	else
		dec->zero_run = 0;

	return 1;
}

void gp_bifs_aa_dec_resync(GF_AADecoder *dec)
{
	u32 rewind;
	if (!dec->needs_flush) return;
	/*magic number from IM1 (spec is wrong there)*/
	rewind = 14;
	//spec: rewind = dec->read_bits - 1 - (dec->used_bits+1);
	if (dec->skip_bits < rewind) gf_bs_rewind_bits(dec->bs, rewind - dec->skip_bits);

	dec->needs_flush = 0;
	dec->code_value = 0;
	dec->low = 0;
	dec->high = AAM_TOP;
	dec->zero_run = 0;
	dec->used_bits = dec->read_bits = 0;
}

void gp_bifs_aa_dec_flush(GF_AADecoder *dec)
{
	if (!bit_out_psc_layer(dec)) return;
	dec->code_value = 2 * dec->code_value + dec->Bit;
	if (!bit_out_psc_layer(dec)) return;
	dec->code_value = (2 * dec->code_value + dec->Bit) & AAM_TOP;

	dec->low = 0;
	dec->high = AAM_TOP;
	dec->zero_run = 0;
}

void gp_bifs_aa_dec_resync_bit(GF_AADecoder *dec)
{
	if (dec->needs_flush && (dec->skip_bits < 16))
		gf_bs_rewind_bits(dec->bs, 16 - dec->skip_bits);

	dec->needs_flush = 0;
}

s32 gp_bifs_aa_dec_get_bit(GF_AADecoder *dec)
{
	/*get flag*/
	s32 res = dec->code_value >> 15;
	/*get next bit*/
	bit_out_psc_layer(dec);
	dec->code_value = (2 * dec->code_value + dec->Bit) & AAM_TOP;
	return res;
}

void gp_bifs_aa_dec_reset(GF_AADecoder *dec)
{
	s32 i;
	dec->code_value = 0;
	dec->low = 0;
	dec->high = AAM_TOP;
	dec->zero_run = 0;
	for (i=0; i < 16; i++) {
		if (!bit_out_psc_layer(dec)) return;
		dec->code_value = 2 * dec->code_value + dec->Bit;
	}
	dec->used_bits = 0;
}


static s32 AADec_Dec(GF_AADecoder *dec, GF_AAModel *model)
{
	u32 sac_index, len;
	s32 sum;

	len = dec->high - dec->low + 1;
	if (!len || !model->cumul_freq[0]) return -1;
	sum = (-1 + (dec->code_value - dec->low + 1) * model->cumul_freq[0]) / len;

	for (sac_index = 1; model->cumul_freq[sac_index] > sum; sac_index++) {
	}
	dec->high = dec->low - 1 + (len * model->cumul_freq[sac_index-1]) / model->cumul_freq[0];
	dec->low += (len * model->cumul_freq[sac_index]) / model->cumul_freq[0];

	for ( ; ; ) {
		if (dec->high < AAM_Q2) {
		} else if (dec->low >= AAM_Q2) {
			dec->code_value -= AAM_Q2;
			dec->low -= AAM_Q2;
			dec->high -= AAM_Q2;
		}
		else if (dec->low >= AAM_Q1 && dec->high < AAM_Q3) {
			dec->code_value -= AAM_Q1;
			dec->low -= AAM_Q1;
			dec->high -= AAM_Q1;
		} else {
			break;
		}

		dec->low *= 2;
		dec->high = 2 * dec->high + 1;
		if (!bit_out_psc_layer(dec)) return -1;
		dec->code_value = 2 * dec->code_value + dec->Bit;
		dec->used_bits++;
	}
	return (sac_index - 1);
}

s32 gp_bifs_aa_decode(GF_AADecoder *dec, GF_AAModel *model)
{
	s32 v;
	v = AADec_Dec(dec, model);
	if (v < 0) return v;
	UpdateAAModel(model, v);
	return v;
}

#endif /*GPAC_ENABLE_BIFS_PMF*/

