98
static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
98
static int xan_huffman_decode(unsigned char *dest, int dest_len,
99
const unsigned char *src, int src_len)
101
101
unsigned char byte = *src++;
102
102
unsigned char ival = byte + 0x16;
103
103
const unsigned char * ptr = src + byte*2;
104
int ptr_len = src_len - 1 - byte*2;
104
105
unsigned char val = ival;
105
106
unsigned char *dest_end = dest + dest_len;
106
107
GetBitContext gb;
108
init_get_bits(&gb, ptr, 0); // FIXME: no src size available
110
while ( val != 0x16 ) {
111
val = src[val - 0x17 + get_bits1(&gb) * byte];
110
return AVERROR_INVALIDDATA;
112
init_get_bits(&gb, ptr, ptr_len * 8);
114
while (val != 0x16) {
115
unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
114
121
if (dest >= dest_end)
127
134
* @param dest destination buffer of dest_len, must be padded with at least 130 bytes
129
static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len)
136
static void xan_unpack(unsigned char *dest, int dest_len,
137
const unsigned char *src, int src_len)
131
139
unsigned char opcode;
141
unsigned char *dest_org = dest;
133
142
unsigned char *dest_end = dest + dest_len;
143
const unsigned char *src_end = src + src_len;
135
while (dest < dest_end) {
145
while (dest < dest_end && src < src_end) {
138
148
if (opcode < 0xe0) {
140
if ( (opcode & 0x80) == 0 ) {
150
if ((opcode & 0x80) == 0) {
142
151
size = opcode & 3;
144
153
back = ((opcode & 0x60) << 3) + *src++ + 1;
145
154
size2 = ((opcode & 0x1c) >> 2) + 3;
147
} else if ( (opcode & 0x40) == 0 ) {
155
} else if ((opcode & 0x40) == 0) {
149
156
size = *src >> 6;
151
158
back = (bytestream_get_be16(&src) & 0x3fff) + 1;
152
159
size2 = (opcode & 0x3f) + 4;
156
161
size = opcode & 3;
158
163
back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
159
164
size2 = ((opcode & 0x0c) << 6) + *src++ + 5;
160
if (size + size2 > dest_end - dest)
167
if (dest_end - dest < size + size2 ||
168
dest + size - dest_org < back ||
169
src_end - src < size)
163
171
memcpy(dest, src, size); dest += size; src += size;
164
172
av_memcpy_backptr(dest, back, size2);
189
199
line_inc = stride - width;
190
200
index = y * stride + x;
192
while(pixel_count && (index < s->frame_size)) {
202
while (pixel_count && index < s->frame_size) {
193
203
int count = FFMIN(pixel_count, width - current_x);
194
204
memcpy(palette_plane + index, pixel_buffer, count);
195
205
pixel_count -= count;
207
static inline void xan_wc3_copy_pixel_run(XanContext *s,
208
int x, int y, int pixel_count, int motion_x, int motion_y)
217
static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
218
int pixel_count, int motion_x,
214
225
int width = s->avctx->width;
215
226
unsigned char *palette_plane, *prev_palette_plane;
228
if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
229
x + motion_x < 0 || x + motion_x >= s->avctx->width)
217
232
palette_plane = s->current_frame.data[0];
218
233
prev_palette_plane = s->last_frame.data[0];
234
if (!prev_palette_plane)
235
prev_palette_plane = palette_plane;
219
236
stride = s->current_frame.linesize[0];
220
237
line_inc = stride - width;
221
238
curframe_index = y * stride + x;
223
240
prevframe_index = (y + motion_y) * stride + x + motion_x;
224
241
prevframe_x = x + motion_x;
225
while(pixel_count && (curframe_index < s->frame_size)) {
226
int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x);
242
while (pixel_count &&
243
curframe_index < s->frame_size &&
244
prevframe_index < s->frame_size) {
245
int count = FFMIN3(pixel_count, width - curframe_x,
246
width - prevframe_x);
228
memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count);
248
memcpy(palette_plane + curframe_index,
249
prev_palette_plane + prevframe_index, count);
229
250
pixel_count -= count;
230
251
curframe_index += count;
231
252
prevframe_index += count;
247
static void xan_wc3_decode_frame(XanContext *s) {
268
static int xan_wc3_decode_frame(XanContext *s) {
249
int width = s->avctx->width;
270
int width = s->avctx->width;
250
271
int height = s->avctx->height;
251
272
int total_pixels = width * height;
252
273
unsigned char opcode;
264
286
const unsigned char *size_segment;
265
287
const unsigned char *vector_segment;
266
288
const unsigned char *imagedata_segment;
268
huffman_segment = s->buf + AV_RL16(&s->buf[0]);
269
size_segment = s->buf + AV_RL16(&s->buf[2]);
270
vector_segment = s->buf + AV_RL16(&s->buf[4]);
271
imagedata_segment = s->buf + AV_RL16(&s->buf[6]);
273
xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size);
275
if (imagedata_segment[0] == 2)
276
xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
289
int huffman_offset, size_offset, vector_offset, imagedata_offset,
293
return AVERROR_INVALIDDATA;
295
huffman_offset = AV_RL16(&s->buf[0]);
296
size_offset = AV_RL16(&s->buf[2]);
297
vector_offset = AV_RL16(&s->buf[4]);
298
imagedata_offset = AV_RL16(&s->buf[6]);
300
if (huffman_offset >= s->size ||
301
size_offset >= s->size ||
302
vector_offset >= s->size ||
303
imagedata_offset >= s->size)
304
return AVERROR_INVALIDDATA;
306
huffman_segment = s->buf + huffman_offset;
307
size_segment = s->buf + size_offset;
308
vector_segment = s->buf + vector_offset;
309
imagedata_segment = s->buf + imagedata_offset;
311
if (xan_huffman_decode(opcode_buffer, opcode_buffer_size,
312
huffman_segment, s->size - huffman_offset) < 0)
313
return AVERROR_INVALIDDATA;
315
if (imagedata_segment[0] == 2) {
316
xan_unpack(s->buffer2, s->buffer2_size,
317
&imagedata_segment[1], s->size - imagedata_offset - 1);
318
imagedata_size = s->buffer2_size;
320
imagedata_size = s->size - imagedata_offset - 1;
278
321
imagedata_buffer = &imagedata_segment[1];
280
324
/* use the decoded data segments to build the frame */
282
while (total_pixels) {
326
while (total_pixels && opcode_buffer < opcode_buffer_end) {
284
328
opcode = *opcode_buffer++;
336
383
xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
338
385
/* output a run of pixels from imagedata_buffer */
386
if (imagedata_size < size)
339
388
xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
340
389
imagedata_buffer += size;
390
imagedata_size -= size;
343
393
/* run-based motion compensation from last frame */
466
517
return AVERROR_INVALIDDATA;
467
518
if (s->palettes_count >= PALETTES_MAX)
468
519
return AVERROR_INVALIDDATA;
469
tmpptr = av_realloc(s->palettes, (s->palettes_count + 1) * AVPALETTE_SIZE);
520
tmpptr = av_realloc(s->palettes,
521
(s->palettes_count + 1) * AVPALETTE_SIZE);
471
523
return AVERROR(ENOMEM);
472
524
s->palettes = tmpptr;
504
556
buf_size = buf_end - buf;
558
if (s->palettes_count <= 0) {
559
av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
560
return AVERROR_INVALIDDATA;
506
563
if ((ret = avctx->get_buffer(avctx, &s->current_frame))) {
507
564
av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
512
569
if (!s->frame_size)
513
570
s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
515
memcpy(s->current_frame.data[1], s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
572
memcpy(s->current_frame.data[1],
573
s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
518
576
s->size = buf_size;
520
xan_wc3_decode_frame(s);
578
if (xan_wc3_decode_frame(s) < 0)
579
return AVERROR_INVALIDDATA;
522
581
/* release the last frame if it is allocated */
523
582
if (s->last_frame.data[0])
553
612
AVCodec ff_xan_wc3_decoder = {
563
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
614
.type = AVMEDIA_TYPE_VIDEO,
615
.id = CODEC_ID_XAN_WC3,
616
.priv_data_size = sizeof(XanContext),
617
.init = xan_decode_init,
618
.close = xan_decode_end,
619
.decode = xan_decode_frame,
620
.capabilities = CODEC_CAP_DR1,
621
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),