/*
 *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license 
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may 
 *  be found in the AUTHORS file in the root of the source tree.
 */


#ifndef bool_coder_h
#define bool_coder_h 1

/* Arithmetic bool coder with largish probability range.
   Timothy S Murphy  6 August 2004 */

/* So as not to force users to drag in too much of my idiosyncratic C++ world,
   I avoid fancy storage management. */

#include <assert.h>

#include <stddef.h>
#include <stdio.h>

typedef unsigned char vp8bc_index_t; // probability index

/* There are a couple of slight variants in the details of finite-precision
   arithmetic coding.  May be safely ignored by most users. */

enum vp8bc_rounding
{
    vp8bc_down = 0,     // just like VP8
    vp8bc_down_full = 1, // handles minimum probability correctly
    vp8bc_up = 2
};

#if _MSC_VER

/* Note that msvc by default does not inline _anything_ (regardless of the
   setting of inline_depth) and that a command-line option (-Ob1 or -Ob2)
   is required to inline even the smallest functions. */

#   pragma inline_depth( 255)           // I mean it when I inline something
#   pragma warning( disable : 4099)     // No class vs. struct harassment
#   pragma warning( disable : 4250)     // dominance complaints
#   pragma warning( disable : 4284)     // operator-> in templates
#   pragma warning( disable : 4800)     // bool conversion

// don't let prefix ++,-- stand in for postfix, disaster would ensue

#   pragma warning( error : 4620 4621)

#endif  // _MSC_VER


#if __cplusplus

// Sometimes one wishes to be definite about integer lengths.

struct int_types
{
    typedef const bool cbool;
    typedef const signed char cchar;
    typedef const short cshort;
    typedef const int cint;
    typedef const int clong;

    typedef const double cdouble;
    typedef const size_t csize_t;

    typedef unsigned char uchar;    // 8 bits
    typedef const uchar cuchar;

    typedef short int16;
    typedef unsigned short uint16;
    typedef const int16 cint16;
    typedef const uint16 cuint16;

    typedef int int32;
    typedef unsigned int uint32;
    typedef const int32 cint32;
    typedef const uint32 cuint32;

    typedef unsigned int uint;
    typedef unsigned int ulong;
    typedef const uint cuint;
    typedef const ulong culong;


    // All structs consume space, may as well have a vptr.

    virtual ~int_types();
};


struct bool_coder_spec;
struct bool_coder;
struct bool_writer;
struct bool_reader;


struct bool_coder_namespace : int_types
{
    typedef vp8bc_index_t Index;
    typedef bool_coder_spec Spec;
    typedef const Spec c_spec;

    enum Rounding
    {
        Down = vp8bc_down,
        down_full = vp8bc_down_full,
        Up = vp8bc_up
    };
};


// Archivable specification of a bool coder includes rounding spec
// and probability mapping table.  The latter replaces a uchar j
// (0 <= j < 256) with an arbitrary uint16 tbl[j] = p.
// p/65536 is then the probability of a zero.

struct bool_coder_spec : bool_coder_namespace
{
    friend struct bool_coder;
    friend struct bool_writer;
    friend struct bool_reader;
    friend struct bool_coder_spec_float;
    friend struct bool_coder_spec_explicit_table;
    friend struct bool_coder_spec_exponential_table;
    friend struct BPsrc;
private:
    uint w;                 // precision
    Rounding r;

    uint ebits, mbits, ebias;
    uint32 mmask;

    Index max_index, half_index;

    uint32 mantissa(Index i) const
    {
        assert(i < half_index);
        return (1 << mbits) + (i & mmask);
    }
    uint exponent(Index i) const
    {
        assert(i < half_index);
        return ebias - (i >> mbits);
    }

    uint16 Ptbl[256];       // kinda clunky, but so is storage management.

    /* Cost in bits of encoding a zero at every probability, scaled by 2^20.
       Assumes that index is at most 8 bits wide. */

    uint32 Ctbl[256];

    uint32 split(Index i, uint32 R) const    // 1 <= split <= max( 1, R-1)
    {
        if (!ebias)
            return 1 + (((R - 1) * Ptbl[i]) >> 16);

        if (i >= half_index)
            return R - split(max_index - i, R);

        return 1 + (((R - 1) * mantissa(i)) >> exponent(i));
    }

    uint32 max_range() const
    {
        return (1 << w) - (r == down_full ? 0 : 1);
    }
    uint32 min_range() const
    {
        return (1 << (w - 1)) + (r == down_full ? 1 : 0);
    }
    uint32 Rinc() const
    {
        return r == Up ? 1 : 0;
    }

    void check_prec() const;

    bool float_init(uint Ebits, uint Mbits);

    void cost_init();

    bool_coder_spec(
        uint prec, Rounding rr, uint Ebits = 0, uint Mbits = 0
    )
        : w(prec), r(rr)
    {
        float_init(Ebits, Mbits);
    }
public:
    // Read complete spec from file.
    bool_coder_spec(FILE *);

    // Write spec to file.
    void dump(FILE *) const;

