FFmpeg
Loading...
Searching...
No Matches
xan.c
Go to the documentation of this file.
1/*
2 * Wing Commander/Xan Video Decoder
3 * Copyright (C) 2003 The FFmpeg project
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * Xan video decoder for Wing Commander III computer game
25 * by Mario Brito (mbrito@student.dei.uc.pt)
26 * and Mike Melanson (melanson@pcisys.net)
27 *
28 * The xan_wc3 decoder outputs PAL8 data.
29 */
30
31#include <string.h>
32
34#include "libavutil/mem.h"
35
36#define BITSTREAM_READER_LE
37#include "avcodec.h"
38#include "bytestream.h"
39#include "codec_internal.h"
40#include "decode.h"
41#include "get_bits.h"
42
43#define RUNTIME_GAMMA 0
44
45#define VGA__TAG MKTAG('V', 'G', 'A', ' ')
46#define PALT_TAG MKTAG('P', 'A', 'L', 'T')
47#define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
48#define PALETTE_COUNT 256
49#define PALETTE_SIZE (PALETTE_COUNT * 3)
50#define PALETTES_MAX 256
51
52typedef struct XanContext {
53
56
57 const uint8_t *buf;
58 int size;
59
60 /* scratch space */
61 uint8_t *buffer1;
63 uint8_t *buffer2;
65
66 unsigned *palettes;
69
71
73
75{
76 XanContext *s = avctx->priv_data;
77
78 av_frame_free(&s->last_frame);
79
80 av_freep(&s->buffer1);
81 av_freep(&s->buffer2);
82 av_freep(&s->palettes);
83
84 return 0;
85}
86
88{
89 XanContext *s = avctx->priv_data;
90
91 s->avctx = avctx;
92 s->frame_size = 0;
93
94 avctx->pix_fmt = AV_PIX_FMT_PAL8;
95
96 s->buffer1_size = avctx->width * avctx->height;
97 s->buffer1 = av_malloc(s->buffer1_size);
98 if (!s->buffer1)
99 return AVERROR(ENOMEM);
100 s->buffer2_size = avctx->width * avctx->height;
101 s->buffer2 = av_malloc(s->buffer2_size + 130);
102 if (!s->buffer2)
103 return AVERROR(ENOMEM);
104
105 s->last_frame = av_frame_alloc();
106 if (!s->last_frame)
107 return AVERROR(ENOMEM);
108
109 return 0;
110}
111
112static int xan_huffman_decode(uint8_t *dest, int dest_len,
113 const uint8_t *src, int src_len)
114{
115 uint8_t byte = *src++;
116 uint8_t ival = byte + 0x16;
117 const uint8_t * ptr = src + byte*2;
118 int ptr_len = src_len - 1 - byte*2;
119 uint8_t val = ival;
120 uint8_t *dest_end = dest + dest_len;
121 uint8_t *dest_start = dest;
122 int ret;
123 GetBitContext gb;
124
125 if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)
126 return ret;
127
128 while (val != 0x16) {
129 unsigned idx;
130 if (get_bits_left(&gb) < 1)
131 return AVERROR_INVALIDDATA;
132 idx = val - 0x17 + get_bits1(&gb) * byte;
133 if (idx >= 2 * byte)
134 return AVERROR_INVALIDDATA;
135 val = src[idx];
136
137 if (val < 0x16) {
138 if (dest >= dest_end)
139 return dest_len;
140 *dest++ = val;
141 val = ival;
142 }
143 }
144
145 return dest - dest_start;
146}
147
148/**
149 * unpack simple compression
150 *
151 * @param dest destination buffer of dest_len, must be padded with at least 130 bytes
152 */
153static void xan_unpack(uint8_t *dest, int dest_len,
154 const uint8_t *src, int src_len)
155{
156 uint8_t opcode;
157 int size;
158 uint8_t *dest_org = dest;
159 uint8_t *dest_end = dest + dest_len;
161
162 bytestream2_init(&ctx, src, src_len);
163 while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
164 opcode = bytestream2_get_byte(&ctx);
165
166 if (opcode < 0xe0) {
167 int size2, back;
168 if ((opcode & 0x80) == 0) {
169 size = opcode & 3;
170
171 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
172 size2 = ((opcode & 0x1c) >> 2) + 3;
173 } else if ((opcode & 0x40) == 0) {
174 size = bytestream2_peek_byte(&ctx) >> 6;
175
176 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
177 size2 = (opcode & 0x3f) + 4;
178 } else {
179 size = opcode & 3;
180
181 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
182 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
183 }
184
185 if (dest_end - dest < size + size2 ||
186 dest + size - dest_org < back ||
188 return;
190 dest += size;
191 av_memcpy_backptr(dest, back, size2);
192 dest += size2;
193 } else {
194 int finish = opcode >= 0xfc;
195 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
196
197 if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
198 return;
200 dest += size;
201 if (finish)
202 return;
203 }
204 }
205}
206
208 const uint8_t *pixel_buffer, int x, int y, int pixel_count)
209{
210 int stride;
211 int line_inc;
212 int index;
213 int current_x;
214 int width = s->avctx->width;
215 uint8_t *palette_plane;
216
217 palette_plane = frame->data[0];
218 stride = frame->linesize[0];
219 line_inc = stride - width;
220 index = y * stride + x;
221 current_x = x;
222 while (pixel_count && index < s->frame_size) {
223 int count = FFMIN(pixel_count, width - current_x);
224 memcpy(palette_plane + index, pixel_buffer, count);
225 pixel_count -= count;
226 index += count;
227 pixel_buffer += count;
228 current_x += count;
229
230 if (current_x >= width) {
231 index += line_inc;
232 current_x = 0;
233 }
234 }
235}
236
238 int x, int y,
239 int pixel_count, int motion_x,
240 int motion_y)
241{
242 int stride;
243 int line_inc;
244 int curframe_index, prevframe_index;
245 int curframe_x, prevframe_x;
246 int width = s->avctx->width;
247 uint8_t *palette_plane, *prev_palette_plane;
248
249 if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
250 x + motion_x < 0 || x + motion_x >= s->avctx->width)
251 return;
252
253 palette_plane = frame->data[0];
254 prev_palette_plane = s->last_frame->data[0];
255 if (!prev_palette_plane)
256 prev_palette_plane = palette_plane;
257 stride = frame->linesize[0];
258 line_inc = stride - width;
259 curframe_index = y * stride + x;
260 curframe_x = x;
261 prevframe_index = (y + motion_y) * stride + x + motion_x;
262 prevframe_x = x + motion_x;
263
264 if (prev_palette_plane == palette_plane && FFABS(motion_x + width*motion_y) < pixel_count) {
265 avpriv_request_sample(s->avctx, "Overlapping copy");
266 return ;
267 }
268
269 while (pixel_count &&
270 curframe_index < s->frame_size &&
271 prevframe_index < s->frame_size) {
272 int count = FFMIN3(pixel_count, width - curframe_x,
273 width - prevframe_x);
274
275 memcpy(palette_plane + curframe_index,
276 prev_palette_plane + prevframe_index, count);
277 pixel_count -= count;
278 curframe_index += count;
279 prevframe_index += count;
280 curframe_x += count;
281 prevframe_x += count;
282
283 if (curframe_x >= width) {
284 curframe_index += line_inc;
285 curframe_x = 0;
286 }
287
288 if (prevframe_x >= width) {
289 prevframe_index += line_inc;
290 prevframe_x = 0;
291 }
292 }
293}
294
296{
297
298 int width = s->avctx->width;
299 int height = s->avctx->height;
300 int total_pixels = width * height;
301 uint8_t opcode;
302 uint8_t flag = 0;
303 int size = 0;
304 int motion_x, motion_y;
305 int x, y, ret;
306
307 uint8_t *opcode_buffer = s->buffer1;
308 uint8_t *opcode_buffer_end = s->buffer1 + s->buffer1_size;
309 int opcode_buffer_size = s->buffer1_size;
310 const uint8_t *imagedata_buffer = s->buffer2;
311
312 /* pointers to segments inside the compressed chunk */
313 const uint8_t *huffman_segment;
314 GetByteContext size_segment;
315 GetByteContext vector_segment;
316 const uint8_t *imagedata_segment;
317 int huffman_offset, size_offset, vector_offset, imagedata_offset,
318 imagedata_size;
319
320 if (s->size < 8)
321 return AVERROR_INVALIDDATA;
322
323 huffman_offset = AV_RL16(&s->buf[0]);
324 size_offset = AV_RL16(&s->buf[2]);
325 vector_offset = AV_RL16(&s->buf[4]);
326 imagedata_offset = AV_RL16(&s->buf[6]);
327
328 if (huffman_offset >= s->size ||
329 size_offset >= s->size ||
330 vector_offset >= s->size ||
331 imagedata_offset >= s->size)
332 return AVERROR_INVALIDDATA;
333
334 huffman_segment = s->buf + huffman_offset;
335 bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset);
336 bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset);
337 imagedata_segment = s->buf + imagedata_offset;
338
339 if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size,
340 huffman_segment, s->size - huffman_offset)) < 0)
341 return AVERROR_INVALIDDATA;
342 opcode_buffer_end = opcode_buffer + ret;
343
344 if (imagedata_segment[0] == 2) {
345 xan_unpack(s->buffer2, s->buffer2_size,
346 &imagedata_segment[1], s->size - imagedata_offset - 1);
347 imagedata_size = s->buffer2_size;
348 } else {
349 imagedata_size = s->size - imagedata_offset - 1;
350 imagedata_buffer = &imagedata_segment[1];
351 }
352
353 /* use the decoded data segments to build the frame */
354 x = y = 0;
355 while (total_pixels && opcode_buffer < opcode_buffer_end) {
356
357 opcode = *opcode_buffer++;
358 size = 0;
359
360 switch (opcode) {
361
362 case 0:
363 flag ^= 1;
364 continue;
365
366 case 1:
367 case 2:
368 case 3:
369 case 4:
370 case 5:
371 case 6:
372 case 7:
373 case 8:
374 size = opcode;
375 break;
376
377 case 12:
378 case 13:
379 case 14:
380 case 15:
381 case 16:
382 case 17:
383 case 18:
384 size += (opcode - 10);
385 break;
386
387 case 9:
388 case 19:
389 if (bytestream2_get_bytes_left(&size_segment) < 1) {
390 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
391 return AVERROR_INVALIDDATA;
392 }
393 size = bytestream2_get_byte(&size_segment);
394 break;
395
396 case 10:
397 case 20:
398 if (bytestream2_get_bytes_left(&size_segment) < 2) {
399 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
400 return AVERROR_INVALIDDATA;
401 }
402 size = bytestream2_get_be16(&size_segment);
403 break;
404
405 case 11:
406 case 21:
407 if (bytestream2_get_bytes_left(&size_segment) < 3) {
408 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
409 return AVERROR_INVALIDDATA;
410 }
411 size = bytestream2_get_be24(&size_segment);
412 break;
413 }
414
415 if (size > total_pixels)
416 break;
417
418 if (opcode < 12) {
419 flag ^= 1;
420 if (flag) {
421 /* run of (size) pixels is unchanged from last frame */
422 xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
423 } else {
424 /* output a run of pixels from imagedata_buffer */
425 if (imagedata_size < size)
426 break;
427 xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
428 imagedata_buffer += size;
429 imagedata_size -= size;
430 }
431 } else {
432 uint8_t vector;
433 if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
434 av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
435 return AVERROR_INVALIDDATA;
436 }
437 /* run-based motion compensation from last frame */
438 vector = bytestream2_get_byte(&vector_segment);
439 motion_x = sign_extend(vector >> 4, 4);
440 motion_y = sign_extend(vector & 0xF, 4);
441
442 /* copy a run of pixels from the previous frame */
443 xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
444
445 flag = 0;
446 }
447
448 /* coordinate accounting */
449 total_pixels -= size;
450 y += (x + size) / width;
451 x = (x + size) % width;
452 }
453 return 0;
454}
455
456#if RUNTIME_GAMMA
457static inline unsigned mul(unsigned a, unsigned b)
458{
459 return (a * b) >> 16;
460}
461
462static inline unsigned pow4(unsigned a)
463{
464 unsigned square = mul(a, a);
465 return mul(square, square);
466}
467
468static inline unsigned pow5(unsigned a)
469{
470 return mul(pow4(a), a);
471}
472
473static uint8_t gamma_corr(uint8_t in) {
474 unsigned lo, hi = 0xff40, target;
475 int i = 15;
476 in = (in << 2) | (in >> 6);
477 /* equivalent float code:
478 if (in >= 252)
479 return 253;
480 return round(pow(in / 256.0, 0.8) * 256);
481 */
482 lo = target = in << 8;
483 do {
484 unsigned mid = (lo + hi) >> 1;
485 unsigned pow = pow5(mid);
486 if (pow > target) hi = mid;
487 else lo = mid;
488 } while (--i);
489 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
490}
491#else
492/**
493 * This is a gamma correction that xan3 applies to all palette entries.
494 *
495 * There is a peculiarity, namely that the values are clamped to 253 -
496 * it seems likely that this table was calculated by a buggy fixed-point
497 * implementation, the one above under RUNTIME_GAMMA behaves like this for
498 * example.
499 * The exponent value of 0.8 can be explained by this as well, since 0.8 = 4/5
500 * and thus pow(x, 0.8) is still easy to calculate.
501 * Also, the input values are first rotated to the left by 2.
502 */
503static const uint8_t gamma_lookup[256] = {
504 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
505 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
506 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
507 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
508 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
509 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
510 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
511 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
512 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
513 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
514 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
515 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
516 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
517 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
518 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
519 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
520 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
521 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
522 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
523 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
524 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
525 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
526 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
527 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
528 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
529 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
530 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
531 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
532 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
533 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
534 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
535 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
536};
537#endif
538
540 int *got_frame, AVPacket *avpkt)
541{
542 const uint8_t *buf = avpkt->data;
543 int ret, buf_size = avpkt->size;
544 XanContext *s = avctx->priv_data;
546 int tag = 0;
547
548 bytestream2_init(&ctx, buf, buf_size);
549 while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
550 unsigned *tmpptr;
551 uint32_t new_pal;
552 int size;
553 int i;
554 tag = bytestream2_get_le32(&ctx);
555 size = bytestream2_get_be32(&ctx);
556 if (size < 0) {
557 av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
558 return AVERROR_INVALIDDATA;
559 }
561 switch (tag) {
562 case PALT_TAG:
563 if (size < PALETTE_SIZE)
564 return AVERROR_INVALIDDATA;
565 if (s->palettes_count >= PALETTES_MAX)
566 return AVERROR_INVALIDDATA;
567 tmpptr = av_realloc_array(s->palettes,
568 s->palettes_count + 1, AVPALETTE_SIZE);
569 if (!tmpptr)
570 return AVERROR(ENOMEM);
571 s->palettes = tmpptr;
572 tmpptr += s->palettes_count * AVPALETTE_COUNT;
573 for (i = 0; i < PALETTE_COUNT; i++) {
574#if RUNTIME_GAMMA
575 int r = gamma_corr(bytestream2_get_byteu(&ctx));
576 int g = gamma_corr(bytestream2_get_byteu(&ctx));
577 int b = gamma_corr(bytestream2_get_byteu(&ctx));
578#else
579 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
580 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
581 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
582#endif
583 *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
584 }
585 s->palettes_count++;
586 break;
587 case SHOT_TAG:
588 if (size < 4)
589 return AVERROR_INVALIDDATA;
590 new_pal = bytestream2_get_le32(&ctx);
591 if (new_pal < s->palettes_count) {
592 s->cur_palette = new_pal;
593 } else
594 av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
595 break;
596 case VGA__TAG:
597 break;
598 default:
600 break;
601 }
602 }
603 buf_size = bytestream2_get_bytes_left(&ctx);
604
605 if (s->palettes_count <= 0) {
606 av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
607 return AVERROR_INVALIDDATA;
608 }
609
610 if (buf_size < 9)
611 return AVERROR_INVALIDDATA;
612
613 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
614 return ret;
615
616 if (!s->frame_size)
617 s->frame_size = frame->linesize[0] * s->avctx->height;
618
619 memcpy(frame->data[1],
620 s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
621
622 s->buf = ctx.buffer;
623 s->size = buf_size;
624
625 if (xan_wc3_decode_frame(s, frame) < 0)
626 return AVERROR_INVALIDDATA;
627
628 if ((ret = av_frame_replace(s->last_frame, frame)) < 0)
629 return ret;
630
631 *got_frame = 1;
632
633 /* always report that the buffer was completely consumed */
634 return buf_size;
635}
636
638 .p.name = "xan_wc3",
639 CODEC_LONG_NAME("Wing Commander III / Xan"),
640 .p.type = AVMEDIA_TYPE_VIDEO,
641 .p.id = AV_CODEC_ID_XAN_WC3,
642 .priv_data_size = sizeof(XanContext),
646 .p.capabilities = AV_CODEC_CAP_DR1,
647 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
648};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_xan_wc3_decoder
Definition xan.c:637
static AVFormatContext * ctx
static void finish(void)
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
return
Libavcodec external API header.
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL byte
Definition bytestream.h:99
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
#define flag(name)
Definition cbs_h264.c:60
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static const uint8_t frame_size[4]
Definition g723_1.h:222
bitstream reader API header.
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition avcodec.h:415
@ AV_CODEC_ID_XAN_WC3
Definition codec_id.h:90
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
int av_frame_replace(AVFrame *dst, const AVFrame *src)
Ensure the destination frame refers to the same data described by the source frame,...
Definition frame.c:376
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition mem.c:445
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int index
Definition gxfenc.c:90
int a
#define PALETTE_COUNT
Definition idcinvideo.c:57
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_RL16(p)
#define av_cold
Definition attributes.h:117
#define FFMIN(a, b)
Definition macros.h:49
#define FFMIN3(a, b, c)
Definition macros.h:50
static av_const int sign_extend(int val, unsigned bits)
Definition mathops.h:135
Memory handling functions.
uint32_t tag
Definition movenc.c:2073
#define av_malloc(s)
Definition ops_static.c:52
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
#define AVPALETTE_COUNT
Definition pixfmt.h:33
#define AVPALETTE_SIZE
Definition pixfmt.h:32
static int square(int x)
#define PALETTE_SIZE
Definition sanm.c:34
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
AVFrame * last_frame
Definition xan.c:55
int frame_size
Definition xan.c:70
int palettes_count
Definition xan.c:67
int cur_palette
Definition xan.c:68
int buffer1_size
Definition xan.c:62
unsigned * palettes
Definition xan.c:66
const uint8_t * buf
Definition xan.c:57
int size
Definition xan.c:58
AVCodecContext * avctx
Definition xan.c:54
uint8_t * buffer1
Definition xan.c:61
uint8_t * buffer2
Definition xan.c:63
int buffer2_size
Definition xan.c:64
#define stride
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
int size
const char * g
Definition vf_curves.c:128
static void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame, const uint8_t *pixel_buffer, int x, int y, int pixel_count)
Definition xan.c:207
#define PALETTES_MAX
Definition xan.c:50
static int xan_huffman_decode(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
Definition xan.c:112
#define VGA__TAG
Definition xan.c:45
static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
Definition xan.c:295
#define SHOT_TAG
Definition xan.c:47
static av_cold int xan_decode_init(AVCodecContext *avctx)
Definition xan.c:87
static int xan_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition xan.c:539
static void xan_unpack(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
unpack simple compression
Definition xan.c:153
static av_cold int xan_decode_end(AVCodecContext *avctx)
Definition xan.c:74
#define PALT_TAG
Definition xan.c:46
static void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame, int x, int y, int pixel_count, int motion_x, int motion_y)
Definition xan.c:237
static const uint8_t gamma_lookup[256]
This is a gamma correction that xan3 applies to all palette entries.
Definition xan.c:503