⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stats.c

📁 source code for arithmatic coding
💻 C
📖 第 1 页 / 共 2 页
字号:
    arithmetic_encode(low_w, high_w, pContext->total);    if (symbol != 1)        /* If not the special ESC / NOT_KNOWN symbol */    {            /*update the singleton count if symbol was previously a singleton */        if (pContext->type == DYNAMIC && high-low == pContext->incr)            pContext->nSingletons -= pContext->incr;            /* increment the symbol's frequency count */        INCR_SYMBOL_PROB(pContext, symbol, low, high, pContext->incr);    }    adjust_zero_freq(pContext);    while (pContext->total > Max_frequency)        halve_context(pContext);    if (symbol == 1) return NOT_KNOWN;    return 0;}/* encode() *//* * * decode function is passed a context, and returns a symbol * */int decode(context *pContext){    int    symbol;    int p, m, e;    freq_value low, high, target;    int            n = pContext->max_length;    freq_value total = pContext->total;    freq_value    *M = pContext->tree;     target = arithmetic_decode_target(total);#ifdef MOST_PROB_AT_END	/* Check if most probable symbol (shortcut decode)	 */    if (target >= total - pContext->most_freq_count) {	  arithmetic_decode( total - pContext->most_freq_count, total, total);	  symbol = pContext->most_freq_symbol;	  low    = pContext->most_freq_pos;	  high   = low + pContext->most_freq_count;      INCR_SYMBOL_PROB(pContext, symbol, low, high, pContext->incr);      if (symbol != 1)         if (pContext->type == DYNAMIC && high-low == pContext->incr)            pContext->nSingletons -= pContext->incr;	}    else	/* Not MPS, have to decode slowly */  {	if (target >= pContext->most_freq_pos)	    target += pContext->most_freq_count;#endif    p = 1; low = 0;    while ( ((p << 1) <= pContext->max_length ) && (M[p] <= target)) {        target -= M[p];        low    += M[p];        p      <<= 1;    }    symbol = p;    m = p >> 1;    e = 0;    while (m >= 1) {        if (symbol + m <= n) {            e += M[symbol + m];            if (M[symbol] - e <= target) {                target    -= M[symbol] - e;                low       += M[symbol] - e;                if (symbol != 1) M[symbol] += pContext->incr;                symbol    += m;                e         =  0;            }        }        m >>= 1;    }    if (symbol!= 1) M[symbol] += pContext->incr;    if (symbol & 1)        high = low + pContext->tree[symbol];    else {        GET_COUNT(pContext, symbol, high);        high += low;    }    if (symbol != 1) high -= pContext->incr;#ifdef MOST_PROB_AT_END    if (low >= pContext->most_freq_pos)   /* Ie: Was moved */	    arithmetic_decode(low  - pContext->most_freq_count,			  high - pContext->most_freq_count,			  total);    else#endif        arithmetic_decode(low, high, total);    /* update the singleton count if symbol was previously a singleton */    if (symbol != 1)    {      if (pContext->type == DYNAMIC && high-low == pContext->incr)        pContext->nSingletons -= pContext->incr;        pContext->total += pContext->incr;        if (symbol == pContext->most_freq_symbol)	        pContext->most_freq_count += pContext->incr;        else if (high-low+pContext->incr > pContext->most_freq_count) {             pContext->most_freq_symbol = symbol;	        pContext->most_freq_count  = high - low + pContext->incr;	        pContext->most_freq_pos    = low;	    } else if (symbol < pContext->most_freq_symbol)	        pContext->most_freq_pos += pContext->incr;    }#ifdef MOST_PROB_AT_END  }  /* If not MPS */#endif    adjust_zero_freq(pContext);    /* halve all frequencies if necessary */    while (pContext->total > Max_frequency)        halve_context(pContext);    if (symbol == 1) return NOT_KNOWN;    return symbol-2;}/* decode() *//* * * Get the low and high limits of the frequency interval * occupied by a symbol. * */static void get_interval(context *pContext, freq_value *pLow, freq_value *pHigh, int symbol){    freq_value low, count;    int p, q;    freq_value *tree = pContext->tree;        /* go too far */    for(p = 1, low = 0 ; p < symbol ; ) {        low  += tree[p],         p   <<= 1;    }        /* subtract off the extra freqs from low */    q = symbol;    while ((q != p) && (q <= pContext->max_length)) {        low -= tree[q],         q   = FORW(q);    }    GET_COUNT(pContext, symbol, count);    *pLow = low;    *pHigh = low + count;} /* * * Halve_context is responsible for halving all the frequency counts in a  * context. * Halves context in linear time by converting tree to list of freqs * then back again. * * It ensures the most probable symbol size and range stay updated. * If halving the context gives rise to a sudden drop in the * ZERO_FREQ_PROB(), and if it was the MPS, it will stay recorded as the most * probable symbol even if it isn't.  This may cause slight compression * inefficiency.  (The ZERO_FREQ_PROB() as implemented does not have this * characteristic, and in this case the inefficiency cannot occur) */static voidhalve_context(context *pContext){    int  shifts, p, symbol;    freq_value incr;    pContext->incr = (pContext->incr + MIN_INCR) >> 1;    /* halve increment */    if (pContext->incr < MIN_INCR)             pContext->incr = MIN_INCR;    pContext->nSingletons = incr = pContext->incr;            /*        ** Convert Moffat tree to array of freqs        */    for (shifts=0 , p = pContext->max_length ; p > 1 ; shifts++ ) p >>= 1;    p  = 1 << shifts;      /* p is now to 2^floor(log_2 pContext->max_length) */    while( p > 1 ) {        symbol = p;        while (symbol + (p >> 1) <= pContext->max_length ) {            pContext->tree[symbol] -= pContext->tree[symbol + (p >> 1)];            symbol                 += p;        }        p >>= 1;    }        /*        ** Halve the counts (ignore tree[1] as it will be changed soon)        */    pContext->total = 0;    for (p = 2; p <= pContext->max_length; p++) {        pContext->tree[p] = (pContext->tree[p] + 1) >> 1;        pContext->total  += pContext->tree[p];        if (pContext->tree[p] == incr)            pContext->nSingletons += incr;    }        /*        ** Convert array of freqs to Moffat tree        */    for (p = 2; p <= pContext->max_length; ) {        symbol = p;        while (symbol + (p >> 1) <= pContext->max_length ) {            pContext->tree[symbol] += pContext->tree[symbol + (p >> 1)];            symbol                 += p;        }        p <<= 1;    }    if (pContext->type == STATIC)        pContext->nSingletons = 0;    pContext->tree[1] = ZERO_FREQ_PROB(pContext);    pContext->total  += ZERO_FREQ_PROB(pContext);    /* Recalc new most_freq_symbol info if it exists     * (since roundoff may mean not exactly half of previous value)     */    if (pContext->most_freq_symbol != -1)       { freq_value low, high;        get_interval(pContext, &low, &high, pContext->most_freq_symbol);        pContext->most_freq_count = high-low;        pContext->most_freq_pos = low;      }    adjust_zero_freq(pContext);}/* halve_context() *//* * * free memory allocated for a context and initialize empty context * of original size * */void purge_context(context *pContext){    int i;    free(pContext->tree);        /* malloc new tree of original size */    if ((pContext->tree = (freq_value *)malloc((pContext->initial_size + 1)                        * sizeof(freq_value))) == NULL)    {    fprintf(stderr, "stats: not enough memory to create context\n");    exit(1);    }    pContext->length = 1;    pContext->total = 0;    pContext->nSymbols = 1;        /* Start with escape symbol */    pContext->most_freq_symbol = -1;    /* Indicates no such symbol */    pContext->most_freq_count = 0;    pContext->most_freq_pos = 0;    pContext->max_length = pContext->initial_size;    for (i = 0; i <= pContext->initial_size; i++)	    pContext->tree[i] = 0;                      /* increment is initially 2 ^ f */    pContext->incr = (freq_value) 1 << F_bits;    pContext->nSingletons = 0;    init_zero_freq(pContext);    adjust_zero_freq(pContext);}/******************************************************************************** functions for binary contexts*******************************************************************************//* * * create a binary_context * binary contexts consist of two counts and an increment which * is normalized * */binary_context *create_binary_context(void){    binary_context *pContext;#ifdef VARY_NBITS    Max_frequency = ((freq_value) 1 << F_bits);#endif    pContext = (binary_context *) malloc(sizeof(binary_context));    if (pContext == NULL)    {    fprintf(stderr, "stats: not enough memory to create context\n");    exit(1);    }                        /* start with incr=2^(f-1) */    pContext->incr = (freq_value) 1 << (F_bits - 1);    pContext->c0 = pContext->incr;    pContext->c1 = pContext->incr;    return pContext;}/* * * encode a binary symbol using special binary arithmetic * coding functions * returns 0 if successful * */intbinary_encode(binary_context *pContext, int bit){    binary_arithmetic_encode(pContext->c0, pContext->c1, bit);    /* increment symbol count */    if (bit == 0)    pContext->c0 += pContext->incr;    else    pContext->c1 += pContext->incr;    /* halve frequencies if necessary */    if (pContext->c0 + pContext->c1 > Max_frequency)    {    pContext->c0 = (pContext->c0 + 1) >> 1;    pContext->c1 = (pContext->c1 + 1) >> 1;    pContext->incr = (pContext->incr + MIN_INCR) >> 1;    }    return 0;}    /* * * decode a binary symbol using specialised binary arithmetic * coding functions * */intbinary_decode(binary_context *pContext){    int bit;    bit = binary_arithmetic_decode(pContext->c0, pContext->c1);    /* increment symbol count */    if (bit == 0)    pContext->c0 += pContext->incr;    else    pContext->c1 += pContext->incr;    /* halve frequencies if necessary */    if (pContext->c0 + pContext->c1 > Max_frequency)    {    pContext->c0 = (pContext->c0 + 1) >> 1;    pContext->c1 = (pContext->c1 + 1) >> 1;    pContext->incr = (pContext->incr + MIN_INCR) >> 1;    }        return bit;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -