Mercurial > libavcodec.hg
annotate xan.c @ 4461:c95e0df9841f libavcodec
some (probably exploitable) out of array write fixes
author | michael |
---|---|
date | Fri, 02 Feb 2007 02:58:01 +0000 |
parents | 05e932ddaaa9 |
children | 231daf8387b1 |
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 /** |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
24 * @file xan.c |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
25 * 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
|
26 * by Mario Brito (mbrito@student.dei.uc.pt) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
27 * and Mike Melanson (melanson@pcisys.net) |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
28 * |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
29 * The xan_wc3 decoder outputs PAL8 data. |
1443
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 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
32 #include <stdio.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
33 #include <stdlib.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
34 #include <string.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
35 #include <unistd.h> |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
36 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
37 #include "common.h" |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
38 #include "avcodec.h" |
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 typedef struct XanContext { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
41 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
42 AVCodecContext *avctx; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
43 AVFrame last_frame; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
44 AVFrame current_frame; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
45 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
46 unsigned char *buf; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
47 int size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
48 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
49 /* scratch space */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
50 unsigned char *buffer1; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
51 int buffer1_size; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
52 unsigned char *buffer2; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
53 int buffer2_size; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
54 |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
55 int frame_size; |
1443
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 } XanContext; |
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 static int xan_decode_init(AVCodecContext *avctx) |
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 XanContext *s = avctx->priv_data; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
62 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
63 s->avctx = avctx; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
64 s->frame_size = 0; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
65 |
2967 | 66 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
|
67 (s->avctx->palctrl == NULL)) { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1585
diff
changeset
|
68 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
|
69 return -1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
70 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
71 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
72 avctx->pix_fmt = PIX_FMT_PAL8; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
73 avctx->has_b_frames = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
74 |
2422 | 75 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) |
76 return -1; | |
2967 | 77 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
78 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
|
79 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
|
80 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
|
81 s->buffer2 = av_malloc(s->buffer2_size); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
82 if (!s->buffer1 || !s->buffer2) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
83 return -1; |
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 return 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
86 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
87 |
2967 | 88 /* 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
|
89 * memcpy because the memory locations often overlap and |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
90 * 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
|
91 * 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
|
92 * 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
|
93 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
|
94 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
95 int 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 for (i = 0; i < count; i++) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
98 dest[i] = src[i]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
99 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
100 |
2967 | 101 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
|
102 int dest_len) |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
103 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
104 unsigned char byte = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
105 unsigned char ival = byte + 0x16; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
106 unsigned char * ptr = src + byte*2; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
107 unsigned char val = ival; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
108 int counter = 0; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
109 unsigned char *dest_end = dest + dest_len; |
1443
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 unsigned char bits = *ptr++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
112 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
113 while ( val != 0x16 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
114 if ( (1 << counter) & bits ) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
115 val = src[byte + val - 0x17]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
116 else |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
117 val = src[val - 0x17]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
118 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
119 if ( val < 0x16 ) { |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
120 if (dest + 1 > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
121 return 0; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
122 *dest++ = val; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
123 val = ival; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
124 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
125 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
126 if (counter++ == 7) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
127 counter = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
128 bits = *ptr++; |
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 } |
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 return 0; |
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 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
135 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
|
136 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
137 unsigned char opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
138 int size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
139 int offset; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
140 int byte1, byte2, byte3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
141 unsigned char *dest_end = dest + dest_len; |
1443
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 for (;;) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
144 opcode = *src++; |
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 if ( (opcode & 0x80) == 0 ) { |
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 offset = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
149 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
150 size = opcode & 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
151 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
152 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
153 bytecopy(dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
154 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
155 size = ((opcode & 0x1c) >> 2) + 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
156 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
157 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
158 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
|
159 dest += size; |
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 } else if ( (opcode & 0x40) == 0 ) { |
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 byte1 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
164 byte2 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
165 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
166 size = byte1 >> 6; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
167 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
168 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
169 bytecopy (dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
170 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
171 size = (opcode & 0x3f) + 4; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
172 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
173 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
174 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
|
175 dest += size; |
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 } else if ( (opcode & 0x20) == 0 ) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
178 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
179 byte1 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
180 byte2 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
181 byte3 = *src++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
182 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
183 size = opcode & 3; |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
184 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
185 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
186 bytecopy (dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
187 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
188 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
|
189 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
190 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
191 bytecopy (dest, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
192 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
|
193 size); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
194 dest += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
195 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
196 size = ((opcode & 0x1f) << 2) + 4; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
197 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
198 if (size > 0x70) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
199 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
200 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
201 if (dest + size > dest_end) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
202 return; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
203 bytecopy (dest, src, size); dest += size; src += size; |
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 } |
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 size = opcode & 3; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
208 bytecopy(dest, src, size); dest += size; src += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
209 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
210 |
2967 | 211 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
|
212 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
|
213 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
214 int stride; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
215 int line_inc; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
216 int index; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
217 int current_x; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
218 int width = s->avctx->width; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
219 unsigned char *palette_plane; |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
220 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
221 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
|
222 stride = s->current_frame.linesize[0]; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
223 line_inc = stride - width; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
224 index = y * stride + x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
225 current_x = x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
226 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
|
227 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
228 /* 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
|
229 * 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
|
230 palette_plane[index++] = *pixel_buffer++; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
231 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
232 current_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
233 if (current_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
234 index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
235 current_x = 0; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
236 } |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
237 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
238 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
239 |
2967 | 240 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
|
241 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
|
242 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
243 int stride; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
244 int line_inc; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
245 int curframe_index, prevframe_index; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
246 int curframe_x, prevframe_x; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
247 int width = s->avctx->width; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
248 unsigned char *palette_plane, *prev_palette_plane; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
249 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
250 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
|
251 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
|
252 stride = s->current_frame.linesize[0]; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
253 line_inc = stride - width; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
254 curframe_index = y * stride + x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
255 curframe_x = x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
256 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
|
257 prevframe_x = x + motion_x; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
258 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
|
259 |
2967 | 260 palette_plane[curframe_index++] = |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
261 prev_palette_plane[prevframe_index++]; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
262 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
263 curframe_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
264 if (curframe_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
265 curframe_index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
266 curframe_x = 0; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
267 } |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
268 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
269 prevframe_x++; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
270 if (prevframe_x >= width) { |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
271 prevframe_index += line_inc; |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
272 prevframe_x = 0; |
1443
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 } |
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 static void xan_wc3_decode_frame(XanContext *s) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
278 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
279 int width = s->avctx->width; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
280 int height = s->avctx->height; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
281 int total_pixels = width * height; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
282 unsigned char opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
283 unsigned char flag = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
284 int size = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
285 int motion_x, motion_y; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
286 int x, y; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
287 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
288 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
|
289 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
|
290 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
|
291 int imagedata_buffer_size = s->buffer2_size; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
292 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
293 /* 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
|
294 unsigned char *huffman_segment; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
295 unsigned char *size_segment; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
296 unsigned char *vector_segment; |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
297 unsigned char *imagedata_segment; |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
298 |
4364 | 299 huffman_segment = s->buf + AV_RL16(&s->buf[0]); |
300 size_segment = s->buf + AV_RL16(&s->buf[2]); | |
301 vector_segment = s->buf + AV_RL16(&s->buf[4]); | |
302 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
|
303 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
304 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
|
305 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
306 if (imagedata_segment[0] == 2) |
2967 | 307 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
|
308 imagedata_buffer_size); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
309 else |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
310 imagedata_buffer = &imagedata_segment[1]; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
311 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
312 /* 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
|
313 x = y = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
314 while (total_pixels) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
315 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
316 opcode = *opcode_buffer++; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
317 size = 0; |
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 switch (opcode) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
320 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
321 case 0: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
322 flag ^= 1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
323 continue; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
324 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
325 case 1: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
326 case 2: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
327 case 3: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
328 case 4: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
329 case 5: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
330 case 6: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
331 case 7: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
332 case 8: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
333 size = opcode; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
334 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
335 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
336 case 12: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
337 case 13: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
338 case 14: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
339 case 15: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
340 case 16: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
341 case 17: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
342 case 18: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
343 size += (opcode - 10); |
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 9: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
347 case 19: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
348 size = *size_segment++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
349 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
350 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
351 case 10: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
352 case 20: |
4364 | 353 size = AV_RB16(&size_segment[0]); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
354 size_segment += 2; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
355 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
356 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
357 case 11: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
358 case 21: |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
359 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
|
360 size_segment[2]; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
361 size_segment += 3; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
362 break; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
363 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
364 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
365 if (opcode < 12) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
366 flag ^= 1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
367 if (flag) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
368 /* 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
|
369 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
|
370 } else { |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
371 /* 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
|
372 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
|
373 imagedata_buffer += size; |
1443
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 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
376 /* run-based motion compensation from last frame */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
377 motion_x = (*vector_segment >> 4) & 0xF; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
378 motion_y = *vector_segment & 0xF; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
379 vector_segment++; |
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 /* sign extension */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
382 if (motion_x & 0x8) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
383 motion_x |= 0xFFFFFFF0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
384 if (motion_y & 0x8) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
385 motion_y |= 0xFFFFFFF0; |
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 /* 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
|
388 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
|
389 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
390 flag = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
391 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
392 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
393 /* coordinate accounting */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
394 total_pixels -= size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
395 while (size) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
396 if (x + size >= width) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
397 y++; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
398 size -= (width - x); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
399 x = 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
400 } else { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
401 x += size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
402 size = 0; |
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 } |
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 static void xan_wc4_decode_frame(XanContext *s) { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
409 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
410 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
411 static int xan_decode_frame(AVCodecContext *avctx, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
412 void *data, int *data_size, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
413 uint8_t *buf, int buf_size) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
414 { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
415 XanContext *s = avctx->priv_data; |
1585
6b224ca24033
revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents:
1476
diff
changeset
|
416 AVPaletteControl *palette_control = avctx->palctrl; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
417 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
418 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
|
419 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
|
420 return -1; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
421 } |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
422 s->current_frame.reference = 3; |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
423 |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
424 if (!s->frame_size) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
425 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
|
426 |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
427 palette_control->palette_changed = 0; |
2967 | 428 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
|
429 AVPALETTE_SIZE); |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
430 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
|
431 |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
432 s->buf = buf; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
433 s->size = buf_size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
434 |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
435 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
|
436 xan_wc3_decode_frame(s); |
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
437 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
|
438 xan_wc4_decode_frame(s); |
1459
201d4e25c207
xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents:
1443
diff
changeset
|
439 |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
440 /* release the last frame if it is allocated */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
441 if (s->last_frame.data[0]) |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
442 avctx->release_buffer(avctx, &s->last_frame); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
443 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
444 /* shuffle frames */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
445 s->last_frame = s->current_frame; |
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 *data_size = sizeof(AVFrame); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
448 *(AVFrame*)data = s->current_frame; |
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 /* always report that the buffer was completely consumed */ |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
451 return buf_size; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
452 } |
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 static int xan_decode_end(AVCodecContext *avctx) |
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 XanContext *s = avctx->priv_data; |
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 /* release the last frame */ |
2831
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
459 if (s->last_frame.data[0]) |
ad9d121cc6e9
tinfoil patch: no array is written to in bulk before counts are
melanson
parents:
2422
diff
changeset
|
460 avctx->release_buffer(avctx, &s->last_frame); |
1443
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
461 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
462 av_free(s->buffer1); |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
463 av_free(s->buffer2); |
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 return 0; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
466 } |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
467 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
468 AVCodec xan_wc3_decoder = { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
469 "xan_wc3", |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
470 CODEC_TYPE_VIDEO, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
471 CODEC_ID_XAN_WC3, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
472 sizeof(XanContext), |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
473 xan_decode_init, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
474 NULL, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
475 xan_decode_end, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
476 xan_decode_frame, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
477 CODEC_CAP_DR1, |
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 |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
480 /* |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
481 AVCodec xan_wc4_decoder = { |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
482 "xan_wc4", |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
483 CODEC_TYPE_VIDEO, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
484 CODEC_ID_XAN_WC4, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
485 sizeof(XanContext), |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
486 xan_decode_init, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
487 NULL, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
488 xan_decode_end, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
489 xan_decode_frame, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
490 CODEC_CAP_DR1, |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
491 }; |
47f4c8a5a7fc
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff
changeset
|
492 */ |