/* * nd.c: Input of prediction tree * * Written by: Ullrich Hafner * * This file is part of FIASCO (Fractal Image And Sequence COdec) * Copyright (C) 1994-2000 Ullrich Hafner */ /* * $Date: 2000/06/14 20:50:13 $ * $Author: hafner $ * $Revision: 5.1 $ * $State: Exp $ */ #include "config.h" #include "types.h" #include "macros.h" #include "error.h" #include "bit-io.h" #include "arith.h" #include "misc.h" #include "list.h" #include "wfalib.h" #include "nd.h" /***************************************************************************** prototypes *****************************************************************************/ static void decode_nd_coefficients (unsigned total, wfa_t *wfa, bitfile_t *input); static unsigned decode_nd_tree (wfa_t *wfa, bitfile_t *input); /***************************************************************************** public code *****************************************************************************/ void read_nd (wfa_t *wfa, bitfile_t *input) /* * Read transitions of the nondetermistic 'wfa' part from 'input' stream. * ND is used only at levels {'wfa->p_min_level', ... , 'wfa->p_max_level'}. * * Side effects: * 'wfa->into' and 'wfa->weights' are filled with the decoded values */ { unsigned total = decode_nd_tree (wfa, input); if (total > 0) decode_nd_coefficients (total, wfa, input); } /***************************************************************************** private code *****************************************************************************/ static unsigned decode_nd_tree (wfa_t *wfa, bitfile_t *input) /* * Read 'wfa' prediction tree of given 'input' stream. * * No return value. * * Side effects: * 'wfa->into' is filled with the decoded values */ { lqueue_t *queue; /* queue of states */ int next, state; /* state and its current child */ unsigned total = 0; /* total number of predicted states */ u_word_t sum0, sum1; /* Probability model */ u_word_t code; /* The present input code value */ u_word_t low; /* Start of the current code range */ u_word_t high; /* End of the current code range */ /* * Initialize arithmetic decoder */ code = get_bits (input, 16); low = 0; high = 0xffff; sum0 = 1; sum1 = 11; queue = alloc_queue (sizeof (int)); state = wfa->root_state; queue_append (queue, &state); /* * Traverse the WFA tree in breadth first order (using a queue). */ while (queue_remove (queue, &next)) { unsigned label; if (wfa->level_of_state [next] > wfa->wfainfo->p_max_level + 1) { /* * Nondetermismn is not allowed at levels larger than * 'wfa->wfainfo->p_max_level'. */ for (label = 0; label < MAXLABELS; label++) if (ischild (state = wfa->tree [next][label])) queue_append (queue, &state); /* continue with children */ } else if (wfa->level_of_state [next] > wfa->wfainfo->p_min_level) { for (label = 0; label < MAXLABELS; label++) if (ischild (state = wfa->tree [next][label])) { unsigned count; /* Current interval count */ unsigned range; /* Current interval range */ count = (((code - low) + 1) * sum1 - 1) / ((high - low) + 1); if (count < sum0) { /* * Decode a '0' symbol * First, the range is expanded to account for the * symbol removal. */ range = (high - low) + 1; high = low + (u_word_t) ((range * sum0) / sum1 - 1 ); RESCALE_INPUT_INTERVAL; /* * Update the frequency counts */ sum0++; sum1++; if (sum1 > 50) /* scale the symbol frequencies */ { sum0 >>= 1; sum1 >>= 1; if (!sum0) sum0 = 1; if (sum0 >= sum1) sum1 = sum0 + 1; } if (wfa->level_of_state [state] > wfa->wfainfo->p_min_level) queue_append (queue, &state); } else { /* * Decode a '1' symbol * First, the range is expanded to account for the * symbol removal. */ range = (high - low) + 1; high = low + (u_word_t) ((range * sum1) / sum1 - 1); low = low + (u_word_t) ((range * sum0) / sum1); RESCALE_INPUT_INTERVAL; /* * Update the frequency counts */ sum1++; if (sum1 > 50) /* scale the symbol frequencies */ { sum0 >>= 1; sum1 >>= 1; if (!sum0) sum0 = 1; if (sum0 >= sum1) sum1 = sum0 + 1; } append_edge (next, 0, -1, label, wfa); total++; } } } } free_queue (queue); INPUT_BYTE_ALIGN (input); return total; } static void decode_nd_coefficients (unsigned total, wfa_t *wfa, bitfile_t *input) /* * Read #'total' weights of nondeterministic part of 'wfa' * of given 'input' stream. * 'frame' gives the current frame number. * * No return value. * * Side effects: * 'wfa->weights' is filled with the decoded values. */ { unsigned *coefficients; /* array of factors to encode */ unsigned *ptr; /* pointer to current factor */ /* * Decode array of coefficients stored with arithmetic coding */ { const int scaling = 50; /* scaling factor of prob. model */ unsigned c_symbols = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1); ptr = coefficients = decode_array (input, NULL, &c_symbols, 1, total, scaling); } /* * Fill 'wfa->weights' with decoded coefficients */ { unsigned state, label; for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (ischild (wfa->tree [state][label]) && isedge (wfa->into [state][label][0])) { wfa->weight [state][label][0] = btor (*ptr++, wfa->wfainfo->dc_rpf); wfa->int_weight [state][label][0] = wfa->weight [state][label][0] * 512 + 0.5; } } Free (coefficients); }