diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/other/fiasco/input | |
download | netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip |
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/fiasco/input')
-rw-r--r-- | converter/other/fiasco/input/Makefile | 26 | ||||
-rw-r--r-- | converter/other/fiasco/input/basis.c | 141 | ||||
-rw-r--r-- | converter/other/fiasco/input/basis.h | 26 | ||||
-rw-r--r-- | converter/other/fiasco/input/matrices.c | 644 | ||||
-rw-r--r-- | converter/other/fiasco/input/matrices.h | 27 | ||||
-rw-r--r-- | converter/other/fiasco/input/mc.c | 334 | ||||
-rw-r--r-- | converter/other/fiasco/input/mc.h | 28 | ||||
-rw-r--r-- | converter/other/fiasco/input/nd.c | 237 | ||||
-rw-r--r-- | converter/other/fiasco/input/nd.h | 28 | ||||
-rw-r--r-- | converter/other/fiasco/input/read.c | 499 | ||||
-rw-r--r-- | converter/other/fiasco/input/read.h | 31 | ||||
-rw-r--r-- | converter/other/fiasco/input/tree.c | 303 | ||||
-rw-r--r-- | converter/other/fiasco/input/tree.h | 28 | ||||
-rw-r--r-- | converter/other/fiasco/input/weights.c | 200 | ||||
-rw-r--r-- | converter/other/fiasco/input/weights.h | 27 |
15 files changed, 2579 insertions, 0 deletions
diff --git a/converter/other/fiasco/input/Makefile b/converter/other/fiasco/input/Makefile new file mode 100644 index 00000000..c01af772 --- /dev/null +++ b/converter/other/fiasco/input/Makefile @@ -0,0 +1,26 @@ +ifeq ($(SRCDIR)x,x) + SRCDIR = $(CURDIR)/../../../.. + BUILDDIR = $(SRCDIR) +endif +FIASCOSUBDIR = converter/other/fiasco +SUBDIR = $(FIASCOSUBDIR)/input +BUILDDIR = ../../../.. +VPATH=.:$(SRCDIR)/$(SUBDIR) + +include $(BUILDDIR)/Makefile.config + +OBJECTS = basis.o matrices.o mc.o nd.o read.o tree.o weights.o + +MERGE_OBJECTS = $(OBJECTS) + +INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \ + -I$(SRCDIR)/$(FIASCOSUBDIR)/codec + +all: libfiasco_input.a + +include $(SRCDIR)/Makefile.common + +libfiasco_input.a: $(OBJECTS) + $(AR) -rc $@ $(OBJECTS) + $(RANLIB) $@ + diff --git a/converter/other/fiasco/input/basis.c b/converter/other/fiasco/input/basis.c new file mode 100644 index 00000000..cef075e6 --- /dev/null +++ b/converter/other/fiasco/input/basis.c @@ -0,0 +1,141 @@ +/* + * basis.c: WFA initial basis files + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/25 16:38:06 $ + * $Author: hafner $ + * $Revision: 5.3 $ + * $State: Exp $ + */ + +#include "config.h" + +#include "types.h" +#include "macros.h" +#include "error.h" + +#include "wfa.h" +#include "wfalib.h" + +#include "basis.h" + +typedef struct basis_values +{ + unsigned states; + real_t *final; + bool_t *use_domain; + real_t (*transitions)[4]; +} basis_values_t; + +typedef struct +{ + const char *filename; + void (*function)(basis_values_t *bv); +} basis_file_t; + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static void +small_init (basis_values_t *bv); + +static basis_file_t const basis_files[] = { + {"small.fco", small_init}, + {"small.wfa", small_init}, + {NULL, NULL} +}; + +/***************************************************************************** + + public code + +*****************************************************************************/ + +bool_t +get_linked_basis (const char *basis_name, wfa_t *wfa) +/* + * Check wether given WFA initial basis 'basis_name' is already linked + * with the excecutable. If the basis is available then fill the 'wfa' struct + * according to the stored data, otherwise print a warning message. + * + * Return value: + * true on success, false if basis is not available yet. + * + * Side effects: + * 'wfa' struct is filled on success. + */ +{ + bool_t success = NO; /* indicates if basis is found */ + unsigned n; /* counter */ + basis_values_t bv; /* basis values */ + + for (n = 0; basis_files [n].filename != NULL; n++) + if (streq (basis_files [n].filename, basis_name)) /* basis is stored */ + { + unsigned state, edge; + + (*basis_files [n].function) (&bv); /* initialize local variables */ + /* + * Generate WFA + */ + wfa->basis_states = wfa->states = bv.states + 1; + wfa->domain_type[0] = USE_DOMAIN_MASK; + wfa->final_distribution[0] = 128; + append_edge (0, 0, 1.0, 0, wfa); + append_edge (0, 0, 1.0, 1, wfa); + for (state = 1; state < wfa->basis_states; state++) + { + wfa->final_distribution [state] = bv.final [state - 1]; + wfa->domain_type [state] = bv.use_domain [state - 1] + ? USE_DOMAIN_MASK + : AUXILIARY_MASK; + } + for (edge = 0; isedge (bv.transitions [edge][0]); edge++) + append_edge (bv.transitions [edge][0], bv.transitions [edge][1], + bv.transitions [edge][2], bv.transitions [edge][3], + wfa); + + success = YES; + break; + } + + if (!success) + warning ("WFA initial basis '%s' isn't linked with the excecutable yet." + "\nLoading basis from disk instead.", basis_name); + + return success; +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +/***************************************************************************** + basis "small.wfa" +*****************************************************************************/ + +static unsigned states_small = 2; +static bool_t use_domain_small[] = {YES, YES}; +static real_t final_small[] = {64, 64}; +static real_t transitions_small[][4] = {{1, 2, 0.5, 0}, {1, 2, 0.5, 1}, + {1, 0, 0.5, 1}, {2, 1, 1.0, 0}, + {2, 1, 1.0, 1}, {-1, 0, 0, 0}}; +static void +small_init (basis_values_t *bv) +{ + bv->states = states_small; + bv->final = final_small; + bv->use_domain = use_domain_small; + bv->transitions = transitions_small; +} diff --git a/converter/other/fiasco/input/basis.h b/converter/other/fiasco/input/basis.h new file mode 100644 index 00000000..fa26bca2 --- /dev/null +++ b/converter/other/fiasco/input/basis.h @@ -0,0 +1,26 @@ +/* + * basis.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _BASIS_H +#define _BASIS_H + +#include "wfa.h" + +bool_t +get_linked_basis (const char *basis_name, wfa_t *wfa); + +#endif /* not _BASIS_H */ + diff --git a/converter/other/fiasco/input/matrices.c b/converter/other/fiasco/input/matrices.c new file mode 100644 index 00000000..47cde1aa --- /dev/null +++ b/converter/other/fiasco/input/matrices.c @@ -0,0 +1,644 @@ +/* + * matrices.c: Input of transition matrices + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $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 "wfalib.h" + +#include "matrices.h" + +#if STDC_HEADERS +# include <stdlib.h> +#endif /* not STDC_HEADERS */ + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static unsigned +delta_decoding (wfa_t *wfa, unsigned last_domain, bitfile_t *input); +static unsigned +column_0_decoding (wfa_t *wfa, unsigned last_row, bitfile_t *input); +static unsigned +chroma_decoding (wfa_t *wfa, bitfile_t *input); +static void +compute_y_state (int state, int y_state, wfa_t *wfa); + +/***************************************************************************** + + public code + +*****************************************************************************/ + +unsigned +read_matrices (wfa_t *wfa, bitfile_t *input) +/* + * Read transitions of WFA given from the stream 'input'. + * + * Return value: + * number of edges + * + * Side effects: + * 'wfa->into' is filled with decoded values + */ +{ + unsigned total; /* total number of edges in the WFA */ + unsigned root_state = wfa->wfainfo->color + ? wfa->tree [wfa->tree [wfa->root_state][0]][0] + : wfa->root_state; + + total = column_0_decoding (wfa, root_state, input); + total += delta_decoding (wfa, root_state, input); + if (wfa->wfainfo->color) + total += chroma_decoding (wfa, input); + + return total; +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static unsigned +delta_decoding (wfa_t *wfa, unsigned last_domain, bitfile_t *input) +/* + * Read transition matrices which are encoded with delta coding + * from stream 'input'. + * 'last_domain' is the maximum state number used as domain image. + * + * Return value: + * number of non-zero matrix elements (WFA edges) + * + * Side effects: + * 'wfa->into' is filled with decoded values + */ +{ + range_sort_t rs; /* ranges are sorted as in the coder */ + unsigned max_domain; /* dummy used for recursion */ + unsigned range; + unsigned count [MAXEDGES + 1]; + unsigned state, label; + unsigned *n_edges; /* number of elements per row */ + unsigned total = 0; /* total number of decoded edges */ + + /* + * Generate a list of range blocks. + * The order is the same as in the coder. + */ + rs.range_state = Calloc ((last_domain + 1) * MAXLABELS, + sizeof (u_word_t)); + rs.range_label = Calloc ((last_domain + 1) * MAXLABELS, + sizeof (byte_t)); + rs.range_max_domain = Calloc ((last_domain + 1) * MAXLABELS, + sizeof (u_word_t)); + rs.range_subdivided = Calloc ((last_domain + 1) * MAXLABELS, + sizeof (bool_t)); + rs.range_no = 0; + max_domain = wfa->basis_states - 1; + sort_ranges (last_domain, &max_domain, &rs, wfa); + + /* + * Get row statistics + */ + { + arith_t *decoder; + model_t *elements; + unsigned max_edges = read_rice_code (3, input); + + /* + * Get the probability array of the number of edges distribution + * and allocate the corresponding model. + */ + { + unsigned edge; + + for (edge = 0; edge <= max_edges; edge++) + count [edge] = read_rice_code ((int) log2 (last_domain) - 2, + input); + elements = alloc_model (max_edges + 1, 0, 0, count); + } + + /* + * Get number of elements per matrix row + */ + { + unsigned row; + + n_edges = Calloc (wfa->states, sizeof (unsigned)); + decoder = alloc_decoder (input); + for (row = range = 0; range < rs.range_no; range++) + if (!rs.range_subdivided [range]) + { + state = rs.range_state [range]; + label = rs.range_label [range]; + + n_edges [row++] + = decode_symbol (decoder, elements) + - (isedge (wfa->into [state][label][0]) ? 1 : 0); + } + + free_decoder (decoder); + free_model (elements); + } + } + + /* + * Get matrix elements + */ + { + unsigned row; + u_word_t *mapping1 = Calloc (wfa->states, sizeof (word_t)); + u_word_t *mapping_coder1 = Calloc (wfa->states, sizeof (word_t)); + u_word_t *mapping2 = Calloc (wfa->states, sizeof (word_t)); + u_word_t *mapping_coder2 = Calloc (wfa->states, sizeof (word_t)); + bool_t use_normal_domains = get_bit (input); + bool_t use_delta_domains = get_bit (input); + + /* + * Generate array of states which are admitted domains. + * When coding intra frames 'mapping1' == 'mapping2' otherwise + * 'mapping1' is a list of 'normal' domains which are admitted for + * coding intra blocks + * 'mapping2' is a list of 'delta' domains which are admitted for + * coding the motion compensated prediction error + */ + { + unsigned n1, n2, state; + + for (n1 = n2 = state = 0; state < wfa->states; state++) + { + mapping1 [n1] = state; + mapping_coder1 [state] = n1; + if (usedomain (state, wfa) + && (state < wfa->basis_states + || use_delta_domains || !wfa->delta_state [state])) + n1++; + + mapping2 [n2] = state; + mapping_coder2 [state] = n2; + if (usedomain (state, wfa) + && (state < wfa->basis_states || use_normal_domains + || wfa->delta_state [state])) + n2++; + } + } + + for (row = 0, range = 0; range < rs.range_no; range++) + if (!rs.range_subdivided [range]) + { + u_word_t *mapping; + u_word_t *mapping_coder; + unsigned max_value; + unsigned edge; + unsigned state = rs.range_state [range]; + unsigned label = rs.range_label [range]; + unsigned last = 1; + + if (wfa->delta_state [state] || + wfa->mv_tree [state][label].type != NONE) + { + mapping = mapping2; + mapping_coder = mapping_coder2; + } + else + { + mapping = mapping1; + mapping_coder = mapping_coder1; + } + max_value = mapping_coder [rs.range_max_domain [range]]; + for (edge = n_edges [row]; edge; edge--) + { + unsigned domain; + + if (max_value - last) + domain = read_bin_code (max_value - last, input) + last; + else + domain = max_value; + append_edge (state, mapping [domain], -1, label, wfa); + last = domain + 1; + total++; + } + row++; + } + Free (mapping1); + Free (mapping_coder1); + Free (mapping2); + Free (mapping_coder2); + } + + Free (n_edges); + Free (rs.range_state); + Free (rs.range_label); + Free (rs.range_max_domain); + Free (rs.range_subdivided); + + return total; +} + +static unsigned +column_0_decoding (wfa_t *wfa, unsigned last_row, bitfile_t *input) +/* + * Read column 0 of the transition matrices of the 'wfa' which are coded + * with quasi arithmetic coding from stream 'input'. + * All rows from 'wfa->basis_states' up to 'last_row' are decoded. + * + * Return value: + * number of non-zero matrix elements (WFA edges) + * + * Side effects: + * 'wfa->into' is filled with decoded values + */ +{ + unsigned row; /* current matrix row */ + unsigned total = 0; /* total number of edges in col 0 */ + unsigned *prob_ptr; /* pointer to current probability */ + unsigned *last; /* pointer to minimum probability */ + unsigned *first; /* pointer to maximum probability */ + unsigned *new_prob_ptr; /* ptr to probability of last domain */ + unsigned *prob; /* probability array */ + u_word_t high; /* Start of the current code range */ + u_word_t low; /* End of the current code range */ + u_word_t code; /* The present input code value */ + word_t *is_leaf; /* pointer to the tree structure */ + + /* + * Compute the asymmetric probability array + * prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4, + * 1/8, ... , 1/16, ..., 1/(MAXPROB+1)} + */ + { + unsigned n; + unsigned index; /* probability index */ + unsigned exp; /* current exponent */ + + prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned)); + + for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++) + for (exp = 0; exp < 1U << n; exp++, index++) + prob [index] = n; + } + + first = prob_ptr = new_prob_ptr = prob; + last = first + 1020; + + is_leaf = wfa->tree [wfa->basis_states]; /* use pointer arithmetics ... */ + + high = HIGH; /* 1.0 */ + low = LOW; /* 0.0 */ + code = get_bits (input, 16); + + /* + * Decode column 0 with a quasi arithmetic coder (QAC). + * Advantage of this QAC with respect to a binary AC: + * Instead of using time consuming multiplications and divisions + * to compute the probability of the most probable symbol (MPS) and + * the range of the interval, a table look up procedure linked + * with a shift operation is used for both computations. + * + * Loops and array accesses have been removed + * to make real time decoding possible. + */ + for (row = wfa->basis_states; row <= last_row; row++) + { + unsigned count; /* value in the current interval */ + + /* + * Read label 0 element + */ + if (isrange (*is_leaf++)) /* valid matrix index */ + { + count = high - ((high - low) >> *prob_ptr); + if (code < count) + { + if (prob_ptr < last) /* model update */ + prob_ptr++; + /* + * Decode the MPS '0' + */ + high = count - 1; + + RESCALE_INPUT_INTERVAL; + } + else + { + prob_ptr = ((prob_ptr - first) >> 1) + first; /* model update */ + /* + * Decode the LPS '1' + */ + low = count; + + RESCALE_INPUT_INTERVAL; + /* + * Restore the transition (weight = -1) + */ + append_edge (row, 0, -1, 0, wfa); + total++; + } + } + /* + * Read label 1 element + */ + if (isrange (*is_leaf++)) /* valid matrix index */ + { + count = high - ((high - low) >> *prob_ptr); + if (code < count) + { + if (prob_ptr < last) + prob_ptr++; /* model update */ + /* + * Decode the MPS '0' + */ + high = count - 1; + + RESCALE_INPUT_INTERVAL; + } + else + { + prob_ptr = ((prob_ptr - first) >> 1) + first; /* model update */ + /* + * Decode the LPS '1' + */ + low = count; + + RESCALE_INPUT_INTERVAL; + /* + * Restore the transition (weight = -1) + */ + append_edge (row, 0, -1, 1, wfa); + total++; + } + } + } + + INPUT_BYTE_ALIGN (input); + + Free (prob); + + return total; +} + +static unsigned +chroma_decoding (wfa_t *wfa, bitfile_t *input) +/* + * Read transition matrices of 'wfa' states which are part of the + * chroma channels Cb and Cr from stream 'input'. + * + * Return value: + * number of non-zero matrix elements (WFA edges) + * + * Side effects: + * 'wfa->into' is filled with decoded values + */ +{ + unsigned domain; /* current domain, counter */ + unsigned total = 0; /* total number of chroma edges */ + unsigned *prob_ptr; /* pointer to current probability */ + unsigned *last; /* pointer to minimum probability */ + unsigned *first; /* pointer to maximum probability */ + unsigned *new_prob_ptr; /* ptr to probability of last domain */ + unsigned *prob; /* probability array */ + u_word_t high; /* Start of the current code range */ + u_word_t low; /* End of the current code range */ + u_word_t code; /* The present input code value */ + word_t *y_domains; /* domain images corresponding to Y */ + int save_index; /* YES: store current probabilty */ + + /* + * Compute the asymmetric probability array + * prob[] = { 1/2, 1/2, 1/4, 1/4, 1/4, 1/4, + * 1/8, ... , 1/16, ..., 1/(MAXPROB+1)} + */ + { + unsigned n; + unsigned index; /* probability index */ + unsigned exp; /* current exponent */ + + prob = Calloc (1 << (MAX_PROB + 1), sizeof (unsigned)); + + for (index = 0, n = MIN_PROB; n <= MAX_PROB; n++) + for (exp = 0; exp < 1U << n; exp++, index++) + prob [index] = n; + } + + high = HIGH; /* 1.0 */ + low = LOW; /* 0.0 */ + code = get_bits (input, 16); + + /* + * Compute list of admitted domains + */ + y_domains = compute_hits (wfa->basis_states, + wfa->tree [wfa->tree [wfa->root_state][0]][0], + wfa->wfainfo->chroma_max_states, wfa); + + first = prob_ptr = new_prob_ptr = prob; + last = first + 1020; + + /* + * First of all, read all matrix columns given in the list 'y_domains' + * which note all admitted domains. + * These matrix elements are stored with QAC (see column_0_decoding ()). + */ + for (domain = 0; y_domains [domain] != -1; domain++) + { + unsigned row = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1; + word_t *is_leaf = wfa->tree [row]; + + prob_ptr = new_prob_ptr; + save_index = YES; + + for (; row < wfa->states; row++) + { + unsigned count; /* value in the current interval */ + /* + * Read label 0 element + */ + if (isrange (*is_leaf++)) /* valid matrix index */ + { + count = high - ((high - low) >> *prob_ptr); + if (code < count) + { + if (prob_ptr < last) + prob_ptr++; + /* + * Decode the MPS '0' + */ + high = count - 1; + + RESCALE_INPUT_INTERVAL; + } + else + { + prob_ptr = ((prob_ptr - first) >> 1) + first; + /* + * Decode the LPS '1' + */ + low = count; + + RESCALE_INPUT_INTERVAL; + /* + * Restore the transition (weight = -1) + */ + append_edge (row, y_domains [domain], -1, 0, wfa); + total++; + } + } + /* + * Read label 1 element + */ + if (isrange (*is_leaf++)) /* valid matrix index */ + { + count = high - ((high - low) >> *prob_ptr); + if (code < count) + { + if (prob_ptr < last) + prob_ptr++; + /* + * Decode the MPS '0' + */ + high = count - 1; + + RESCALE_INPUT_INTERVAL; + } + else + { + prob_ptr = ((prob_ptr - first) >> 1) + first; + /* + * Decode the LPS '1' + */ + low = count; + + RESCALE_INPUT_INTERVAL; + /* + * Restore the transition (weight = -1) + */ + append_edge (row, y_domains [domain], -1, 1, wfa); + total++; + } + } + if (save_index) + { + save_index = NO; + new_prob_ptr = prob_ptr; + } + } + } + + Free (y_domains); + + compute_y_state (wfa->tree [wfa->tree [wfa->root_state][0]][1], + wfa->tree [wfa->tree [wfa->root_state][0]][0], wfa); + compute_y_state (wfa->tree [wfa->tree [wfa->root_state][1]][0], + wfa->tree [wfa->tree [wfa->root_state][0]][0], wfa); + + first = prob_ptr = new_prob_ptr = prob; + + /* + * Decode the additional column which indicates whether there + * are transitions to a state with same spatial coordinates + * in the Y component. + * + * Again, quasi arithmetic decoding is used for this task. + */ + { + unsigned row; + + for (row = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1; + row < wfa->states; row++) + { + int label; /* current label */ + + for (label = 0; label < MAXLABELS; label++) + { + u_word_t count = high - ((high - low) >> *prob_ptr); + + if (code < count) + { + if (prob_ptr < last) + prob_ptr++; + /* + * Decode the MPS '0' + */ + high = count - 1; + + RESCALE_INPUT_INTERVAL; + } + else + { + prob_ptr = ((prob_ptr - first) >> 1) + first; + /* + * Decode the LPS '1' + */ + low = count; + + RESCALE_INPUT_INTERVAL; + /* + * Restore the transition (weight = -1) + */ + append_edge (row, wfa->y_state [row][label], -1, label, wfa); + total++; + } + } + } + } + + INPUT_BYTE_ALIGN (input); + + Free (prob); + + return total; +} + +static void +compute_y_state (int state, int y_state, wfa_t *wfa) +/* + * Compute the 'wfa->y_state' array which denotes those states of + * the Y band that have the same spatial coordinates as the corresponding + * states of the Cb and Cr bands. + * The current root of the Y tree is given by 'y_state'. + * The current root of the tree of the chroma channel is given by 'state'. + * + * No return value. + * + * Side effects: + * 'wfa->y_state' is filled with the generated tree structure. + */ +{ + unsigned label; + + for (label = 0; label < MAXLABELS; label++) + if (isrange (y_state)) + wfa->y_state [state][label] = RANGE; + else + { + wfa->y_state [state][label] = wfa->tree [y_state][label]; + if (!isrange (wfa->tree [state][label])) + compute_y_state (wfa->tree [state][label], + wfa->y_state [state][label], wfa); + } + +} diff --git a/converter/other/fiasco/input/matrices.h b/converter/other/fiasco/input/matrices.h new file mode 100644 index 00000000..ba8fd9bf --- /dev/null +++ b/converter/other/fiasco/input/matrices.h @@ -0,0 +1,27 @@ +/* + * matrices.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _MATRICES_H +#define _MATRICES_H + +#include "wfa.h" +#include "bit-io.h" + +unsigned +read_matrices (wfa_t *wfa, bitfile_t *input); + +#endif /* not _MATRICES_H */ + diff --git a/converter/other/fiasco/input/mc.c b/converter/other/fiasco/input/mc.c new file mode 100644 index 00000000..070d839e --- /dev/null +++ b/converter/other/fiasco/input/mc.c @@ -0,0 +1,334 @@ +/* + * mc.c: Input of motion compensation + * + * written by: Michael Unger + * Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#include <stdlib.h> +#include "config.h" + +#include "types.h" +#include "macros.h" +#include "error.h" + +#include "wfa.h" +#include "bit-io.h" +#include "misc.h" +#include "mvcode.h" + +#include "mc.h" + +/***************************************************************************** + + local variables + +*****************************************************************************/ + +typedef struct huff_node +{ + int code_index; /* leaf if index >= 0 */ + struct huff_node *left; /* follow if '0' bit read */ + struct huff_node *right; /* follow if '1' bit read */ + int index_set [34]; +} huff_node_t; + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static void +decode_mc_tree (frame_type_e frame_type, unsigned max_state, + wfa_t *wfa, bitfile_t *input); +static void +decode_mc_coords (unsigned max_state, wfa_t *wfa, bitfile_t *input); +static int +get_mv (int f_code, huff_node_t *hn, bitfile_t *input); +static huff_node_t * +create_huff_tree (void); +static void +create_huff_node (huff_node_t *hn, int bits_processed); + +/***************************************************************************** + + public code + +*****************************************************************************/ + +void +read_mc (frame_type_e frame_type, wfa_t *wfa, bitfile_t *input) +/* + * Read motion compensation information of the 'input' stream. + * Depending on 'frame_type' different decoding methods are used. + * + * No return value. + * + * Side effects: + * 'wfa->mv_tree' is filled with the decoded values. + */ +{ + unsigned max_state = wfa->wfainfo->color + ? wfa->tree [wfa->tree [wfa->root_state][0]][0] + : wfa->states; + + decode_mc_tree (frame_type, max_state, wfa, input); + decode_mc_coords (max_state, wfa, input); +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static void +decode_mc_tree (frame_type_e frame_type, unsigned max_state, + wfa_t *wfa, bitfile_t *input) +/* + * Read tree of motion compensation decisions of the 'input' stream. + * Depending on 'frame_type' different decoding methods are used. + * 'max_state' is the last state with motion compensation infos. + * + * No return value. + * + * Side effects: + * 'wfa->mv_tree' is filled with decoded values. + */ +{ + unsigned state; /* current state */ + unsigned *queue; /* states in breadth first order */ + unsigned last; /* last node + (update for each new node) */ + + /* + * Traverse tree in breadth first order (starting at level + * 'wfa->wfainfo->p_max_level'). Use a queue to store the childs + * of each node ('last' is the next free queue element). + */ + queue = Calloc (MAXSTATES, sizeof (unsigned)); + for (last = 0, state = wfa->basis_states; state < max_state; state++) + if (wfa->level_of_state [state] - 1 == (int) wfa->wfainfo->p_max_level) + queue [last++] = state; /* init level 'p_max_level' */ + + if (frame_type == P_FRAME) + { + unsigned label; /* current label */ + unsigned current; /* current node to process */ + + for (current = 0; current < last; current++) + for (label = 0; label < MAXLABELS; label++) + { + state = queue[current]; + if (wfa->x [state][label] /* process visible states only */ + + width_of_level (wfa->level_of_state [state] - 1) + <= wfa->wfainfo->width + && + wfa->y [state][label] + + height_of_level (wfa->level_of_state [state] - 1) + <= wfa->wfainfo->height) + { + wfa->mv_tree [state][label].type + = get_bit (input) ? NONE : FORWARD; + } + else + wfa->mv_tree [state][label].type = NONE; + if (wfa->mv_tree [state][label].type == NONE && + !isrange (wfa->tree [state][label]) && + wfa->level_of_state [state] - 1 >= + (int) wfa->wfainfo->p_min_level) + queue [last++] = wfa->tree [state][label]; /* append child */ + } + } + else + { + unsigned label; /* current label */ + unsigned current; /* current node to process */ + + for (current = 0; current < last; current++) + for (label = 0; label < MAXLABELS; label++) + { + state = queue[current]; + if (wfa->x [state][label] /* process visible states only */ + + width_of_level (wfa->level_of_state [state] - 1) + > wfa->wfainfo->width + || + wfa->y [state][label] + + height_of_level (wfa->level_of_state [state] - 1) + > wfa->wfainfo->height) + wfa->mv_tree[state][label].type = NONE; + else if (get_bit (input)) /* 1 */ + wfa->mv_tree[state][label].type = NONE; + else if (get_bit (input)) /* 01 */ + wfa->mv_tree[state][label].type = INTERPOLATED; + else if (get_bit (input)) /* 001 */ + wfa->mv_tree[state][label].type = BACKWARD; + else /* 000 */ + wfa->mv_tree[state][label].type = FORWARD; + if (wfa->mv_tree[state][label].type == NONE && + !isrange (wfa->tree[state][label]) && + wfa->level_of_state[state] - 1 + >= (int) wfa->wfainfo->p_min_level) + queue[last++] = wfa->tree[state][label]; /* append child */ + } + } + + INPUT_BYTE_ALIGN (input); + Free (queue); +} + +static void +decode_mc_coords (unsigned max_state, wfa_t *wfa, bitfile_t *input) +/* + * Read motion vector coordinates of the 'input' stream. They are stored + * with the static Huffman code of the MPEG and H.263 standards. + * 'max_state' is the last state with motion compensation infos. + * + * No return value. + * + * Side effects: + * 'wfa->mv_tree' is filled with decoded values. + */ +{ + unsigned label; /* current label */ + unsigned state; /* current state */ + mv_t *mv; /* current motion vector */ + static huff_node_t *huff_mv_root = NULL; /* root of huffman tree */ + + if (huff_mv_root == NULL) + huff_mv_root = create_huff_tree (); + + for (state = wfa->basis_states; state < max_state; state++) + for (label = 0; label < MAXLABELS; label++) + { + mv = &wfa->mv_tree[state][label]; + switch (mv->type) + { + case NONE: + break; + case FORWARD: + mv->fx = get_mv (1, huff_mv_root, input); + mv->fy = get_mv (1, huff_mv_root, input); + break; + case BACKWARD: + mv->bx = get_mv (1, huff_mv_root, input); + mv->by = get_mv (1, huff_mv_root, input); + break; + case INTERPOLATED: + mv->fx = get_mv (1, huff_mv_root, input); + mv->fy = get_mv (1, huff_mv_root, input); + mv->bx = get_mv (1, huff_mv_root, input); + mv->by = get_mv (1, huff_mv_root, input); + break; + } + } + + INPUT_BYTE_ALIGN (input); +} + +static int +get_mv (int f_code, huff_node_t *hn, bitfile_t *input) +/* + * Decode next motion vector component in bitstream + * by traversing the huffman tree. + */ +{ + int vlc_code, vlc_code_magnitude, residual, diffvec; + + while (hn->code_index < 0) + { + if (hn->code_index == -2) + error ("wrong huffman code !"); + if (get_bit (input)) + hn = hn->right; + else + hn = hn->left; + } + vlc_code = hn->code_index - 16; + if (vlc_code == 0 || f_code == 1) + return vlc_code; + + vlc_code_magnitude = abs (vlc_code) - 1; + if (f_code <= 1) + residual = 0; + else + residual = get_bits (input, f_code - 1); + diffvec = (vlc_code_magnitude << (f_code - 1)) + residual + 1; + + return vlc_code > 0 ? diffvec : - diffvec; +} + +static huff_node_t * +create_huff_tree (void) +/* + * Construct huffman tree from code table + */ +{ + unsigned i; + huff_node_t *huff_root = Calloc (1, sizeof (huff_node_t)); + + /* + * The nodes' index set contains indices of all codewords that are + * still decodable by traversing further down from the node. + * (The root node has the full index set.) + */ + + for (i = 0; i < 33; i++) + huff_root->index_set [i] = i; + huff_root->index_set [i] = -1; /* end marker */ + + create_huff_node (huff_root, 0); + + return huff_root; +} + +static void +create_huff_node (huff_node_t *hn, int bits_processed) +/* + * Create one node in the huffman tree + */ +{ + int lind = 0; /* next index of left huff_node */ + int rind = 0; /* next index of right huff_node */ + int code_len, i, ind; + + hn->code_index = -1; + if (hn->index_set [0] < 0) /* empty index set ? */ + { + hn->code_index = -2; /* error */ + return; + } + hn->left = Calloc (1, sizeof (huff_node_t)); + hn->right = Calloc (1, sizeof (huff_node_t)); + + for (i = 0; (ind = hn->index_set[i]) >= 0; i++) + { + code_len = mv_code_table[ind][1]; + if (code_len == bits_processed) /* generate leaf */ + { + hn->code_index = ind; + Free (hn->left); + Free (hn->right); + return; + } + if (mv_code_table[ind][0] & (1 << (code_len - 1 - bits_processed))) + hn->right->index_set[rind++] = ind; + else + hn->left->index_set[lind++] = ind; + } + hn->right->index_set[rind] = -1; /* set end markers */ + hn->left->index_set[lind] = -1; + create_huff_node (hn->left, bits_processed + 1); + create_huff_node (hn->right, bits_processed + 1); +} diff --git a/converter/other/fiasco/input/mc.h b/converter/other/fiasco/input/mc.h new file mode 100644 index 00000000..1e14d287 --- /dev/null +++ b/converter/other/fiasco/input/mc.h @@ -0,0 +1,28 @@ +/* + * mc.h + * + * written by: Michael Unger + * Ullrich Hafner + + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _MC_H +#define _MC_H + +#include "wfa.h" +#include "bit-io.h" + +void +read_mc (frame_type_e frame_type, wfa_t *wfa, bitfile_t *input); + +#endif /* not _MC_H */ + diff --git a/converter/other/fiasco/input/nd.c b/converter/other/fiasco/input/nd.c new file mode 100644 index 00000000..1a68bfbf --- /dev/null +++ b/converter/other/fiasco/input/nd.c @@ -0,0 +1,237 @@ +/* + * nd.c: Input of prediction tree + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $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 childs */ + } + 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); +} diff --git a/converter/other/fiasco/input/nd.h b/converter/other/fiasco/input/nd.h new file mode 100644 index 00000000..2c2fff4b --- /dev/null +++ b/converter/other/fiasco/input/nd.h @@ -0,0 +1,28 @@ +/* + * nd.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _ND_H +#define _ND_H + +#include "wfa.h" +#include "rpf.h" +#include "bit-io.h" + +void +read_nd (wfa_t *wfa, bitfile_t *input); + +#endif /* not _ND_H */ + diff --git a/converter/other/fiasco/input/read.c b/converter/other/fiasco/input/read.c new file mode 100644 index 00000000..26bae7e4 --- /dev/null +++ b/converter/other/fiasco/input/read.c @@ -0,0 +1,499 @@ +/* + * read.c: Input of WFA files + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/07/18 15:44:58 $ + * $Author: hafner $ + * $Revision: 5.4 $ + * $State: Exp $ + */ + +#define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ +#define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ + +#include "config.h" + +#include <stdio.h> + +#include <string.h> + +#include "types.h" +#include "macros.h" +#include "error.h" + +#include "wfa.h" +#include "misc.h" +#include "rpf.h" +#include "bit-io.h" +#include "wfalib.h" + +#include "tree.h" +#include "matrices.h" +#include "weights.h" +#include "nd.h" +#include "mc.h" +#include "basis.h" +#include "read.h" + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static void +read_tiling (tiling_t *tiling, unsigned image_width, unsigned image_height, + unsigned image_level, bitfile_t *input); + +/***************************************************************************** + + public code + +*****************************************************************************/ + +bitfile_t * +open_wfa (const char *filename, wfa_info_t *wi) +/* + * Open WFA file 'filename' and read header information. + * + * Return value: + * Pointer to input stream (fileposition: first WFA frame) + * + * Side effects: + * The values of the header of 'filename' are copied to 'wfainfo'. + * + */ +{ + bitfile_t *input; /* pointer to WFA bitfile */ + + assert (filename && wi); + + wi->wfa_name = strdup (filename); + + /* + * Check whether 'filename' is a regular WFA file + */ + { + unsigned n; + const char *str; + + if (!(input = open_bitfile (filename, "FIASCO_DATA", READ_ACCESS))) + file_error (filename); + + for (str = FIASCO_MAGIC, n = strlen (FIASCO_MAGIC); n; n--) + if (get_bits (input, 8) != (unsigned) *str++) + error ("Input file %s is not a valid FIASCO file!", filename); + get_bits (input, 8); /* fetch newline */ + } + + /* + * Read WFA header information + */ + { + char basis_name [MAXSTRLEN]; /* temp. buffer */ + const unsigned rice_k = 8; /* parameter of Rice Code */ + char *str = basis_name; + + while ((*str++ = get_bits (input, 8)) != 0 + && str < basis_name + MAXSTRLEN) + ; + if (str == basis_name + MAXSTRLEN) + error ("Input file %s is not a valid FIASCO file!", filename); + + { + wi->release = read_rice_code (rice_k, input); + + if (wi->release > FIASCO_BINFILE_RELEASE) + error ("Can't decode FIASCO files of file format release `%d'." + "\nCurrent file format release is `%d'.", wi->release, + FIASCO_BINFILE_RELEASE); + } + + if (wi->release > 1) + { + header_type_e type; + + while ((type = read_rice_code (rice_k, input)) != HEADER_END) + { + char buffer [MAXSTRLEN]; + unsigned n = 0; + + switch (type) + { + case HEADER_TITLE: + while ((buffer [n++] = get_bits (input, 8))) + ; + wi->title = strdup (buffer); + break; + case HEADER_COMMENT: + while ((buffer [n++] = get_bits (input, 8))) + ; + wi->comment = strdup (buffer); + break; + default: /* should not happen */ + break; + } + } + } + + wi->basis_name = strdup (basis_name); + wi->max_states = read_rice_code (rice_k, input); + wi->color = get_bit (input) ? YES : NO; + wi->width = read_rice_code (rice_k, input); + wi->height = read_rice_code (rice_k, input); + + /* + * Compute bintree level + */ + { + unsigned lx = log2 (wi->width - 1) + 1; + unsigned ly = log2 (wi->height - 1) + 1; + + wi->level = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0); + } + wi->chroma_max_states = wi->color ? read_rice_code (rice_k, input) : -1; + wi->p_min_level = read_rice_code (rice_k, input); + wi->p_max_level = read_rice_code (rice_k, input); + wi->frames = read_rice_code (rice_k, input); + wi->smoothing = read_rice_code (rice_k, input); + + /* + * Read RPF models from disk + */ + { + unsigned mantissa; + fiasco_rpf_range_e range; + + mantissa = get_bits (input, 3) + 2; + range = get_bits (input, 2); + wi->rpf = alloc_rpf (mantissa, range); + + if (get_bit (input)) /* different DC model */ + { + mantissa = get_bits (input, 3) + 2; + range = get_bits (input, 2); + wi->dc_rpf = alloc_rpf (mantissa, range); + } + else /* use same model for DC coefficents */ + wi->dc_rpf = alloc_rpf (wi->rpf->mantissa_bits, + wi->rpf->range_e); + + if (get_bit (input)) /* different delta model */ + { + mantissa = get_bits (input, 3) + 2; + range = get_bits (input, 2); + wi->d_rpf = alloc_rpf (mantissa, range); + } + else + wi->d_rpf = alloc_rpf (wi->rpf->mantissa_bits, + wi->rpf->range_e); + + if (get_bit (input)) /* different DC delta model */ + { + mantissa = get_bits (input, 3) + 2; + range = get_bits (input, 2); + wi->d_dc_rpf = alloc_rpf (mantissa, range); + } + else + wi->d_dc_rpf = alloc_rpf (wi->dc_rpf->mantissa_bits, + wi->dc_rpf->range_e); + } + + if (wi->frames > 1) /* motion compensation stuff */ + { + wi->fps = read_rice_code (rice_k, input); + wi->search_range = read_rice_code (rice_k, input); + wi->half_pixel = get_bit (input) ? YES : NO; + wi->B_as_past_ref = get_bit (input) ? YES : NO; + } + } + + INPUT_BYTE_ALIGN (input); + + return input; +} + +void +read_basis (const char *filename, wfa_t *wfa) +/* + * Read WFA initial basis 'filename' and fill 'wfa' struct. + * + * No return value. + * + * Side effects: + * wfa->into, wfa->weights, wfa->final_distribution, wfa->basis_states + * wfa->domain_type wfa->wfainfo->basis_name, are filled with the + * values of the WFA basis. + */ +{ + FILE *input; /* ASCII WFA initial basis file */ + + assert (filename && wfa); + + if (!wfa->wfainfo->basis_name || + !streq (wfa->wfainfo->basis_name, filename)) + { + if (wfa->wfainfo->basis_name) + Free (wfa->wfainfo->basis_name); + wfa->wfainfo->basis_name = strdup (filename); + } + + if (get_linked_basis (filename, wfa)) + return; /* basis is linked with excecutable */ + + /* + * Check whether 'wfa_name' is a regular ASCII WFA initial basis file + */ + { + char magic [MAXSTRLEN]; /* WFA magic number */ + + if (!(input = open_file (filename, "FIASCO_DATA", READ_ACCESS))) + file_error(filename); + + if (fscanf (input, MAXSTRLEN_SCANF, magic) != 1) + error ("Format error: ASCII FIASCO initial basis file %s", filename); + else if (strneq (FIASCO_BASIS_MAGIC, magic)) + error ("Input file %s is not an ASCII FIASCO initial basis!", + filename); + } + + /* + * WFA ASCII format: + * + * Note: State 0 is assumed to be the constant function f(x, y) = 128. + * Don't define any transitions of state 0 in an initial basis. + * + * Header: + * type |description + * ----------------+----------- + * string |MAGIC Number "Wfa" + * int |Number of basis states 'N' + * bool_t-array[N] |use vector in linear combinations, + * |0: don't use vector (auxilliary state) + * |1: use vector in linear combinations + * float-array[N] |final distribution of every state + * + * Transitions: + * + * <state 1> current state + * <label> <into> <weight> transition 1 of current state + * <label> <into> <weight> transition 2 of current state + * ... + * <-1> last transition marker + * <state 2> + * ... + * <-1> last transition marker + * <state N> + * ... + * + * <-1> last transition marker + * <-1> last state marker + */ + { + unsigned state; + + if (fscanf (input ,"%u", &wfa->basis_states) != 1) + error ("Format error: ASCII FIASCO initial basis file %s", filename); + + /* + * State 0 is assumed to be the constant function f(x, y) = 128. + */ + wfa->domain_type [0] = USE_DOMAIN_MASK; + wfa->final_distribution [0] = 128; + wfa->states = wfa->basis_states; + wfa->basis_states++; + + append_edge (0, 0, 1.0, 0, wfa); + append_edge (0, 0, 1.0, 1, wfa); + + for (state = 1; state < wfa->basis_states; state++) + wfa->domain_type [state] + = read_int (input) ? USE_DOMAIN_MASK : AUXILIARY_MASK; + + for (state = 1; state < wfa->basis_states; state++) + wfa->final_distribution[state] = read_real (input); + + /* + * Read transitions + */ + for (state = 1; state < wfa->basis_states; state++) + { + unsigned domain; + int label; + real_t weight; + + if (read_int (input) != (int) state) + error ("Format error: ASCII FIASCO initial basis file %s", + filename); + + while((label = read_int (input)) != -1) + { + domain = read_int (input); + weight = read_real (input); + append_edge (state, domain, weight, label, wfa); + } + } + } + + fclose (input); +} + +unsigned +read_next_wfa (wfa_t *wfa, bitfile_t *input) +/* + * Read next WFA frame of the WFA stream 'input'. + * WFA header information has to be already present in the 'wfainfo' struct. + * (i.e. open_wfa must be called first!) + * + * No return value. + * + * Side effects: + * wfa->into, wfa->weights, wfa->final_distribution, wfa->states + * wfa->x, wfa->y, wfa->level_of_state, wfa->domain_type + * mt->type, mt->number are filled with the values of the WFA file. + */ +{ + tiling_t tiling; /* tiling information */ + unsigned frame_number; /* current frame number */ + + assert (wfa && input); + + /* + * Frame header information + */ + { + const unsigned rice_k = 8; /* parameter of Rice Code */ + + wfa->states = read_rice_code (rice_k, input); + wfa->frame_type = read_rice_code (rice_k, input); + frame_number = read_rice_code (rice_k, input); + } + + if (wfa->wfainfo->release > 1) /* no alignment in version 1 */ + { + INPUT_BYTE_ALIGN (input); + } + + /* + * Read image tiling info + */ + if (get_bit (input)) /* tiling performed ? */ + read_tiling (&tiling, wfa->wfainfo->width, wfa->wfainfo->height, + wfa->wfainfo->level, input); + else + tiling.exponent = 0; + + INPUT_BYTE_ALIGN (input); + + read_tree (wfa, &tiling, input); + + /* + * Compute domain pool. + * Large images have not been used due to image tiling. + */ + { + unsigned state; + + for (state = wfa->basis_states; state < wfa->states; state++) + if ((!wfa->wfainfo->color + || (int) state <= wfa->tree [wfa->tree [wfa->root_state][0]][0]) + && + (!tiling.exponent || + wfa->level_of_state [state] <= (wfa->wfainfo->level + - tiling.exponent)) + && ((wfa->x [state][0] + + width_of_level (wfa->level_of_state [state])) + <= wfa->wfainfo->width) + && ((wfa->y [state][0] + + height_of_level (wfa->level_of_state [state])) + <= wfa->wfainfo->height)) + wfa->domain_type [state] = USE_DOMAIN_MASK; + else + wfa->domain_type [state] = 0; + } + + if (tiling.exponent) + Free (tiling.vorder); + + if (get_bit (input)) /* nondeterministic prediction used */ + read_nd (wfa, input); + + if (wfa->frame_type != I_FRAME) /* motion compensation used */ + read_mc (wfa->frame_type, wfa, input); + + locate_delta_images (wfa); + + /* + * Read linear combinations (coefficients and indices) + */ + { + unsigned edges = read_matrices (wfa, input); + + if (edges) + read_weights (edges, wfa, input); + } + + /* + * Compute final distribution of all states + */ + { + unsigned state; + + for (state = wfa->basis_states; state <= wfa->states; state++) + wfa->final_distribution[state] + = compute_final_distribution (state, wfa); + } + + return frame_number; +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static void +read_tiling (tiling_t *tiling, unsigned image_width, unsigned image_height, + unsigned image_level, bitfile_t *input) +/* + * Read image tiling information from the given file 'input' + * and store parameters in struct 'tiling'. + * + * No return value. + */ +{ + const unsigned rice_k = 8; /* parameter of Rice Code */ + + tiling->exponent = read_rice_code (rice_k, input); + + if (get_bit (input)) /* variance order */ + { + unsigned tile; /* current image tile */ + unsigned x0, y0; /* NW corner of image tile */ + unsigned width, height; /* size of image tile */ + + tiling->vorder = Calloc (1 << tiling->exponent, sizeof (int)); + for (tile = 0; tile < 1U << tiling->exponent; tile++) + { + locate_subimage (image_level, image_level - tiling->exponent, tile, + &x0, &y0, &width, &height); + if (x0 < image_width && y0 < image_height) + tiling->vorder [tile] = get_bits (input, tiling->exponent); + else + tiling->vorder [tile] = -1; + } + } + else /* spiral order */ + { + tiling->vorder = Calloc (1 << tiling->exponent, sizeof (int)); + compute_spiral (tiling->vorder, image_width, image_height, + tiling->exponent, get_bit (input) ? YES : NO); + } +} diff --git a/converter/other/fiasco/input/read.h b/converter/other/fiasco/input/read.h new file mode 100644 index 00000000..d0d0ee13 --- /dev/null +++ b/converter/other/fiasco/input/read.h @@ -0,0 +1,31 @@ +/* + * read.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _READ_H +#define _READ_H + +#include "wfa.h" +#include "bit-io.h" + +bitfile_t * +open_wfa (const char *filename, wfa_info_t *wfainfo); +void +read_basis (const char *filename, wfa_t *wfa); +unsigned +read_next_wfa (wfa_t *wfa, bitfile_t *input); + +#endif /* not _READ_H */ + diff --git a/converter/other/fiasco/input/tree.c b/converter/other/fiasco/input/tree.c new file mode 100644 index 00000000..e3e7117e --- /dev/null +++ b/converter/other/fiasco/input/tree.c @@ -0,0 +1,303 @@ +/* + * tree.c: Input of bintree partitioning + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $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 "wfalib.h" +#include "tiling.h" + +#include "tree.h" + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static unsigned +restore_depth_first_order (unsigned src_state, unsigned level, unsigned x, + unsigned y, unsigned *dst_state, + word_t (*bfo_tree)[MAXLABELS], + wfa_t *wfa, tiling_t *tiling); +static void +decode_tree (bitfile_t *input, byte_t *data, unsigned n_data, unsigned scaling, + u_word_t sum0, u_word_t sum1); + +/***************************************************************************** + + public code + +*****************************************************************************/ + +void +read_tree (wfa_t *wfa, tiling_t *tiling, bitfile_t *input) +/* + * Read bintree partitioning of WFA from the 'input' stream. + * 'tiling' provides the information about image tiling, if applied. + * + * No return value. + * + * Side effects: + * 'wfa->tree', 'wfa->x', 'wfa->y', 'wfa->level_of_state' + * are filled with decoded values. + */ +{ + byte_t *bitstring; /* the encoded data */ + word_t (*bfo_tree)[MAXLABELS]; /* node numbers in BFO */ + + /* + * Read WFA tree stored in breadth first order + */ + { + unsigned total = (wfa->states - wfa->basis_states) * MAXLABELS; + unsigned scale = total / 20; + + bitstring = Calloc (total, sizeof (byte_t)); + decode_tree (input, bitstring, total, scale, 1, 11); + } + + /* + * Generate tree using a breadth first traversal + */ + { + unsigned next; /* next free node number of the tree */ + unsigned state; + unsigned label; + byte_t *buffer = bitstring; /* pointer to decoded data */ + + bfo_tree = Calloc (wfa->states * MAXLABELS, sizeof (word_t)); + for (state = 0, next = 1; state < next; state++) + for (label = 0; label < MAXLABELS; label++) + bfo_tree [state][label] = *buffer++ ? next++ : RANGE; + } + + /* + * Traverse tree and restore depth first order + */ + { + unsigned dst_state = wfa->basis_states; + + wfa->root_state + = restore_depth_first_order (0, (wfa->wfainfo->level + + (wfa->wfainfo->color ? 2 : 0)), + 0, 0, &dst_state, bfo_tree, wfa, tiling); + } + + Free (bitstring); + Free (bfo_tree); +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static unsigned +restore_depth_first_order (unsigned src_state, unsigned level, unsigned x, + unsigned y, unsigned *dst_state, + word_t (*bfo_tree)[MAXLABELS], + wfa_t *wfa, tiling_t *tiling) +/* + * Map state 'src_state' (breadth first order) + * to state '*dst_state' (depth first order) + * Add a tree edge 'state' --> 'child' with label and weight 1.0 + * if required. + * 'x', 'y' give the coordinates of the current state in the 'color' image + * of size 'image_level'. 'tiling' defines the image partitioning. + * + * Return value: + * new node number in depth first order + * + * Side effects: + * 'wfa->tree', 'wfa->x', 'wfa->y', 'wfa->level_of_state' + * are filled with decoded values. + */ +{ + unsigned newx [MAXLABELS]; /* x coordinate of childs */ + unsigned newy [MAXLABELS]; /* y coordinate of childs */ + unsigned x0, y0; /* NW corner of image tile */ + unsigned width, height; /* size of image tile */ + + /* + * If tiling is performed then replace current coordinates + */ + if (tiling->exponent && level == wfa->wfainfo->level - tiling->exponent) + { + unsigned tile; + + for (tile = 0; tile < 1U << tiling->exponent; tile++) + { + locate_subimage (wfa->wfainfo->level, level, tile, + &x0, &y0, &width, &height); + if (x0 == x && y0 == y) /* matched ! */ + { + locate_subimage (wfa->wfainfo->level, level, tiling->vorder[tile], + &x, &y, &width, &height); + break; + } + } + } + /* + * Coordinates of childs 0 and 1 + */ + if (wfa->wfainfo->color && level == wfa->wfainfo->level + 1) + newx[0] = newy[0] = newx[1] = newy[1] = 0; + else + { + newx[0] = x; + newy[0] = y; + newx[1] = level & 1 ? x : x + width_of_level (level - 1); + newy[1] = level & 1 ? y + height_of_level (level - 1) : y; + } + + /* + * Remap node numbers + */ + { + int child [MAXLABELS]; /* childs of current node (state) */ + int domain; /* current domain */ + unsigned label; + + for (label = 0; label < MAXLABELS; label++) + if (!isrange (domain = bfo_tree [src_state][label])) + child [label] = restore_depth_first_order (domain, level - 1, + newx [label], + newy [label], dst_state, + bfo_tree, wfa, tiling); + else + child [label] = RANGE; + + for (label = 0; label < MAXLABELS; label++) + { + wfa->tree [*dst_state][label] = child [label]; + wfa->x [*dst_state][label] = newx [label]; + wfa->y [*dst_state][label] = newy [label]; + } + wfa->level_of_state [*dst_state] = level; + } + + return (*dst_state)++; +} + +/**************************************************************************** + + Binary adaptive arithmetic compression + +****************************************************************************/ + +static void +decode_tree (bitfile_t *input, byte_t *data, unsigned n_data, unsigned scaling, + u_word_t sum0, u_word_t sum1) +/* + * Decode bintree partitioning using adaptive binary arithmetic decoding. + * 'input' input stream, + * 'data' buffer for decoded szmbols, + * 'n_data' number of symbols to decode, + * 'scaling' rescale probability models if range > 'scaling' + * 'sum0' initial totals of symbol '0' + * 'sum1' initial totals of symbol '1' + * + * No return value. + * + * Side effects: + * 'data []' is filled with the decoded bitstring + */ +{ + 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 */ + unsigned n; /* Data counter */ + + assert (data); + + code = get_bits (input, 16); + low = 0; + high = 0xffff; + + for (n = n_data; n; n--) + { + 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; + + *data++ = 0; + /* + * Update the frequency counts + */ + sum0++; + sum1++; + if (sum1 > scaling) /* scale the symbol frequencies */ + { + sum0 >>= 1; + sum1 >>= 1; + if (!sum0) + sum0 = 1; + if (sum0 >= sum1) + sum1 = sum0 + 1; + } + + } + 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; + + *data++ = 1; + /* + * Update the frequency counts + */ + sum1++; + if (sum1 > scaling) /* scale the symbol frequencies */ + { + sum0 >>= 1; + sum1 >>= 1; + if (!sum0) + sum0 = 1; + if (sum0 >= sum1) + sum1 = sum0 + 1; + } + } + } + INPUT_BYTE_ALIGN (input); +} + + diff --git a/converter/other/fiasco/input/tree.h b/converter/other/fiasco/input/tree.h new file mode 100644 index 00000000..e4b5f2d8 --- /dev/null +++ b/converter/other/fiasco/input/tree.h @@ -0,0 +1,28 @@ +/* + * tree.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _TREE_H +#define _TREE_H + +#include "wfa.h" +#include "bit-io.h" +#include "tiling.h" + +void +read_tree (wfa_t *wfa, tiling_t *tiling, bitfile_t *input); + +#endif /* not _TREE_H */ + diff --git a/converter/other/fiasco/input/weights.c b/converter/other/fiasco/input/weights.c new file mode 100644 index 00000000..55339980 --- /dev/null +++ b/converter/other/fiasco/input/weights.c @@ -0,0 +1,200 @@ +/* + * weights.c: Input of weights + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $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 "rpf.h" +#include "misc.h" + +#include "weights.h" + +/***************************************************************************** + + public code + +*****************************************************************************/ + +void +read_weights (unsigned total, wfa_t *wfa, bitfile_t *input) +/* + * Read #'total' weights from input stream 'input' and + * update transitions of the WFA states with corresponding weights. + * + * No return value. + * + * Side effects: + * 'wfa->weights' are filled with the decoded values + */ +{ + unsigned state; + unsigned label; + unsigned edge; /* current edge */ + unsigned *weights_array; /* array of weights to encode */ + unsigned *level_array; /* array of corresponding levels */ + unsigned offset1, offset2; /* prob. model offsets. */ + unsigned offset3, offset4; /* prob. model offsets. */ + bool_t delta_approx = NO; /* true if delta has been used */ + + /* + * Check whether delta approximation has been used + */ + for (state = wfa->basis_states; state < wfa->states; state++) + if (wfa->delta_state [state]) + { + delta_approx = YES; + break; + } + + /* + * Generate array of corresponding levels (context of probability model) + */ + { + int min_level, max_level; /* min and max range level */ + int d_min_level, d_max_level; /* min and max range level (delta) */ + unsigned *lptr; /* pointer to current corresp. level */ + int domain; /* current domain */ + bool_t dc, d_dc; /* indicates whether DC is used */ + + /* + * Compute minimum and maximum level of delta and normal approximations + */ + min_level = d_min_level = MAXLEVEL; + max_level = d_max_level = 0; + dc = d_dc = NO; + + for (state = wfa->basis_states; state < wfa->states; state++) + for (label = 0; label < MAXLABELS; label++) + if (isrange (wfa->tree [state][label])) + { + if (delta_approx && wfa->delta_state [state]) + { + d_min_level = min (d_min_level, + wfa->level_of_state [state] - 1); + d_max_level = max (d_max_level, + wfa->level_of_state [state] - 1); + if (wfa->into [state][label][0] == 0) + d_dc = YES; + } + else + { + min_level = min (min_level, wfa->level_of_state [state] - 1); + max_level = max (max_level, wfa->level_of_state [state] - 1); + if (wfa->into [state][label][0] == 0) + dc = YES; + } + } + if (min_level > max_level) /* no lc found */ + max_level = min_level - 1; + if (d_min_level > d_max_level) + d_max_level = d_min_level - 1; + + offset1 = dc ? 1 : 0; + offset2 = offset1 + (d_dc ? 1 : 0); + offset3 = offset2 + (max_level - min_level + 1); + offset4 = offset3 + (d_max_level - d_min_level + 1); + + lptr = level_array = Calloc (total, sizeof (int)); + for (state = wfa->basis_states; state < wfa->states; state++) + for (label = 0; label < MAXLABELS; label++) + if (isrange (wfa->tree[state][label])) + for (edge = 0; isedge (domain = wfa->into[state][label][edge]); + edge++) + { + if ((unsigned) (lptr - level_array) >= total) + error ("Can't read more than %d weights.", total); + if (domain) + { + if (delta_approx && wfa->delta_state [state]) + *lptr++ = offset3 + wfa->level_of_state [state] + - 1 - d_min_level; + else + *lptr++ = offset2 + wfa->level_of_state [state] + - 1 - min_level; + } + else + *lptr++ = delta_approx && wfa->delta_state [state] + ? offset1 : 0; + } + } + + /* + * Decode the list of weights with an arithmetic decoder + */ + { + unsigned i; + unsigned *c_symbols = Calloc (offset4, sizeof (unsigned)); + const unsigned scale = 500; /* scaling of probability model */ + + c_symbols [0] = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1); + if (offset1 != offset2) + c_symbols [offset1] = 1 << (wfa->wfainfo->d_dc_rpf->mantissa_bits + + 1); + for (i = offset2; i < offset3; i++) + c_symbols [i] = 1 << (wfa->wfainfo->rpf->mantissa_bits + 1); + for (; i < offset4; i++) + c_symbols [i] = 1 << (wfa->wfainfo->d_rpf->mantissa_bits + 1); + + weights_array = decode_array (input, level_array, c_symbols, + offset4, total, scale); + Free (c_symbols); + } + Free (level_array); + + /* + * Update transitions with decoded weights + */ + { + unsigned *wptr = weights_array; /* pointer to current weight */ + int domain; /* current domain */ + + for (state = wfa->basis_states; state < wfa->states; state++) + for (label = 0; label < MAXLABELS; label++) + if (isrange (wfa->tree[state][label])) + for (edge = 0; isedge (domain = wfa->into[state][label][edge]); + edge++) + { + if (domain) /* not DC component */ + { + if (delta_approx && wfa->delta_state [state]) + wfa->weight [state][label][edge] + = btor (*wptr++, wfa->wfainfo->d_rpf); + else + wfa->weight [state][label][edge] + = btor (*wptr++, wfa->wfainfo->rpf); + } + else + { + if (delta_approx && wfa->delta_state [state]) + wfa->weight [state][label][edge] + = btor (*wptr++, wfa->wfainfo->d_dc_rpf); + else + wfa->weight [state][label][edge] + = btor (*wptr++, wfa->wfainfo->dc_rpf); + } + wfa->int_weight [state][label][edge] + = wfa->weight [state][label][edge] * 512 + 0.5; + } + } + + Free (weights_array); +} + diff --git a/converter/other/fiasco/input/weights.h b/converter/other/fiasco/input/weights.h new file mode 100644 index 00000000..1e2285a9 --- /dev/null +++ b/converter/other/fiasco/input/weights.h @@ -0,0 +1,27 @@ +/* + * weights.h + * + * Written by: Ullrich Hafner + * + * This file is part of FIASCO («F»ractal «I»mage «A»nd «S»equence «CO»dec) + * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> + */ + +/* + * $Date: 2000/06/14 20:50:13 $ + * $Author: hafner $ + * $Revision: 5.1 $ + * $State: Exp $ + */ + +#ifndef _WEIGHTS_H +#define _WEIGHTS_H + +#include "wfa.h" +#include "bit-io.h" + +void +read_weights (unsigned total, wfa_t *wfa, bitfile_t *input); + +#endif /* not _WEIGHTS_H */ + |