summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManfred Tremmel <manfredtremmel@users.sourceforge.net>2004-02-22 12:36:35 +0000
committerManfred Tremmel <manfredtremmel@users.sourceforge.net>2004-02-22 12:36:35 +0000
commitb27f4fe6eb2afaa977c0dc600d6a13e5e9d426a6 (patch)
treebdf31e81b2659d2f5a4197af566b38d70d508a94 /src
parent3a63bde079305ed3eb3de74a1e9c551b6b6e2a3a (diff)
downloadxine-lib-b27f4fe6eb2afaa977c0dc600d6a13e5e9d426a6.tar.gz
xine-lib-b27f4fe6eb2afaa977c0dc600d6a13e5e9d426a6.tar.bz2
added IFF-ANIM support, opt5 and (untested, can't finde samples) opt 4 codings
CVS patchset: 6182 CVS date: 2004/02/22 12:36:35
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_iff.c1409
-rw-r--r--src/demuxers/iff.h350
-rw-r--r--src/libxinevdec/bitplane.c700
3 files changed, 1571 insertions, 888 deletions
diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c
index e37ff8032..965a7a65e 100644
--- a/src/demuxers/demux_iff.c
+++ b/src/demuxers/demux_iff.c
@@ -33,8 +33,10 @@
* * 16SV, the same support as 8SVX
* * ILBM (Bitmap Picturs)
* - simple pictures work, nothing more (most work is done in bitmap-decoder)
+ * * ANIM (Animations)
+ * - Animation can displayed, but has to be improved
*
- * $Id: demux_iff.c,v 1.6 2004/02/09 22:24:36 jstembridge Exp $
+ * $Id: demux_iff.c,v 1.7 2004/02/22 12:36:37 manfredtremmel Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -53,104 +55,7 @@
#include "buffer.h"
#include "bswap.h"
-#define FOURCC_CHUNK BE_FOURCC
-#define IFF_16SV_CHUNK FOURCC_CHUNK('1', '6', 'S', 'V')
-#define IFF_8SVX_CHUNK FOURCC_CHUNK('8', 'S', 'V', 'X')
-#define IFF_ANFI_CHUNK FOURCC_CHUNK('A', 'N', 'F', 'I')
-#define IFF_ANHD_CHUNK FOURCC_CHUNK('A', 'N', 'H', 'D')
-#define IFF_ANIM_CHUNK FOURCC_CHUNK('A', 'N', 'I', 'M')
-#define IFF_ANNO_CHUNK FOURCC_CHUNK('A', 'N', 'N', 'O')
-#define IFF_ANSQ_CHUNK FOURCC_CHUNK('A', 'N', 'S', 'Q')
-#define IFF_ATAK_CHUNK FOURCC_CHUNK('A', 'T', 'A', 'K')
-#define IFF_AUTH_CHUNK FOURCC_CHUNK('A', 'U', 'T', 'H')
-#define IFF_BMHD_CHUNK FOURCC_CHUNK('B', 'M', 'H', 'D')
-#define IFF_BODY_CHUNK FOURCC_CHUNK('B', 'O', 'D', 'Y')
-#define IFF_CAMG_CHUNK FOURCC_CHUNK('C', 'A', 'M', 'G')
-#define IFF_CCRT_CHUNK FOURCC_CHUNK('C', 'C', 'R', 'T')
-#define IFF_CHAN_CHUNK FOURCC_CHUNK('C', 'H', 'A', 'N')
-#define IFF_CMAP_CHUNK FOURCC_CHUNK('C', 'M', 'A', 'P')
-#define IFF_COPY_CHUNK FOURCC_CHUNK('(', 'c', ')', ' ')
-#define IFF_CRNG_CHUNK FOURCC_CHUNK('C', 'R', 'N', 'G')
-#define IFF_DEST_CHUNK FOURCC_CHUNK('D', 'E', 'S', 'T')
-#define IFF_DLTA_CHUNK FOURCC_CHUNK('D', 'L', 'T', 'A')
-#define IFF_DPAN_CHUNK FOURCC_CHUNK('D', 'P', 'A', 'N')
-#define IFF_DPI_CHUNK FOURCC_CHUNK('D', 'P', 'I', ' ')
-#define IFF_DPPS_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'S')
-#define IFF_DPPV_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'V')
-#define IFF_DRNG_CHUNK FOURCC_CHUNK('D', 'R', 'N', 'G')
-#define IFF_FACE_CHUNK FOURCC_CHUNK('F', 'A', 'C', 'E')
-#define IFF_FADE_CHUNK FOURCC_CHUNK('F', 'A', 'D', 'E')
-#define IFF_FORM_CHUNK FOURCC_CHUNK('F', 'O', 'R', 'M')
-#define IFF_FVER_CHUNK FOURCC_CHUNK('F', 'V', 'E', 'R')
-#define IFF_GRAB_CHUNK FOURCC_CHUNK('G', 'R', 'A', 'B')
-#define IFF_ILBM_CHUNK FOURCC_CHUNK('I', 'L', 'B', 'M')
-#define IFF_INS1_CHUNK FOURCC_CHUNK('I', 'N', 'S', '1')
-#define IFF_IMRT_CHUNK FOURCC_CHUNK('I', 'M', 'R', 'T')
-#define IFF_JUNK_CHUNK FOURCC_CHUNK('J', 'U', 'N', 'K')
-#define IFF_LIST_CHUNK FOURCC_CHUNK('L', 'I', 'S', 'T')
-#define IFF_MHDR_CHUNK FOURCC_CHUNK('M', 'H', 'D', 'R')
-#define IFF_NAME_CHUNK FOURCC_CHUNK('N', 'A', 'M', 'E')
-#define IFF_PAN_CHUNK FOURCC_CHUNK('P', 'A', 'N', ' ')
-#define IFF_PROP_CHUNK FOURCC_CHUNK('P', 'R', 'O', 'P')
-#define IFF_RLSE_CHUNK FOURCC_CHUNK('R', 'L', 'S', 'E')
-#define IFF_SAMP_CHUNK FOURCC_CHUNK('S', 'A', 'M', 'P')
-#define IFF_SEQN_CHUNK FOURCC_CHUNK('S', 'E', 'Q', 'N')
-#define IFF_SHDR_CHUNK FOURCC_CHUNK('S', 'H', 'D', 'R')
-#define IFF_SMUS_CHUNK FOURCC_CHUNK('S', 'M', 'U', 'S')
-#define IFF_SPRT_CHUNK FOURCC_CHUNK('S', 'P', 'R', 'T')
-#define IFF_TEXT_CHUNK FOURCC_CHUNK('T', 'E', 'X', 'T')
-#define IFF_TINY_CHUNK FOURCC_CHUNK('T', 'I', 'N', 'Y')
-#define IFF_TRAK_CHUNK FOURCC_CHUNK('T', 'R', 'A', 'K')
-#define IFF_VHDR_CHUNK FOURCC_CHUNK('V', 'H', 'D', 'R')
-
-#define MONO 0L
-#define PAN 1L
-#define LEFT 2L
-#define RIGHT 4L
-#define STEREO 6L
-
-#define SND_COMPRESSION_NONE 0
-#define SND_COMPRESSION_FIBONACCI 1
-#define SND_COMPRESSION_EXPONENTIAL 2
-
-#define PIC_MASK_NONE 0
-#define PIC_MASK_HASMASK 1
-#define PIC_MASK_HASTRANSPARENTMASK 2
-#define PIC_MASK_LASSO 3
-
-#define PIC_COMPRESSION_NONE 0
-#define PIC_COMPRESSION_BYTERUN1 1
-
-#define PREAMBLE_SIZE 8
-#define IFF_JUNK_SIZE 8
-#define IFF_SIGNATURE_SIZE 12
-#define PCM_BLOCK_ALIGN 1024
-
-#define max_volume 65536 /* Unity = Fixed 1.0 = maximum volume */
-
-int8_t fibonacci[] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 };
-
-int8_t exponential[] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 };
-
-
-typedef struct {
- uint16_t atak_duration; /* segment duration in milliseconds */
- uint32_t atak_dest; /* destination volume factor */
-} eg_point;
-
-typedef struct {
- uint8_t cmap_red;
- uint8_t cmap_green;
- uint8_t cmap_blue;
-} color_register;
-
-typedef struct {
- int16_t crng_pad1; /* reserved for future use; store 0 here */
- int16_t crng_rate; /* color cycling rate, 16384 = 60 steps/second */
- int16_t crng_active; /* nonzero means color cycling is turned on */
- uint8_t crng_low; /* lower color registers selected */
- uint8_t crng_high; /* upper color registers selected */
-} color_range;
+#include "iff.h"
typedef struct {
demux_plugin_t demux_plugin;
@@ -164,67 +69,33 @@ typedef struct {
int status;
- uint32_t iff_type; /* Type of iff-file, see TAGs above */
-
- /* chunk infos to be rememberd */
- /* audio chunks */
- uint32_t vhdr_oneShotHiSamples; /* # samples in the high octave 1-shot part */
- uint32_t vhdr_repeatHiSamples; /* # samples in the high octave repeat part */
- uint32_t vhdr_samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */
- uint16_t vhdr_samplesPerSec; /* data sampling rate */
- uint8_t vhdr_ctOctave; /* # of octaves of waveforms */
- uint8_t vhdr_sCompression; /* data compression technique used */
- uint32_t vhdr_volume; /* playback nominal volume from 0 to Unity
- * (full volume). Map this value into
- * the output hardware's dynamic range.
- */
- eg_point *atak_eg_point; /* ? */
- eg_point *rlse_eg_point; /* ? */
+ uint32_t iff_type; /* Type of iff-file */
+ uint32_t iff_sub_type; /* Type of iff-sub-file */
+
+ /* Sound chunks */
+ Voice8Header *vhdr; /* vhdr chunk */
+ EGPoint *atak; /* atak chunk */
+ EGPoint *rlse; /* rlse chunk */
uint32_t chan_settings; /* Mono, Stereo, Left or Right Channel */
uint32_t pan_sposition; /* */
/* picture chunks */
- uint16_t bmhd_w; /* raster width in pixels */
- uint16_t bmhd_h; /* raster height in pixels */
- int16_t bmhd_x; /* raster width in pixels */
- int16_t bmhd_y; /* raster height in pixels */
- uint8_t bmhd_nplanes; /* # source bitplanes */
- uint8_t bmhd_masking; /* masking technique */
- uint8_t bmhd_compression; /* compression algoithm */
- uint8_t bmhd_pad1; /* UNUSED. For consistency, put 0 here. */
- uint16_t bmhd_transparentColor; /* transparent "color number" */
- uint8_t bmhd_xaspect; /* aspect ratio, a rational number x/y */
- uint8_t bmhd_yaspect; /* aspect ratio, a rational number x/y */
- int16_t bmhd_pagewidth; /* source "page" size in pixels */
- int16_t bmhd_pageheight; /* source "page" size in pixels */
- uint8_t dest_depth; /* # bitplanes in the original source */
- uint8_t dest_pad1; /* UNUSED; for consistency store 0 here */
- uint16_t dest_plane_pick; /* how to scatter source bitplanes into destination */
- uint16_t dest_plane_onoff; /* default bitplane data for planePick */
- uint16_t dest_plane_mask; /* selects which bitplanes to store into */
-
- color_register *cmap_color_register; /* colors of the bitmap picture */
- uint32_t cmap_color_register_num; /* number of the bitmap colors */
-
- int16_t grab_x; /* coordinate x */
- int16_t grab_y; /* coordinate y */
-
- uint16_t sprt_sprite_precedence; /* A SpritePrecedence is stored in a SPRT chunk. */
-
- uint32_t camg_view_modes; /* A Commodore Amiga ViewPort->Modes is stored
- * in a CAMG chunk.
- * The chunk's content is declared as a LONG. */
- color_range crng_color_range[256]; /* color range infos for color cycling */
- int crng_color_range_used; /* number of color range fields used */
- uint16_t dpi_x; /* dots per inch - x direction */
- uint16_t dpi_y; /* dots per inch - y direction */
-
- int16_t ccrt_direction; /* 0=don't cycle, 1=forward, -1=backwards */
- uint8_t ccrt_start; /* range lower */
- uint8_t ccrt_end; /* range upper */
- int32_t ccrt_seconds; /* seconds between cycling */
- int32_t ccrt_microseconds; /* msecs between cycling */
- int16_t ccrt_pad; /* future exp - store 0 here */
+ BitMapHeader *bmhd; /* BITMAP-Header-Date (IFF-ILBM/ANIM */
+ ColorRegister *cmap; /* colors of the bitmap picture */
+ uint32_t cmap_num; /* number of the bitmap colors */
+ Point2D *grab; /* grab chunk */
+ DestMerge *dest; /* dest chunk */
+ SpritePrecedence sprt; /* sprt chunk */
+ CamgChunk *camg; /* camg chunk */
+ CRange crng[256]; /* color range infos for color cycling */
+ uint32_t crng_used; /* number of color range fields used */
+ CcrtChunk *ccrt; /* ccrt chunk */
+ DPIHeader *dpi; /* dpi chunk */
+
+
+ /* anim chunks */
+ AnimHeader *anhd; /* anhd chunk */
+ DPAnimChunk *dpan; /* dpan chunk */
/* some common informations */
char *title; /* Name of the stream from NAME-Tag*/
@@ -252,6 +123,7 @@ typedef struct {
int audio_compression_factor;
/* picture information */
+ int video_send_palette;
unsigned int video_type;
int64_t video_pts;
int64_t video_pts_inc;
@@ -296,133 +168,31 @@ static void delta_decode(int8_t *dest, int8_t *source, int32_t n, int8_t *table)
}
/* returns 1 if the IFF file was opened successfully, 0 otherwise */
-static int open_iff_file(demux_iff_t *this) {
-
+static int read_iff_chunk(demux_iff_t *this) {
unsigned char signature[IFF_SIGNATURE_SIZE];
unsigned char buffer[512];
unsigned int keep_on_reading = 1;
uint32_t junk_size;
- if (_x_demux_read_header(this->input, signature, IFF_SIGNATURE_SIZE) != IFF_SIGNATURE_SIZE)
- return 0;
-
- this->title = 0;
- this->copyright = 0;
- this->author = 0;
- this->annotations = 0;
- this->version = 0;
- this->text = 0;
-
- this->vhdr_oneShotHiSamples = 0;
- this->vhdr_repeatHiSamples = 0;
- this->vhdr_samplesPerHiCycle = 0;
- this->vhdr_samplesPerSec = 0;
- this->vhdr_ctOctave = 0;
- this->vhdr_sCompression = 0;
- this->vhdr_volume = 0;
- this->chan_settings = 0;
- this->audio_type = 0;
- this->audio_frames = 0;
- this->audio_bits = 0;
- this->audio_channels = 0;
- this->audio_block_align = 0;
- this->audio_bytes_per_second = 0;
- this->running_time = 0;
- this->data_start = 0;
- this->data_size = 0;
- this->seek_flag = 0;
- this->audio_interleave_buffer = 0;
- this->audio_interleave_buffer_size = 0;
- this->audio_read_buffer = 0;
- this->audio_read_buffer_size = 0;
- this->audio_buffer_filled = 0;
- this->audio_compression_factor = 1;
- this->audio_position = 0;
- this->atak_eg_point = 0;
- this->rlse_eg_point = 0;
- this->bmhd_w = 0;
- this->bmhd_h = 0;
- this->bmhd_x = 0;
- this->bmhd_y = 0;
- this->bmhd_nplanes = 0;
- this->bmhd_masking = 0;
- this->bmhd_compression = 0;
- this->bmhd_pad1 = 0;
- this->bmhd_transparentColor = 0;
- this->bmhd_xaspect = 0;
- this->bmhd_yaspect = 0;
- this->bmhd_pagewidth = 0;
- this->bmhd_pageheight = 0;
- this->cmap_color_register = 0;
- this->cmap_color_register_num = 0;
- this->grab_x = 0;
- this->grab_y = 0;
- this->dest_depth = 0;
- this->dest_pad1 = 0;
- this->dest_plane_pick = 0;
- this->dest_plane_onoff = 0;
- this->dest_plane_mask = 0;
- this->sprt_sprite_precedence = 0;
- this->camg_view_modes = 0;
- this->crng_color_range_used = 0;
- this->ccrt_direction = 0;
- this->ccrt_start = 0;
- this->ccrt_end = 0;
- this->ccrt_seconds = 0;
- this->ccrt_microseconds = 0;
- this->ccrt_pad = 0;
- this->dpi_x = 0;
- this->dpi_y = 0;
-
- this->iff_type = BE_32(&signature[8]);
-
- this->video_type = 0;
- this->video_pts = 0;
- this->video_pts_inc = 0;
-
- this->bih.biSize = 0;
- this->bih.biWidth = 0;
- this->bih.biHeight = 0;
- this->bih.biPlanes = 0;
- this->bih.biBitCount = 0;
- this->bih.biCompression = 0;
- this->bih.biSizeImage = 0;
- this->bih.biXPelsPerMeter = 0;
- this->bih.biYPelsPerMeter = 0;
- this->bih.biClrUsed = 0;
- this->bih.biClrImportant = 0;
-
- /* check the signature */
- if (BE_32(&signature[0]) == IFF_FORM_CHUNK)
- {
- switch( this->iff_type )
- {
- case IFF_8SVX_CHUNK:
- this->audio_bits = 8;
- break;
- case IFF_16SV_CHUNK:
- this->audio_bits = 16;
- break;
- case IFF_ILBM_CHUNK:
- break;
-/* case IFF_ANIM_CHUNK:*/
- default:
- return 0;
- break;
- }
- } else
- return 0;
-
- /* file is qualified; skip over the header bytes in the stream */
- this->input->seek(this->input, IFF_SIGNATURE_SIZE, SEEK_SET);
-
-
while ( keep_on_reading == 1 ) {
if (this->input->read(this->input, signature, IFF_JUNK_SIZE) == IFF_JUNK_SIZE) {
+ if( signature[0] == 0 && signature[1] > 0 ) {
+ signature[0] = signature[1];
+ signature[1] = signature[2];
+ signature[2] = signature[3];
+ signature[3] = signature[4];
+ signature[4] = signature[5];
+ signature[5] = signature[6];
+ signature[6] = signature[7];
+ if (this->input->read(this->input, &signature[7], 1) != 1)
+ return 0;
+ }
junk_size = BE_32(&signature[4]);
switch( BE_32(&signature[0]) ) {
case IFF_CMAP_CHUNK:
case IFF_BODY_CHUNK:
+ case IFF_DLTA_CHUNK:
+ case IFF_FORM_CHUNK:
/* don't read this chunks, will be done later */
break;
default:
@@ -437,16 +207,23 @@ static int open_iff_file(demux_iff_t *this) {
}
switch( BE_32(&signature[0]) ) {
+ case IFF_FORM_CHUNK:
+ if (this->input->read(this->input, buffer, 4) != 4)
+ return 0;
+ this->iff_sub_type = BE_32(&buffer[0]);
+ break;
case IFF_VHDR_CHUNK:
- this->vhdr_oneShotHiSamples = BE_32(&buffer[0]);
- this->vhdr_repeatHiSamples = BE_32(&buffer[4]);
- this->vhdr_samplesPerHiCycle = BE_32(&buffer[8]);
- this->vhdr_samplesPerSec = BE_16(&buffer[12]);
- this->vhdr_ctOctave = buffer[14];
- this->vhdr_sCompression = buffer[15];
+ if( this->vhdr == NULL )
+ this->vhdr = (Voice8Header *)xine_xmalloc(sizeof(Voice8Header));
+ this->vhdr->oneShotHiSamples = BE_32(&buffer[0]);
+ this->vhdr->repeatHiSamples = BE_32(&buffer[4]);
+ this->vhdr->samplesPerHiCycle = BE_32(&buffer[8]);
+ this->vhdr->samplesPerSec = BE_16(&buffer[12]);
+ this->vhdr->ctOctave = buffer[14];
+ this->vhdr->sCompression = buffer[15];
this->audio_channels = 1;
this->chan_settings = MONO;
- switch( this->vhdr_sCompression ) {
+ switch( this->vhdr->sCompression ) {
case SND_COMPRESSION_NONE: /* uncompressed */
case SND_COMPRESSION_FIBONACCI: /* Fibonacci */
case SND_COMPRESSION_EXPONENTIAL: /* Exponential*/
@@ -456,37 +233,65 @@ static int open_iff_file(demux_iff_t *this) {
default: /* unknown codec */
xine_log(this->stream->xine, XINE_LOG_MSG,
_("iff-8svx/16sv: unknown compression: %d\n"),
- this->vhdr_sCompression);
+ this->vhdr->sCompression);
return 0;
break;
}
- this->vhdr_volume = BE_32(&buffer[16]);
- if (this->vhdr_volume > max_volume)
- this->vhdr_volume = max_volume;
+ this->vhdr->volume = BE_32(&buffer[16]);
+ if (this->vhdr->volume > max_volume)
+ this->vhdr->volume = max_volume;
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->oneShotHiSamples %d\n",
+ this->vhdr->oneShotHiSamples);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->repeatHiSamples %d\n",
+ this->vhdr->repeatHiSamples);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->samplesPerHiCycle %d\n",
+ this->vhdr->samplesPerHiCycle);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->samplesPerSec %d\n",
+ this->vhdr->samplesPerSec);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->ctOctave %d\n",
+ this->vhdr->ctOctave);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->sCompression %d\n",
+ this->vhdr->sCompression);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->volume %d\n",
+ this->vhdr->volume);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "chan_settings %d\n",
+ this->chan_settings);
break;
case IFF_NAME_CHUNK:
- if (this->title == 0)
+ if (this->title == NULL)
this->title = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "title %s\n",
+ this->title);
break;
case IFF_COPY_CHUNK:
- if (this->copyright == 0)
+ if (this->copyright == NULL)
this->copyright = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "copyright %s\n",
+ this->copyright);
break;
case IFF_AUTH_CHUNK:
- if (this->author == 0)
+ if (this->author == NULL)
this->author = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "author %s\n",
+ this->author);
break;
case IFF_ANNO_CHUNK:
- if (this->annotations == 0)
+ if (this->annotations == NULL)
this->annotations = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "annotations %s\n",
+ this->annotations);
break;
case IFF_FVER_CHUNK:
- if (this->version == 0)
+ if (this->version == NULL)
this->version = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "version %s\n",
+ this->version);
break;
case IFF_TEXT_CHUNK:
- if (this->text == 0)
+ if (this->text == NULL)
this->text = strndup( (const char *)buffer, (size_t)junk_size);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "text %s\n",
+ this->text);
break;
case IFF_ATAK_CHUNK:
/* not yet implemented */
@@ -498,18 +303,18 @@ static int open_iff_file(demux_iff_t *this) {
this->chan_settings = BE_32(&buffer[0]);
switch( this->chan_settings ) {
case STEREO:
- this->audio_volume_left = this->vhdr_volume;
- this->audio_volume_right = this->vhdr_volume;
+ this->audio_volume_left = this->vhdr->volume;
+ this->audio_volume_right = this->vhdr->volume;
this->audio_channels = 2;
break;
case LEFT:
- this->audio_volume_left = this->vhdr_volume;
+ this->audio_volume_left = this->vhdr->volume;
this->audio_volume_right = 0;
this->audio_channels = 2;
break;
case RIGHT:
this->audio_volume_left = 0;
- this->audio_volume_right = this->vhdr_volume;
+ this->audio_volume_right = this->vhdr->volume;
this->audio_channels = 2;
break;
default:
@@ -522,36 +327,37 @@ static int open_iff_file(demux_iff_t *this) {
this->chan_settings = PAN;
this->pan_sposition = BE_32(&buffer[0]);
this->audio_channels = 2;
- this->audio_volume_left = this->vhdr_volume / (max_volume / this->pan_sposition);
- this->audio_volume_right = this->vhdr_volume - this->audio_volume_left;
+ this->audio_volume_left = this->vhdr->volume / (max_volume / this->pan_sposition);
+ this->audio_volume_right = this->vhdr->volume - this->audio_volume_left;
break;
case IFF_BMHD_CHUNK:
- this->bmhd_w = BE_16(&buffer[0]);
- this->bmhd_h = BE_16(&buffer[2]);
- this->bmhd_x = BE_16(&buffer[4]);
- this->bmhd_y = BE_16(&buffer[6]);
- this->bmhd_nplanes = buffer[8];
- this->bmhd_masking = buffer[9];
- this->bmhd_compression = buffer[10];
- this->bmhd_pad1 = buffer[11];
- this->bmhd_transparentColor = BE_16(&buffer[12]);
- this->bmhd_xaspect = buffer[14];
- this->bmhd_yaspect = buffer[15];
- this->bmhd_pagewidth = BE_16(&buffer[16]);
- this->bmhd_pageheight = BE_16(&buffer[18]);
-
- if (this->bmhd_w > 0)
- this->bih.biWidth = this->bmhd_w;
+ if( this->bmhd == NULL )
+ this->bmhd = (BitMapHeader *)xine_xmalloc(sizeof(BitMapHeader));
+ this->bmhd->w = BE_16(&buffer[0]);
+ this->bmhd->h = BE_16(&buffer[2]);
+ this->bmhd->x = BE_16(&buffer[4]);
+ this->bmhd->y = BE_16(&buffer[6]);
+ this->bmhd->nplanes = buffer[8];
+ this->bmhd->masking = buffer[9];
+ this->bmhd->compression = buffer[10];
+ this->bmhd->pad1 = buffer[11];
+ this->bmhd->transparentColor = BE_16(&buffer[12]);
+ this->bmhd->xaspect = buffer[14];
+ this->bmhd->yaspect = buffer[15];
+ this->bmhd->pagewidth = BE_16(&buffer[16]);
+ this->bmhd->pageheight = BE_16(&buffer[18]);
+
+ if (this->bmhd->w > 0)
+ this->bih.biWidth = this->bmhd->w;
else
- this->bih.biWidth = this->bmhd_pagewidth;
- if (this->bmhd_h > 0)
- this->bih.biHeight = this->bmhd_h;
+ this->bih.biWidth = this->bmhd->pagewidth;
+ if (this->bmhd->h > 0)
+ this->bih.biHeight = this->bmhd->h;
else
- this->bih.biHeight = this->bmhd_pageheight;
- this->bih.biPlanes = this->bmhd_nplanes;
- this->bih.biBitCount = this->bmhd_nplanes;
- this->video_pts_inc = 10000000;
- switch( this->bmhd_compression ) {
+ this->bih.biHeight = this->bmhd->pageheight;
+ this->bih.biPlanes = this->bmhd->nplanes;
+ this->bih.biBitCount = this->bmhd->nplanes;
+ switch( this->bmhd->compression ) {
case PIC_COMPRESSION_NONE: /* uncompressed */
this->video_type = BUF_VIDEO_BITPLANE;
break;
@@ -561,69 +367,168 @@ static int open_iff_file(demux_iff_t *this) {
default:
xine_log(this->stream->xine, XINE_LOG_MSG,
_("iff-ilbm: unknown compression: %d\n"),
- this->bmhd_compression);
+ this->bmhd->compression);
return 0;
break;
}
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->w %d\n",
+ this->bmhd->w);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->h %d\n",
+ this->bmhd->h);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->x %d\n",
+ this->bmhd->x);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->y %d\n",
+ this->bmhd->y);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->nplanes %d\n",
+ this->bmhd->nplanes);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->masking %d\n",
+ this->bmhd->masking);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->compression %d\n",
+ this->bmhd->compression);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pad1 %d\n",
+ this->bmhd->pad1);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->transparentColor %d\n",
+ this->bmhd->transparentColor);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->xaspect %d\n",
+ this->bmhd->xaspect);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->yaspect %d\n",
+ this->bmhd->yaspect);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pagewidth %d\n",
+ this->bmhd->pagewidth);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pageheight %d\n",
+ this->bmhd->pageheight);
break;
case IFF_CMAP_CHUNK:
/* every color contains red, green and blue componente using 8Bit */
- this->cmap_color_register_num = junk_size / 3;
- this->cmap_color_register = (color_register *)xine_xmalloc(junk_size);
- if (this->input->read(this->input, (char *)this->cmap_color_register, junk_size) != junk_size)
+ this->cmap_num = junk_size / PIC_SIZE_OF_COLOR_REGISTER;
+ this->cmap = (ColorRegister *)xine_xmalloc(junk_size);
+ this->video_send_palette = 1;
+ if (this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size)
return 0;
break;
case IFF_GRAB_CHUNK:
- this->grab_x = BE_16(&buffer[0]);
- this->grab_y = BE_16(&buffer[2]);
+ if( this->grab == NULL )
+ this->grab = (Point2D *)xine_xmalloc(sizeof(Point2D));
+ this->grab->x = BE_16(&buffer[0]);
+ this->grab->y = BE_16(&buffer[2]);
break;
case IFF_DEST_CHUNK:
- this->dest_depth = buffer[0];
- this->dest_pad1 = buffer[1];
- this->dest_plane_pick = BE_16(&buffer[2]);
- this->dest_plane_onoff = BE_16(&buffer[4]);
- this->dest_plane_mask = BE_16(&buffer[6]);
+ if( this->dest == NULL )
+ this->dest = (DestMerge *)xine_xmalloc(sizeof(DestMerge));
+ this->dest->depth = buffer[0];
+ this->dest->pad1 = buffer[1];
+ this->dest->plane_pick = BE_16(&buffer[2]);
+ this->dest->plane_onoff = BE_16(&buffer[4]);
+ this->dest->plane_mask = BE_16(&buffer[6]);
break;
case IFF_SPRT_CHUNK:
- this->sprt_sprite_precedence = BE_16(&buffer[0]);
+ this->sprt = BE_16(&buffer[0]);
break;
case IFF_CAMG_CHUNK:
- this->camg_view_modes = BE_32(&buffer[0]);
- this->bih.biCompression = this->camg_view_modes;
+ if( this->camg == NULL )
+ this->camg = (CamgChunk *)xine_xmalloc(sizeof(CamgChunk));
+ this->camg->view_modes = BE_32(&buffer[0]);
+ this->bih.biCompression = this->camg->view_modes;
+ if( this->camg->view_modes & CAMG_PAL &&
+ this->video_pts_inc == 4500 )
+ this->video_pts_inc = 5400;
break;
case IFF_CRNG_CHUNK:
- if (this->crng_color_range_used < 256) {
- this->crng_color_range[this->crng_color_range_used].crng_pad1 = BE_16(&buffer[0]);
- this->crng_color_range[this->crng_color_range_used].crng_rate = BE_16(&buffer[2]);
- this->crng_color_range[this->crng_color_range_used].crng_active = BE_16(&buffer[4]);
- this->crng_color_range[this->crng_color_range_used].crng_low = buffer[6];
- this->crng_color_range[this->crng_color_range_used].crng_high = buffer[7];
- this->crng_color_range_used++;
+ if (this->crng_used < 256) {
+ this->crng[this->crng_used].pad1 = BE_16(&buffer[0]);
+ this->crng[this->crng_used].rate = BE_16(&buffer[2]);
+ this->crng[this->crng_used].active = BE_16(&buffer[4]);
+ this->crng[this->crng_used].low = buffer[6];
+ this->crng[this->crng_used].high = buffer[7];
+ this->crng_used++;
}
break;
case IFF_CCRT_CHUNK:
- this->ccrt_direction = BE_16(&buffer[0]);
- this->ccrt_start = buffer[2];
- this->ccrt_end = buffer[3];
- this->ccrt_seconds = BE_32(&buffer[4]);
- this->ccrt_microseconds = BE_32(&buffer[8]);
- this->ccrt_pad = BE_16(&buffer[12]);
+ if( this->ccrt == NULL )
+ this->ccrt = (CcrtChunk *)xine_xmalloc(sizeof(CcrtChunk));
+ this->ccrt->direction = BE_16(&buffer[0]);
+ this->ccrt->start = buffer[2];
+ this->ccrt->end = buffer[3];
+ this->ccrt->seconds = BE_32(&buffer[4]);
+ this->ccrt->microseconds = BE_32(&buffer[8]);
+ this->ccrt->pad = BE_16(&buffer[12]);
break;
case IFF_DPI_CHUNK:
- this->dpi_x = BE_16(&buffer[0]);
- this->dpi_y = BE_16(&buffer[0]);
+ if( this->dpi == NULL )
+ this->dpi = (DPIHeader *)xine_xmalloc(sizeof(DPIHeader));
+ this->dpi->x = BE_16(&buffer[0]);
+ this->dpi->y = BE_16(&buffer[0]);
+ break;
+ case IFF_ANHD_CHUNK:
+ if( this->anhd == NULL )
+ this->anhd = (AnimHeader *)xine_xmalloc(sizeof(AnimHeader));
+ this->anhd->operation = buffer[0];
+ this->anhd->mask = buffer[1];
+ this->anhd->w = BE_16(&buffer[2]);
+ this->anhd->h = BE_16(&buffer[4]);
+ this->anhd->x = BE_16(&buffer[6]);
+ this->anhd->y = BE_16(&buffer[8]);
+ this->anhd->abs_time = BE_32(&buffer[10]);
+ this->anhd->rel_time = BE_32(&buffer[14]);
+ this->anhd->interleave = buffer[18];
+ this->anhd->pad0 = buffer[19];
+ this->anhd->bits = BE_32(&buffer[20]);
+ if( this->dpan == NULL )
+ this->video_pts += this->video_pts_inc * this->anhd->rel_time;
+ else
+ this->video_pts += this->video_pts_inc;
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->operation %d\n",
+ this->anhd->operation);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->mask %d\n",
+ this->anhd->mask);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->w %d\n",
+ this->anhd->w);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->h %d\n",
+ this->anhd->h);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->x %d\n",
+ this->anhd->x);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->y %d\n",
+ this->anhd->y);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->abs_time %d\n",
+ this->anhd->abs_time);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->rel_time %d\n",
+ this->anhd->rel_time);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->interleave %d\n",
+ this->anhd->interleave);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->bits %d\n",
+ this->anhd->bits);
+ break;
+ case IFF_DPAN_CHUNK:
+ if( this->dpan == NULL )
+ this->dpan = (DPAnimChunk *)xine_xmalloc(sizeof(DPAnimChunk));
+ this->dpan->version = BE_16(&buffer[0]);
+ this->dpan->nframes = BE_16(&buffer[2]);
+ this->dpan->fps = buffer[4];
+ this->dpan->unused1 = buffer[5];
+ this->dpan->unused2 = buffer[6];
+ this->dpan->unused3 = buffer[7];
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->version %d\n",
+ this->dpan->version);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->nframes %d\n",
+ this->dpan->nframes);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->fps %d\n",
+ this->dpan->fps);
+ break;
+ case IFF_DPPS_CHUNK:
+ /* DPPS contains DeluxePaint specific information, no documentation available */
break;
case IFF_JUNK_CHUNK:
/* JUNK contains garbage and should be ignored */
break;
case IFF_BODY_CHUNK:
+ case IFF_DLTA_CHUNK:
this->data_start = this->input->get_current_pos(this->input);
this->data_size = junk_size;
switch( this->iff_type )
{
case IFF_8SVX_CHUNK:
case IFF_16SV_CHUNK:
- if( this->vhdr_sCompression > SND_COMPRESSION_NONE ) {
+ if( this->vhdr->sCompression > SND_COMPRESSION_NONE ) {
this->audio_interleave_buffer_size = this->data_size * 2;
this->audio_read_buffer_size = this->data_size;
} else {
@@ -631,18 +536,27 @@ static int open_iff_file(demux_iff_t *this) {
this->audio_read_buffer_size = 0;
}
if( this->chan_settings == MONO)
- this->audio_volume_left = this->vhdr_volume;
+ this->audio_volume_left = this->vhdr->volume;
this->audio_bytes_per_second = this->audio_channels *
(this->audio_bits / 8) *
- this->vhdr_samplesPerSec;
- this->running_time = ((this->vhdr_oneShotHiSamples +
- this->vhdr_repeatHiSamples) *
- 1000 / this->vhdr_samplesPerSec) /
- this->audio_channels;
+ this->vhdr->samplesPerSec;
+ this->running_time = ((this->vhdr->oneShotHiSamples +
+ this->vhdr->repeatHiSamples) *
+ 1000 / this->vhdr->samplesPerSec) /
+ this->audio_channels;
break;
case IFF_ILBM_CHUNK:
- this->bih.biSize = this->data_size;
- this->bih.biSizeImage = this->data_size;
+ this->bih.biSize = this->data_size;
+ this->bih.biSizeImage = this->data_size;
+ break;
+ case IFF_ANIM_CHUNK:
+ this->bih.biSize = this->data_size;
+ this->bih.biSizeImage = this->data_size;
+ if( this->dpan ) {
+ if( this->dpan->fps > 0 && this->dpan->fps <= 60)
+ this->video_pts_inc = 90000 / this->dpan->fps;
+ this->running_time = (this->video_pts_inc * this->dpan->nframes) / 90;
+ }
break;
default:
break;
@@ -655,86 +569,112 @@ static int open_iff_file(demux_iff_t *this) {
break;
}
} else
- keep_on_reading = 0;
- }
-
- switch( this->iff_type )
- {
- case IFF_8SVX_CHUNK:
- case IFF_16SV_CHUNK:
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_oneShotHiSamples %d\n",
- this->vhdr_oneShotHiSamples);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_repeatHiSamples %d\n",
- this->vhdr_repeatHiSamples);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_samplesPerHiCycle %d\n",
- this->vhdr_samplesPerHiCycle);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_samplesPerSec %d\n",
- this->vhdr_samplesPerSec);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_ctOctave %d\n",
- this->vhdr_ctOctave);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_sCompression %d\n",
- this->vhdr_sCompression);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr_volume %d\n",
- this->vhdr_volume);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "chan_settings %d\n",
- this->chan_settings);
- break;
- case IFF_ILBM_CHUNK:
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_w %d\n",
- this->bmhd_w);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_h %d\n",
- this->bmhd_h);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_x %d\n",
- this->bmhd_x);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_y %d\n",
- this->bmhd_y);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_nplanes %d\n",
- this->bmhd_nplanes);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_masking %d\n",
- this->bmhd_masking);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_compression %d\n",
- this->bmhd_compression);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_pad1 %d\n",
- this->bmhd_pad1);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_transparentColor %d\n",
- this->bmhd_transparentColor);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_xaspect %d\n",
- this->bmhd_xaspect);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_yaspect %d\n",
- this->bmhd_yaspect);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_pagewidth %d\n",
- this->bmhd_pagewidth);
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd_pageheight %d\n",
- this->bmhd_pageheight);
- break;
- default:
- break;
+ return 0;
}
- if( this->title )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "title %s\n",
- this->title);
- if( this->copyright )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "copyright %s\n",
- this->copyright);
- if( this->author )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "author %s\n",
- this->author);
- if( this->annotations )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "annotations %s\n",
- this->annotations);
- if( this->version )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "version %s\n",
- this->version);
- if( this->text )
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "text %s\n",
- this->text);
-
-/* if( this->iff_type == IFF_ILBM_CHUNK )
- return 0;*/
return 1;
}
+/* returns 1 if the IFF file was opened successfully, 0 otherwise */
+static int open_iff_file(demux_iff_t *this) {
+
+ unsigned char signature[IFF_SIGNATURE_SIZE];
+
+ if (_x_demux_read_header(this->input, signature, IFF_SIGNATURE_SIZE) != IFF_SIGNATURE_SIZE)
+ return 0;
+
+ this->title = NULL;
+ this->copyright = NULL;
+ this->author = NULL;
+ this->annotations = NULL;
+ this->version = NULL;
+ this->text = NULL;
+
+ this->vhdr = NULL;
+ this->atak = NULL;
+ this->rlse = NULL;
+ this->chan_settings = 0;
+ this->audio_type = 0;
+ this->audio_frames = 0;
+ this->audio_bits = 0;
+ this->audio_channels = 0;
+ this->audio_block_align = 0;
+ this->audio_bytes_per_second = 0;
+ this->running_time = 0;
+ this->data_start = 0;
+ this->data_size = 0;
+ this->seek_flag = 0;
+ this->audio_interleave_buffer = 0;
+ this->audio_interleave_buffer_size = 0;
+ this->audio_read_buffer = 0;
+ this->audio_read_buffer_size = 0;
+ this->audio_buffer_filled = 0;
+ this->audio_compression_factor = 1;
+ this->audio_position = 0;
+ this->bmhd = NULL;
+ this->cmap = NULL;
+ this->cmap_num = 0;
+ this->grab = NULL;
+ this->dest = NULL;
+ this->sprt = 0;
+ this->camg = NULL;
+ this->crng_used = 0;
+ this->ccrt = NULL;
+ this->dpi = NULL;
+ this->anhd = NULL;
+ this->dpan = NULL;
+
+ this->iff_type = BE_32(&signature[8]);
+ this->iff_sub_type = this->iff_type;
+
+ this->video_type = 0;
+ this->video_pts = 0;
+ this->video_pts_inc = 0;
+ this->video_send_palette = 0;
+
+ this->bih.biSize = 0;
+ this->bih.biWidth = 0;
+ this->bih.biHeight = 0;
+ this->bih.biPlanes = 0;
+ this->bih.biBitCount = 0;
+ this->bih.biCompression = 0;
+ this->bih.biSizeImage = 0;
+ this->bih.biXPelsPerMeter = 0;
+ this->bih.biYPelsPerMeter = 0;
+ this->bih.biClrUsed = 0;
+ this->bih.biClrImportant = 0;
+
+ /* check the signature */
+ if (BE_32(&signature[0]) == IFF_FORM_CHUNK)
+ {
+ switch( this->iff_type )
+ {
+ case IFF_8SVX_CHUNK:
+ this->audio_bits = 8;
+ break;
+ case IFF_16SV_CHUNK:
+ this->audio_bits = 16;
+ break;
+ case IFF_ILBM_CHUNK:
+ this->video_pts_inc = 10000000;
+ break;
+ case IFF_ANIM_CHUNK:
+ this->video_pts_inc = 4500;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ } else
+ return 0;
+
+ /* file is qualified; skip over the header bytes in the stream */
+ this->input->seek(this->input, IFF_SIGNATURE_SIZE, SEEK_SET);
+
+ return read_iff_chunk( this );
+
+}
+
static int demux_iff_send_chunk(demux_plugin_t *this_gen) {
demux_iff_t *this = (demux_iff_t *) this_gen;
@@ -759,287 +699,298 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) {
* leaved, the same way as in the sega film demuxer. I've copied
* it out there
*/
- if(this->audio_bits > 0) {
- /* just load data chunks from wherever the stream happens to be
- * pointing; issue a DEMUX_FINISHED status if EOF is reached */
- current_file_pos = this->audio_position;
-
- /* load the whole chunk into the buffer */
- if (this->audio_buffer_filled == 0) {
- if (this->audio_interleave_buffer_size > 0)
- this->audio_interleave_buffer =
- xine_xmalloc(this->audio_interleave_buffer_size);
- if (this->audio_read_buffer_size > 0)
- this->audio_read_buffer =
- xine_xmalloc(this->audio_read_buffer_size);
- if (this->audio_read_buffer) {
- if (this->input->read(this->input, this->audio_read_buffer,
- this->data_size) != this->data_size) {
- this->status = DEMUX_FINISHED;
- return this->status;
- }
+ switch( this->iff_sub_type ) {
+ case IFF_8SVX_CHUNK:
+ case IFF_16SV_CHUNK:
+ /* just load data chunks from wherever the stream happens to be
+ * pointing; issue a DEMUX_FINISHED status if EOF is reached */
+ current_file_pos = this->audio_position;
+
+ /* load the whole chunk into the buffer */
+ if (this->audio_buffer_filled == 0) {
+ if (this->audio_interleave_buffer_size > 0)
+ this->audio_interleave_buffer =
+ xine_xmalloc(this->audio_interleave_buffer_size);
+ if (this->audio_read_buffer_size > 0)
+ this->audio_read_buffer =
+ xine_xmalloc(this->audio_read_buffer_size);
+ if (this->audio_read_buffer) {
+ if (this->input->read(this->input, this->audio_read_buffer,
+ this->data_size) != this->data_size) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
- switch( this->vhdr_sCompression ) {
- case SND_COMPRESSION_FIBONACCI:
- if (this->chan_settings == STEREO) {
- delta_decode((int8_t *)(this->audio_interleave_buffer),
- (int8_t *)(this->audio_read_buffer),
- (this->data_size/2),
- fibonacci);
- delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])),
- (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])),
- (this->data_size/2),
- fibonacci);
- } else
- delta_decode((int8_t *)(this->audio_interleave_buffer),
- (int8_t *)(this->audio_read_buffer),
- this->data_size,
- fibonacci);
- this->audio_compression_factor = 2;
- break;
- case SND_COMPRESSION_EXPONENTIAL:
- if (this->chan_settings == STEREO) {
- delta_decode((int8_t *)(this->audio_interleave_buffer),
- (int8_t *)(this->audio_read_buffer),
- (this->data_size/2),
- exponential);
- delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])),
- (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])),
- (this->data_size/2),
- exponential);
- } else
- delta_decode((int8_t *)(this->audio_interleave_buffer),
- (int8_t *)(this->audio_read_buffer),
- this->data_size,
- exponential);
- this->audio_compression_factor = 2;
- break;
- default:
- break;
- }
- free( this->audio_read_buffer );
- this->audio_read_buffer = 0;
- } else {
- if (this->input->read(this->input, this->audio_interleave_buffer,
- this->data_size) != this->data_size) {
- this->status = DEMUX_FINISHED;
- return this->status;
+ switch( this->vhdr->sCompression ) {
+ case SND_COMPRESSION_FIBONACCI:
+ if (this->chan_settings == STEREO) {
+ delta_decode((int8_t *)(this->audio_interleave_buffer),
+ (int8_t *)(this->audio_read_buffer),
+ (this->data_size/2),
+ fibonacci);
+ delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])),
+ (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])),
+ (this->data_size/2),
+ fibonacci);
+ } else
+ delta_decode((int8_t *)(this->audio_interleave_buffer),
+ (int8_t *)(this->audio_read_buffer),
+ this->data_size,
+ fibonacci);
+ this->audio_compression_factor = 2;
+ break;
+ case SND_COMPRESSION_EXPONENTIAL:
+ if (this->chan_settings == STEREO) {
+ delta_decode((int8_t *)(this->audio_interleave_buffer),
+ (int8_t *)(this->audio_read_buffer),
+ (this->data_size/2),
+ exponential);
+ delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])),
+ (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])),
+ (this->data_size/2),
+ exponential);
+ } else
+ delta_decode((int8_t *)(this->audio_interleave_buffer),
+ (int8_t *)(this->audio_read_buffer),
+ this->data_size,
+ exponential);
+ this->audio_compression_factor = 2;
+ break;
+ default:
+ break;
+ }
+ free( this->audio_read_buffer );
+ this->audio_read_buffer = NULL;
+ } else {
+ if (this->input->read(this->input, this->audio_interleave_buffer,
+ this->data_size) != this->data_size) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
}
+ this->audio_buffer_filled = 1;
}
- this->audio_buffer_filled = 1;
- }
- /* proceed to de-interleave into individual buffers */
- if (this->chan_settings == STEREO) {
- remaining_sample_bytes = ((this->data_size - current_file_pos) *
+ /* proceed to de-interleave into individual buffers */
+ if (this->chan_settings == STEREO) {
+ remaining_sample_bytes = ((this->data_size - current_file_pos) *
this->audio_compression_factor) / 2;
- interleave_index = (current_file_pos *
+ interleave_index = (current_file_pos *
this->audio_compression_factor) / 2;
- } else {
- remaining_sample_bytes = ((this->data_size - current_file_pos) *
+ } else {
+ remaining_sample_bytes = ((this->data_size - current_file_pos) *
this->audio_compression_factor);
- interleave_index = (current_file_pos *
+ interleave_index = (current_file_pos *
this->audio_compression_factor);
- }
- first_buf = 1;
+ }
+ first_buf = 1;
- zw_pts = current_file_pos;
+ zw_pts = current_file_pos;
- if (this->chan_settings == STEREO)
- input_length = this->data_size *
+ if (this->chan_settings == STEREO)
+ input_length = this->data_size *
this->audio_compression_factor;
- else
- input_length = this->data_size *
+ else
+ input_length = this->data_size *
this->audio_compression_factor *
this->audio_channels;
- while (remaining_sample_bytes) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = this->audio_type;
- buf->extra_info->input_pos = zw_pts;
- buf->extra_info->input_length = input_length;
- buf->pts = zw_pts * 90000 / this->audio_bytes_per_second;
- buf->extra_info->input_time = buf->pts / 90;
-
- if (remaining_sample_bytes > buf->max_size / this->audio_channels)
- buf->size = buf->max_size;
- else
- buf->size = remaining_sample_bytes * this->audio_channels;
- remaining_sample_bytes -= buf->size / this->audio_channels;
- zw_pts += buf->size;
-
- /* 16 bit sound */
- if (this->audio_bits == 16) {
-
- pointer16_from = (int16_t *)this->audio_interleave_buffer;
- pointer16_to = (int16_t *)buf->content;
-
- if (this->chan_settings == STEREO ||
- this->chan_settings == LEFT ||
- this->chan_settings == PAN ||
- this->chan_settings == MONO) {
- if( this->audio_volume_left == max_volume ) {
- for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) {
- pointer16_to[j] = pointer16_from[k++];
+ while (remaining_sample_bytes) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = this->audio_type;
+ buf->extra_info->input_pos = zw_pts;
+ buf->extra_info->input_length = input_length;
+ buf->pts = zw_pts * 90000 / this->audio_bytes_per_second;
+ buf->extra_info->input_time = buf->pts / 90;
+
+ if (remaining_sample_bytes > buf->max_size / this->audio_channels)
+ buf->size = buf->max_size;
+ else
+ buf->size = remaining_sample_bytes * this->audio_channels;
+ remaining_sample_bytes -= buf->size / this->audio_channels;
+ zw_pts += buf->size;
+
+ /* 16 bit sound */
+ if (this->audio_bits == 16) {
+
+ pointer16_from = (int16_t *)this->audio_interleave_buffer;
+ pointer16_to = (int16_t *)buf->content;
+
+ if (this->chan_settings == STEREO ||
+ this->chan_settings == LEFT ||
+ this->chan_settings == PAN ||
+ this->chan_settings == MONO) {
+ if( this->audio_volume_left == max_volume ) {
+ for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) {
+ pointer16_to[j] = pointer16_from[k++];
+ }
+ } else {
+ for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) {
+ zw_16 = BE_16(&pointer16_from[k++]);
+ zw_rescale = zw_16;
+ zw_rescale *= this->audio_volume_left;
+ zw_rescale /= max_volume;
+ zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale);
+ pointer16_to[j] = BE_16(&zw_16);
+ }
}
} else {
- for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) {
- zw_16 = BE_16(&pointer16_from[k++]);
- zw_rescale = zw_16;
- zw_rescale *= this->audio_volume_left;
- zw_rescale /= max_volume;
- zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale);
- pointer16_to[j] = BE_16(&zw_16);
+ for (j = 0; j < (buf->size / 2); j += this->audio_channels) {
+ pointer16_to[j] = 0;
}
}
- } else {
- for (j = 0; j < (buf->size / 2); j += this->audio_channels) {
- pointer16_to[j] = 0;
- }
- }
- if (this->chan_settings == STEREO ||
- this->chan_settings == RIGHT ||
- this->chan_settings == PAN) {
- if (this->chan_settings == STEREO)
- k = (interleave_index +
+ if (this->chan_settings == STEREO ||
+ this->chan_settings == RIGHT ||
+ this->chan_settings == PAN) {
+ if (this->chan_settings == STEREO)
+ k = (interleave_index +
(this->data_size *
this->audio_compression_factor / 2)) / 2;
- else
- k = interleave_index / 2;
- if( this->audio_volume_right == max_volume ) {
- for (j = 1; j < (buf->size / 2); j += this->audio_channels) {
- pointer16_to[j] = pointer16_from[k++];
+ else
+ k = interleave_index / 2;
+ if( this->audio_volume_right == max_volume ) {
+ for (j = 1; j < (buf->size / 2); j += this->audio_channels) {
+ pointer16_to[j] = pointer16_from[k++];
+ }
+ } else {
+ for (j = 1; j < (buf->size / 2); j += this->audio_channels) {
+ zw_16 = BE_16(&pointer16_from[k++]);
+ zw_rescale = zw_16;
+ zw_rescale *= this->audio_volume_left;
+ zw_rescale /= max_volume;
+ zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale);
+ pointer16_to[j] = BE_16(&zw_16);
+ }
}
- } else {
+ } else if (this->chan_settings == LEFT) {
for (j = 1; j < (buf->size / 2); j += this->audio_channels) {
- zw_16 = BE_16(&pointer16_from[k++]);
- zw_rescale = zw_16;
- zw_rescale *= this->audio_volume_left;
- zw_rescale /= max_volume;
- zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale);
- pointer16_to[j] = BE_16(&zw_16);
+ pointer16_to[j] = 0;
}
}
- } else if (this->chan_settings == LEFT) {
- for (j = 1; j < (buf->size / 2); j += this->audio_channels) {
- pointer16_to[j] = 0;
- }
- }
- /* 8 bit sound */
- } else {
- if (this->chan_settings == STEREO ||
- this->chan_settings == LEFT ||
- this->chan_settings == PAN ||
- this->chan_settings == MONO) {
- if( this->audio_volume_left == max_volume ) {
- for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) {
- buf->content[j] = this->audio_interleave_buffer[k++] + 0x80;
+ /* 8 bit sound */
+ } else {
+ if (this->chan_settings == STEREO ||
+ this->chan_settings == LEFT ||
+ this->chan_settings == PAN ||
+ this->chan_settings == MONO) {
+ if( this->audio_volume_left == max_volume ) {
+ for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) {
+ buf->content[j] = this->audio_interleave_buffer[k++] + 0x80;
+ }
+ } else {
+ for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) {
+ zw_rescale = this->audio_interleave_buffer[k++];
+ zw_rescale *= this->audio_volume_left;
+ zw_rescale /= max_volume;
+ zw_rescale += 0x80;
+ buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale);
+ }
}
} else {
- for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) {
- zw_rescale = this->audio_interleave_buffer[k++];
- zw_rescale *= this->audio_volume_left;
- zw_rescale /= max_volume;
- zw_rescale += 0x80;
- buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale);
+ for (j = 0; j < buf->size; j += 2) {
+ buf->content[j] = 0;
}
}
- } else {
- for (j = 0; j < buf->size; j += 2) {
- buf->content[j] = 0;
- }
- }
- if (this->chan_settings == STEREO ||
- this->chan_settings == RIGHT ||
- this->chan_settings == PAN) {
- if (this->chan_settings == STEREO)
- k = interleave_index +
+ if (this->chan_settings == STEREO ||
+ this->chan_settings == RIGHT ||
+ this->chan_settings == PAN) {
+ if (this->chan_settings == STEREO)
+ k = interleave_index +
(this->data_size *
this->audio_compression_factor / 2);
- else
- k = interleave_index;
- if( this->audio_volume_right == max_volume ) {
- for (j = 1; j < buf->size; j += this->audio_channels) {
- buf->content[j] = this->audio_interleave_buffer[k++] + 0x80;
+ else
+ k = interleave_index;
+ if( this->audio_volume_right == max_volume ) {
+ for (j = 1; j < buf->size; j += this->audio_channels) {
+ buf->content[j] = this->audio_interleave_buffer[k++] + 0x80;
+ }
+ } else {
+ for (j = 1; j < buf->size; j += this->audio_channels) {
+ zw_rescale = this->audio_interleave_buffer[k++];
+ zw_rescale *= this->audio_volume_right;
+ zw_rescale /= max_volume;
+ zw_rescale += 0x80;
+ buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale);
+ }
}
- } else {
+ } else if (this->chan_settings == LEFT) {
for (j = 1; j < buf->size; j += this->audio_channels) {
- zw_rescale = this->audio_interleave_buffer[k++];
- zw_rescale *= this->audio_volume_right;
- zw_rescale /= max_volume;
- zw_rescale += 0x80;
- buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale);
+ buf->content[j] = 0;
}
}
- } else if (this->chan_settings == LEFT) {
- for (j = 1; j < buf->size; j += this->audio_channels) {
- buf->content[j] = 0;
- }
}
- }
- interleave_index += buf->size / this->audio_channels;
+ interleave_index += buf->size / this->audio_channels;
- if (!remaining_sample_bytes)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
-
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
- "sending audio buf with %d bytes, %lld pts, %d duration\n",
- buf->size, buf->pts, buf->decoder_info[0]);
- this->audio_fifo->put(this->audio_fifo, buf);
- }
- this->status = DEMUX_FINISHED;
- }
- if ( this->iff_type == IFF_ILBM_CHUNK )
- {
- /* send off the palette, if there is one */
- if ( this->cmap_color_register_num > 0 ) {
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
- buf->decoder_info[1] = BUF_SPECIAL_PALETTE;
- buf->decoder_info[2] = this->cmap_color_register_num;
- buf->decoder_info_ptr[2] = this->cmap_color_register;
- buf->size = 0;
- buf->type = this->video_type;
- this->video_fifo->put (this->video_fifo, buf);
- }
+ if (!remaining_sample_bytes)
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
- /* And now let's start with the picture */
- size = this->data_size;
- while (size > 0) {
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->content = buf->mem;
- buf->type = this->video_type;
- buf->decoder_flags = BUF_FLAG_FRAMERATE;
- buf->decoder_info[0] = 0;
- buf->extra_info->input_pos = this->input->get_current_pos(this->input);
- buf->extra_info->input_time = 0;
- buf->pts = 0;
-
- if (size > buf->max_size) {
- buf->size = buf->max_size;
- } else {
- buf->size = size;
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "sending audio buf with %d bytes, %lld pts, %d duration\n",
+ buf->size, buf->pts, buf->decoder_info[0]);
+ this->audio_fifo->put(this->audio_fifo, buf);
}
- size -= buf->size;
-
- if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
+ break;
+ case IFF_ILBM_CHUNK:
+ /* send off the palette, if there is one */
+ if ( this->video_send_palette == 1 ) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
+ buf->decoder_info[1] = BUF_SPECIAL_PALETTE;
+ buf->decoder_info[2] = this->cmap_num;
+ buf->decoder_info_ptr[2] = this->cmap;
+ buf->size = 0;
+ buf->type = this->video_type;
+ this->video_fifo->put (this->video_fifo, buf);
+ this->video_send_palette = 0;
}
- if (size <= 0)
- {
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
- buf->decoder_info[1] = this->video_pts_inc; /* initial video_step */
- }
+ /* And now let's start with the picture */
+ size = this->data_size;
+ while (size > 0) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->content = buf->mem;
+ buf->type = this->video_type;
+ buf->decoder_flags = BUF_FLAG_FRAMERATE;
+ if( this->anhd == NULL )
+ buf->decoder_info[0] = 0;
+ else
+ buf->decoder_info[0] = this->video_pts_inc;
+ buf->decoder_info_ptr[0] = this->anhd;
+ buf->extra_info->input_pos = this->input->get_current_pos(this->input);
+ buf->pts = this->video_pts;
+ buf->extra_info->input_time = buf->pts / 90;
+
+ if (size > buf->max_size) {
+ buf->size = buf->max_size;
+ } else {
+ buf->size = size;
+ }
+ size -= buf->size;
+ if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ }
- this->video_fifo->put(this->video_fifo, buf);
- }
- this->status = DEMUX_FINISHED;
+ if (size <= 0)
+ {
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
+ if (this->iff_type == IFF_ILBM_CHUNK )
+ buf->decoder_info[1] = this->video_pts_inc; /* initial video_step */
+ }
+
+ this->video_fifo->put(this->video_fifo, buf);
+ }
+ break;
}
+ /* look for other multimedia parts */
+ if( read_iff_chunk( this ) )
+ this->status = DEMUX_OK;
+ else
+ this->status = DEMUX_FINISHED;
+
return this->status;
}
@@ -1072,7 +1023,7 @@ static void demux_iff_send_headers(demux_plugin_t *this_gen) {
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS,
this->audio_channels);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE,
- this->vhdr_samplesPerSec);
+ this->vhdr->samplesPerSec);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS,
this->audio_bits);
@@ -1085,18 +1036,20 @@ static void demux_iff_send_headers(demux_plugin_t *this_gen) {
buf->type = this->audio_type;
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
buf->decoder_info[0] = 0;
- buf->decoder_info[1] = this->vhdr_samplesPerSec;
+ buf->decoder_info[1] = this->vhdr->samplesPerSec;
buf->decoder_info[2] = this->audio_bits;
buf->decoder_info[3] = this->audio_channels;
this->audio_fifo->put (this->audio_fifo, buf);
}
break;
case IFF_ILBM_CHUNK:
+ case IFF_ANIM_CHUNK:
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_pts_inc);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION,
+ this->video_pts_inc);
/* send start buffers */
_x_demux_control_start(this->stream);
@@ -1104,19 +1057,15 @@ static void demux_iff_send_headers(demux_plugin_t *this_gen) {
buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
buf->type = this->video_type;
buf->size = sizeof(xine_bmiheader);
- buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE|
- BUF_FLAG_FRAME_END;
+ buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE|BUF_FLAG_FRAME_END;
buf->decoder_info[0] = this->video_pts_inc; /* initial video_step */
- buf->decoder_info[2] = this->bmhd_xaspect;
- buf->decoder_info[3] = this->bmhd_yaspect;
+ buf->decoder_info[1] = 0;
+ buf->decoder_info[2] = this->bmhd->xaspect;
+ buf->decoder_info[3] = this->bmhd->yaspect;
memcpy(buf->content, &this->bih, sizeof(this->bih));
this->video_fifo->put(this->video_fifo, buf);
break;
- case IFF_ANIM_CHUNK:
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
- break;
default:
break;
}
@@ -1145,6 +1094,7 @@ static int demux_iff_seek (demux_plugin_t *this_gen,
((start_pos >= this->data_size) ?
this->data_size : start_pos);
case IFF_ILBM_CHUNK:
+ case IFF_ANIM_CHUNK:
break;
default:
break;
@@ -1155,43 +1105,94 @@ static int demux_iff_seek (demux_plugin_t *this_gen,
static void demux_iff_dispose (demux_plugin_t *this_gen) {
demux_iff_t *this = (demux_iff_t *) this_gen;
- if( this->title )
+ if( this->bmhd ) {
+ free(this->bmhd);
+ this->bmhd = NULL;
+ }
+ if( this->cmap ) {
+ free( this->cmap );
+ this->cmap = NULL;
+ }
+ if( this->grab ) {
+ free(this->grab);
+ this->grab = NULL;
+ }
+ if( this->dest ) {
+ free(this->dest);
+ this->dest = NULL;
+ }
+ if( this->camg ) {
+ free(this->camg);
+ this->camg = NULL;
+ }
+ if( this->ccrt ) {
+ free(this->ccrt);
+ this->ccrt = NULL;
+ }
+ if( this->dpi ) {
+ free(this->dpi);
+ this->dpi = NULL;
+ }
+
+ if( this->vhdr ) {
+ free(this->vhdr);
+ this->vhdr = NULL;
+ }
+ if( this->atak )
+ {
+ free( this->atak );
+ this->atak = NULL;
+ }
+ if( this->rlse ) {
+ free( this->rlse );
+ this->rlse = NULL;
+ }
+
+ if( this->anhd ) {
+ free( this->anhd );
+ this->anhd = NULL;
+ }
+
+ if( this->dpan ) {
+ free( this->dpan );
+ this->dpan = NULL;
+ }
+
+ if( this->title ) {
free (this->title);
- if( this->copyright )
+ this->title = NULL;
+ }
+ if( this->copyright ) {
free (this->copyright);
- if( this->author )
+ this->copyright = NULL;
+ }
+ if( this->author ) {
free (this->author);
- if( this->annotations )
+ this->author = NULL;
+ }
+ if( this->annotations ) {
free (this->annotations);
- if( this->version )
+ this->annotations = NULL;
+ }
+ if( this->version ) {
free (this->version);
- if( this->text )
+ this->version = NULL;
+ }
+ if( this->text ) {
free (this->text);
+ this->text = NULL;
+ }
if( this->audio_interleave_buffer ) {
free (this->audio_interleave_buffer);
- this->audio_interleave_buffer = 0;
+ this->audio_interleave_buffer = NULL;
}
if( this->audio_read_buffer ) {
free (this->audio_read_buffer);
- this->audio_read_buffer = 0;
- }
- if( this->atak_eg_point )
- {
- free( this->atak_eg_point );
- this->atak_eg_point = 0;
- }
- if( this->rlse_eg_point ) {
- free( this->rlse_eg_point );
- this->rlse_eg_point = 0;
+ this->audio_read_buffer = NULL;
}
this->audio_buffer_filled = 0;
- if( this->cmap_color_register ) {
- free( this->cmap_color_register );
- this->cmap_color_register = 0;
- }
-
free(this);
}
@@ -1280,7 +1281,7 @@ static char *get_identifier (demux_class_t *this_gen) {
}
static char *get_extensions (demux_class_t *this_gen) {
- return "iff svx 8svx 16sv ilbm pic";
+ return "iff svx 8svx 16sv ilbm pic anim";
}
static char *get_mimetypes (demux_class_t *this_gen) {
@@ -1289,7 +1290,9 @@ static char *get_mimetypes (demux_class_t *this_gen) {
"audio/x-16sv: 16sv: IFF-16SV Audio;"
"audio/168sv: 16sv: IFF-16SV Audio;"
"image/x-ilbm: ilbm: IFF-ILBM Picture;"
- "image/ilbm: ilbm: IFF-ILBM Picture;";
+ "image/ilbm: ilbm: IFF-ILBM Picture;"
+ "video/x-anim: anim: IFF-ANIM Video;"
+ "video/anim: anim: IFF-ANIM Video;";
}
static void class_dispose (demux_class_t *this_gen) {
diff --git a/src/demuxers/iff.h b/src/demuxers/iff.h
new file mode 100644
index 000000000..129503694
--- /dev/null
+++ b/src/demuxers/iff.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2004 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * IFF header file by Manfred Tremmel (Manfred.Tremmel@iiv.de)
+ * Based on the information of the Amiga Developer CD
+ *
+ * $Id: iff.h,v 1.1 2004/02/22 12:36:37 manfredtremmel Exp $
+ */
+
+#ifndef IFFP_IFF_H
+#define IFFP_IFF_H
+
+#define IFF_OKAY 0L
+#define CLIENT_ERROR 1L
+#define NOFILE 5L
+
+#define FOURCC_CHUNK BE_FOURCC
+#define IFF_16SV_CHUNK FOURCC_CHUNK('1', '6', 'S', 'V')
+#define IFF_8SVX_CHUNK FOURCC_CHUNK('8', 'S', 'V', 'X')
+#define IFF_ANFI_CHUNK FOURCC_CHUNK('A', 'N', 'F', 'I')
+#define IFF_ANHD_CHUNK FOURCC_CHUNK('A', 'N', 'H', 'D')
+#define IFF_ANIM_CHUNK FOURCC_CHUNK('A', 'N', 'I', 'M')
+#define IFF_ANNO_CHUNK FOURCC_CHUNK('A', 'N', 'N', 'O')
+#define IFF_ANSQ_CHUNK FOURCC_CHUNK('A', 'N', 'S', 'Q')
+#define IFF_ATAK_CHUNK FOURCC_CHUNK('A', 'T', 'A', 'K')
+#define IFF_AUTH_CHUNK FOURCC_CHUNK('A', 'U', 'T', 'H')
+#define IFF_BMHD_CHUNK FOURCC_CHUNK('B', 'M', 'H', 'D')
+#define IFF_BODY_CHUNK FOURCC_CHUNK('B', 'O', 'D', 'Y')
+#define IFF_CAMG_CHUNK FOURCC_CHUNK('C', 'A', 'M', 'G')
+#define IFF_CCRT_CHUNK FOURCC_CHUNK('C', 'C', 'R', 'T')
+#define IFF_CHAN_CHUNK FOURCC_CHUNK('C', 'H', 'A', 'N')
+#define IFF_CMAP_CHUNK FOURCC_CHUNK('C', 'M', 'A', 'P')
+#define IFF_COPY_CHUNK FOURCC_CHUNK('(', 'c', ')', ' ')
+#define IFF_CRNG_CHUNK FOURCC_CHUNK('C', 'R', 'N', 'G')
+#define IFF_DEST_CHUNK FOURCC_CHUNK('D', 'E', 'S', 'T')
+#define IFF_DLTA_CHUNK FOURCC_CHUNK('D', 'L', 'T', 'A')
+#define IFF_DPAN_CHUNK FOURCC_CHUNK('D', 'P', 'A', 'N')
+#define IFF_DPI_CHUNK FOURCC_CHUNK('D', 'P', 'I', ' ')
+#define IFF_DPPS_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'S')
+#define IFF_DPPV_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'V')
+#define IFF_DRNG_CHUNK FOURCC_CHUNK('D', 'R', 'N', 'G')
+#define IFF_FACE_CHUNK FOURCC_CHUNK('F', 'A', 'C', 'E')
+#define IFF_FADE_CHUNK FOURCC_CHUNK('F', 'A', 'D', 'E')
+#define IFF_FORM_CHUNK FOURCC_CHUNK('F', 'O', 'R', 'M')
+#define IFF_FVER_CHUNK FOURCC_CHUNK('F', 'V', 'E', 'R')
+#define IFF_GRAB_CHUNK FOURCC_CHUNK('G', 'R', 'A', 'B')
+#define IFF_ILBM_CHUNK FOURCC_CHUNK('I', 'L', 'B', 'M')
+#define IFF_INS1_CHUNK FOURCC_CHUNK('I', 'N', 'S', '1')
+#define IFF_IMRT_CHUNK FOURCC_CHUNK('I', 'M', 'R', 'T')
+#define IFF_JUNK_CHUNK FOURCC_CHUNK('J', 'U', 'N', 'K')
+#define IFF_LIST_CHUNK FOURCC_CHUNK('L', 'I', 'S', 'T')
+#define IFF_MHDR_CHUNK FOURCC_CHUNK('M', 'H', 'D', 'R')
+#define IFF_NAME_CHUNK FOURCC_CHUNK('N', 'A', 'M', 'E')
+#define IFF_PAN_CHUNK FOURCC_CHUNK('P', 'A', 'N', ' ')
+#define IFF_PROP_CHUNK FOURCC_CHUNK('P', 'R', 'O', 'P')
+#define IFF_RLSE_CHUNK FOURCC_CHUNK('R', 'L', 'S', 'E')
+#define IFF_SAMP_CHUNK FOURCC_CHUNK('S', 'A', 'M', 'P')
+#define IFF_SEQN_CHUNK FOURCC_CHUNK('S', 'E', 'Q', 'N')
+#define IFF_SHDR_CHUNK FOURCC_CHUNK('S', 'H', 'D', 'R')
+#define IFF_SMUS_CHUNK FOURCC_CHUNK('S', 'M', 'U', 'S')
+#define IFF_SPRT_CHUNK FOURCC_CHUNK('S', 'P', 'R', 'T')
+#define IFF_TEXT_CHUNK FOURCC_CHUNK('T', 'E', 'X', 'T')
+#define IFF_TINY_CHUNK FOURCC_CHUNK('T', 'I', 'N', 'Y')
+#define IFF_TRAK_CHUNK FOURCC_CHUNK('T', 'R', 'A', 'K')
+#define IFF_VHDR_CHUNK FOURCC_CHUNK('V', 'H', 'D', 'R')
+
+/* IFF-ILBM Definitions */
+
+/* Use this constant instead of sizeof(ColorRegister). */
+#define PIC_SIZE_OF_COLOR_REGISTER 3
+
+/* Maximum number of bitplanes storable in BitMap structure */
+#define PIC_MAXAMDEPTH 8
+
+/* Maximum planes we can save */
+#define PIC_MAXSAVEDEPTH 24
+
+/* Masking techniques */
+#define PIC_MASK_NONE 0
+#define PIC_MASK_HASMASK 1
+#define PIC_MASK_HASTRANSPARENTMASK 2
+#define PIC_MASK_LASSO 3
+
+/* Compression techniques */
+#define PIC_COMPRESSION_NONE 0
+#define PIC_COMPRESSION_BYTERUN1 1
+
+#define VIDEOBUFSIZE 128*1024
+
+#define CAMG_LACE 0x0004 /* Interlaced Modi */
+#define CAMG_EHB 0x0080 /* extra halfe brite */
+#define CAMG_HAM 0x0800 /* hold and modify */
+#define CAMG_HIRES 0x8000 /* Hires Modi */
+
+#define CAMG_PAL 0x00021000 /* Hires Modi */
+#define CAMG_NTSC 0x00011000 /* Hires Modi */
+
+#define HAMBITS_CMAP 0 /* take color from colormap */
+#define HAMBITS_BLUE 1 /* modify blue component */
+#define HAMBITS_RED 2 /* modify red component */
+#define HAMBITS_GREEN 3 /* modify green component */
+
+int bitplainoffeset[] = { 1, 2, 4, 8,
+ 16, 32, 64, 128,
+ 1, 2, 4, 8,
+ 16, 32, 64, 128,
+ 1, 2, 4, 8,
+ 16, 32, 64, 128
+ };
+
+/* ---------- BitMapHeader ---------------------------------------------*/
+/* Required Bitmap header (BMHD) structure describes an ILBM */
+typedef struct {
+ uint16_t w; /* raster width in pixels */
+ uint16_t h; /* raster height in pixels */
+ int16_t x; /* raster width in pixels */
+ int16_t y; /* raster height in pixels */
+ uint8_t nplanes; /* # source bitplanes */
+ uint8_t masking; /* masking technique */
+ uint8_t compression; /* compression algoithm */
+ uint8_t pad1; /* UNUSED. For consistency, put 0 here. */
+ uint16_t transparentColor; /* transparent "color number" */
+ uint8_t xaspect; /* aspect ratio, a rational number x/y */
+ uint8_t yaspect; /* aspect ratio, a rational number x/y */
+ int16_t pagewidth; /* source "page" size in pixels */
+ int16_t pageheight; /* source "page" size in pixels */
+} BitMapHeader;
+
+/* ---------- ColorRegister --------------------------------------------*/
+/* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */
+typedef struct {
+ uint8_t cmap_red; /* red color component */
+ uint8_t cmap_green; /* green color component */
+ uint8_t cmap_blue; /* blue color component */
+} ColorRegister;
+
+/* ---------- Point2D --------------------------------------------------*/
+/* A Point2D is stored in a GRAB chunk. */
+typedef struct {
+ int16_t x; /* coordinates x pixels */
+ int16_t y; /* coordinates y pixels */
+} Point2D;
+
+/* ---------- DestMerge ------------------------------------------------*/
+/* A DestMerge is stored in a DEST chunk. */
+typedef struct {
+ uint8_t depth; /* # bitplanes in the original source */
+ uint8_t pad1; /* UNUSED; for consistency store 0 here */
+ uint16_t plane_pick; /* how to scatter source bitplanes into destination */
+ uint16_t plane_onoff; /* default bitplane data for planePick */
+ uint16_t plane_mask; /* selects which bitplanes to store into */
+} DestMerge;
+
+/* ---------- SpritePrecedence -----------------------------------------*/
+/* A SpritePrecedence is stored in a SPRT chunk. */
+typedef uint16_t SpritePrecedence;
+
+/* ---------- Camg Amiga Viewport Mode Display ID ----------------------*/
+/* The CAMG chunk is used to store the Amiga display mode in which
+ * an ILBM is meant to be displayed. This is very important, especially
+ * for special display modes such as HAM and HALFBRITE where the
+ * pixels are interpreted differently.
+ * Under V37 and higher, store a 32-bit Amiga DisplayID (aka. ModeID)
+ * in the ULONG ViewModes CAMG variable (from GetVPModeID(viewport)).
+ * Pre-V37, instead store the 16-bit viewport->Modes.
+ * See the current IFF manual for information on screening for bad CAMG
+ * chunks when interpreting a CAMG as a 32-bit DisplayID or 16-bit ViewMode.
+ * The chunk's content is declared as a ULONG.
+ */
+typedef struct {
+ uint32_t view_modes;
+} CamgChunk;
+
+/* ---------- CRange cycling chunk -------------------------------------*/
+#define RNG_NORATE 36 /* Dpaint uses this rate to mean non-active */
+/* A CRange is store in a CRNG chunk. */
+typedef struct {
+ int16_t pad1; /* reserved for future use; store 0 here */
+ int16_t rate; /* 60/sec=16384, 30/sec=8192, 1/sec=16384/60=273 */
+ int16_t active; /* bit0 set = active, bit 1 set = reverse */
+ uint8_t low; /* lower color registers selected */
+ uint8_t high; /* upper color registers selected */
+} CRange;
+
+/* ---------- Ccrt (Graphicraft) cycling chunk -------------------------*/
+/* A Ccrt is stored in a CCRT chunk. */
+typedef struct {
+ int16_t direction; /* 0=don't cycle, 1=forward, -1=backwards */
+ uint8_t start; /* range lower */
+ uint8_t end; /* range upper */
+ int32_t seconds; /* seconds between cycling */
+ int32_t microseconds; /* msecs between cycling */
+ int16_t pad; /* future exp - store 0 here */
+} CcrtChunk;
+
+/* ---------- DPIHeader chunk ------------------------------------------*/
+/* A DPIHeader is stored in a DPI chunk. */
+typedef struct {
+ int16_t x;
+ int16_t y;
+} DPIHeader;
+
+/* IFF-8SVX/16SV Definitions */
+
+#define MONO 0L
+#define PAN 1L
+#define LEFT 2L
+#define RIGHT 4L
+#define STEREO 6L
+
+#define SND_COMPRESSION_NONE 0
+#define SND_COMPRESSION_FIBONACCI 1
+#define SND_COMPRESSION_EXPONENTIAL 2
+
+#define PREAMBLE_SIZE 8
+#define IFF_JUNK_SIZE 8
+#define IFF_SIGNATURE_SIZE 12
+#define PCM_BLOCK_ALIGN 1024
+
+#define max_volume 65536 /* Unity = Fixed 1.0 = maximum volume */
+
+int8_t fibonacci[] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 };
+
+int8_t exponential[] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 };
+
+typedef struct {
+ uint32_t oneShotHiSamples; /* # samples in the high octave 1-shot part */
+ uint32_t repeatHiSamples; /* # samples in the high octave repeat part */
+ uint32_t samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */
+ uint16_t samplesPerSec; /* data sampling rate */
+ uint8_t ctOctave; /* # of octaves of waveforms */
+ uint8_t sCompression; /* data compression technique used */
+ uint32_t volume; /* playback nominal volume from 0 to Unity
+ * (full volume). Map this value into
+ * the output hardware's dynamic range.
+ */
+} Voice8Header;
+
+typedef struct {
+ uint16_t duration; /* segment duration in milliseconds */
+ uint32_t dest; /* destination volume factor */
+} EGPoint;
+
+/* IFF-ANIM Definitions */
+
+#define IFF_ANHD_ILBM 0
+#define IFF_ANHD_XOR 1
+#define IFF_ANHD_LDELTA 2
+#define IFF_ANHD_SDELTA 3
+#define IFF_ANHD_SLDELTA 4
+#define IFF_ANHD_BVDELTA 5
+#define IFF_ANHD_STEREOO5 6
+#define IFF_ANHD_ASCIIJ 74
+
+/* ---------- AnimHeader ----------------------------------------------*/
+/* Required Anim Header (anhd) structure describes an ANIM-Frame */
+typedef struct {
+ uint8_t operation; /* The compression method:
+ * 0 set directly (normal ILBM BODY),
+ * 1 XOR ILBM mode,
+ * 2 Long Delta mode,
+ * 3 Short Delta mode,
+ * 4 Generalized short/long Delta mode,
+ * 5 Byte Vertical Delta mode
+ * 6 Stereo op 5 (third party)
+ * 74 (ascii 'J') reserved for Eric Graham's
+ * compression technique
+ */
+ uint8_t mask; /* (XOR mode only - plane mask where each
+ * bit is set =1 if there is data and =0
+ * if not.)
+ */
+ uint16_t w; /* (XOR mode only - width and height of the */
+ uint16_t h; /* area represented by the BODY to eliminate */
+ /* unnecessary un-changed data) */
+ int16_t x; /* (XOR mode only - position of rectangular */
+ int16_t y; /* area representd by the BODY) */
+ uint32_t abs_time; /* (currently unused - timing for a frame */
+ /* relative to the time the first frame */
+ /* was displayed - in jiffies (1/60 sec)) */
+ uint32_t rel_time; /* (timing for frame relative to time */
+ /* previous frame was displayed - in */
+ /* jiffies (1/60 sec)) */
+ uint8_t interleave; /* (unused so far - indicates how may frames */
+ /* back this data is to modify. =0 defaults */
+ /* to indicate two frames back (for double */
+ /* buffering). =n indicates n frames back. */
+ /* The main intent here is to allow values */
+ /* of =1 for special applications where */
+ /* frame data would modify the immediately */
+ /* previous frame) */
+ uint8_t pad0; /* Pad byte, not used at present. */
+ uint32_t bits; /* 32 option bits used by options=4 and 5. */
+ /* At present only 6 are identified, but the */
+ /* rest are set =0 so they can be used to */
+ /* implement future ideas. These are defined*/
+ /* for option 4 only at this point. It is */
+ /* recommended that all bits be set =0 for */
+ /* option 5 and that any bit settings */
+ /* used in the future (such as for XOR mode) */
+ /* be compatible with the option 4 */
+ /* bit settings. Player code should check */
+ /*undefined bits in options 4 and 5 to assure*/
+ /* they are zero. */
+ /* */
+ /* The six bits for current use are: */
+ /* */
+ /* bit # set =0 set =1 */
+ /* ========================================= */
+ /* 0 short data long data */
+ /* 1 set XOR */
+ /* 2 separate info one info list */
+ /* for each plane for all planes*/
+ /* 3 not RLC RLC(run length c.)*/
+ /* 4 horizontal vertical */
+ /* 5 short info offsets long info offs.*/
+ uint8_t pad[16]; /* This is a pad for future use for future */
+ /* compression modes. */
+} AnimHeader;
+
+/* ---------- DPAnim-Chunk ----------------------------------------------*/
+/* Deluxe Paint Anim (DPAN) Chunk */
+typedef struct {
+ uint16_t version; /* Version */
+ uint16_t nframes; /* number of frames in the animation.*/
+ uint8_t fps; /* frames per second */
+ uint8_t unused1;
+ uint8_t unused2;
+ uint8_t unused3;
+} DPAnimChunk;
+
+#endif /* IFFP_IFF_H */
diff --git a/src/libxinevdec/bitplane.c b/src/libxinevdec/bitplane.c
index cbc78760a..f97b2174a 100644
--- a/src/libxinevdec/bitplane.c
+++ b/src/libxinevdec/bitplane.c
@@ -22,7 +22,7 @@
* suitable for display under xine. It's based on the rgb-decoder
* and the development documentation from the Amiga Developer CD
*
- * $Id: bitplane.c,v 1.2 2004/02/09 22:04:11 jstembridge Exp $
+ * $Id: bitplane.c,v 1.3 2004/02/22 12:36:37 manfredtremmel Exp $
*/
#include <stdio.h>
@@ -37,25 +37,28 @@
#include "xineutils.h"
#include "bswap.h"
-#define VIDEOBUFSIZE 128*1024
-
-#define CAMG_LACE 0x0004 /* Interlaced Modi */
-#define CAMG_EHB 0x0080 /* extra halfe brite */
-#define CAMG_HAM 0x0800 /* hold and modify */
-#define CAMG_HIRES 0x8000 /* Hires Modi */
-
-#define HAMBITS_CMAP 0 /* take color from colormap */
-#define HAMBITS_BLUE 1 /* modify blue component */
-#define HAMBITS_RED 2 /* modify red component */
-#define HAMBITS_GREEN 3 /* modify green component */
-
-int bitplainoffeset[] = { 1, 2, 4, 8,
- 16, 32, 64, 128,
- 1, 2, 4, 8,
- 16, 32, 64, 128,
- 1, 2, 4, 8,
- 16, 32, 64, 128
- };
+#include "demuxers/iff.h"
+
+#define IFF_REPLACE_BYTE(ptr, old_data, new_data, colorindex ) { \
+ register uint8_t *index_ptr = ptr; \
+ *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \
+ *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \
+ *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \
+ *index_ptr += ((new_data & 0x01) ? colorindex : 0); \
+ old_data = new_data; \
+}
typedef struct {
video_decoder_class_t decoder_class;
@@ -64,7 +67,7 @@ typedef struct {
typedef struct bitplane_decoder_s {
video_decoder_t video_decoder; /* parent video decoder structure */
- bitplane_class_t *class;
+ bitplane_class_t *class;
xine_stream_t *stream;
/* these are traditional variables in a video decoder object */
@@ -75,12 +78,14 @@ typedef struct bitplane_decoder_s {
unsigned char *buf; /* the accumulated buffer data */
int bufsize; /* the maximum size of buf */
int size; /* the current size of buf */
+ int size_uk; /* size of unkompressed bitplane */
int width_decode;/* the width of a video frame decoding*/
int width; /* the width of a video frame */
int height; /* the height of a video frame */
double ratio; /* the width to height ratio */
int bytes_per_pixel;
+ int full_bytes_per_pixel;
int num_bitplanes;
int camg_mode;
@@ -88,29 +93,318 @@ typedef struct bitplane_decoder_s {
unsigned char rgb_palette[256 * 4];
yuv_planes_t yuv_planes;
+ uint8_t *buf_uk; /* uncompressed buffer */
+ uint8_t *buf_uk_hist; /* uncompressed buffer historic */
+ uint8_t *index_buf; /* index buffer (for indexed pics) */
+ uint8_t *index_buf_hist;/* index buffer historic */
+ uint8_t *rgb_buf; /* rgb buffer (for HAM and TrueColor) */
+
} bitplane_decoder_t;
+/* create a new buffer and decde a byterun1 decoded buffer into it */
+static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed,
+ int size_compressed,
+ int size_uncompressed) {
+
+ /* BytRun1 decompression */
+ int pixel_ptr = 0;
+ int i = 0;
+ int j = 0;
+
+ uint8_t *uncompressed = xine_xmalloc( size_uncompressed );
+
+ while ( i < size_compressed &&
+ pixel_ptr < size_uncompressed ) {
+ if( compressed[i] <= 127 ) {
+ j = compressed[i++];
+ if( (i+j) > size_compressed )
+ return NULL;
+ for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) {
+ uncompressed[pixel_ptr++] = compressed[i++];
+ }
+ } else if ( compressed[i] > 128 ) {
+ j = 256 - compressed[i++];
+ if( i >= size_compressed )
+ return NULL;
+ for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) {
+ uncompressed[pixel_ptr++] = compressed[i];
+ }
+ i++;
+ }
+ }
+ return uncompressed;
+}
+
+/* create a new buffer with "normal" index or rgb numbers out of a bitplane */
+static uint8_t *bitplane_decode_bitplane (uint8_t *bitplane_buffer,
+ uint8_t *index_buf,
+ int width,
+ int height,
+ int num_bitplanes,
+ int bytes_per_pixel ) {
+
+ int rowsize = width / 8;
+ int pixel_ptr = 0;
+ int row_ptr = 0;
+ int palette_index = 0;
+ int i = 0;
+ int j = 0;
+ uint8_t color = 0;
+ uint8_t data = 0;
+
+ for (i = 0; i < (width * height * bytes_per_pixel); index_buf[i++] = 0);
+
+ /* decode Bitplanes to RGB/Index Numbers */
+ for (row_ptr = 0; row_ptr < height; row_ptr++) {
+ for (palette_index = 0; palette_index < num_bitplanes; palette_index++) {
+ for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) {
+ i = (row_ptr * width * bytes_per_pixel) +
+ (pixel_ptr * bytes_per_pixel * 8) +
+ ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0);
+ j = (row_ptr * rowsize * num_bitplanes) +
+ (palette_index * rowsize) +
+ pixel_ptr;
+ color = bitplainoffeset[palette_index];
+ data = bitplane_buffer[j];
+
+ index_buf[i] += ((data & 0x80) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x40) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x20) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x10) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x08) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x04) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x02) ? color : 0);
+ i += bytes_per_pixel;
+ index_buf[i] += ((data & 0x01) ? color : 0);
+ }
+ }
+ }
+ return index_buf;
+}
+
+/* create Buffer decode HAM6 and HAM8 to 24 Bit RGB color */
+static uint8_t *bitplane_decode_ham (uint8_t *ham_buffer,
+ uint8_t *truecolor_buf,
+ int width,
+ int height,
+ int num_bitplanes,
+ int bytes_per_pixel,
+ unsigned char *rgb_palette ) {
+
+ int pixel_ptr = 0;
+ int row_ptr = 0;
+ int buf_ptr = 0;
+ int i = 0;
+ int j = 0;
+ unsigned char r = 0;
+ unsigned char g = 0;
+ unsigned char b = 0;
+ /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */
+ int hambits = num_bitplanes > 6 ? 6 : 4;
+ /* the other bits contain the real data, dreate a mask out of it */
+ int maskbits = 8 - hambits;
+ int mask = ( 1 << hambits ) - 1;
+
+ for (row_ptr = 0; row_ptr < height; row_ptr++) {
+ for (pixel_ptr = 0; pixel_ptr < width; pixel_ptr++) {
+ i = (row_ptr * width) + pixel_ptr;
+ buf_ptr = (row_ptr * width * bytes_per_pixel) +
+ (pixel_ptr * bytes_per_pixel);
+ j = ham_buffer[i];
+ switch ( j >> hambits ) {
+ case HAMBITS_CMAP:
+ /* Take colors from palette */
+ r = rgb_palette[(j & mask) * 4 + 0];
+ g = rgb_palette[(j & mask) * 4 + 1];
+ b = rgb_palette[(j & mask) * 4 + 2];
+ break;
+ case HAMBITS_BLUE:
+ /* keep red and green and modify blue */
+ b = ( j & mask ) << maskbits;
+ b |= b >> hambits;
+ break;
+ case HAMBITS_RED:
+ /* keep green and blue and modify red */
+ r = ( j & mask ) << maskbits;
+ r |= r >> hambits;
+ break;
+ case HAMBITS_GREEN:
+ /* keep red and blue and modify green */
+ g = ( j & mask ) << maskbits;
+ g |= g >> hambits;
+ break;
+ default:
+ break;
+ }
+ /* put colors to buffer */
+ truecolor_buf[buf_ptr++] = r;
+ truecolor_buf[buf_ptr++] = g;
+ truecolor_buf[buf_ptr] = b;
+ }
+ }
+
+ return truecolor_buf;
+}
+
+/* decoding method 4 */
+static void bitplane_set_dlta_short (uint8_t *current_buffer,
+ uint8_t *index_buf,
+ /* uint8_t *delta_buffer,*/
+ uint8_t *delta,
+ /*int delta_buf_size,*/
+ int dsize,
+ int width,
+ int height,
+ int num_bitplanes ) {
+
+ uint32_t rowsize = width / 8;
+
+ uint32_t palette_index = 0;
+ uint32_t *deltadata = (uint32_t *)delta;
+ uint16_t *ptr = NULL;
+ uint16_t *planeptr = NULL;
+ uint16_t *data = NULL;
+ uint16_t *dest = NULL;
+ int32_t s = 0;
+ int32_t size = 0;
+ int32_t nw = rowsize >> 1;
+
+ /* Repeat for each plane */
+ for(palette_index = 0; palette_index < num_bitplanes; palette_index++) {
+
+ planeptr = (uint16_t *)(&current_buffer[(palette_index * rowsize)]);
+ /* data starts at beginn of delta-Buffer + offset of the first */
+ /* 32 Bit long word in the buffer. The buffer starts with 8 */
+ /* of this Offset, for every bitplane (max 8) one */
+ data = (uint16_t *)(delta + BE_32(&deltadata[palette_index]));
+ /* This 8 Pointers are followd by another 8 */
+ ptr = (uint16_t *)(delta + BE_32(&deltadata[(palette_index+8)]));
+
+ /* in this case, I think big/little endian is not important ;-) */
+ while( *ptr != 0xFFFF) {
+ dest = planeptr + BE_16(ptr++);
+ size = BE_16(ptr++);
+ if (size < 0) {
+ for (s = size; s < 0; s++) {
+ *dest = *data;
+ dest += nw;
+ }
+ data++;
+ }
+ else {
+ for (s = 0; s < size; s++) {
+ *dest = *data++;
+ dest += nw;
+ }
+ }
+ }
+ }
+ bitplane_decode_bitplane(current_buffer, index_buf, width, height, num_bitplanes, 1);
+}
+
+/* decoding method 5 */
+static void bitplane_dlta_5 (uint8_t *current_buffer,
+ uint8_t *index_buf,
+ uint8_t *delta,
+ int dsize,
+ int width,
+ int height,
+ int num_bitplanes ) {
+
+ uint32_t rowsize = width / 8;
+ uint32_t rowsize_all_planes = rowsize * num_bitplanes;
+
+ uint32_t delta_offset = 0;
+ uint32_t palette_index = 0;
+ uint32_t pixel_ptr = 0;
+ uint32_t row_ptr = 0;
+ uint32_t *deltadata = (uint32_t *)delta;
+ uint8_t *planeptr = NULL;
+ uint8_t *rowworkptr = NULL;
+ uint8_t *picture_end = current_buffer + (rowsize_all_planes * height);
+ uint8_t *data = NULL;
+ uint8_t *data_end = delta + dsize;
+ uint8_t op_count = 0;
+ uint8_t op = 0;
+ uint8_t count = 0;
+
+ /* Repeat for each plane */
+ for(palette_index = 0; palette_index < num_bitplanes; palette_index++) {
+
+ planeptr = &current_buffer[(palette_index * rowsize)];
+ /* data starts at beginn of delta-Buffer + offset of the first */
+ /* 32 Bit long word in the buffer. The buffer starts with 8 */
+ /* of this Offset, for every bitplane (max 8) one */
+ delta_offset = BE_32(&deltadata[palette_index]);
+
+ if (delta_offset > 0) {
+ data = delta + delta_offset;
+ for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) {
+ rowworkptr = planeptr + pixel_ptr;
+ row_ptr = 0;
+ /* execute ops */
+ for( op_count = *data++; op_count; op_count--) {
+ op = *data++;
+ if (op & 0x80) {
+ /* Uniq ops */
+ count = op & 0x7f; /* get count */
+ while(count--) {
+ if (data > data_end || rowworkptr > picture_end)
+ return;
+ IFF_REPLACE_BYTE( &index_buf[((row_ptr * width) + (pixel_ptr * 8))],
+ *rowworkptr, *data, bitplainoffeset[palette_index] );
+ *rowworkptr = *data++;
+ rowworkptr += rowsize_all_planes;
+ row_ptr++;
+ }
+ } else {
+ if (op == 0) {
+ /* Same ops */
+ count = *data++;
+ while(count--) {
+ if (data > data_end || rowworkptr > picture_end)
+ return;
+ IFF_REPLACE_BYTE( &index_buf[((row_ptr * width) + (pixel_ptr * 8))],
+ *rowworkptr, *data, bitplainoffeset[palette_index] );
+ *rowworkptr = *data;
+ rowworkptr += rowsize_all_planes;
+ row_ptr++;
+ }
+ data++;
+ } else {
+ /* Skip ops */
+ rowworkptr += (rowsize_all_planes * op);
+ row_ptr += op;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
static void bitplane_decode_data (video_decoder_t *this_gen,
buf_element_t *buf) {
bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen;
xine_bmiheader *bih = 0;
palette_entry_t *palette = 0;
+ AnimHeader *anhd = NULL;
int i = 0;
int j = 0;
int pixel_ptr = 0;
int row_ptr = 0;
- int palette_index = 0;
int buf_ptr = 0;
- int hambits = 0;
- int maskbits = 0;
- int mask = 0;
unsigned char r = 0;
unsigned char g = 0;
unsigned char b = 0;
- uint8_t *bitmap_buf = 0;
- uint8_t *index_buf = 0;
- uint8_t *decoded_buf = 0;
+ uint8_t *buf_exchange = NULL;
vo_frame_t *img = 0; /* video out frame */
@@ -155,11 +449,6 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
return;
}
-
- if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
- this->video_step = buf->decoder_info[0];
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step);
- }
if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */
this->stream->video_out->open (this->stream->video_out, this->stream);
@@ -172,10 +461,26 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
this->width_decode = (bih->biWidth + 15) & ~0x0f;
this->height = bih->biHeight;
this->ratio = (double)this->width/(double)this->height;
+ this->video_step = buf->decoder_info[1];
/* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */
this->bytes_per_pixel = (bih->biBitCount + 1) / 8;
if( this->bytes_per_pixel < 1 )
this->bytes_per_pixel = 1;
+ if(bih->biCompression & CAMG_HAM )
+ this->full_bytes_per_pixel = 3;
+ else
+ this->full_bytes_per_pixel = this->bytes_per_pixel;
+
+ /* New Buffer for indexes (palette based formats) */
+ if( this->bytes_per_pixel < 3 )
+ {
+ this->index_buf = xine_xmalloc( (this->width_decode * this->height * this->bytes_per_pixel) );
+ this->index_buf_hist = xine_xmalloc( (this->width_decode * this->height * this->bytes_per_pixel) );
+ }
+
+ /* New Buffer for RGB Colors */
+ if(this->full_bytes_per_pixel > 1)
+ this->rgb_buf = xine_xmalloc( (this->width_decode * this->height * this->full_bytes_per_pixel) );
this->num_bitplanes = bih->biPlanes;
this->camg_mode = bih->biCompression;
@@ -188,13 +493,13 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
if( (bih->biCompression & CAMG_HIRES) &&
!(bih->biCompression & CAMG_LACE) ) {
- if( (buf->decoder_info[2] * 18) > (buf->decoder_info[3] * 10) )
+ if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) )
this->ratio /= 2.0;
}
if( !(bih->biCompression & CAMG_HIRES) &&
(bih->biCompression & CAMG_LACE) ) {
- if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 18) )
+ if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) )
this->ratio *= 2.0;
}
@@ -234,6 +539,9 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
this->size += buf->size;
+ if (buf->decoder_flags & BUF_FLAG_FRAMERATE)
+ this->video_step = buf->decoder_info[0];
+
if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
img = this->stream->video_out->get_frame (this->stream->video_out,
@@ -244,163 +552,159 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
img->duration = this->video_step;
img->pts = buf->pts;
img->bad_frame = 0;
-
- /* iterate through each row */
- buf_ptr = 0;
-
- switch( buf->type ) {
- case BUF_VIDEO_BITPLANE:
- /* uncompressed Buffer, set decoded_buf pointer direct to input stream */
- decoded_buf = this->buf;
- break;
- case BUF_VIDEO_BITPLANE_BR1:
- /* create Buffer for decompressed bitmap */
- bitmap_buf = xine_xmalloc( ((this->width_decode * this->height) / 8) * this->num_bitplanes );
- /* BytRun1 decompression */
- pixel_ptr = 0;
- i = 0;
- while ( i < this->size &&
- pixel_ptr < (this->width_decode * this->height * this->bytes_per_pixel) ) {
- if( this->buf[i] <= 127 ) {
- j = this->buf[i++];
- if( (i+j) > this->size ) {
- xine_log(this->stream->xine, XINE_LOG_MSG,
- _("bitplane: error doing ByteRun1 decompression(1)\n"));
- free(bitmap_buf);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
- return;
- }
- for( ; j >= 0; j-- ) {
- bitmap_buf[pixel_ptr++] = this->buf[i++];
- }
- } else if ( this->buf[i] > 128 ) {
- j = 256 - this->buf[i++];
- if( i >= this->size ) {
- xine_log(this->stream->xine, XINE_LOG_MSG,
- _("bitplane: error doing ByteRun1 decompression(2)\n"));
- free(bitmap_buf);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
- return;
- }
- for( ; j >= 0; j-- ) {
- bitmap_buf[pixel_ptr++] = this->buf[i];
- }
- i++;
+ anhd = (AnimHeader *)(buf->decoder_info_ptr[0]);
+
+ if( (this->buf_uk == NULL) ||
+ (anhd == NULL) ||
+ (anhd->operation == IFF_ANHD_ILBM) ) {
+
+ /* iterate through each row */
+ buf_ptr = 0;
+ this->size_uk = (((this->width_decode * this->height) / 8) * this->num_bitplanes);
+
+ if( this->buf_uk_hist != NULL )
+ xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk);
+ switch( buf->type ) {
+ case BUF_VIDEO_BITPLANE:
+ /* uncompressed Buffer, set decoded_buf pointer direct to input stream */
+ if( this->buf_uk == NULL )
+ this->buf_uk = xine_xmalloc( (this->size) );
+ xine_fast_memcpy (this->buf_uk, this->buf, this->size);
+ break;
+ case BUF_VIDEO_BITPLANE_BR1:
+ /* create Buffer for decompressed bitmap */
+ this->buf_uk = bitplane_decode_byterun1(
+ this->buf, /* compressed buffer */
+ this->size, /* size of compressed data */
+ this->size_uk ); /* size of uncompressed data */
+
+ if( this->buf_uk == NULL ) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: error doing ByteRun1 decompression\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
}
- }
- /* set pointer to decompressed Buffer */
- decoded_buf = bitmap_buf;
- break;
- }
-
- /* New Buffer for index (palette based formats) or RGB Colors */
- index_buf = xine_xmalloc( (this->width_decode * this->height * this->bytes_per_pixel) );
-
- /* decode Bitplanes to RGB/Index Numbers */
- for (row_ptr = 0; row_ptr < this->height; row_ptr++) {
- for (palette_index = 0; palette_index < this->num_bitplanes; palette_index++) {
- for (pixel_ptr = 0; pixel_ptr < (this->width_decode / 8); pixel_ptr++) {
- i = (row_ptr * this->width_decode * this->bytes_per_pixel) +
- (pixel_ptr * this->bytes_per_pixel * 8) +
- ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0);
- j = (row_ptr * (this->width_decode / 8) * this->num_bitplanes) +
- (palette_index * (this->width_decode / 8)) +
- pixel_ptr;
- index_buf[i] += ((decoded_buf[j] & 0x80) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x40) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x20) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x10) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x08) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x04) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x02) ? bitplainoffeset[palette_index] : 0);
- i += this->bytes_per_pixel;
- index_buf[i] += ((decoded_buf[j] & 0x01) ? bitplainoffeset[palette_index] : 0);
- }
+ /* set pointer to decompressed Buffer */
+ break;
+ default:
+ break;
+ }
+ if( this->bytes_per_pixel > 1 )
+ bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */
+ this->rgb_buf, /* rgb buffer, direct 24Bit*/
+ this->width_decode, /* width */
+ this->height, /* hight */
+ this->num_bitplanes, /* number bitplanes */
+ this->bytes_per_pixel); /* used Bytes per pixel */
+ else
+ bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */
+ this->index_buf, /* index buffer */
+ this->width_decode, /* width */
+ this->height, /* hight */
+ this->num_bitplanes, /* number bitplanes */
+ this->bytes_per_pixel); /* used Bytes per pixel */
+
+ if( this->buf_uk_hist == NULL ) {
+ this->buf_uk_hist = xine_xmalloc( (this->size_uk) );
+ xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk);
+ xine_fast_memcpy (this->index_buf_hist, this->index_buf,
+ (this->width_decode * this->height * this->bytes_per_pixel));
}
+ } else {
+ switch( anhd->operation ) {
+ /* also known as IFF-ANIM OPT1 (never seen in real world) */
+ case IFF_ANHD_XOR:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: Anim Opt 1 is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ /* also known as IFF-ANIM OPT2 (never seen in real world) */
+ case IFF_ANHD_LDELTA:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: Anim Opt 2 is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ /* also known as IFF-ANIM OPT3 */
+ case IFF_ANHD_SDELTA:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: Anim Opt 3 is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ /* also known as IFF-ANIM OPT4 (never seen in real world) */
+ case IFF_ANHD_SLDELTA:
+ _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)");
+ bitplane_set_dlta_short ( this->buf_uk_hist,
+ this->index_buf_hist,
+ this->buf,
+ this->size,
+ this->width,
+ this->height,
+ this->num_bitplanes);
+ break;
+ /* also known as IFF-ANIM OPT5 */
+ case IFF_ANHD_BVDELTA:
+ _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)");
+ bitplane_dlta_5 ( this->buf_uk_hist,
+ this->index_buf_hist,
+ this->buf,
+ this->size,
+ this->width,
+ this->height,
+ this->num_bitplanes);
+ break;
+ case IFF_ANHD_STEREOO5:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: Anim Opt 6 is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ case IFF_ANHD_ASCIIJ:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: Anim Opt 7 is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ default:
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("bitplane: This anim-type is not supported at the moment\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
+ return;
+ break;
+ }
+ /* change old bitmap buffer (which now is the new one) with new buffer */
+ buf_exchange = this->buf_uk;
+ this->buf_uk = this->buf_uk_hist;
+ this->buf_uk_hist = buf_exchange;
+ /* do the same with the index buffer */
+ buf_exchange = this->index_buf;
+ this->index_buf = this->index_buf_hist;
+ this->index_buf_hist = buf_exchange;
}
- /* is there a buffer for uncompressed bitplane? we don't need anymore! */
- if( bitmap_buf > 0 )
- free(bitmap_buf);
- bitmap_buf = 0;
-
/* HAM-pictrues need special handling */
- if( (this->bytes_per_pixel == 1) &&
- (this->camg_mode & CAMG_HAM) ) {
+ if( this->camg_mode & CAMG_HAM ) {
/* HAM-Pictures must always be extended to 24-Bit RGB, so extended buffer is needed */
- this->bytes_per_pixel = 3;
- /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */
- hambits = this->num_bitplanes > 6 ? 6 : 4;
- /* the other bits contain the real data, dreate a mask out of it */
- maskbits = 8 - hambits;
- mask = ( 1 << hambits ) - 1;
-
- /* one more step, make index_buf to decode_buf */
- decoded_buf = index_buf;
- /* and allocate a new index_buf */
- index_buf = xine_xmalloc( (this->width_decode * this->height * this->bytes_per_pixel) );
- for (pixel_ptr = 0; pixel_ptr < (this->width_decode * this->height * this->bytes_per_pixel); pixel_ptr++) {
- index_buf[pixel_ptr] = 0;
- }
-
- for (row_ptr = 0; row_ptr < this->height; row_ptr++) {
- for (pixel_ptr = 0; pixel_ptr < this->width_decode; pixel_ptr++) {
- i = (row_ptr * this->width_decode) + pixel_ptr;
- buf_ptr = (row_ptr * this->width_decode * this->bytes_per_pixel) +
- (pixel_ptr * this->bytes_per_pixel);
- j = decoded_buf[i];
- switch ( j >> hambits ) {
- case HAMBITS_CMAP:
- /* Take colors from palette */
- r = this->rgb_palette[(j & mask) * 4 + 0];
- g = this->rgb_palette[(j & mask) * 4 + 1];
- b = this->rgb_palette[(j & mask) * 4 + 2];
- break;
- case HAMBITS_BLUE:
- /* keep red and green and modify blue */
- b = ( j & mask ) << maskbits;
- b |= b >> hambits;
- break;
- case HAMBITS_RED:
- /* keep green and blue and modify red */
- r = ( j & mask ) << maskbits;
- r |= r >> hambits;
- break;
- case HAMBITS_GREEN:
- /* keep red and blue and modify green */
- g = ( j & mask ) << maskbits;
- g |= g >> hambits;
- break;
- default:
- break;
- }
- /* put colors to buffer */
- index_buf[buf_ptr] = r;
- index_buf[buf_ptr+1] = g;
- index_buf[buf_ptr+2] = b;
- }
- }
- /* free the buffer of the HAM-Picture */
- if( decoded_buf > 0 )
- free(decoded_buf);
- decoded_buf = 0;
+ bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */
+ this->rgb_buf, /* 24 Bit RGB buffer */
+ this->width_decode, /* width */
+ this->height, /* hight */
+ this->num_bitplanes, /* number bitplanes */
+ this->bytes_per_pixel, /* used Bytes per pixel */
+ this->rgb_palette); /* Palette (RGB) */
}
- switch (this->bytes_per_pixel) {
+ switch (this->full_bytes_per_pixel) {
case 1:
for (row_ptr = 0; row_ptr < this->height; row_ptr++) {
for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) {
i = (row_ptr * this->width_decode) + pixel_ptr;
j = (row_ptr * this->width) + pixel_ptr;
- this->yuv_planes.y[j] = this->yuv_palette[index_buf[i] * 4 + 0];
- this->yuv_planes.u[j] = this->yuv_palette[index_buf[i] * 4 + 1];
- this->yuv_planes.v[j] = this->yuv_palette[index_buf[i] * 4 + 2];
+ this->yuv_planes.y[j] = this->yuv_palette[this->index_buf[i] * 4 + 0];
+ this->yuv_planes.u[j] = this->yuv_palette[this->index_buf[i] * 4 + 1];
+ this->yuv_planes.v[j] = this->yuv_palette[this->index_buf[i] * 4 + 2];
}
}
break;
@@ -410,9 +714,9 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
i = (row_ptr * this->width_decode * this->bytes_per_pixel) +
(pixel_ptr * this->bytes_per_pixel);
j = (row_ptr * this->width) + pixel_ptr;
- r = index_buf[i++];
- g = index_buf[i++];
- b = index_buf[i];
+ r = this->rgb_buf[i++];
+ g = this->rgb_buf[i++];
+ b = this->rgb_buf[i];
this->yuv_planes.y[j] = COMPUTE_Y(r, g, b);
this->yuv_planes.u[j] = COMPUTE_U(r, g, b);
@@ -429,10 +733,8 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
img->draw(img, this->stream);
img->free(img);
- if( index_buf > 0 )
- free(index_buf);
this->size = 0;
- if ( buf->decoder_info[1] > 0 )
+ if ( buf->decoder_info[1] > 90000 )
xine_usec_sleep(buf->decoder_info[1]);
}
}
@@ -468,6 +770,31 @@ static void bitplane_dispose (video_decoder_t *this_gen) {
this->buf = NULL;
}
+ if (this->buf_uk) {
+ free (this->buf_uk);
+ this->buf_uk = NULL;
+ }
+
+ if (this->buf_uk_hist) {
+ free (this->buf_uk_hist);
+ this->buf_uk_hist = NULL;
+ }
+
+ if (this->index_buf) {
+ free (this->index_buf);
+ this->index_buf = NULL;
+ }
+
+ if (this->index_buf_hist) {
+ free (this->index_buf_hist);
+ this->index_buf_hist = NULL;
+ }
+
+ if (this->rgb_buf) {
+ free (this->rgb_buf);
+ this->rgb_buf = NULL;
+ }
+
if (this->decoder_ok) {
this->decoder_ok = 0;
this->stream->video_out->close(this->stream->video_out, this->stream);
@@ -492,6 +819,9 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
this->decoder_ok = 0;
this->buf = NULL;
+ this->buf_uk = NULL;
+ this->index_buf = NULL;
+ this->rgb_buf = NULL;
return &this->video_decoder;
}