annotate xan.c @ 9473:e38284cd69dc libavcodec

Use memcpy instead of the very inefficient bytecopy where both are correct (i.e. no overlap of src and dst is possible).
author reimar
date Fri, 17 Apr 2009 17:20:48 +0000
parents 54bc8a2727b0
children 4faccfb98672
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
1 /*
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
2 * Wing Commander/Xan Video Decoder
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
3 * Copyright (C) 2003 the ffmpeg project
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
4 *
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 /**
8718
e9d9d946f213 Use full internal pathname in doxygen @file directives.
diego
parents: 8573
diff changeset
23 * @file libavcodec/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
8573
2acf0ae7b041 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 7040
diff changeset
36 #include "libavutil/intreadwrite.h"
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
37 #include "avcodec.h"
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
38
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
39 typedef struct XanContext {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
40
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
41 AVCodecContext *avctx;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
42 AVFrame last_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
43 AVFrame current_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
44
6302
michael
parents: 5215
diff changeset
45 const unsigned char *buf;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
46 int size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
47
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
48 /* scratch space */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
49 unsigned char *buffer1;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
50 int buffer1_size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
51 unsigned char *buffer2;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
52 int buffer2_size;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
53
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
54 int frame_size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
55
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
56 } XanContext;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
57
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6452
diff changeset
58 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
59 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
60 XanContext *s = avctx->priv_data;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
61
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
62 s->avctx = avctx;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
63 s->frame_size = 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
64
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
65 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
66 (s->avctx->palctrl == NULL)) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
67 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
68 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
69 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
70
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
71 avctx->pix_fmt = PIX_FMT_PAL8;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
72
2422
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
73 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
74 return -1;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
75
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
76 s->buffer1_size = avctx->width * avctx->height;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
77 s->buffer1 = av_malloc(s->buffer1_size);
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
78 s->buffer2_size = avctx->width * avctx->height;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
79 s->buffer2 = av_malloc(s->buffer2_size);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
80 if (!s->buffer1 || !s->buffer2)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
81 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
82
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
83 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
84 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
85
4796
diego
parents: 4364
diff changeset
86 /* 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
87 * memcpy because the memory locations often overlap and
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
88 * memcpy doesn't like that; it's not uncommon, for example, for
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
89 * dest = src+1, to turn byte A into pattern AAAAAAAA.
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
90 * This was originally repz movsb in Intel x86 ASM. */
6302
michael
parents: 5215
diff changeset
91 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
92 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
93 int i;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
94
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
95 for (i = 0; i < count; i++)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
96 dest[i] = src[i];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
97 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
98
6302
michael
parents: 5215
diff changeset
99 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
100 int dest_len)
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
101 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
102 unsigned char byte = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
103 unsigned char ival = byte + 0x16;
6302
michael
parents: 5215
diff changeset
104 const unsigned char * ptr = src + byte*2;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
105 unsigned char val = ival;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
106 int counter = 0;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
107 unsigned char *dest_end = dest + dest_len;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
108
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
109 unsigned char bits = *ptr++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
110
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
111 while ( val != 0x16 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
112 if ( (1 << counter) & bits )
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
113 val = src[byte + val - 0x17];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
114 else
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
115 val = src[val - 0x17];
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
116
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
117 if ( val < 0x16 ) {
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
118 if (dest + 1 > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
119 return 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
120 *dest++ = val;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
121 val = ival;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
122 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
123
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
124 if (counter++ == 7) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
125 counter = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
126 bits = *ptr++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
127 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
128 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
129
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
130 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
131 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
132
6302
michael
parents: 5215
diff changeset
133 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
134 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
135 unsigned char opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
136 int size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
137 int offset;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
138 int byte1, byte2, byte3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
139 unsigned char *dest_end = dest + dest_len;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
140
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
141 for (;;) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
142 opcode = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
143
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
144 if ( (opcode & 0x80) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
145
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
146 offset = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
147
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
148 size = opcode & 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
149 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
150 return;
9473
e38284cd69dc Use memcpy instead of the very inefficient bytecopy where both are correct
reimar
parents: 9355
diff changeset
151 memcpy(dest, src, size); dest += size; src += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
152
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
153 size = ((opcode & 0x1c) >> 2) + 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
154 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
155 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
156 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
157 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
158
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
159 } else if ( (opcode & 0x40) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
160
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
161 byte1 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
162 byte2 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
163
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
164 size = byte1 >> 6;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
165 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
166 return;
9473
e38284cd69dc Use memcpy instead of the very inefficient bytecopy where both are correct
reimar
parents: 9355
diff changeset
167 memcpy(dest, src, size); dest += size; src += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
168
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
169 size = (opcode & 0x3f) + 4;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
170 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
171 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
172 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
173 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
174
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
175 } else if ( (opcode & 0x20) == 0 ) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
176
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
177 byte1 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
178 byte2 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
179 byte3 = *src++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
180
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
181 size = opcode & 3;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
182 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
183 return;
9473
e38284cd69dc Use memcpy instead of the very inefficient bytecopy where both are correct
reimar
parents: 9355
diff changeset
184 memcpy(dest, src, size); dest += size; src += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
185
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
186 size = byte3 + 5 + ((opcode & 0xc) << 6);
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
187 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
188 return;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
189 bytecopy (dest,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
190 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
191 size);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
192 dest += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
193 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
194 size = ((opcode & 0x1f) << 2) + 4;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
195
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
196 if (size > 0x70)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
197 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
198
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
199 if (dest + size > dest_end)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
200 return;
9473
e38284cd69dc Use memcpy instead of the very inefficient bytecopy where both are correct
reimar
parents: 9355
diff changeset
201 memcpy(dest, src, size); dest += size; src += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
202 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
203 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
204
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
205 size = opcode & 3;
9473
e38284cd69dc Use memcpy instead of the very inefficient bytecopy where both are correct
reimar
parents: 9355
diff changeset
206 memcpy(dest, src, size); dest += size; src += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
207 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
208
4908
777f250df232 Fix multiple "¡Æinline/static¡Ç is not at beginning of declaration" warnings.
diego
parents: 4801
diff changeset
209 static inline void xan_wc3_output_pixel_run(XanContext *s,
6303
aurel
parents: 6302
diff changeset
210 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
211 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
212 int stride;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
213 int line_inc;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
214 int index;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
215 int current_x;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
216 int width = s->avctx->width;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
217 unsigned char *palette_plane;
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
218
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
219 palette_plane = s->current_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
220 stride = s->current_frame.linesize[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
221 line_inc = stride - width;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
222 index = y * stride + x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
223 current_x = x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
224 while((pixel_count--) && (index < s->frame_size)) {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
225
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
226 /* don't do a memcpy() here; keyframes generally copy an entire
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
227 * frame of data and the stride needs to be accounted for */
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
228 palette_plane[index++] = *pixel_buffer++;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
229
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
230 current_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
231 if (current_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
232 index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
233 current_x = 0;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
234 }
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
235 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
236 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
237
4908
777f250df232 Fix multiple "¡Æinline/static¡Ç is not at beginning of declaration" warnings.
diego
parents: 4801
diff changeset
238 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
239 int x, int y, int pixel_count, int motion_x, int motion_y)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
240 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
241 int stride;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
242 int line_inc;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
243 int curframe_index, prevframe_index;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
244 int curframe_x, prevframe_x;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
245 int width = s->avctx->width;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
246 unsigned char *palette_plane, *prev_palette_plane;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
247
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
248 palette_plane = s->current_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
249 prev_palette_plane = s->last_frame.data[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
250 stride = s->current_frame.linesize[0];
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
251 line_inc = stride - width;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
252 curframe_index = y * stride + x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
253 curframe_x = x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
254 prevframe_index = (y + motion_y) * stride + x + motion_x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
255 prevframe_x = x + motion_x;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
256 while((pixel_count--) && (curframe_index < s->frame_size)) {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
257
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
258 palette_plane[curframe_index++] =
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
259 prev_palette_plane[prevframe_index++];
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
260
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
261 curframe_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
262 if (curframe_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
263 curframe_index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
264 curframe_x = 0;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
265 }
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
266
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
267 prevframe_x++;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
268 if (prevframe_x >= width) {
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
269 prevframe_index += line_inc;
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
270 prevframe_x = 0;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
271 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
272 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
273 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
274
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
275 static void xan_wc3_decode_frame(XanContext *s) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
276
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
277 int width = s->avctx->width;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
278 int height = s->avctx->height;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
279 int total_pixels = width * height;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
280 unsigned char opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
281 unsigned char flag = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
282 int size = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
283 int motion_x, motion_y;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
284 int x, y;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
285
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
286 unsigned char *opcode_buffer = s->buffer1;
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
287 int opcode_buffer_size = s->buffer1_size;
6303
aurel
parents: 6302
diff changeset
288 const unsigned char *imagedata_buffer = s->buffer2;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
289
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
290 /* pointers to segments inside the compressed chunk */
6302
michael
parents: 5215
diff changeset
291 const unsigned char *huffman_segment;
michael
parents: 5215
diff changeset
292 const unsigned char *size_segment;
michael
parents: 5215
diff changeset
293 const unsigned char *vector_segment;
michael
parents: 5215
diff changeset
294 const unsigned char *imagedata_segment;
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
295
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
296 huffman_segment = s->buf + AV_RL16(&s->buf[0]);
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
297 size_segment = s->buf + AV_RL16(&s->buf[2]);
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
298 vector_segment = s->buf + AV_RL16(&s->buf[4]);
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
299 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
300
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
301 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
302
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
303 if (imagedata_segment[0] == 2)
6303
aurel
parents: 6302
diff changeset
304 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
305 else
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
306 imagedata_buffer = &imagedata_segment[1];
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
307
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
308 /* 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
309 x = y = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
310 while (total_pixels) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
311
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
312 opcode = *opcode_buffer++;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
313 size = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
314
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
315 switch (opcode) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
316
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
317 case 0:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
318 flag ^= 1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
319 continue;
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 1:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
322 case 2:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
323 case 3:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
324 case 4:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
325 case 5:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
326 case 6:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
327 case 7:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
328 case 8:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
329 size = opcode;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
330 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
331
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
332 case 12:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
333 case 13:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
334 case 14:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
335 case 15:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
336 case 16:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
337 case 17:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
338 case 18:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
339 size += (opcode - 10);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
340 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
341
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
342 case 9:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
343 case 19:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
344 size = *size_segment++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
345 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
346
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
347 case 10:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
348 case 20:
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
349 size = AV_RB16(&size_segment[0]);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
350 size_segment += 2;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
351 break;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
352
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
353 case 11:
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
354 case 21:
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 4962
diff changeset
355 size = AV_RB24(size_segment);
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
356 size_segment += 3;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
357 break;
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
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
360 if (opcode < 12) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
361 flag ^= 1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
362 if (flag) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
363 /* 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
364 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
365 } else {
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
366 /* 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
367 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
368 imagedata_buffer += size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
369 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
370 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
371 /* run-based motion compensation from last frame */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
372 motion_x = (*vector_segment >> 4) & 0xF;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
373 motion_y = *vector_segment & 0xF;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
374 vector_segment++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
375
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
376 /* sign extension */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
377 if (motion_x & 0x8)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
378 motion_x |= 0xFFFFFFF0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
379 if (motion_y & 0x8)
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
380 motion_y |= 0xFFFFFFF0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
381
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
382 /* 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
383 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
384
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
385 flag = 0;
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
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
388 /* coordinate accounting */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
389 total_pixels -= size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
390 while (size) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
391 if (x + size >= width) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
392 y++;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
393 size -= (width - x);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
394 x = 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
395 } else {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
396 x += size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
397 size = 0;
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
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
403 static void xan_wc4_decode_frame(XanContext *s) {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
404 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
405
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
406 static int xan_decode_frame(AVCodecContext *avctx,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
407 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
408 AVPacket *avpkt)
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
409 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
410 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8718
diff changeset
411 int buf_size = avpkt->size;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
412 XanContext *s = avctx->priv_data;
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1476
diff changeset
413 AVPaletteControl *palette_control = avctx->palctrl;
1443
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 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
416 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
417 return -1;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
418 }
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
419 s->current_frame.reference = 3;
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
420
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
421 if (!s->frame_size)
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
422 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
423
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
424 palette_control->palette_changed = 0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2831
diff changeset
425 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
426 AVPALETTE_SIZE);
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
427 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
428
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
429 s->buf = buf;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
430 s->size = buf_size;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
431
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
432 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
433 xan_wc3_decode_frame(s);
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
434 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
435 xan_wc4_decode_frame(s);
1459
201d4e25c207 xan_wc3 decoder now works correctly; added a bunch of output
tmmm
parents: 1443
diff changeset
436
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
437 /* release the last frame if it is allocated */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
438 if (s->last_frame.data[0])
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
439 avctx->release_buffer(avctx, &s->last_frame);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
440
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
441 *data_size = sizeof(AVFrame);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
442 *(AVFrame*)data = s->current_frame;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
443
6452
2a2f9cb7f1b0 fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents: 6303
diff changeset
444 /* shuffle frames */
2a2f9cb7f1b0 fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents: 6303
diff changeset
445 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
446
1443
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
447 /* always report that the buffer was completely consumed */
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
448 return buf_size;
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
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6452
diff changeset
451 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
452 {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
453 XanContext *s = avctx->priv_data;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
454
6452
2a2f9cb7f1b0 fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents: 6303
diff changeset
455 /* release the frames */
2831
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
456 if (s->last_frame.data[0])
ad9d121cc6e9 tinfoil patch: no array is written to in bulk before counts are
melanson
parents: 2422
diff changeset
457 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
458 if (s->current_frame.data[0])
2a2f9cb7f1b0 fix the WC3 Xan decoder by correcting the frame accounting logic
melanson
parents: 6303
diff changeset
459 avctx->release_buffer(avctx, &s->current_frame);
1443
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 av_free(s->buffer1);
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
462 av_free(s->buffer2);
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 return 0;
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
465 }
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
466
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
467 AVCodec xan_wc3_decoder = {
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
468 "xan_wc3",
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
469 CODEC_TYPE_VIDEO,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
470 CODEC_ID_XAN_WC3,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
471 sizeof(XanContext),
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
472 xan_decode_init,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
473 NULL,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
474 xan_decode_end,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
475 xan_decode_frame,
47f4c8a5a7fc New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
tmmm
parents:
diff changeset
476 CODEC_CAP_DR1,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6712
diff changeset
477 .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
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 */