Mercurial > libavcodec.hg
annotate xan.c @ 3176:babf844e1308 libavcodec
Init simplification and 2% faster wma_decode_block on amd64 with tables use
instead of pow().
author | banan |
---|---|
date | Wed, 08 Mar 2006 09:26:57 +0000 |
parents | 0b546eab515d |
children | c8c591fe26f8 |
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 | 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 | 73 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) |
74 return -1; | |
2967 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 */ |