diff options
Diffstat (limited to 'converter/other/fiasco/output/write.c')
-rw-r--r-- | converter/other/fiasco/output/write.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/converter/other/fiasco/output/write.c b/converter/other/fiasco/output/write.c new file mode 100644 index 00000000..e6185ad3 --- /dev/null +++ b/converter/other/fiasco/output/write.c @@ -0,0 +1,250 @@ +/* + * write.c: Output 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:59 $ + * $Author: hafner $ + * $Revision: 5.3 $ + * $State: Exp $ + */ + +#include "config.h" + +#include "types.h" +#include "macros.h" +#include "error.h" + +#include "cwfa.h" +#include "image.h" +#include "misc.h" +#include "bit-io.h" +#include "rpf.h" + +#include "tree.h" +#include "matrices.h" +#include "weights.h" +#include "mc.h" +#include "nd.h" +#include "write.h" + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static void +write_tiling (const tiling_t *tiling, bitfile_t *output); + +/***************************************************************************** + + public code + + +*****************************************************************************/ + + +void +write_next_wfa (const wfa_t *wfa, const coding_t *c, bitfile_t *output) +/* + * Write 'wfa' to stream 'output'. If the first frame should be written + * then also store the header information of the coding struct 'c'. + * + * No return value. + */ +{ + unsigned edges = 0; /* number of transitions */ + unsigned bits; + + debug_message ("--------------------------------------" + "--------------------------------------"); + + if (c->mt->number == 0) /* first WFA */ + write_header (wfa->wfainfo, output); + + bits = bits_processed (output); + + /* + * Frame header information + */ + { + const int rice_k = 8; /* parameter of Rice Code */ + + write_rice_code (wfa->states, rice_k, output); + write_rice_code (c->mt->frame_type, rice_k, output); + write_rice_code (c->mt->number, rice_k, output); + } + + OUTPUT_BYTE_ALIGN (output); + + debug_message ("frame-header: %5d bits.", bits_processed (output) - bits); + + if (c->tiling->exponent) /* write tiling permutation */ + { + put_bit (output, 1); + write_tiling (c->tiling, output); + } + else + put_bit (output, 0); + + OUTPUT_BYTE_ALIGN (output); + + write_tree (wfa, output); + + if (c->options.prediction) /* write nondeterministic approx. */ + { + put_bit (output, 1); + write_nd (wfa, output); + } + else + put_bit (output, 0); + + if (c->mt->frame_type != I_FRAME) /* write motion compensation info */ + write_mc (c->mt->frame_type, wfa, output); + + edges = write_matrices (c->options.normal_domains, + c->options.delta_domains, wfa, output); + + if (edges) /* found at least one approximation */ + write_weights (edges, wfa, output); + + debug_message ("--------------------------------------" + "--------------------------------------"); +} + +void +write_header (const wfa_info_t *wi, bitfile_t *output) +/* + * Write the header information describing the type of 'wfa' + * to stream 'output'. + * + * No return value. + */ +{ + const unsigned rice_k = 8; /* parameter of Rice Code */ + unsigned bits = bits_processed (output); + const char *text; /* next character to write */ + + /* + * Write magic number and name of initial basis + */ + for (text = FIASCO_MAGIC; *text; text++) + put_bits (output, *text, 8); + put_bits (output, '\n', 8); + for (text = wi->basis_name; *text; text++) + put_bits (output, *text, 8); + put_bits (output, *text, 8); + + write_rice_code (FIASCO_BINFILE_RELEASE, rice_k, output); + + write_rice_code (HEADER_TITLE, rice_k, output); + for (text = wi->title; + text && *text && text - wi->title < MAXSTRLEN - 2; + text++) + put_bits (output, *text, 8); + put_bits (output, 0, 8); + + write_rice_code (HEADER_COMMENT, rice_k, output); + for (text = wi->comment; + text && *text && text - wi->comment < MAXSTRLEN - 2; + text++) + put_bits (output, *text, 8); + put_bits (output, 0, 8); + + write_rice_code (HEADER_END, rice_k, output); + + write_rice_code (wi->max_states, rice_k, output); + put_bit (output, wi->color ? 1 : 0); + write_rice_code (wi->width, rice_k, output); + write_rice_code (wi->height, rice_k, output); + if (wi->color) + write_rice_code (wi->chroma_max_states, rice_k, output); + write_rice_code (wi->p_min_level, rice_k, output); + write_rice_code (wi->p_max_level, rice_k, output); + write_rice_code (wi->frames, rice_k, output); + write_rice_code (wi->smoothing, rice_k, output); + + put_bits (output, wi->rpf->mantissa_bits - 2, 3); + put_bits (output, wi->rpf->range_e, 2); + if (wi->rpf->mantissa_bits != wi->dc_rpf->mantissa_bits || + wi->rpf->range != wi->dc_rpf->range) + { + put_bit (output, YES); + put_bits (output, wi->dc_rpf->mantissa_bits - 2, 3); + put_bits (output, wi->dc_rpf->range_e, 2); + } + else + put_bit (output, NO); + if (wi->rpf->mantissa_bits != wi->d_rpf->mantissa_bits || + wi->rpf->range != wi->d_rpf->range) + { + put_bit (output, YES); + put_bits (output, wi->d_rpf->mantissa_bits - 2, 3); + put_bits (output, wi->d_rpf->range_e, 2); + } + else + put_bit (output, NO); + if (wi->dc_rpf->mantissa_bits != wi->d_dc_rpf->mantissa_bits || + wi->dc_rpf->range != wi->d_dc_rpf->range) + { + put_bit (output, YES); + put_bits (output, wi->d_dc_rpf->mantissa_bits - 2, 3); + put_bits (output, wi->d_dc_rpf->range_e, 2); + } + else + put_bit (output, NO); + + if (wi->frames > 1) /* motion compensation stuff */ + { + write_rice_code (wi->fps, rice_k, output); + write_rice_code (wi->search_range, rice_k, output); + put_bit (output, wi->half_pixel ? 1 : 0); + put_bit (output, wi->B_as_past_ref ? 1 : 0); + } + + OUTPUT_BYTE_ALIGN (output); + debug_message ("header: %d bits.", bits_processed (output) - bits); +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static void +write_tiling (const tiling_t *tiling, bitfile_t *output) +/* + * Write image tiling information given by 'tiling' to stream 'output'. + * + * No return value. + */ +{ + const unsigned rice_k = 8; /* parameter of Rice Code */ + unsigned bits = bits_processed (output); + + write_rice_code (tiling->exponent, rice_k, output); + if (tiling->method == FIASCO_TILING_VARIANCE_ASC + || tiling->method == FIASCO_TILING_VARIANCE_DSC) + { + unsigned tile; /* current image tile */ + + put_bit (output, 1); + for (tile = 0; tile < 1U << tiling->exponent; tile++) + if (tiling->vorder [tile] != -1) /* image tile is visible */ + put_bits (output, tiling->vorder [tile], tiling->exponent); + } + else + { + put_bit (output, 0); + put_bit (output, tiling->method == FIASCO_TILING_SPIRAL_ASC); + } + + debug_message ("tiling: %4d bits.", bits_processed (output) - bits); +} |