// This may look like C code, but it is really -*- C++ -*-
/*
 ************************************************************************
 *
 *		            Arithmetic Coding
 *	      Adaptive Histogram-based model for the source of data
 *
 * This is an extension over the basic Input_Data_Model for an adaptive
 * model of the input source, which, however, uses the histogram to
 * find out which symbols are expected to come out and how often. This
 * is to get around the flaw of the simple AdaptiveModel, which wastes
 * the probability space by assigning the frequency count 1 to a lot
 * of symbols that might appear but never show up in the reality. 
 * E.g., in coding the Laplacian pyramid of typical images, the
 * node value of the pyramid lies in the interval [-255,255].
 * The simple AdaptiveModel assigns all the possible symbols
 * (511 symbols) the frequency count at least 1. Though, it turns out
 * that there are only about 130 distinct values of the pyramid nodes.
 * I.e. only 130/511 of the probability space is made use of.
 * Except that modification, the functionality of the present model is 
 * very similar to that of the AdaptiveModel.
 *
 * The program assumes the total no. of distinct input symbols
 * (integers) is relatively small, so simple linear arrays can be used
 * for storing and looking up the frequency tables. 
 *
 * $Id: arithm_modadh.h,v 2.4 1998/03/15 23:08:21 oleg Exp oleg $
 *
 ************************************************************************
 */

#ifndef __GNUC__
#pragma once
#endif

#ifndef _arithm_modadh_h
#define _arithm_modadh_h

#ifdef __GNUC__
#pragma interface
#endif

#include "arithm.h"
#include "histogram.h"

class AdaptiveHistModel : public Input_Data_Model
{
  Symbol symbol_lwb;			// Region potential input symbols
  Symbol symbol_upb;			// are expected in
  int no_potential_symbols;		// which are expected to occur
  int no_distinct_symbols;		// which have occurred

  int update_inc;		// Increment to update freq counts by during
  				// adaptation
  
  Index  * symbol_to_index;	// Symbol-to-index conversion
  Symbol * index_to_symbol;	// Conversion from symbol index to symbol value

  void initialize_model(const Histogram& histogram);
  void initial_distribution(void);	// Assign initial pdf

  AdaptiveHistModel(const AdaptiveHistModel&);	// Private and unimplemented:
  void operator = (const AdaptiveHistModel&);	// cloning is not allowed

public:
					// Construct a model for a given
					// histogram
  AdaptiveHistModel(const Histogram& histogram);
  AdaptiveHistModel(void);		// With parameters are assumed to
					// be read in
  virtual ~AdaptiveHistModel(void);

					// Write out/Read in the histogram
					// to/from the coded stream
  void open(BitIn& file);
  void open(BitOut& file);

					// Update the model to account 
					// for a symbol
  void update_model(const Index index);

					// Scale the accumulated statistics
					// down in anticipation of a change
  void scale_down_past(void);

					// Return the index of a symbol
  Index  get_index(const Symbol symbol) const;
					// and the symbol for an index
  Symbol get_symbol(const Index index) const;
};

#endif
