FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mem.h"
37 
38 #define BITSTREAM_READER_LE
39 #include "avcodec.h"
40 #include "bytestream.h"
41 #include "get_bits.h"
42 #include "internal.h"
43 
44 #define RUNTIME_GAMMA 0
45 
46 #define VGA__TAG MKTAG('V', 'G', 'A', ' ')
47 #define PALT_TAG MKTAG('P', 'A', 'L', 'T')
48 #define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
49 #define PALETTE_COUNT 256
50 #define PALETTE_SIZE (PALETTE_COUNT * 3)
51 #define PALETTES_MAX 256
52 
53 typedef struct XanContext {
54 
57 
58  const uint8_t *buf;
59  int size;
60 
61  /* scratch space */
66 
67  unsigned *palettes;
70 
72 
73 } XanContext;
74 
76 {
77  XanContext *s = avctx->priv_data;
78 
80 
81  av_freep(&s->buffer1);
82  av_freep(&s->buffer2);
83  av_freep(&s->palettes);
84 
85  return 0;
86 }
87 
89 {
90  XanContext *s = avctx->priv_data;
91 
92  s->avctx = avctx;
93  s->frame_size = 0;
94 
95  avctx->pix_fmt = AV_PIX_FMT_PAL8;
96 
97  s->buffer1_size = avctx->width * avctx->height;
99  if (!s->buffer1)
100  return AVERROR(ENOMEM);
101  s->buffer2_size = avctx->width * avctx->height;
102  s->buffer2 = av_malloc(s->buffer2_size + 130);
103  if (!s->buffer2) {
104  av_freep(&s->buffer1);
105  return AVERROR(ENOMEM);
106  }
107 
108  s->last_frame = av_frame_alloc();
109  if (!s->last_frame) {
110  xan_decode_end(avctx);
111  return AVERROR(ENOMEM);
112  }
113 
114  return 0;
115 }
116 
117 static int xan_huffman_decode(uint8_t *dest, int dest_len,
118  const uint8_t *src, int src_len)
119 {
120  uint8_t byte = *src++;
121  uint8_t ival = byte + 0x16;
122  const uint8_t * ptr = src + byte*2;
123  int ptr_len = src_len - 1 - byte*2;
124  uint8_t val = ival;
125  uint8_t *dest_end = dest + dest_len;
126  uint8_t *dest_start = dest;
127  int ret;
128  GetBitContext gb;
129 
130  if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)
131  return ret;
132 
133  while (val != 0x16) {
134  unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
135  if (idx >= 2 * byte)
136  return AVERROR_INVALIDDATA;
137  val = src[idx];
138 
139  if (val < 0x16) {
140  if (dest >= dest_end)
141  return dest_len;
142  *dest++ = val;
143  val = ival;
144  }
145  }
146 
147  return dest - dest_start;
148 }
149 
150 /**
151  * unpack simple compression
152  *
153  * @param dest destination buffer of dest_len, must be padded with at least 130 bytes
154  */
155 static void xan_unpack(uint8_t *dest, int dest_len,
156  const uint8_t *src, int src_len)
157 {
158  uint8_t opcode;
159  int size;
160  uint8_t *dest_org = dest;
161  uint8_t *dest_end = dest + dest_len;
163 
164  bytestream2_init(&ctx, src, src_len);
165  while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
166  opcode = bytestream2_get_byte(&ctx);
167 
168  if (opcode < 0xe0) {
169  int size2, back;
170  if ((opcode & 0x80) == 0) {
171  size = opcode & 3;
172 
173  back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
174  size2 = ((opcode & 0x1c) >> 2) + 3;
175  } else if ((opcode & 0x40) == 0) {
176  size = bytestream2_peek_byte(&ctx) >> 6;
177 
178  back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
179  size2 = (opcode & 0x3f) + 4;
180  } else {
181  size = opcode & 3;
182 
183  back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
184  size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
185  }
186 
187  if (dest_end - dest < size + size2 ||
188  dest + size - dest_org < back ||
189  bytestream2_get_bytes_left(&ctx) < size)
190  return;
191  bytestream2_get_buffer(&ctx, dest, size);
192  dest += size;
193  av_memcpy_backptr(dest, back, size2);
194  dest += size2;
195  } else {
196  int finish = opcode >= 0xfc;
197  size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
198 
199  if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
200  return;
201  bytestream2_get_buffer(&ctx, dest, size);
202  dest += size;
203  if (finish)
204  return;
205  }
206  }
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(curframe_index - prevframe_index) < 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) {
348  &imagedata_segment[1], s->size - imagedata_offset - 1);
349  imagedata_size = s->buffer2_size;
350  } else {
351  imagedata_size = s->size - imagedata_offset - 1;
352  imagedata_buffer = &imagedata_segment[1];
353  }
354 
355  /* use the decoded data segments to build the frame */
356  x = y = 0;
357  while (total_pixels && opcode_buffer < opcode_buffer_end) {
358 
359  opcode = *opcode_buffer++;
360  size = 0;
361 
362  switch (opcode) {
363 
364  case 0:
365  flag ^= 1;
366  continue;
367 
368  case 1:
369  case 2:
370  case 3:
371  case 4:
372  case 5:
373  case 6:
374  case 7:
375  case 8:
376  size = opcode;
377  break;
378 
379  case 12:
380  case 13:
381  case 14:
382  case 15:
383  case 16:
384  case 17:
385  case 18:
386  size += (opcode - 10);
387  break;
388 
389  case 9:
390  case 19:
391  if (bytestream2_get_bytes_left(&size_segment) < 1) {
392  av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
393  return AVERROR_INVALIDDATA;
394  }
395  size = bytestream2_get_byte(&size_segment);
396  break;
397 
398  case 10:
399  case 20:
400  if (bytestream2_get_bytes_left(&size_segment) < 2) {
401  av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
402  return AVERROR_INVALIDDATA;
403  }
404  size = bytestream2_get_be16(&size_segment);
405  break;
406 
407  case 11:
408  case 21:
409  if (bytestream2_get_bytes_left(&size_segment) < 3) {
410  av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
411  return AVERROR_INVALIDDATA;
412  }
413  size = bytestream2_get_be24(&size_segment);
414  break;
415  }
416 
417  if (size > total_pixels)
418  break;
419 
420  if (opcode < 12) {
421  flag ^= 1;
422  if (flag) {
423  /* run of (size) pixels is unchanged from last frame */
424  xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
425  } else {
426  /* output a run of pixels from imagedata_buffer */
427  if (imagedata_size < size)
428  break;
429  xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
430  imagedata_buffer += size;
431  imagedata_size -= size;
432  }
433  } else {
434  uint8_t vector;
435  if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
436  av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
437  return AVERROR_INVALIDDATA;
438  }
439  /* run-based motion compensation from last frame */
440  vector = bytestream2_get_byte(&vector_segment);
441  motion_x = sign_extend(vector >> 4, 4);
442  motion_y = sign_extend(vector & 0xF, 4);
443 
444  /* copy a run of pixels from the previous frame */
445  xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
446 
447  flag = 0;
448  }
449 
450  /* coordinate accounting */
451  total_pixels -= size;
452  y += (x + size) / width;
453  x = (x + size) % width;
454  }
455  return 0;
456 }
457 
458 #if RUNTIME_GAMMA
459 static inline unsigned mul(unsigned a, unsigned b)
460 {
461  return (a * b) >> 16;
462 }
463 
464 static inline unsigned pow4(unsigned a)
465 {
466  unsigned square = mul(a, a);
467  return mul(square, square);
468 }
469 
470 static inline unsigned pow5(unsigned a)
471 {
472  return mul(pow4(a), a);
473 }
474 
475 static uint8_t gamma_corr(uint8_t in) {
476  unsigned lo, hi = 0xff40, target;
477  int i = 15;
478  in = (in << 2) | (in >> 6);
479  /* equivalent float code:
480  if (in >= 252)
481  return 253;
482  return round(pow(in / 256.0, 0.8) * 256);
483  */
484  lo = target = in << 8;
485  do {
486  unsigned mid = (lo + hi) >> 1;
487  unsigned pow = pow5(mid);
488  if (pow > target) hi = mid;
489  else lo = mid;
490  } while (--i);
491  return (pow4((lo + hi) >> 1) + 0x80) >> 8;
492 }
493 #else
494 /**
495  * This is a gamma correction that xan3 applies to all palette entries.
496  *
497  * There is a peculiarity, namely that the values are clamped to 253 -
498  * it seems likely that this table was calculated by a buggy fixed-point
499  * implementation, the one above under RUNTIME_GAMMA behaves like this for
500  * example.
501  * The exponent value of 0.8 can be explained by this as well, since 0.8 = 4/5
502  * and thus pow(x, 0.8) is still easy to calculate.
503  * Also, the input values are first rotated to the left by 2.
504  */
505 static const uint8_t gamma_lookup[256] = {
506  0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
507  0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
508  0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
509  0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
510  0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
511  0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
512  0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
513  0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
514  0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
515  0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
516  0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
517  0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
518  0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
519  0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
520  0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
521  0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
522  0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
523  0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
524  0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
525  0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
526  0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
527  0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
528  0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
529  0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
530  0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
531  0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
532  0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
533  0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
534  0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
535  0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
536  0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
537  0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
538 };
539 #endif
540 
542  void *data, int *got_frame,
543  AVPacket *avpkt)
544 {
545  AVFrame *frame = data;
546  const uint8_t *buf = avpkt->data;
547  int ret, buf_size = avpkt->size;
548  XanContext *s = avctx->priv_data;
550  int tag = 0;
551 
552  bytestream2_init(&ctx, buf, buf_size);
553  while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
554  unsigned *tmpptr;
555  uint32_t new_pal;
556  int size;
557  int i;
558  tag = bytestream2_get_le32(&ctx);
559  size = bytestream2_get_be32(&ctx);
560  if (size < 0) {
561  av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
562  return AVERROR_INVALIDDATA;
563  }
564  size = FFMIN(size, bytestream2_get_bytes_left(&ctx));
565  switch (tag) {
566  case PALT_TAG:
567  if (size < PALETTE_SIZE)
568  return AVERROR_INVALIDDATA;
569  if (s->palettes_count >= PALETTES_MAX)
570  return AVERROR_INVALIDDATA;
571  tmpptr = av_realloc_array(s->palettes,
573  if (!tmpptr)
574  return AVERROR(ENOMEM);
575  s->palettes = tmpptr;
576  tmpptr += s->palettes_count * AVPALETTE_COUNT;
577  for (i = 0; i < PALETTE_COUNT; i++) {
578 #if RUNTIME_GAMMA
579  int r = gamma_corr(bytestream2_get_byteu(&ctx));
580  int g = gamma_corr(bytestream2_get_byteu(&ctx));
581  int b = gamma_corr(bytestream2_get_byteu(&ctx));
582 #else
583  int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
584  int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
585  int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
586 #endif
587  *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
588  }
589  s->palettes_count++;
590  break;
591  case SHOT_TAG:
592  if (size < 4)
593  return AVERROR_INVALIDDATA;
594  new_pal = bytestream2_get_le32(&ctx);
595  if (new_pal < s->palettes_count) {
596  s->cur_palette = new_pal;
597  } else
598  av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
599  break;
600  case VGA__TAG:
601  break;
602  default:
603  bytestream2_skip(&ctx, size);
604  break;
605  }
606  }
607  buf_size = bytestream2_get_bytes_left(&ctx);
608 
609  if (s->palettes_count <= 0) {
610  av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
611  return AVERROR_INVALIDDATA;
612  }
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],
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 
630  if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
631  return ret;
632 
633  *got_frame = 1;
634 
635  /* always report that the buffer was completely consumed */
636  return buf_size;
637 }
638 
640  .name = "xan_wc3",
641  .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
642  .type = AVMEDIA_TYPE_VIDEO,
643  .id = AV_CODEC_ID_XAN_WC3,
644  .priv_data_size = sizeof(XanContext),
646  .close = xan_decode_end,
648  .capabilities = AV_CODEC_CAP_DR1,
649 };
static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
Definition: xan.c:297
const char const char void * val
Definition: avisynth_c.h:771
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
Memory handling functions.
int frame_size
Definition: xan.c:71
const char * g
Definition: vf_curves.c:112
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1602
const char * b
Definition: vf_curves.c:113
int flag
Definition: cpu.c:34
int palettes_count
Definition: xan.c:68
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1904
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
static void xan_unpack(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
unpack simple compression
Definition: xan.c:155
static const uint8_t gamma_lookup[256]
This is a gamma correction that xan3 applies to all palette entries.
Definition: xan.c:505
AVCodec.
Definition: avcodec.h:3600
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define PALETTES_MAX
Definition: xan.c:51
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:145
uint8_t * buffer1
Definition: xan.c:62
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:73
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
int buffer1_size
Definition: xan.c:63
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:383
AVCodec ff_xan_wc3_decoder
Definition: xan.c:639
static AVFrame * frame
#define height
static void finish(void)
Definition: movenc.c:344
uint8_t * data
Definition: avcodec.h:1601
const uint8_t * buffer
Definition: bytestream.h:34
#define FFMIN3(a, b, c)
Definition: common.h:97
uint32_t tag
Definition: movenc.c:1382
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition: mem.c:430
bitstream reader API header.
#define SHOT_TAG
Definition: xan.c:48
ptrdiff_t size
Definition: opengl_enc.c:101
const uint8_t * buf
Definition: xan.c:58
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:208
#define av_log(a,...)
#define PALT_TAG
Definition: xan.c:47
#define U(x)
Definition: vp56_arith.h:37
static int xan_huffman_decode(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
Definition: xan.c:117
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static av_cold int xan_decode_init(AVCodecContext *avctx)
Definition: xan.c:88
#define AVERROR(e)
Definition: error.h:43
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:158
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
const char * r
Definition: vf_curves.c:111
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
const char * name
Name of the codec implementation.
Definition: avcodec.h:3607
static int square(int x)
Definition: roqvideoenc.c:113
GLsizei count
Definition: opengl_enc.c:109
#define VGA__TAG
Definition: xan.c:46
return
int size
Definition: xan.c:59
#define FFMIN(a, b)
Definition: common.h:96
int buffer2_size
Definition: xan.c:65
#define width
int width
picture width / height.
Definition: avcodec.h:1863
AVFormatContext * ctx
Definition: movenc.c:48
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
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 src
Definition: vp9dsp.c:530
int frame_size
Definition: mxfenc.c:1820
Libavcodec external API header.
static av_cold int xan_decode_end(AVCodecContext *avctx)
Definition: xan.c:75
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:87
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:437
main external API structure.
Definition: avcodec.h:1676
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:947
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
void * buf
Definition: avisynth_c.h:690
Definition: xan.c:53
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:299
unsigned * palettes
Definition: xan.c:67
int index
Definition: gxfenc.c:89
#define AVPALETTE_COUNT
Definition: pixfmt.h:33
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:139
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:493
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
common internal api header.
#define PALETTE_COUNT
Definition: xan.c:49
#define PALETTE_SIZE
Definition: xan.c:50
void * priv_data
Definition: avcodec.h:1718
int cur_palette
Definition: xan.c:69
static int xan_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: xan.c:541
#define av_freep(p)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2035
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
#define stride
This structure stores compressed data.
Definition: avcodec.h:1578
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:1354
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:959
AVCodecContext * avctx
Definition: xan.c:55
AVFrame * last_frame
Definition: xan.c:56
uint8_t * buffer2
Definition: xan.c:64