annotate xan.c @ 3198:6b9f0c4fbdbe libavcodec

First part of a series of speed-enchancing patches. This one sets up a snow.h and makes snow use the dsputil function pointer framework to access the three functions that will be implemented in asm in the other parts of the patchset. Patch by Robert Edele < yartrebo AH earthlink POIS net> Original thread: Subject: [Ffmpeg-devel] [PATCH] Snow mmx+sse2 asm optimizations Date: Sun, 05 Feb 2006 12:47:14 -0500
author gpoirier
date Thu, 16 Mar 2006 19:18:18 +0000
parents 0b546eab515d
children c8c591fe26f8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
1 /*
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
2 * Wing Commander/Xan Video Decoder
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
3 * Copyright (C) 2003 the ffmpeg project
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
4 *
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
9 *
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
13 * Lesser General Public License for more details.
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
14 *
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2967
diff changeset
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
18 *
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
19 */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
20
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
21 /**
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
22 * @file xan.c
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
23 * Xan video decoder for Wing Commander III computer game
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
24 * by Mario Brito (mbrito@student.dei.uc.pt)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
25 * and Mike Melanson (melanson@pcisys.net)
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
26 *
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
27 * The xan_wc3 decoder outputs PAL8 data.
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
28 */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
29
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
30 #include <stdio.h>
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
31 #include <stdlib.h>
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
32 #include <string.h>
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
33 #include <unistd.h>
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
34
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
35 #include "common.h"
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
36 #include "avcodec.h"
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
37
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
38 typedef struct XanContext {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
39
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
40 AVCodecContext *avctx;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
41 AVFrame last_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
42 AVFrame current_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
43
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
44 unsigned char *buf;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
45 int size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
46
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
47 /* scratch space */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
48 unsigned char *buffer1;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
49 int buffer1_size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
50 unsigned char *buffer2;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
51 int buffer2_size;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
52
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
53 int frame_size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
54
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
55 } XanContext;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
56
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
57 static int xan_decode_init(AVCodecContext *avctx)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
58 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
59 XanContext *s = avctx->priv_data;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
60
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
61 s->avctx = avctx;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
62 s->frame_size = 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
63
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
64 if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1476
diff changeset
65 (s->avctx->palctrl == NULL)) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
66 av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
67 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
68 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
69
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
70 avctx->pix_fmt = PIX_FMT_PAL8;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
71 avctx->has_b_frames = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
72
2422
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
73 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
74 return -1;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
75
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
76 s->buffer1_size = avctx->width * avctx->height;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
77 s->buffer1 = av_malloc(s->buffer1_size);
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
78 s->buffer2_size = avctx->width * avctx->height;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
79 s->buffer2 = av_malloc(s->buffer2_size);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
80 if (!s->buffer1 || !s->buffer2)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
81 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
82
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
83 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
84 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
85
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
86 /* This function is used in lieu of memcpy(). This decoder can not use
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
87 * memcpy because the memory locations often overlap and
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
88 * memcpy doesn't like that; it's not uncommon, for example, for
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
89 * dest = src+1, to turn byte A into pattern AAAAAAAA.
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
90 * This was originally repz movsb in Intel x86 ASM. */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
91 static inline void bytecopy(unsigned char *dest, unsigned char *src, int count)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
92 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
93 int i;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
94
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
95 for (i = 0; i < count; i++)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
96 dest[i] = src[i];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
97 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
98
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
99 static int xan_huffman_decode(unsigned char *dest, unsigned char *src,
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
100 int dest_len)
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
101 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
102 unsigned char byte = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
103 unsigned char ival = byte + 0x16;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
104 unsigned char * ptr = src + byte*2;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
105 unsigned char val = ival;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
106 int counter = 0;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
107 unsigned char *dest_end = dest + dest_len;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
108
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
109 unsigned char bits = *ptr++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
110
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
111 while ( val != 0x16 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
112 if ( (1 << counter) & bits )
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
113 val = src[byte + val - 0x17];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
114 else
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
115 val = src[val - 0x17];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
116
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
117 if ( val < 0x16 ) {
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
118 if (dest + 1 > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
119 return 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
120 *dest++ = val;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
121 val = ival;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
122 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
123
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
124 if (counter++ == 7) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
125 counter = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
126 bits = *ptr++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
127 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
128 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
129
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
130 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
131 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
132
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
133 static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len)
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
134 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
135 unsigned char opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
136 int size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
137 int offset;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
138 int byte1, byte2, byte3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
139 unsigned char *dest_end = dest + dest_len;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
140
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
141 for (;;) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
142 opcode = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
143
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
144 if ( (opcode & 0x80) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
145
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
146 offset = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
147
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
148 size = opcode & 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
149 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
150 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
151 bytecopy(dest, src, size); dest += size; src += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
152
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
153 size = ((opcode & 0x1c) >> 2) + 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
154 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
155 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
156 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
157 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
158
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
159 } else if ( (opcode & 0x40) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
160
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
161 byte1 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
162 byte2 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
163
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
164 size = byte1 >> 6;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
165 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
166 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
167 bytecopy (dest, src, size); dest += size; src += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
168
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
169 size = (opcode & 0x3f) + 4;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
170 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
171 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
172 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
173 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
174
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
175 } else if ( (opcode & 0x20) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
176
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
177 byte1 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
178 byte2 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
179 byte3 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
180
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
181 size = opcode & 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
182 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
183 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
184 bytecopy (dest, src, size); dest += size; src += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
185
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
186 size = byte3 + 5 + ((opcode & 0xc) << 6);
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
187 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
188 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
189 bytecopy (dest,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
190 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
191 size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
192 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
193 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
194 size = ((opcode & 0x1f) << 2) + 4;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
195
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
196 if (size > 0x70)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
197 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
198
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
199 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
200 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
201 bytecopy (dest, src, size); dest += size; src += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
202 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
203 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
204
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
205 size = opcode & 3;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
206 bytecopy(dest, src, size); dest += size; src += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
207 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
208
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
209 static void inline xan_wc3_output_pixel_run(XanContext *s,
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
210 unsigned char *pixel_buffer, int x, int y, int pixel_count)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
211 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
212 int stride;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
213 int line_inc;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
214 int index;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
215 int current_x;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
216 int width = s->avctx->width;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
217 unsigned char *palette_plane;
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
218
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
219 palette_plane = s->current_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
220 stride = s->current_frame.linesize[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
221 line_inc = stride - width;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
222 index = y * stride + x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
223 current_x = x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
224 while((pixel_count--) && (index < s->frame_size)) {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
225
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
226 /* don't do a memcpy() here; keyframes generally copy an entire
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
227 * frame of data and the stride needs to be accounted for */
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
228 palette_plane[index++] = *pixel_buffer++;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
229
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
230 current_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
231 if (current_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
232 index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
233 current_x = 0;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
234 }
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
235 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
236 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
237
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
238 static void inline xan_wc3_copy_pixel_run(XanContext *s,
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
239 int x, int y, int pixel_count, int motion_x, int motion_y)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
240 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
241 int stride;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
242 int line_inc;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
243 int curframe_index, prevframe_index;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
244 int curframe_x, prevframe_x;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
245 int width = s->avctx->width;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
246 unsigned char *palette_plane, *prev_palette_plane;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
247
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
248 palette_plane = s->current_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
249 prev_palette_plane = s->last_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
250 stride = s->current_frame.linesize[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
251 line_inc = stride - width;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
252 curframe_index = y * stride + x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
253 curframe_x = x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
254 prevframe_index = (y + motion_y) * stride + x + motion_x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
255 prevframe_x = x + motion_x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
256 while((pixel_count--) && (curframe_index < s->frame_size)) {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
257
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
258 palette_plane[curframe_index++] =
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
259 prev_palette_plane[prevframe_index++];
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
260
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
261 curframe_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
262 if (curframe_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
263 curframe_index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
264 curframe_x = 0;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
265 }
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
266
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
267 prevframe_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
268 if (prevframe_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
269 prevframe_index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
270 prevframe_x = 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
271 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
272 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
273 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
274
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
275 static void xan_wc3_decode_frame(XanContext *s) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
276
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
277 int width = s->avctx->width;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
278 int height = s->avctx->height;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
279 int total_pixels = width * height;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
280 unsigned char opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
281 unsigned char flag = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
282 int size = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
283 int motion_x, motion_y;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
284 int x, y;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
285
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
286 unsigned char *opcode_buffer = s->buffer1;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
287 int opcode_buffer_size = s->buffer1_size;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
288 unsigned char *imagedata_buffer = s->buffer2;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
289 int imagedata_buffer_size = s->buffer2_size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
290
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
291 /* pointers to segments inside the compressed chunk */
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
292 unsigned char *huffman_segment;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
293 unsigned char *size_segment;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
294 unsigned char *vector_segment;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
295 unsigned char *imagedata_segment;
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
296
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
297 huffman_segment = s->buf + LE_16(&s->buf[0]);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
298 size_segment = s->buf + LE_16(&s->buf[2]);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
299 vector_segment = s->buf + LE_16(&s->buf[4]);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
300 imagedata_segment = s->buf + LE_16(&s->buf[6]);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
301
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
302 xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
303
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
304 if (imagedata_segment[0] == 2)
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
305 xan_unpack(imagedata_buffer, &imagedata_segment[1],
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
306 imagedata_buffer_size);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
307 else
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
308 imagedata_buffer = &imagedata_segment[1];
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
309
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
310 /* use the decoded data segments to build the frame */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
311 x = y = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
312 while (total_pixels) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
313
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
314 opcode = *opcode_buffer++;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
315 size = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
316
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
317 switch (opcode) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
318
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
319 case 0:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
320 flag ^= 1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
321 continue;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
322
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
323 case 1:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
324 case 2:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
325 case 3:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
326 case 4:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
327 case 5:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
328 case 6:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
329 case 7:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
330 case 8:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
331 size = opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
332 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
333
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
334 case 12:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
335 case 13:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
336 case 14:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
337 case 15:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
338 case 16:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
339 case 17:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
340 case 18:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
341 size += (opcode - 10);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
342 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
343
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
344 case 9:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
345 case 19:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
346 size = *size_segment++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
347 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
348
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
349 case 10:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
350 case 20:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
351 size = BE_16(&size_segment[0]);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
352 size_segment += 2;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
353 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
354
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
355 case 11:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
356 case 21:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
357 size = (size_segment[0] << 16) | (size_segment[1] << 8) |
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
358 size_segment[2];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
359 size_segment += 3;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
360 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
361 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
362
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
363 if (opcode < 12) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
364 flag ^= 1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
365 if (flag) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
366 /* run of (size) pixels is unchanged from last frame */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
367 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
368 } else {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
369 /* output a run of pixels from imagedata_buffer */
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
370 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
371 imagedata_buffer += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
372 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
373 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
374 /* run-based motion compensation from last frame */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
375 motion_x = (*vector_segment >> 4) & 0xF;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
376 motion_y = *vector_segment & 0xF;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
377 vector_segment++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
378
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
379 /* sign extension */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
380 if (motion_x & 0x8)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
381 motion_x |= 0xFFFFFFF0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
382 if (motion_y & 0x8)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
383 motion_y |= 0xFFFFFFF0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
384
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
385 /* copy a run of pixels from the previous frame */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
386 xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
387
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
388 flag = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
389 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
390
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
391 /* coordinate accounting */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
392 total_pixels -= size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
393 while (size) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
394 if (x + size >= width) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
395 y++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
396 size -= (width - x);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
397 x = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
398 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
399 x += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
400 size = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
401 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
402 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
403 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
404 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
405
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
406 static void xan_wc4_decode_frame(XanContext *s) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
407 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
408
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
409 static int xan_decode_frame(AVCodecContext *avctx,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
410 void *data, int *data_size,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
411 uint8_t *buf, int buf_size)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
412 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
413 XanContext *s = avctx->priv_data;
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1476
diff changeset
414 AVPaletteControl *palette_control = avctx->palctrl;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
415
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
416 if (avctx->get_buffer(avctx, &s->current_frame)) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
417 av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n");
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
418 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
419 }
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
420 s->current_frame.reference = 3;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
421
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
422 if (!s->frame_size)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
423 s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
424
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
425 palette_control->palette_changed = 0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
426 memcpy(s->current_frame.data[1], palette_control->palette,
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
427 AVPALETTE_SIZE);
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
428 s->current_frame.palette_has_changed = 1;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
429
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
430 s->buf = buf;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
431 s->size = buf_size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
432
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
433 if (avctx->codec->id == CODEC_ID_XAN_WC3)
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
434 xan_wc3_decode_frame(s);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
435 else if (avctx->codec->id == CODEC_ID_XAN_WC4)
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
436 xan_wc4_decode_frame(s);
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
437
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
438 /* release the last frame if it is allocated */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
439 if (s->last_frame.data[0])
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
440 avctx->release_buffer(avctx, &s->last_frame);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
441
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
442 /* shuffle frames */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
443 s->last_frame = s->current_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
444
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
445 *data_size = sizeof(AVFrame);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
446 *(AVFrame*)data = s->current_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
447
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
448 /* always report that the buffer was completely consumed */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
449 return buf_size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
450 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
451
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
452 static int xan_decode_end(AVCodecContext *avctx)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
453 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
454 XanContext *s = avctx->priv_data;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
455
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
456 /* release the last frame */
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
457 if (s->last_frame.data[0])
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
458 avctx->release_buffer(avctx, &s->last_frame);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
459
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
460 av_free(s->buffer1);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
461 av_free(s->buffer2);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
462
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
463 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
464 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
465
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
466 AVCodec xan_wc3_decoder = {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
467 "xan_wc3",
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
468 CODEC_TYPE_VIDEO,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
469 CODEC_ID_XAN_WC3,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
470 sizeof(XanContext),
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
471 xan_decode_init,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
472 NULL,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
473 xan_decode_end,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
474 xan_decode_frame,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
475 CODEC_CAP_DR1,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
476 };
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
477
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
478 /*
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
479 AVCodec xan_wc4_decoder = {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
480 "xan_wc4",
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
481 CODEC_TYPE_VIDEO,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
482 CODEC_ID_XAN_WC4,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
483 sizeof(XanContext),
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
484 xan_decode_init,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
485 NULL,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
486 xan_decode_end,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
487 xan_decode_frame,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
488 CODEC_CAP_DR1,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
489 };
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
490 */