Mercurial > libavcodec.hg
annotate xan.c @ 7983:47f50599b368 libavcodec
x264 has removed the b-rdo and bime options, and instead integrated
them into the subme number to attempt to reduce the number of
unnecessary options. subme now scales up to 9.
Patch by Jason Garett-Glaser %darkshikari A gmail P com%
author | gpoirier |
---|---|
date | Thu, 02 Oct 2008 19:05:35 +0000 |
parents | e943e1409077 |
children | 2acf0ae7b041 |
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 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
8 * 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
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
13 * 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
|
14 * 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
|
15 * Lesser General Public License for more details. |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
16 * |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * 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
|
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 /** |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
23 * @file xan.c |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
24 * 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
|
25 * by Mario Brito (mbrito@student.dei.uc.pt) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
26 * and Mike Melanson (melanson@pcisys.net) |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
27 * |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
28 * The xan_wc3 decoder outputs PAL8 data. |
1443
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 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
31 #include <stdio.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
32 #include <stdlib.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
33 #include <string.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
34 #include <unistd.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
35 |
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 |
6302 | 44 const unsigned char *buf; |
1443
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 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6452
diff
changeset
|
57 static av_cold int xan_decode_init(AVCodecContext *avctx) |
1443
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 |
2422 | 72 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) |
73 return -1; | |
2967 | 74 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
75 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
|
76 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
|
77 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
|
78 s->buffer2 = av_malloc(s->buffer2_size); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
79 if (!s->buffer1 || !s->buffer2) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
80 return -1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
81 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
82 return 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
83 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
84 |
4796 | 85 /* This function is used in lieu of memcpy(). This decoder cannot use |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
86 * memcpy because the memory locations often overlap and |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
87 * 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
|
88 * 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
|
89 * This was originally repz movsb in Intel x86 ASM. */ |
6302 | 90 static inline void bytecopy(unsigned char *dest, const unsigned char *src, int count) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
91 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
92 int i; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
93 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
94 for (i = 0; i < count; i++) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
95 dest[i] = src[i]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
96 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
97 |
6302 | 98 static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
99 int dest_len) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
100 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
101 unsigned char byte = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
102 unsigned char ival = byte + 0x16; |
6302 | 103 const unsigned char * ptr = src + byte*2; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
104 unsigned char val = ival; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
105 int counter = 0; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
106 unsigned char *dest_end = dest + dest_len; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
107 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
108 unsigned char bits = *ptr++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
109 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
110 while ( val != 0x16 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
111 if ( (1 << counter) & bits ) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
112 val = src[byte + val - 0x17]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
113 else |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
114 val = src[val - 0x17]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
115 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
116 if ( val < 0x16 ) { |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
117 if (dest + 1 > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
118 return 0; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
119 *dest++ = val; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
120 val = ival; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
121 } |
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 if (counter++ == 7) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
124 counter = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
125 bits = *ptr++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
126 } |
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 return 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
130 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
131 |
6302 | 132 static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
133 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
134 unsigned char opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
135 int size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
136 int offset; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
137 int byte1, byte2, byte3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
138 unsigned char *dest_end = dest + dest_len; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
139 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
140 for (;;) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
141 opcode = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
142 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
143 if ( (opcode & 0x80) == 0 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
144 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
145 offset = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
146 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
147 size = opcode & 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
148 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
149 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
150 bytecopy(dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
151 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
152 size = ((opcode & 0x1c) >> 2) + 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
153 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
154 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
155 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
|
156 dest += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
157 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
158 } else if ( (opcode & 0x40) == 0 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
159 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
160 byte1 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
161 byte2 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
162 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
163 size = byte1 >> 6; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
164 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
165 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
166 bytecopy (dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
167 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
168 size = (opcode & 0x3f) + 4; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
169 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
170 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
171 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
|
172 dest += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
173 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
174 } else if ( (opcode & 0x20) == 0 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
175 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
176 byte1 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
177 byte2 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
178 byte3 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
179 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
180 size = opcode & 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
181 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
182 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
183 bytecopy (dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
184 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
185 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
|
186 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
187 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
188 bytecopy (dest, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
189 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
|
190 size); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
191 dest += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
192 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
193 size = ((opcode & 0x1f) << 2) + 4; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
194 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
195 if (size > 0x70) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
196 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
197 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
198 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
199 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
200 bytecopy (dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
201 } |
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 size = opcode & 3; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
205 bytecopy(dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
206 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
207 |
4908
777f250df232
Fix multiple "¡Æinline/static¡Ç is not at beginning of declaration" warnings.
diego
parents:
4801
diff
changeset
|
208 static inline void xan_wc3_output_pixel_run(XanContext *s, |
6303 | 209 const unsigned char *pixel_buffer, int x, int y, int pixel_count) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
210 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
211 int stride; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
212 int line_inc; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
213 int index; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
214 int current_x; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
215 int width = s->avctx->width; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
216 unsigned char *palette_plane; |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
217 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
218 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
|
219 stride = s->current_frame.linesize[0]; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
220 line_inc = stride - width; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
221 index = y * stride + x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
222 current_x = x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
223 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
|
224 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
225 /* 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
|
226 * 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
|
227 palette_plane[index++] = *pixel_buffer++; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
228 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
229 current_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
230 if (current_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
231 index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
232 current_x = 0; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
233 } |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
234 } |
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 |
4908
777f250df232
Fix multiple "¡Æinline/static¡Ç is not at beginning of declaration" warnings.
diego
parents:
4801
diff
changeset
|
237 static inline void xan_wc3_copy_pixel_run(XanContext *s, |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
238 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
|
239 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
240 int stride; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
241 int line_inc; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
242 int curframe_index, prevframe_index; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
243 int curframe_x, prevframe_x; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
244 int width = s->avctx->width; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
245 unsigned char *palette_plane, *prev_palette_plane; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
246 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
247 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
|
248 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
|
249 stride = s->current_frame.linesize[0]; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
250 line_inc = stride - width; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
251 curframe_index = y * stride + x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
252 curframe_x = x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
253 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
|
254 prevframe_x = x + motion_x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
255 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
|
256 |
2967 | 257 palette_plane[curframe_index++] = |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
258 prev_palette_plane[prevframe_index++]; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
259 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
260 curframe_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
261 if (curframe_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
262 curframe_index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
263 curframe_x = 0; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
264 } |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
265 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
266 prevframe_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
267 if (prevframe_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
268 prevframe_index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
269 prevframe_x = 0; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
270 } |
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 static void xan_wc3_decode_frame(XanContext *s) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
275 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
276 int width = s->avctx->width; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
277 int height = s->avctx->height; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
278 int total_pixels = width * height; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
279 unsigned char opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
280 unsigned char flag = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
281 int size = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
282 int motion_x, motion_y; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
283 int x, y; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
284 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
285 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
|
286 int opcode_buffer_size = s->buffer1_size; |
6303 | 287 const unsigned char *imagedata_buffer = s->buffer2; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
288 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
289 /* pointers to segments inside the compressed chunk */ |
6302 | 290 const unsigned char *huffman_segment; |
291 const unsigned char *size_segment; | |
292 const unsigned char *vector_segment; | |
293 const unsigned char *imagedata_segment; | |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
294 |
4364 | 295 huffman_segment = s->buf + AV_RL16(&s->buf[0]); |
296 size_segment = s->buf + AV_RL16(&s->buf[2]); | |
297 vector_segment = s->buf + AV_RL16(&s->buf[4]); | |
298 imagedata_segment = s->buf + AV_RL16(&s->buf[6]); | |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
299 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
300 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
|
301 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
302 if (imagedata_segment[0] == 2) |
6303 | 303 xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
304 else |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
305 imagedata_buffer = &imagedata_segment[1]; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
306 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
307 /* 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
|
308 x = y = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
309 while (total_pixels) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
310 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
311 opcode = *opcode_buffer++; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
312 size = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
313 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
314 switch (opcode) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
315 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
316 case 0: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
317 flag ^= 1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
318 continue; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
319 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
320 case 1: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
321 case 2: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
322 case 3: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
323 case 4: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
324 case 5: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
325 case 6: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
326 case 7: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
327 case 8: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
328 size = opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
329 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
330 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
331 case 12: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
332 case 13: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
333 case 14: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
334 case 15: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
335 case 16: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
336 case 17: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
337 case 18: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
338 size += (opcode - 10); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
339 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
340 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
341 case 9: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
342 case 19: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
343 size = *size_segment++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
344 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
345 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
346 case 10: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
347 case 20: |
4364 | 348 size = AV_RB16(&size_segment[0]); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
349 size_segment += 2; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
350 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
351 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
352 case 11: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
353 case 21: |
5089 | 354 size = AV_RB24(size_segment); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
355 size_segment += 3; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
356 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
357 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
358 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
359 if (opcode < 12) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
360 flag ^= 1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
361 if (flag) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
362 /* 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
|
363 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
|
364 } else { |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
365 /* 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
|
366 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
|
367 imagedata_buffer += size; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
368 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
369 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
370 /* run-based motion compensation from last frame */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
371 motion_x = (*vector_segment >> 4) & 0xF; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
372 motion_y = *vector_segment & 0xF; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
373 vector_segment++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
374 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
375 /* sign extension */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
376 if (motion_x & 0x8) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
377 motion_x |= 0xFFFFFFF0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
378 if (motion_y & 0x8) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
379 motion_y |= 0xFFFFFFF0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
380 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
381 /* 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
|
382 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
|
383 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
384 flag = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
385 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
386 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
387 /* coordinate accounting */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
388 total_pixels -= size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
389 while (size) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
390 if (x + size >= width) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
391 y++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
392 size -= (width - x); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
393 x = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
394 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
395 x += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
396 size = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
397 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
398 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
399 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
400 } |
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 static void xan_wc4_decode_frame(XanContext *s) { |
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 static int xan_decode_frame(AVCodecContext *avctx, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
406 void *data, int *data_size, |
6302 | 407 const uint8_t *buf, int buf_size) |
1443
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 XanContext *s = avctx->priv_data; |
1585
6b224ca24033
revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents:
1476
diff
changeset
|
410 AVPaletteControl *palette_control = avctx->palctrl; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
411 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
412 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
|
413 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
|
414 return -1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
415 } |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
416 s->current_frame.reference = 3; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
417 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
418 if (!s->frame_size) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
419 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
|
420 |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
421 palette_control->palette_changed = 0; |
2967 | 422 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
|
423 AVPALETTE_SIZE); |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
424 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
|
425 |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
426 s->buf = buf; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
427 s->size = buf_size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
428 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
429 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
|
430 xan_wc3_decode_frame(s); |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
431 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
|
432 xan_wc4_decode_frame(s); |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
433 |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
434 /* release the last frame if it is allocated */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
435 if (s->last_frame.data[0]) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
436 avctx->release_buffer(avctx, &s->last_frame); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
437 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
438 *data_size = sizeof(AVFrame); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
439 *(AVFrame*)data = s->current_frame; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
440 |
6452
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
441 /* shuffle frames */ |
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
442 FFSWAP(AVFrame, s->current_frame, s->last_frame); |
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
443 |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
444 /* always report that the buffer was completely consumed */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
445 return buf_size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
446 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
447 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6452
diff
changeset
|
448 static av_cold int xan_decode_end(AVCodecContext *avctx) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
449 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
450 XanContext *s = avctx->priv_data; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
451 |
6452
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
452 /* release the frames */ |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
453 if (s->last_frame.data[0]) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
454 avctx->release_buffer(avctx, &s->last_frame); |
6452
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
455 if (s->current_frame.data[0]) |
2a2f9cb7f1b0
fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents:
6303
diff
changeset
|
456 avctx->release_buffer(avctx, &s->current_frame); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
457 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
458 av_free(s->buffer1); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
459 av_free(s->buffer2); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
460 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
461 return 0; |
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 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
464 AVCodec xan_wc3_decoder = { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
465 "xan_wc3", |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
466 CODEC_TYPE_VIDEO, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
467 CODEC_ID_XAN_WC3, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
468 sizeof(XanContext), |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
469 xan_decode_init, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
470 NULL, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
471 xan_decode_end, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
472 xan_decode_frame, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
473 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
474 .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
475 }; |
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 AVCodec xan_wc4_decoder = { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
479 "xan_wc4", |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
480 CODEC_TYPE_VIDEO, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
481 CODEC_ID_XAN_WC4, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
482 sizeof(XanContext), |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
483 xan_decode_init, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
484 NULL, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
485 xan_decode_end, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
486 xan_decode_frame, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
487 CODEC_CAP_DR1, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
488 }; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
489 */ |