    // return probability index best approximating prob.
    Index operator()(double prob) const;

    // probability corresponding to index
    double operator()(Index i) const;

    Index complement(Index i) const
    {
        return max_index - i;
    }

    Index max_index() const
    {
        return max_index;
    }
    Index half_index() const
    {
        return half_index;
    }

    uint32 cost_zero(Index i) const
    {
        return Ctbl[i];
    }
    uint32 cost_one(Index i) const
    {
        return Ctbl[ max_index - i];
    }
    uint32 cost_bit(Index i, bool b) const
    {
        return Ctbl[b? max_index-i:i];
    }
};


/* Pseudo floating-point probability specification.

   At least one of Ebits and Mbits must be nonzero.

   Since all arithmetic is done at 32 bits, Ebits is at most 5.

   Total significant bits in index is Ebits + Mbits + 1.

   Below the halfway point (i.e. when the top significant bit is 0),
   the index is (e << Mbits) + m.

   The exponent e is between 0 and (2**Ebits) - 1,
   the mantissa m is between 0 and (2**Mbits) - 1.

   Prepending an implicit 1 to the mantissa, the probability is then

        (2**Mbits + m) >> (e - 2**Ebits - 1 - Mbits),

   which has (1/2)**(2**Ebits + 1) as a minimum
   and (1/2) * [1 - 2**(Mbits + 1)] as a maximum.

   When the index is above the halfway point, the probability is the
   complement of the probability associated to the complement of the index.

   Note that the probability increases with the index and that, because of
   the symmetry, we cannot encode probability exactly 1/2; though we
   can get as close to 1/2 as we like, provided we have enough Mbits.

   The latter is of course not a problem in practice, one never has
   exact probabilities and entropy errors are second order, that is, the
   "overcoding" of a zero will be largely compensated for by the
   "undercoding" of a one (or vice-versa).

   Compared to arithmetic probability specs (a la VP8), this will do better
   at very high and low probabilities and worse at probabilities near 1/2,
   as well as facilitating the usage of wider or narrower probability indices.
*/

struct bool_coder_spec_float : bool_coder_spec
{
    bool_coder_spec_float(
        uint Ebits = 3, uint Mbits = 4, Rounding rr = down_full, uint prec = 12
    )
        : bool_coder_spec(prec, rr, Ebits, Mbits)
    {
        cost_init();
    }
};


struct bool_coder_spec_explicit_table : bool_coder_spec
{
    bool_coder_spec_explicit_table(
        cuint16 probability_table[256] = 0,  // default is tbl[i] = i << 8.
        Rounding = down_full,
        uint precision = 16
    );
};

// Contruct table via multiplicative interpolation between
// p[128] = 1/2  and p[0] = (1/2)^x.
// Since we are working with 16-bit precision, x is at most 16.
// For probabilities to increase with i, we must have x > 1.
// For 0 <= i <= 128, p[i] = (1/2)^{ 1 + [1 - (i/128)]*[x-1] }.
// Finally, p[128+i] = 1 - p[128 - i].

struct bool_coder_spec_exponential_table : bool_coder_spec
{
    bool_coder_spec_exponential_table(uint x, Rounding = down_full, uint prec = 16);
};


// Commonalities between writer and reader.

struct bool_coder : bool_coder_namespace
{
    friend struct bool_writer;
    friend struct bool_reader;
    friend struct BPsrc;
private:
    uint32 Low, Range;
    cuint32 min_range;
    cuint32 rinc;
    c_spec spec;

    void _reset()
    {
        Low = 0;
        Range = spec.max_range();
    }

    bool_coder(c_spec &s)
        :  min_range(s.min_range()),
           rinc(s.Rinc()),
           spec(s)
    {
        _reset();
    }

    uint32 half() const
    {
        return 1 + ((Range - 1) >> 1);
    }
public:
    c_spec &Spec() const
    {
        return spec;
    }
};


struct bool_writer : bool_coder
{
    friend struct BPsrc;
private:
    uchar *Bstart, *Bend, *B;
    int bit_lag;
    bool is_toast;
    void carry();
    void reset()
    {
        _reset();
        bit_lag = 32 - spec.w;
        is_toast = 0;
    }
    void raw(bool value, uint32 split);
public:
    bool_writer(c_spec &, uchar *Dest, size_t Len);
    virtual ~bool_writer();

    void operator()(Index p, bool v)
    {
        raw(v, spec.split(p, Range));
    }

    uchar *buf() const
    {
        return Bstart;
    }
    size_t bytes_written() const
    {
        return B - Bstart;
    }

    // Call when done with input, flushes internal state.
    // DO NOT write any more data after calling this.

    bool_writer &flush();

    void write_bits(int n, uint val)
    {
        if (n)
        {
            uint m = 1 << (n - 1);

            do
            {
                raw((bool)(val & m), half());
            }
            while (m >>= 1);
        }
    }

#   if 0
    // We are agnostic about storage management.
    // By default, overflows throw an assert but user can
    // override to provide an expanding buffer using ...

