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 * @return number of bytes written to dest
153 */
154static int xan_unpack(uint8_t *dest, int dest_len,
155 const uint8_t *src, int src_len)
156{
157 uint8_t opcode;
158 int size;
159 uint8_t *dest_org = dest;
160 uint8_t *dest_end = dest + dest_len;
162
163 bytestream2_init(&ctx, src, src_len);
164 while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
165 opcode = bytestream2_get_byte(&ctx);
166
167 if (opcode < 0xe0) {
168 int size2, back;
169 if ((opcode & 0x80) == 0) {
170 size = opcode & 3;
171
172 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
173 size2 = ((opcode & 0x1c) >> 2) + 3;
174 } else if ((opcode & 0x40) == 0) {
175 size = bytestream2_peek_byte(&ctx) >> 6;
176
177 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
178 size2 = (opcode & 0x3f) + 4;
179 } else {
180 size = opcode & 3;
181
182 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
183 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
184 }
185
186 if (dest_end - dest < size + size2 ||
187 dest + size - dest_org < back ||
189 break;
191 dest += size;
192 av_memcpy_backptr(dest, back, size2);
193 dest += size2;
194 } else {
195 int finish = opcode >= 0xfc;
196 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
197
198 if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
199 break;
201 dest += size;
202 if (finish)
203 break;
204 }
205 }
206 return dest - dest_org;
207}
208
210 const uint8_t *pixel_buffer, int x, int y, int pixel_count)
211{
212 int stride;
213 int line_inc;
214 int index;
215 int current_x;
216 int width = s->avctx->width;
217 uint8_t *palette_plane;
218
219 palette_plane = frame->data[0];
220 stride = frame->linesize[0];
221 line_inc = stride - width;
222 index = y * stride + x;
223 current_x = x;
224 while (pixel_count && index < s->frame_size) {
225 int count = FFMIN(pixel_count, width - current_x);
226 memcpy(palette_plane + index, pixel_buffer, count);
227 pixel_count -= count;
228 index += count;
229 pixel_buffer += count;
230 current_x += count;
231
232 if (current_x >= width) {
233 index += line_inc;
234 current_x = 0;
235 }
236 }
237}
238
240 int x, int y,
241 int pixel_count, int motion_x,
242 int motion_y)
243{
244 int stride;
245 int line_inc;
246 int curframe_index, prevframe_index;
247 int curframe_x, prevframe_x;
248 int width = s->avctx->width;
249 uint8_t *palette_plane, *prev_palette_plane;
250
251 if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
252 x + motion_x < 0 || x + motion_x >= s->avctx->width)
253 return;
254
255 palette_plane = frame->data[0];
256 prev_palette_plane = s->last_frame->data[0];
257 if (!prev_palette_plane)
258 prev_palette_plane = palette_plane;
259 stride = frame->linesize[0];
260 line_inc = stride - width;
261 curframe_index = y * stride + x;
262 curframe_x = x;
263 prevframe_index = (y + motion_y) * stride + x + motion_x;
264 prevframe_x = x + motion_x;
265
266 if (prev_palette_plane == palette_plane && FFABS(motion_x + width*motion_y) < pixel_count) {
267 avpriv_request_sample(s->avctx, "Overlapping copy");
268 return ;
269 }
270
271 while (pixel_count &&
272 curframe_index < s->frame_size &&
273 prevframe_index < s->frame_size) {
274 int count = FFMIN3(pixel_count, width - curframe_x,
275 width - prevframe_x);
276
277 memcpy(palette_plane + curframe_index,
278 prev_palette_plane + prevframe_index, count);
279 pixel_count -= count;
280 curframe_index += count;
281 prevframe_index += count;
282 curframe_x += count;
283 prevframe_x += count;
284
285 if (curframe_x >= width) {
286 curframe_index += line_inc;
287 curframe_x = 0;
288 }
289
290 if (prevframe_x >= width) {
291 prevframe_index += line_inc;
292 prevframe_x = 0;
293 }
294 }
295}
296
298{
299
300 int width = s->avctx->width;
301 int height = s->avctx->height;
302 int total_pixels = width * height;
303 uint8_t opcode;
304 uint8_t flag = 0;
305 int size = 0;
306 int motion_x, motion_y;
307 int x, y, ret;
308
309 uint8_t *opcode_buffer = s->buffer1;
310 uint8_t *opcode_buffer_end = s->buffer1 + s->buffer1_size;
311 int opcode_buffer_size = s->buffer1_size;
312 const uint8_t *imagedata_buffer = s->buffer2;
313
314 /* pointers to segments inside the compressed chunk */
315 const uint8_t *huffman_segment;
316 GetByteContext size_segment;
317 GetByteContext vector_segment;
318 const uint8_t *imagedata_segment;
319 int huffman_offset, size_offset, vector_offset, imagedata_offset,
320 imagedata_size;
321
322 if (s->size < 8)
323 return AVERROR_INVALIDDATA;
324
325 huffman_offset = AV_RL16(&s->buf[0]);
326 size_offset = AV_RL16(&s->buf[2]);
327 vector_offset = AV_RL16(&s->buf[4]);
328 imagedata_offset = AV_RL16(&s->buf[6]);
329
330 if (huffman_offset >= s->size ||
331 size_offset >= s->size ||
332 vector_offset >= s->size ||
333 imagedata_offset >= s->size)
334 return AVERROR_INVALIDDATA;
335
336 huffman_segment = s->buf + huffman_offset;
337 bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset);
338 bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset);
339 imagedata_segment = s->buf + imagedata_offset;
340
341 if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size,
342 huffman_segment, s->size - huffman_offset)) < 0)
343 return AVERROR_INVALIDDATA;
344 opcode_buffer_end = opcode_buffer + ret;
345
346 if (imagedata_segment[0] == 2) {
347 imagedata_size = xan_unpack(s->buffer2, s->buffer2_size,
348 &imagedata_segment[1], s->size - imagedata_offset - 1);
349 } else {
350 imagedata_size = s->size - imagedata_offset - 1;
351 imagedata_buffer = &imagedata_segment[1];
352 }
353
354 /* use the decoded data segments to build the frame */
355 x = y = 0;
356 while (total_pixels && opcode_buffer < opcode_buffer_end) {
357
358 opcode = *opcode_buffer++;
359 size = 0;
360
361 switch (opcode) {
362
363 case 0:
364 flag ^= 1;
365 continue;
366
367 case 1:
368 case 2:
369 case 3:
370 case 4:
371 case 5:
372 case 6:
373 case 7:
374 case 8:
375 size = opcode;
376 break;
377
378 case 12:
379 case 13:
380 case 14:
381 case 15:
382 case 16:
383 case 17:
384 case 18:
385 size += (opcode - 10);
386 break;
387
388 case 9:
389 case 19:
390 if (bytestream2_get_bytes_left(&size_segment) < 1) {
391 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
392 return AVERROR_INVALIDDATA;
393 }
394 size = bytestream2_get_byte(&size_segment);
395 break;
396
397 case 10:
398 case 20:
399 if (bytestream2_get_bytes_left(&size_segment) < 2) {
400 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
401 return AVERROR_INVALIDDATA;
402 }
403 size = bytestream2_get_be16(&size_segment);
404 break;
405
406 case 11:
407 case 21:
408 if (bytestream2_get_bytes_left(&size_segment) < 3) {
409 av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
410 return AVERROR_INVALIDDATA;
411 }
412 size = bytestream2_get_be24(&size_segment);
413 break;
414 }
415
416 if (size > total_pixels)
417 break;
418
419 if (opcode < 12) {
420 flag ^= 1;
421 if (flag) {
422 /* run of (size) pixels is unchanged from last frame */
423 xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
424 } else {
425 /* output a run of pixels from imagedata_buffer */
426 if (imagedata_size < size)
427 break;
428 xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
429 imagedata_buffer += size;
430 imagedata_size -= size;
431 }
432 } else {
433 uint8_t vector;
434 if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
435 av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
436 return AVERROR_INVALIDDATA;
437 }
438 /* run-based motion compensation from last frame */
439 vector = bytestream2_get_byte(&vector_segment);
440 motion_x = sign_extend(vector >> 4, 4);
441 motion_y = sign_extend(vector & 0xF, 4);
442
443 /* copy a run of pixels from the previous frame */
444 xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
445
446 flag = 0;
447 }
448
449 /* coordinate accounting */
450 total_pixels -= size;
451 y += (x + size) / width;
452 x = (x + size) % width;
453 }
454 return 0;
455}
456
457#if RUNTIME_GAMMA
458static inline unsigned mul(unsigned a, unsigned b)
459{
460 return (a * b) >> 16;
461}
462
463static inline unsigned pow4(unsigned a)
464{
465 unsigned square = mul(a, a);
466 return mul(square, square);
467}
468
469static inline unsigned pow5(unsigned a)
470{
471 return mul(pow4(a), a);
472}
473
474static uint8_t gamma_corr(uint8_t in) {
475 unsigned lo, hi = 0xff40, target;
476 int i = 15;
477 in = (in << 2) | (in >> 6);
478 /* equivalent float code:
479 if (in >= 252)
480 return 253;
481 return round(pow(in / 256.0, 0.8) * 256);
482 */
483 lo = target = in << 8;
484 do {
485 unsigned mid = (lo + hi) >> 1;
486 unsigned pow = pow5(mid);
487 if (pow > target) hi = mid;
488 else lo = mid;
489 } while (--i);
490 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
491}
492#else
493/**
494 * This is a gamma correction that xan3 applies to all palette entries.
495 *
496 * There is a peculiarity, namely that the values are clamped to 253 -
497 * it seems likely that this table was calculated by a buggy fixed-point
498 * implementation, the one above under RUNTIME_GAMMA behaves like this for
499 * example.
500 * The exponent value of 0.8 can be explained by this as well, since 0.8 = 4/5
501 * and thus pow(x, 0.8) is still easy to calculate.
502 * Also, the input values are first rotated to the left by 2.
503 */
504static const uint8_t gamma_lookup[256] = {
505 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
506 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
507 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
508 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
509 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
510 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
511 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
512 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
513 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
514 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
515 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
516 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
517 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
518 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
519 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
520 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
521 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
522 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
523 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
524 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
525 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
526 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
527 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
528 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
529 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
530 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
531 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
532 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
533 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
534 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
535 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
536 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
537};
538#endif
539
541 int *got_frame, AVPacket *avpkt)
542{
543 const uint8_t *buf = avpkt->data;
544 int ret, buf_size = avpkt->size;
545 XanContext *s = avctx->priv_data;
547 int tag = 0;
548
549 bytestream2_init(&ctx, buf, buf_size);
550 while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
551 unsigned *tmpptr;
552 uint32_t new_pal;
553 int size;
554 int i;
555 tag = bytestream2_get_le32(&ctx);
556 size = bytestream2_get_be32(&ctx);
557 if (size < 0) {
558 av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
559 return AVERROR_INVALIDDATA;
560 }
562 switch (tag) {
563 case PALT_TAG:
564 if (size < PALETTE_SIZE)
565 return AVERROR_INVALIDDATA;
566 if (s->palettes_count >= PALETTES_MAX)
567 return AVERROR_INVALIDDATA;
568 tmpptr = av_realloc_array(s->palettes,
569 s->palettes_count + 1, AVPALETTE_SIZE);
570 if (!tmpptr)
571 return AVERROR(ENOMEM);
572 s->palettes = tmpptr;
573 tmpptr += s->palettes_count * AVPALETTE_COUNT;
574 for (i = 0; i < PALETTE_COUNT; i++) {
575#if RUNTIME_GAMMA
576 int r = gamma_corr(bytestream2_get_byteu(&ctx));
577 int g = gamma_corr(bytestream2_get_byteu(&ctx));
578 int b = gamma_corr(bytestream2_get_byteu(&ctx));
579#else
580 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
581 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
582 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
583#endif
584 *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
585 }
586 s->palettes_count++;
587 break;
588 case SHOT_TAG:
589 if (size < 4)
590 return AVERROR_INVALIDDATA;
591 new_pal = bytestream2_get_le32(&ctx);
592 if (new_pal < s->palettes_count) {
593 s->cur_palette = new_pal;
594 } else
595 av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
596 break;
597 case VGA__TAG:
598 break;
599 default:
601 break;
602 }
603 }
604 buf_size = bytestream2_get_bytes_left(&ctx);
605
606 if (s->palettes_count <= 0) {
607 av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
608 return AVERROR_INVALIDDATA;
609 }
610
611 if (buf_size < 9)
612 return AVERROR_INVALIDDATA;
613
614 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
615 return ret;
616
617 if (!s->frame_size)
618 s->frame_size = frame->linesize[0] * s->avctx->height;
619
620 memcpy(frame->data[1],
621 s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
622
623 s->buf = ctx.buffer;
624 s->size = buf_size;
625
626 if (xan_wc3_decode_frame(s, frame) < 0)
627 return AVERROR_INVALIDDATA;
628
629 if ((ret = av_frame_replace(s->last_frame, frame)) < 0)
630 return ret;
631
632 *got_frame = 1;
633
634 /* always report that the buffer was completely consumed */
635 return buf_size;
636}
637
639 .p.name = "xan_wc3",
640 CODEC_LONG_NAME("Wing Commander III / Xan"),
641 .p.type = AVMEDIA_TYPE_VIDEO,
642 .p.id = AV_CODEC_ID_XAN_WC3,
643 .priv_data_size = sizeof(XanContext),
647 .p.capabilities = AV_CODEC_CAP_DR1,
648 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
649};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_xan_wc3_decoder
Definition xan.c:638
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:1781
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:318
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition mem.c:551
@ 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:2127
#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:479
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:209
#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:297
#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:540
static av_cold int xan_decode_end(AVCodecContext *avctx)
Definition xan.c:74
#define PALT_TAG
Definition xan.c:46
static int xan_unpack(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
unpack simple compression
Definition xan.c:154
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:239
static const uint8_t gamma_lookup[256]
This is a gamma correction that xan3 applies to all palette entries.
Definition xan.c:504