diff options
Diffstat (limited to 'converter/other/fiasco/codec/dfiasco.c')
-rw-r--r-- | converter/other/fiasco/codec/dfiasco.c | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/converter/other/fiasco/codec/dfiasco.c b/converter/other/fiasco/codec/dfiasco.c new file mode 100644 index 00000000..1cdfc672 --- /dev/null +++ b/converter/other/fiasco/codec/dfiasco.c @@ -0,0 +1,398 @@ +/* + * dfiasco.c: Decoder public interface + * + * 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/10/28 17:39:30 $ + * $Author: hafner $ + * $Revision: 5.7 $ + * $State: Exp $ + */ + +#include <string.h> + +#include "config.h" + +#include "types.h" +#include "macros.h" +#include "error.h" + +#include "dfiasco.h" +#include "wfa.h" +#include "read.h" +#include "misc.h" +#include "bit-io.h" +#include "decoder.h" +#include "options.h" +#include "wfalib.h" + +/***************************************************************************** + + prototypes + +*****************************************************************************/ + +static dfiasco_t * +cast_dfiasco (fiasco_decoder_t *dfiasco); +static void +free_dfiasco (dfiasco_t *dfiasco); +static dfiasco_t * +alloc_dfiasco (wfa_t *wfa, video_t *video, bitfile_t *input, + int enlarge_factor, int smoothing, format_e image_format); + +/***************************************************************************** + + public code + +*****************************************************************************/ + +fiasco_decoder_t * +fiasco_decoder_new (const char *filename, const fiasco_d_options_t *options) +{ + try + { + bitfile_t *input; /* pointer to WFA FIASCO stream */ + wfa_t *wfa; /* wfa structure */ + video_t *video; /* information about decoder state */ + const d_options_t *dop; /* decoder additional options */ + dfiasco_t *dfiasco; /* decoder internal state */ + fiasco_decoder_t *decoder; /* public interface to decoder */ + fiasco_d_options_t *default_options = NULL; + + if (options) + { + dop = cast_d_options ((fiasco_d_options_t *) options); + if (!dop) + return NULL; + } + else + { + default_options = fiasco_d_options_new (); + dop = cast_d_options (default_options); + } + + wfa = alloc_wfa (NO); + video = alloc_video (NO); + input = open_wfa (filename, wfa->wfainfo); + read_basis (wfa->wfainfo->basis_name, wfa); + + decoder = Calloc (1, sizeof (fiasco_decoder_t)); + decoder->delete = fiasco_decoder_delete; + decoder->write_frame = fiasco_decoder_write_frame; + decoder->get_frame = fiasco_decoder_get_frame; + decoder->get_length = fiasco_decoder_get_length; + decoder->get_rate = fiasco_decoder_get_rate; + decoder->get_width = fiasco_decoder_get_width; + decoder->get_height = fiasco_decoder_get_height; + decoder->get_title = fiasco_decoder_get_title; + decoder->get_comment = fiasco_decoder_get_comment; + decoder->is_color = fiasco_decoder_is_color; + + decoder->private = dfiasco + = alloc_dfiasco (wfa, video, input, + dop->magnification, + dop->smoothing, + dop->image_format); + + if (default_options) + fiasco_d_options_delete (default_options); + if (dfiasco->enlarge_factor >= 0) + { + int n; + unsigned long pixels = wfa->wfainfo->width * wfa->wfainfo->height; + + for (n = 1; n <= (int) dfiasco->enlarge_factor; n++) + { + if (pixels << (n << 1) > 2048 * 2048) + { + set_error (_("Magnifaction factor `%d' is too large. " + "Maximium value is %d."), + dfiasco->enlarge_factor, max (0, n - 1)); + fiasco_decoder_delete (decoder); + return NULL; + } + } + } + else + { + int n; + + for (n = 0; n <= (int) - dfiasco->enlarge_factor; n++) + { + if (wfa->wfainfo->width >> n < 32 + || wfa->wfainfo->height >> n < 32) + { + set_error (_("Magnifaction factor `%d' is too small. " + "Minimum value is %d."), + dfiasco->enlarge_factor, - max (0, n - 1)); + fiasco_decoder_delete (decoder); + return NULL; + } + } + } + return (fiasco_decoder_t *) decoder; + } + catch + { + return NULL; + } +} + +int +fiasco_decoder_write_frame (fiasco_decoder_t *decoder, + const char *filename) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + { + try + { + image_t *frame = get_next_frame (NO, dfiasco->enlarge_factor, + dfiasco->smoothing, NULL, + FORMAT_4_4_4, dfiasco->video, NULL, + dfiasco->wfa, dfiasco->input); + write_image (filename, frame); + } + catch + { + return 0; + } + return 1; + } +} + +fiasco_image_t * +fiasco_decoder_get_frame (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return NULL; + else + { + try + { + fiasco_image_t *image = Calloc (1, sizeof (fiasco_image_t)); + image_t *frame = get_next_frame (NO, dfiasco->enlarge_factor, + dfiasco->smoothing, NULL, + dfiasco->image_format, + dfiasco->video, NULL, + dfiasco->wfa, dfiasco->input); + + frame->reference_count++; /* for motion compensation */ + image->private = frame; + image->delete = fiasco_image_delete; + image->get_width = fiasco_image_get_width; + image->get_height = fiasco_image_get_height; + image->is_color = fiasco_image_is_color; + + return image; + } + catch + { + return NULL; + } + } +} + +unsigned +fiasco_decoder_get_length (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + return dfiasco->wfa->wfainfo->frames; +} + +unsigned +fiasco_decoder_get_rate (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + return dfiasco->wfa->wfainfo->fps; +} + +unsigned +fiasco_decoder_get_width (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + { + unsigned width; + + if (dfiasco->enlarge_factor >= 0) + width = dfiasco->wfa->wfainfo->width << dfiasco->enlarge_factor; + else + width = dfiasco->wfa->wfainfo->width >> - dfiasco->enlarge_factor; + + return width & 1 ? width + 1 : width; + } +} + +unsigned +fiasco_decoder_get_height (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + { + unsigned height; + + if (dfiasco->enlarge_factor >= 0) + height = dfiasco->wfa->wfainfo->height << dfiasco->enlarge_factor; + else + height = dfiasco->wfa->wfainfo->height >> - dfiasco->enlarge_factor; + + return height & 1 ? height + 1 : height; + } +} + +const char * +fiasco_decoder_get_title (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return NULL; + else + return dfiasco->wfa->wfainfo->title; +} + +const char * +fiasco_decoder_get_comment (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return NULL; + else + return dfiasco->wfa->wfainfo->comment; +} + +int +fiasco_decoder_is_color (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 0; + else + return dfiasco->wfa->wfainfo->color; +} + +int +fiasco_decoder_delete (fiasco_decoder_t *decoder) +{ + dfiasco_t *dfiasco = cast_dfiasco (decoder); + + if (!dfiasco) + return 1; + + try + { + free_wfa (dfiasco->wfa); + free_video (dfiasco->video); + close_bitfile (dfiasco->input); + strcpy (dfiasco->id, " "); + free_dfiasco(dfiasco); + Free (decoder); + } + catch + { + return 0; + } + + return 1; +} + +/***************************************************************************** + + private code + +*****************************************************************************/ + +static dfiasco_t * +alloc_dfiasco (wfa_t *wfa, video_t *video, bitfile_t *input, + int enlarge_factor, int smoothing, format_e image_format) +/* + * FIASCO decoder constructor: + * Initialize decoder structure. + * + * Return value: + * pointer to the new decoder structure + */ +{ + dfiasco_t *dfiasco = Calloc (1, sizeof (dfiasco_t)); + + strcpy (dfiasco->id, "DFIASCO"); + + dfiasco->wfa = wfa; + dfiasco->video = video; + dfiasco->input = input; + dfiasco->enlarge_factor = enlarge_factor; + dfiasco->smoothing = smoothing; + dfiasco->image_format = image_format; + + return dfiasco; +} + +static void +free_dfiasco (dfiasco_t *dfiasco) +/* + * FIASCO decoder destructor: + * Free memory of given 'decoder' struct. + * + * No return value. + * + * Side effects: + * 'video' struct is discarded. + */ +{ + Free (dfiasco); +} + +static dfiasco_t * +cast_dfiasco (fiasco_decoder_t *dfiasco) +/* + * Cast pointer `dfiasco' to type dfiasco_t. + * Check whether `dfiasco' is a valid object of type dfiasco_t. + * + * Return value: + * pointer to dfiasco_t struct on success + * NULL otherwise + */ +{ + dfiasco_t *this = (dfiasco_t *) dfiasco->private; + if (this) + { + if (!streq (this->id, "DFIASCO")) + { + set_error (_("Parameter `dfiasco' doesn't match required type.")); + return NULL; + } + } + else + { + set_error (_("Parameter `%s' not defined (NULL)."), "dfiasco"); + } + + return this; +} |