    virtual void overflow(uint Len) const;

    // ... this function copies already-written data into new buffer
    // and retains new buffer location.

    void new_buffer(uchar *dest, uint Len);

    // Note that storage management is the user's responsibility.
#   endif
};


// This could be adjusted to use a little less lookahead.

struct bool_reader : bool_coder
{
    friend struct BPsrc;
private:
    cuchar *const Bstart;   // for debugging
    cuchar *B;
    cuchar *const Bend;
    cuint shf;
    uint bct;
    bool raw(uint32 split);
public:
    bool_reader(c_spec &s, cuchar *src, size_t Len);

    bool operator()(Index p)
    {
        return raw(spec.split(p, Range));
    }

    uint read_bits(int num_bits)
    {
        uint v = 0;

        while (--num_bits >= 0)
            v += v + (raw(half()) ? 1 : 0);

        return v;
    }
};

extern "C" {

#endif /*  __cplusplus */


    /* C interface */

    typedef struct bool_coder_spec bool_coder_spec;
    typedef struct bool_writer bool_writer;
    typedef struct bool_reader bool_reader;

    typedef const bool_coder_spec c_bool_coder_spec;
    typedef const bool_writer c_bool_writer;
    typedef const bool_reader c_bool_reader;


    /* Optionally override default precision when constructing coder_specs.
       Just pass a zero pointer if you don't care.
       Precision is at most 16 bits for table specs, at most 23 otherwise. */

    struct vp8bc_prec
    {
        enum vp8bc_rounding r;      /* see top header file for def */
        unsigned int prec;          /* range precision in bits */
    };

    typedef const struct vp8bc_prec vp8bc_c_prec;

    /* bool_coder_spec contains mapping of uchars to actual probabilities
       (16 bit uints) as well as (usually immaterial) selection of
       exact finite-precision algorithm used (for now, the latter can only
       be overridden using the C++ interface).
       See comments above the corresponding C++ constructors for discussion,
       especially of exponential probability table generation. */

    bool_coder_spec *vp8bc_vp8spec(); // just like vp8

    bool_coder_spec *vp8bc_literal_spec(
        const unsigned short prob_map[256],  // 0 is like vp8 w/more precision
        vp8bc_c_prec*
    );

    bool_coder_spec *vp8bc_float_spec(
        unsigned int exponent_bits, unsigned int mantissa_bits, vp8bc_c_prec*
    );

    bool_coder_spec *vp8bc_exponential_spec(unsigned int min_exp, vp8bc_c_prec *);

    bool_coder_spec *vp8bc_spec_from_file(FILE *);


    void vp8bc_destroy_spec(c_bool_coder_spec *);

    void vp8bc_spec_to_file(c_bool_coder_spec *, FILE *);


    /* Nearest index to supplied probability of zero, 0 <= prob <= 1. */

    vp8bc_index_t vp8bc_index(c_bool_coder_spec *, double prob);

    vp8bc_index_t vp8bc_index_from_counts(
        c_bool_coder_spec *p, unsigned int zero_ct, unsigned int one_ct
    );

    /* In case you want to look */

    double vp8bc_probability(c_bool_coder_spec *, vp8bc_index_t);

    /* Opposite index */

    vp8bc_index_t vp8bc_complement(c_bool_coder_spec *, vp8bc_index_t);

    /* Cost in bits of encoding a zero at given probability, scaled by 2^20.
       (assumes that an int holds at least 32 bits). */

    unsigned int vp8bc_cost_zero(c_bool_coder_spec *, vp8bc_index_t);

    unsigned int vp8bc_cost_one(c_bool_coder_spec *, vp8bc_index_t);
    unsigned int vp8bc_cost_bit(c_bool_coder_spec *, vp8bc_index_t, int);


    /* bool_writer interface */

    /* Length = 0 disables checking for writes beyond buffer end. */

    bool_writer *vp8bc_create_writer(
        c_bool_coder_spec *, unsigned char *Destination, size_t Length
    );

    /* Flushes out any buffered data and returns total # of bytes written. */

    size_t vp8bc_destroy_writer(bool_writer *);

    void vp8bc_write_bool(bool_writer *, int boolean_val, vp8bc_index_t false_prob);

    void vp8bc_write_bits(
        bool_writer *, unsigned int integer_value, int number_of_bits
    );

    c_bool_coder_spec *vp8bc_writer_spec(c_bool_writer *);


    /* bool_reader interface */

    /* Length = 0 disables checking for reads beyond buffer end. */

    bool_reader *vp8bc_create_reader(
        c_bool_coder_spec *, const unsigned char *Source, size_t Length
    );
    void vp8bc_destroy_reader(bool_reader *);

    int vp8bc_read_bool(bool_reader *, vp8bc_index_t false_prob);

    unsigned int vp8bc_read_bits(bool_reader *, int number_of_bits);

    c_bool_coder_spec *vp8bc_reader_spec(c_bool_reader *);

#if __cplusplus
}
#endif

#endif  /* bool_coder_h */
