FFmpeg
dxv.c
Go to the documentation of this file.
1 /*
2  * Resolume DXV decoder
3  * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
4  * Copyright (C) 2018 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <stdint.h>
24 
25 #include "libavutil/imgutils.h"
26 
27 #include "mathops.h"
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "internal.h"
31 #include "lzf.h"
32 #include "texturedsp.h"
33 #include "thread.h"
34 
35 typedef struct DXVContext {
38 
39  uint8_t *tex_data; // Compressed texture
40  uint8_t *ctex_data; // Compressed texture
41  int tex_rat; // Compression ratio
42  int tex_step; // Distance between blocks
43  int ctex_step; // Distance between blocks
44  int64_t tex_size; // Texture size
45  int64_t ctex_size; // Texture size
46 
47  /* Optimal number of slices for parallel decoding */
49 
50  uint8_t *op_data[4]; // Opcodes
51  int64_t op_size[4]; // Opcodes size
52 
55 
58 
59  /* Pointer to the selected decompression function */
60  int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
61  int (*tex_funct_planar[2])(uint8_t *plane0, ptrdiff_t stride0,
62  uint8_t *plane1, ptrdiff_t stride1,
63  const uint8_t *block);
64 } DXVContext;
65 
66 static void decompress_indices(uint8_t *dst, const uint8_t *src)
67 {
68  int block, i;
69 
70  for (block = 0; block < 2; block++) {
71  int tmp = AV_RL24(src);
72 
73  /* Unpack 8x3 bit from last 3 byte block */
74  for (i = 0; i < 8; i++)
75  dst[i] = (tmp >> (i * 3)) & 0x7;
76 
77  src += 3;
78  dst += 8;
79  }
80 }
81 
82 static int extract_component(int yo0, int yo1, int code)
83 {
84  int yo;
85 
86  if (yo0 == yo1) {
87  yo = yo0;
88  } else if (code == 0) {
89  yo = yo0;
90  } else if (code == 1) {
91  yo = yo1;
92  } else {
93  if (yo0 > yo1) {
94  yo = (uint8_t) (((8 - code) * yo0 +
95  (code - 1) * yo1) / 7);
96  } else {
97  if (code == 6) {
98  yo = 0;
99  } else if (code == 7) {
100  yo = 255;
101  } else {
102  yo = (uint8_t) (((6 - code) * yo0 +
103  (code - 1) * yo1) / 5);
104  }
105  }
106  }
107 
108  return yo;
109 }
110 
111 static int cocg_block(uint8_t *plane0, ptrdiff_t stride0,
112  uint8_t *plane1, ptrdiff_t stride1,
113  const uint8_t *block)
114 {
115  uint8_t co_indices[16];
116  uint8_t cg_indices[16];
117  uint8_t co0 = *(block);
118  uint8_t co1 = *(block + 1);
119  uint8_t cg0 = *(block + 8);
120  uint8_t cg1 = *(block + 9);
121  int x, y;
122 
123  decompress_indices(co_indices, block + 2);
124  decompress_indices(cg_indices, block + 10);
125 
126  for (y = 0; y < 4; y++) {
127  for (x = 0; x < 4; x++) {
128  int co_code = co_indices[x + y * 4];
129  int cg_code = cg_indices[x + y * 4];
130 
131  plane0[x] = extract_component(cg0, cg1, cg_code);
132  plane1[x] = extract_component(co0, co1, co_code);
133  }
134  plane0 += stride0;
135  plane1 += stride1;
136  }
137 
138  return 16;
139 }
140 
141 static void yao_subblock(uint8_t *dst, uint8_t *yo_indices,
142  ptrdiff_t stride, const uint8_t *block)
143 {
144  uint8_t yo0 = *(block);
145  uint8_t yo1 = *(block + 1);
146  int x, y;
147 
148  decompress_indices(yo_indices, block + 2);
149 
150  for (y = 0; y < 4; y++) {
151  for (x = 0; x < 4; x++) {
152  int yo_code = yo_indices[x + y * 4];
153 
154  dst[x] = extract_component(yo0, yo1, yo_code);
155  }
156  dst += stride;
157  }
158 }
159 
160 static int yo_block(uint8_t *dst, ptrdiff_t stride,
161  uint8_t *unused0, ptrdiff_t unused1,
162  const uint8_t *block)
163 {
164  uint8_t yo_indices[16];
165 
166  yao_subblock(dst, yo_indices, stride, block);
167  yao_subblock(dst + 4, yo_indices, stride, block + 8);
168  yao_subblock(dst + 8, yo_indices, stride, block + 16);
169  yao_subblock(dst + 12, yo_indices, stride, block + 24);
170 
171  return 32;
172 }
173 
174 static int yao_block(uint8_t *plane0, ptrdiff_t stride0,
175  uint8_t *plane3, ptrdiff_t stride1,
176  const uint8_t *block)
177 {
178  uint8_t yo_indices[16];
179  uint8_t a_indices[16];
180 
181  yao_subblock(plane0, yo_indices, stride0, block);
182  yao_subblock(plane3, a_indices, stride1, block + 8);
183  yao_subblock(plane0 + 4, yo_indices, stride0, block + 16);
184  yao_subblock(plane3 + 4, a_indices, stride1, block + 24);
185  yao_subblock(plane0 + 8, yo_indices, stride0, block + 32);
186  yao_subblock(plane3 + 8, a_indices, stride1, block + 40);
187  yao_subblock(plane0 + 12, yo_indices, stride0, block + 48);
188  yao_subblock(plane3 + 12, a_indices, stride1, block + 56);
189 
190  return 64;
191 }
192 
194  int slice, int thread_nb)
195 {
196  DXVContext *ctx = avctx->priv_data;
197  AVFrame *frame = arg;
198  const uint8_t *d = ctx->tex_data;
199  int w_block = avctx->coded_width / ctx->texture_block_w;
200  int h_block = avctx->coded_height / ctx->texture_block_h;
201  int x, y;
202  int start_slice, end_slice;
203 
204  start_slice = h_block * slice / ctx->slice_count;
205  end_slice = h_block * (slice + 1) / ctx->slice_count;
206 
207  if (ctx->tex_funct) {
208  for (y = start_slice; y < end_slice; y++) {
209  uint8_t *p = frame->data[0] + y * frame->linesize[0] * ctx->texture_block_h;
210  int off = y * w_block;
211  for (x = 0; x < w_block; x++) {
212  ctx->tex_funct(p + x * 4 * ctx->texture_block_w, frame->linesize[0],
213  d + (off + x) * ctx->tex_step);
214  }
215  }
216  } else {
217  const uint8_t *c = ctx->ctex_data;
218 
219  for (y = start_slice; y < end_slice; y++) {
220  uint8_t *p0 = frame->data[0] + y * frame->linesize[0] * ctx->texture_block_h;
221  uint8_t *p3 = ctx->tex_step != 64 ? NULL : frame->data[3] + y * frame->linesize[3] * ctx->texture_block_h;
222  int off = y * w_block;
223  for (x = 0; x < w_block; x++) {
224  ctx->tex_funct_planar[0](p0 + x * ctx->texture_block_w, frame->linesize[0],
225  p3 != NULL ? p3 + x * ctx->texture_block_w : NULL, frame->linesize[3],
226  d + (off + x) * ctx->tex_step);
227  }
228  }
229 
230  w_block = (avctx->coded_width / 2) / ctx->ctexture_block_w;
231  h_block = (avctx->coded_height / 2) / ctx->ctexture_block_h;
232  start_slice = h_block * slice / ctx->slice_count;
233  end_slice = h_block * (slice + 1) / ctx->slice_count;
234 
235  for (y = start_slice; y < end_slice; y++) {
236  uint8_t *p0 = frame->data[1] + y * frame->linesize[1] * ctx->ctexture_block_h;
237  uint8_t *p1 = frame->data[2] + y * frame->linesize[2] * ctx->ctexture_block_h;
238  int off = y * w_block;
239  for (x = 0; x < w_block; x++) {
240  ctx->tex_funct_planar[1](p0 + x * ctx->ctexture_block_w, frame->linesize[1],
241  p1 + x * ctx->ctexture_block_w, frame->linesize[2],
242  c + (off + x) * ctx->ctex_step);
243  }
244  }
245  }
246 
247  return 0;
248 }
249 
250 /* This scheme addresses already decoded elements depending on 2-bit status:
251  * 0 -> copy new element
252  * 1 -> copy one element from position -x
253  * 2 -> copy one element from position -(get_byte() + 2) * x
254  * 3 -> copy one element from position -(get_16le() + 0x102) * x
255  * x is always 2 for dxt1 and 4 for dxt5. */
256 #define CHECKPOINT(x) \
257  do { \
258  if (state == 0) { \
259  if (bytestream2_get_bytes_left(gbc) < 4) \
260  return AVERROR_INVALIDDATA; \
261  value = bytestream2_get_le32(gbc); \
262  state = 16; \
263  } \
264  op = value & 0x3; \
265  value >>= 2; \
266  state--; \
267  switch (op) { \
268  case 1: \
269  idx = x; \
270  break; \
271  case 2: \
272  idx = (bytestream2_get_byte(gbc) + 2) * x; \
273  if (idx > pos) { \
274  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
275  return AVERROR_INVALIDDATA; \
276  } \
277  break; \
278  case 3: \
279  idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
280  if (idx > pos) { \
281  av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
282  return AVERROR_INVALIDDATA; \
283  } \
284  break; \
285  } \
286  } while(0)
287 
289 {
290  DXVContext *ctx = avctx->priv_data;
291  GetByteContext *gbc = &ctx->gbc;
292  uint32_t value, prev, op;
293  int idx = 0, state = 0;
294  int pos = 2;
295 
296  /* Copy the first two elements */
297  AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
298  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
299 
300  /* Process input until the whole texture has been filled */
301  while (pos + 2 <= ctx->tex_size / 4) {
302  CHECKPOINT(2);
303 
304  /* Copy two elements from a previous offset or from the input buffer */
305  if (op) {
306  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
307  AV_WL32(ctx->tex_data + 4 * pos, prev);
308  pos++;
309 
310  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
311  AV_WL32(ctx->tex_data + 4 * pos, prev);
312  pos++;
313  } else {
314  CHECKPOINT(2);
315 
316  if (op)
317  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
318  else
319  prev = bytestream2_get_le32(gbc);
320  AV_WL32(ctx->tex_data + 4 * pos, prev);
321  pos++;
322 
323  CHECKPOINT(2);
324 
325  if (op)
326  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
327  else
328  prev = bytestream2_get_le32(gbc);
329  AV_WL32(ctx->tex_data + 4 * pos, prev);
330  pos++;
331  }
332  }
333 
334  return 0;
335 }
336 
337 typedef struct OpcodeTable {
338  int16_t next;
341 } OpcodeTable;
342 
343 static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
344 {
345  unsigned half = 512, bits = 1023, left = 1024, input, mask;
346  int value, counter = 0, rshift = 10, lshift = 30;
347 
348  mask = bytestream2_get_le32(gb) >> 2;
349  while (left) {
350  if (counter >= 256)
351  return AVERROR_INVALIDDATA;
352  value = bits & mask;
353  left -= bits & mask;
354  mask >>= rshift;
355  lshift -= rshift;
356  table[counter++] = value;
357  if (lshift < 16) {
358  if (bytestream2_get_bytes_left(gb) <= 0)
359  return AVERROR_INVALIDDATA;
360 
361  input = bytestream2_get_le16(gb);
362  mask += input << lshift;
363  lshift += 16;
364  }
365  if (left < half) {
366  half >>= 1;
367  bits >>= 1;
368  rshift--;
369  }
370  }
371 
372  for (; !table[counter - 1]; counter--)
373  if (counter <= 0)
374  return AVERROR_INVALIDDATA;
375 
376  *nb_elements = counter;
377 
378  if (counter < 256)
379  memset(&table[counter], 0, 4 * (256 - counter));
380 
381  if (lshift >= 16)
382  bytestream2_seek(gb, -2, SEEK_CUR);
383 
384  return 0;
385 }
386 
387 static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
388 {
389  unsigned table2[256] = { 0 };
390  unsigned x = 0;
391  int val0, val1, i, j = 2, k = 0;
392 
393  table2[0] = table0[0];
394  for (i = 0; i < nb_elements - 1; i++, table2[i] = val0) {
395  val0 = table0[i + 1] + table2[i];
396  }
397 
398  if (!table2[0]) {
399  do {
400  k++;
401  } while (!table2[k]);
402  }
403 
404  j = 2;
405  for (i = 1024; i > 0; i--) {
406  for (table1[x].val1 = k; k < 256 && j > table2[k]; k++);
407  x = (x - 383) & 0x3FF;
408  j++;
409  }
410 
411  if (nb_elements > 0)
412  memcpy(&table2[0], table0, 4 * nb_elements);
413 
414  for (i = 0; i < 1024; i++) {
415  val0 = table1[i].val1;
416  val1 = table2[val0];
417  table2[val0]++;
418  x = 31 - ff_clz(val1);
419  if (x > 10)
420  return AVERROR_INVALIDDATA;
421  table1[i].val2 = 10 - x;
422  table1[i].next = (val1 << table1[i].val2) - 1024;
423  }
424 
425  return 0;
426 }
427 
428 static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
429 {
430  OpcodeTable optable[1024];
431  int sum, x, val, lshift, rshift, ret, i, idx;
432  int64_t size_in_bits;
433  unsigned endoffset, newoffset, offset;
434  unsigned next;
435  uint8_t *src = (uint8_t *)gb->buffer;
436 
437  ret = fill_optable(table, optable, nb_elements);
438  if (ret < 0)
439  return ret;
440 
441  size_in_bits = bytestream2_get_le32(gb);
442  endoffset = ((size_in_bits + 7) >> 3) - 4;
443  if (endoffset <= 0 || bytestream2_get_bytes_left(gb) < endoffset)
444  return AVERROR_INVALIDDATA;
445 
446  offset = endoffset;
447  next = AV_RL32(src + endoffset);
448  rshift = (((size_in_bits & 0xFF) - 1) & 7) + 15;
449  lshift = 32 - rshift;
450  idx = (next >> rshift) & 0x3FF;
451  for (i = 0; i < op_size; i++) {
452  dst[i] = optable[idx].val1;
453  val = optable[idx].val2;
454  sum = val + lshift;
455  x = (next << lshift) >> 1 >> (31 - val);
456  newoffset = offset - (sum >> 3);
457  lshift = sum & 7;
458  idx = x + optable[idx].next;
459  offset = newoffset;
460  if (offset > endoffset)
461  return AVERROR_INVALIDDATA;
462  next = AV_RL32(src + offset);
463  }
464 
465  bytestream2_skip(gb, (size_in_bits + 7 >> 3) - 4);
466 
467  return 0;
468 }
469 
470 static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
471 {
472  int pos = bytestream2_tell(gb);
473  int flag = bytestream2_peek_byte(gb);
474 
475  if ((flag & 3) == 0) {
476  bytestream2_skip(gb, 1);
477  bytestream2_get_buffer(gb, dstp, op_size);
478  } else if ((flag & 3) == 1) {
479  bytestream2_skip(gb, 1);
480  memset(dstp, bytestream2_get_byte(gb), op_size);
481  } else {
482  uint32_t table[256];
483  int ret, elements = 0;
484 
485  ret = fill_ltable(gb, table, &elements);
486  if (ret < 0)
487  return ret;
488  ret = get_opcodes(gb, table, dstp, op_size, elements);
489  if (ret < 0)
490  return ret;
491  }
492  return bytestream2_tell(gb) - pos;
493 }
494 
496  uint8_t *tex_data, int tex_size,
497  uint8_t *op_data, int *oindex,
498  int op_size,
499  uint8_t **dstp, int *statep,
500  uint8_t **tab0, uint8_t **tab1,
501  int offset)
502 {
503  uint8_t *dst = *dstp;
504  uint8_t *tptr0, *tptr1, *tptr3;
505  int oi = *oindex;
506  int state = *statep;
507  int opcode, v, vv;
508 
509  if (state <= 0) {
510  if (oi >= op_size)
511  return AVERROR_INVALIDDATA;
512  opcode = op_data[oi++];
513  if (!opcode) {
514  v = bytestream2_get_byte(gb);
515  if (v == 255) {
516  do {
517  if (bytestream2_get_bytes_left(gb) <= 0)
518  return AVERROR_INVALIDDATA;
519  opcode = bytestream2_get_le16(gb);
520  v += opcode;
521  } while (opcode == 0xFFFF);
522  }
523  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
524  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
525  state = v + 4;
526  goto done;
527  }
528 
529  switch (opcode) {
530  case 1:
531  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
532  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
533  break;
534  case 2:
535  vv = (8 + offset) * (bytestream2_get_le16(gb) + 1);
536  if (vv < 0 || vv > dst - tex_data)
537  return AVERROR_INVALIDDATA;
538  tptr0 = dst - vv;
539  v = AV_RL32(tptr0);
540  AV_WL32(dst, AV_RL32(tptr0));
541  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
542  tab0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
543  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
544  break;
545  case 3:
546  AV_WL32(dst, bytestream2_get_le32(gb));
547  AV_WL32(dst + 4, bytestream2_get_le32(gb));
548  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
549  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
550  break;
551  case 4:
552  tptr3 = tab1[bytestream2_get_byte(gb)];
553  if (!tptr3)
554  return AVERROR_INVALIDDATA;
555  AV_WL16(dst, bytestream2_get_le16(gb));
556  AV_WL16(dst + 2, AV_RL16(tptr3));
557  dst[4] = tptr3[2];
558  AV_WL16(dst + 5, bytestream2_get_le16(gb));
559  dst[7] = bytestream2_get_byte(gb);
560  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
561  break;
562  case 5:
563  tptr3 = tab1[bytestream2_get_byte(gb)];
564  if (!tptr3)
565  return AVERROR_INVALIDDATA;
566  AV_WL16(dst, bytestream2_get_le16(gb));
567  AV_WL16(dst + 2, bytestream2_get_le16(gb));
568  dst[4] = bytestream2_get_byte(gb);
569  AV_WL16(dst + 5, AV_RL16(tptr3));
570  dst[7] = tptr3[2];
571  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
572  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
573  break;
574  case 6:
575  tptr0 = tab1[bytestream2_get_byte(gb)];
576  if (!tptr0)
577  return AVERROR_INVALIDDATA;
578  tptr1 = tab1[bytestream2_get_byte(gb)];
579  if (!tptr1)
580  return AVERROR_INVALIDDATA;
581  AV_WL16(dst, bytestream2_get_le16(gb));
582  AV_WL16(dst + 2, AV_RL16(tptr0));
583  dst[4] = tptr0[2];
584  AV_WL16(dst + 5, AV_RL16(tptr1));
585  dst[7] = tptr1[2];
586  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
587  break;
588  case 7:
589  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
590  if (v < 0 || v > dst - tex_data)
591  return AVERROR_INVALIDDATA;
592  tptr0 = dst - v;
593  AV_WL16(dst, bytestream2_get_le16(gb));
594  AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
595  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
596  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
597  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
598  break;
599  case 8:
600  tptr1 = tab0[bytestream2_get_byte(gb)];
601  if (!tptr1)
602  return AVERROR_INVALIDDATA;
603  AV_WL16(dst, AV_RL16(tptr1));
604  AV_WL16(dst + 2, bytestream2_get_le16(gb));
605  AV_WL32(dst + 4, bytestream2_get_le32(gb));
606  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
607  break;
608  case 9:
609  tptr1 = tab0[bytestream2_get_byte(gb)];
610  if (!tptr1)
611  return AVERROR_INVALIDDATA;
612  tptr3 = tab1[bytestream2_get_byte(gb)];
613  if (!tptr3)
614  return AVERROR_INVALIDDATA;
615  AV_WL16(dst, AV_RL16(tptr1));
616  AV_WL16(dst + 2, AV_RL16(tptr3));
617  dst[4] = tptr3[2];
618  AV_WL16(dst + 5, bytestream2_get_le16(gb));
619  dst[7] = bytestream2_get_byte(gb);
620  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
621  break;
622  case 10:
623  tptr1 = tab0[bytestream2_get_byte(gb)];
624  if (!tptr1)
625  return AVERROR_INVALIDDATA;
626  tptr3 = tab1[bytestream2_get_byte(gb)];
627  if (!tptr3)
628  return AVERROR_INVALIDDATA;
629  AV_WL16(dst, AV_RL16(tptr1));
630  AV_WL16(dst + 2, bytestream2_get_le16(gb));
631  dst[4] = bytestream2_get_byte(gb);
632  AV_WL16(dst + 5, AV_RL16(tptr3));
633  dst[7] = tptr3[2];
634  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
635  break;
636  case 11:
637  tptr0 = tab0[bytestream2_get_byte(gb)];
638  if (!tptr0)
639  return AVERROR_INVALIDDATA;
640  tptr3 = tab1[bytestream2_get_byte(gb)];
641  if (!tptr3)
642  return AVERROR_INVALIDDATA;
643  tptr1 = tab1[bytestream2_get_byte(gb)];
644  if (!tptr1)
645  return AVERROR_INVALIDDATA;
646  AV_WL16(dst, AV_RL16(tptr0));
647  AV_WL16(dst + 2, AV_RL16(tptr3));
648  dst[4] = tptr3[2];
649  AV_WL16(dst + 5, AV_RL16(tptr1));
650  dst[7] = tptr1[2];
651  break;
652  case 12:
653  tptr1 = tab0[bytestream2_get_byte(gb)];
654  if (!tptr1)
655  return AVERROR_INVALIDDATA;
656  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
657  if (v < 0 || v > dst - tex_data)
658  return AVERROR_INVALIDDATA;
659  tptr0 = dst - v;
660  AV_WL16(dst, AV_RL16(tptr1));
661  AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
662  AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
663  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
664  break;
665  case 13:
666  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
667  AV_WL16(dst + 2, bytestream2_get_le16(gb));
668  AV_WL32(dst + 4, bytestream2_get_le32(gb));
669  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
670  break;
671  case 14:
672  tptr3 = tab1[bytestream2_get_byte(gb)];
673  if (!tptr3)
674  return AVERROR_INVALIDDATA;
675  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
676  AV_WL16(dst + 2, AV_RL16(tptr3));
677  dst[4] = tptr3[2];
678  AV_WL16(dst + 5, bytestream2_get_le16(gb));
679  dst[7] = bytestream2_get_byte(gb);
680  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
681  break;
682  case 15:
683  tptr3 = tab1[bytestream2_get_byte(gb)];
684  if (!tptr3)
685  return AVERROR_INVALIDDATA;
686  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
687  AV_WL16(dst + 2, bytestream2_get_le16(gb));
688  dst[4] = bytestream2_get_byte(gb);
689  AV_WL16(dst + 5, AV_RL16(tptr3));
690  dst[7] = tptr3[2];
691  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
692  break;
693  case 16:
694  tptr3 = tab1[bytestream2_get_byte(gb)];
695  if (!tptr3)
696  return AVERROR_INVALIDDATA;
697  tptr1 = tab1[bytestream2_get_byte(gb)];
698  if (!tptr1)
699  return AVERROR_INVALIDDATA;
700  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
701  AV_WL16(dst + 2, AV_RL16(tptr3));
702  dst[4] = tptr3[2];
703  AV_WL16(dst + 5, AV_RL16(tptr1));
704  dst[7] = tptr1[2];
705  break;
706  case 17:
707  v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
708  if (v < 0 || v > dst - tex_data)
709  return AVERROR_INVALIDDATA;
710  AV_WL16(dst, AV_RL16(dst - (8 + offset)));
711  AV_WL16(dst + 2, AV_RL16(&dst[-v + 2]));
712  AV_WL32(dst + 4, AV_RL32(&dst[-v + 4]));
713  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
714  break;
715  default:
716  break;
717  }
718  } else {
719 done:
720  AV_WL32(dst, AV_RL32(dst - (8 + offset)));
721  AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
722  state--;
723  }
724  if (dst - tex_data + 8 > tex_size)
725  return AVERROR_INVALIDDATA;
726  dst += 8;
727 
728  *oindex = oi;
729  *dstp = dst;
730  *statep = state;
731 
732  return 0;
733 }
734 
736  uint8_t *tex_data, int tex_size,
737  uint8_t *op_data0, uint8_t *op_data1,
738  int max_op_size0, int max_op_size1)
739 {
740  uint8_t *dst, *tab2[256] = { 0 }, *tab0[256] = { 0 }, *tab3[256] = { 0 }, *tab1[256] = { 0 };
741  int op_offset = bytestream2_get_le32(gb);
742  unsigned op_size0 = bytestream2_get_le32(gb);
743  unsigned op_size1 = bytestream2_get_le32(gb);
744  int data_start = bytestream2_tell(gb);
745  int skip0, skip1, oi0 = 0, oi1 = 0;
746  int ret, state0 = 0, state1 = 0;
747 
748  if (op_offset < 12 || op_offset - 12 > bytestream2_get_bytes_left(gb))
749  return AVERROR_INVALIDDATA;
750 
751  dst = tex_data;
752  bytestream2_skip(gb, op_offset - 12);
753  if (op_size0 > max_op_size0)
754  return AVERROR_INVALIDDATA;
755  skip0 = dxv_decompress_opcodes(gb, op_data0, op_size0);
756  if (skip0 < 0)
757  return skip0;
758  if (op_size1 > max_op_size1)
759  return AVERROR_INVALIDDATA;
760  skip1 = dxv_decompress_opcodes(gb, op_data1, op_size1);
761  if (skip1 < 0)
762  return skip1;
763  bytestream2_seek(gb, data_start, SEEK_SET);
764 
765  AV_WL32(dst, bytestream2_get_le32(gb));
766  AV_WL32(dst + 4, bytestream2_get_le32(gb));
767  AV_WL32(dst + 8, bytestream2_get_le32(gb));
768  AV_WL32(dst + 12, bytestream2_get_le32(gb));
769 
770  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
771  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
772  tab2[0x9E3779B1 * AV_RL16(dst + 8) >> 24] = dst + 8;
773  tab3[0x9E3779B1 * (AV_RL32(dst + 10) & 0xFFFFFF) >> 24] = dst + 10;
774  dst += 16;
775  while (dst + 10 < tex_data + tex_size) {
776  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data0, &oi0, op_size0,
777  &dst, &state0, tab0, tab1, 8);
778  if (ret < 0)
779  return ret;
780  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data1, &oi1, op_size1,
781  &dst, &state1, tab2, tab3, 8);
782  if (ret < 0)
783  return ret;
784  }
785 
786  bytestream2_seek(gb, data_start - 12 + op_offset + skip0 + skip1, SEEK_SET);
787 
788  return 0;
789 }
790 
792  uint8_t *tex_data, int tex_size,
793  uint8_t *op_data, int max_op_size)
794 {
795  int op_offset = bytestream2_get_le32(gb);
796  unsigned op_size = bytestream2_get_le32(gb);
797  int data_start = bytestream2_tell(gb);
798  uint8_t *dst, *table0[256] = { 0 }, *table1[256] = { 0 };
799  int ret, state = 0, skip, oi = 0, v, vv;
800 
801  if (op_offset < 8 || op_offset - 8 > bytestream2_get_bytes_left(gb))
802  return AVERROR_INVALIDDATA;
803 
804  dst = tex_data;
805  bytestream2_skip(gb, op_offset - 8);
806  if (op_size > max_op_size)
807  return AVERROR_INVALIDDATA;
808  skip = dxv_decompress_opcodes(gb, op_data, op_size);
809  if (skip < 0)
810  return skip;
811  bytestream2_seek(gb, data_start, SEEK_SET);
812 
813  v = bytestream2_get_le32(gb);
814  AV_WL32(dst, v);
815  vv = bytestream2_get_le32(gb);
816  table0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
817  AV_WL32(dst + 4, vv);
818  table1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
819  dst += 8;
820 
821  while (dst < tex_data + tex_size) {
822  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data, &oi, op_size,
823  &dst, &state, table0, table1, 0);
824  if (ret < 0)
825  return ret;
826  }
827 
828  bytestream2_seek(gb, data_start + op_offset + skip - 8, SEEK_SET);
829 
830  return 0;
831 }
832 
834 {
835  DXVContext *ctx = avctx->priv_data;
836  GetByteContext *gb = &ctx->gbc;
837  int ret;
838 
839  ret = dxv_decompress_yo(ctx, gb, ctx->tex_data, ctx->tex_size,
840  ctx->op_data[0], ctx->op_size[0]);
841  if (ret < 0)
842  return ret;
843 
844  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
845  ctx->op_data[1], ctx->op_data[2],
846  ctx->op_size[1], ctx->op_size[2]);
847 }
848 
850 {
851  DXVContext *ctx = avctx->priv_data;
852  GetByteContext *gb = &ctx->gbc;
853  int ret;
854 
855  ret = dxv_decompress_cocg(ctx, gb, ctx->tex_data, ctx->tex_size,
856  ctx->op_data[0], ctx->op_data[3],
857  ctx->op_size[0], ctx->op_size[3]);
858  if (ret < 0)
859  return ret;
860 
861  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
862  ctx->op_data[1], ctx->op_data[2],
863  ctx->op_size[1], ctx->op_size[2]);
864 }
865 
867 {
868  DXVContext *ctx = avctx->priv_data;
869  GetByteContext *gbc = &ctx->gbc;
870  uint32_t value, op;
871  int idx, prev, state = 0;
872  int pos = 4;
873  int run = 0;
874  int probe, check;
875 
876  /* Copy the first four elements */
877  AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
878  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
879  AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
880  AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
881 
882  /* Process input until the whole texture has been filled */
883  while (pos + 2 <= ctx->tex_size / 4) {
884  if (run) {
885  run--;
886 
887  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
888  AV_WL32(ctx->tex_data + 4 * pos, prev);
889  pos++;
890  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
891  AV_WL32(ctx->tex_data + 4 * pos, prev);
892  pos++;
893  } else {
894  if (bytestream2_get_bytes_left(gbc) < 1)
895  return AVERROR_INVALIDDATA;
896  if (state == 0) {
897  value = bytestream2_get_le32(gbc);
898  state = 16;
899  }
900  op = value & 0x3;
901  value >>= 2;
902  state--;
903 
904  switch (op) {
905  case 0:
906  /* Long copy */
907  check = bytestream2_get_byte(gbc) + 1;
908  if (check == 256) {
909  do {
910  probe = bytestream2_get_le16(gbc);
911  check += probe;
912  } while (probe == 0xFFFF);
913  }
914  while (check && pos + 4 <= ctx->tex_size / 4) {
915  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
916  AV_WL32(ctx->tex_data + 4 * pos, prev);
917  pos++;
918 
919  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
920  AV_WL32(ctx->tex_data + 4 * pos, prev);
921  pos++;
922 
923  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
924  AV_WL32(ctx->tex_data + 4 * pos, prev);
925  pos++;
926 
927  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
928  AV_WL32(ctx->tex_data + 4 * pos, prev);
929  pos++;
930 
931  check--;
932  }
933 
934  /* Restart (or exit) the loop */
935  continue;
936  break;
937  case 1:
938  /* Load new run value */
939  run = bytestream2_get_byte(gbc);
940  if (run == 255) {
941  do {
942  probe = bytestream2_get_le16(gbc);
943  run += probe;
944  } while (probe == 0xFFFF);
945  }
946 
947  /* Copy two dwords from previous data */
948  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
949  AV_WL32(ctx->tex_data + 4 * pos, prev);
950  pos++;
951 
952  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
953  AV_WL32(ctx->tex_data + 4 * pos, prev);
954  pos++;
955  break;
956  case 2:
957  /* Copy two dwords from a previous index */
958  idx = 8 + bytestream2_get_le16(gbc);
959  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
960  return AVERROR_INVALIDDATA;
961  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
962  AV_WL32(ctx->tex_data + 4 * pos, prev);
963  pos++;
964 
965  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
966  AV_WL32(ctx->tex_data + 4 * pos, prev);
967  pos++;
968  break;
969  case 3:
970  /* Copy two dwords from input */
971  prev = bytestream2_get_le32(gbc);
972  AV_WL32(ctx->tex_data + 4 * pos, prev);
973  pos++;
974 
975  prev = bytestream2_get_le32(gbc);
976  AV_WL32(ctx->tex_data + 4 * pos, prev);
977  pos++;
978  break;
979  }
980  }
981 
982  CHECKPOINT(4);
983  if (pos + 2 > ctx->tex_size / 4)
984  return AVERROR_INVALIDDATA;
985 
986  /* Copy two elements from a previous offset or from the input buffer */
987  if (op) {
988  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
989  return AVERROR_INVALIDDATA;
990  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
991  AV_WL32(ctx->tex_data + 4 * pos, prev);
992  pos++;
993 
994  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
995  AV_WL32(ctx->tex_data + 4 * pos, prev);
996  pos++;
997  } else {
998  CHECKPOINT(4);
999 
1000  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
1001  return AVERROR_INVALIDDATA;
1002  if (op)
1003  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1004  else
1005  prev = bytestream2_get_le32(gbc);
1006  AV_WL32(ctx->tex_data + 4 * pos, prev);
1007  pos++;
1008 
1009  CHECKPOINT(4);
1010 
1011  if (op)
1012  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1013  else
1014  prev = bytestream2_get_le32(gbc);
1015  AV_WL32(ctx->tex_data + 4 * pos, prev);
1016  pos++;
1017  }
1018  }
1019 
1020  return 0;
1021 }
1022 
1024 {
1025  DXVContext *ctx = avctx->priv_data;
1026  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
1027 }
1028 
1030 {
1031  DXVContext *ctx = avctx->priv_data;
1032  GetByteContext *gbc = &ctx->gbc;
1033 
1034  if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
1035  return AVERROR_INVALIDDATA;
1036 
1037  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
1038  return 0;
1039 }
1040 
1041 static int dxv_decode(AVCodecContext *avctx, void *data,
1042  int *got_frame, AVPacket *avpkt)
1043 {
1044  DXVContext *ctx = avctx->priv_data;
1045  ThreadFrame tframe;
1046  GetByteContext *gbc = &ctx->gbc;
1047  int (*decompress_tex)(AVCodecContext *avctx);
1048  const char *msgcomp, *msgtext;
1049  uint32_t tag;
1050  int version_major, version_minor = 0;
1051  int size = 0, old_type = 0;
1052  int ret;
1053 
1054  bytestream2_init(gbc, avpkt->data, avpkt->size);
1055 
1056  ctx->texture_block_h = 4;
1057  ctx->texture_block_w = 4;
1058 
1059  avctx->pix_fmt = AV_PIX_FMT_RGBA;
1060  avctx->colorspace = AVCOL_SPC_RGB;
1061 
1062  ctx->tex_funct = NULL;
1063  ctx->tex_funct_planar[0] = NULL;
1064  ctx->tex_funct_planar[1] = NULL;
1065 
1066  tag = bytestream2_get_le32(gbc);
1067  switch (tag) {
1068  case MKBETAG('D', 'X', 'T', '1'):
1069  decompress_tex = dxv_decompress_dxt1;
1070  ctx->tex_funct = ctx->texdsp.dxt1_block;
1071  ctx->tex_rat = 8;
1072  ctx->tex_step = 8;
1073  msgcomp = "DXTR1";
1074  msgtext = "DXT1";
1075  break;
1076  case MKBETAG('D', 'X', 'T', '5'):
1077  decompress_tex = dxv_decompress_dxt5;
1078  ctx->tex_funct = ctx->texdsp.dxt5_block;
1079  ctx->tex_rat = 4;
1080  ctx->tex_step = 16;
1081  msgcomp = "DXTR5";
1082  msgtext = "DXT5";
1083  break;
1084  case MKBETAG('Y', 'C', 'G', '6'):
1085  decompress_tex = dxv_decompress_ycg6;
1086  ctx->tex_funct_planar[0] = yo_block;
1087  ctx->tex_funct_planar[1] = cocg_block;
1088  ctx->tex_rat = 8;
1089  ctx->tex_step = 32;
1090  ctx->ctex_step = 16;
1091  msgcomp = "YOCOCG6";
1092  msgtext = "YCG6";
1093  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1094  ctx->texture_block_h = 4;
1095  ctx->texture_block_w = 16;
1096  ctx->ctexture_block_h = 4;
1097  ctx->ctexture_block_w = 4;
1098  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1099  avctx->colorspace = AVCOL_SPC_YCOCG;
1100  break;
1101  case MKBETAG('Y', 'G', '1', '0'):
1102  decompress_tex = dxv_decompress_yg10;
1103  ctx->tex_funct_planar[0] = yao_block;
1104  ctx->tex_funct_planar[1] = cocg_block;
1105  ctx->tex_rat = 4;
1106  ctx->tex_step = 64;
1107  ctx->ctex_step = 16;
1108  msgcomp = "YAOCOCG10";
1109  msgtext = "YG10";
1110  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1111  ctx->texture_block_h = 4;
1112  ctx->texture_block_w = 16;
1113  ctx->ctexture_block_h = 4;
1114  ctx->ctexture_block_w = 4;
1115  avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
1116  avctx->colorspace = AVCOL_SPC_YCOCG;
1117  break;
1118  default:
1119  /* Old version does not have a real header, just size and type. */
1120  size = tag & 0x00FFFFFF;
1121  old_type = tag >> 24;
1122  version_major = (old_type & 0x0F) - 1;
1123 
1124  if (old_type & 0x80) {
1125  msgcomp = "RAW";
1126  decompress_tex = dxv_decompress_raw;
1127  } else {
1128  msgcomp = "LZF";
1129  decompress_tex = dxv_decompress_lzf;
1130  }
1131 
1132  if (old_type & 0x40) {
1133  msgtext = "DXT5";
1134 
1135  ctx->tex_funct = ctx->texdsp.dxt5_block;
1136  ctx->tex_step = 16;
1137  } else if (old_type & 0x20 || version_major == 1) {
1138  msgtext = "DXT1";
1139 
1140  ctx->tex_funct = ctx->texdsp.dxt1_block;
1141  ctx->tex_step = 8;
1142  } else {
1143  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
1144  return AVERROR_INVALIDDATA;
1145  }
1146  ctx->tex_rat = 1;
1147  break;
1148  }
1149 
1150  ctx->slice_count = av_clip(avctx->thread_count, 1,
1151  avctx->coded_height / FFMAX(ctx->texture_block_h,
1152  ctx->ctexture_block_h));
1153 
1154  /* New header is 12 bytes long. */
1155  if (!old_type) {
1156  version_major = bytestream2_get_byte(gbc) - 1;
1157  version_minor = bytestream2_get_byte(gbc);
1158 
1159  /* Encoder copies texture data when compression is not advantageous. */
1160  if (bytestream2_get_byte(gbc)) {
1161  msgcomp = "RAW";
1162  ctx->tex_rat = 1;
1163  decompress_tex = dxv_decompress_raw;
1164  }
1165 
1166  bytestream2_skip(gbc, 1); // unknown
1167  size = bytestream2_get_le32(gbc);
1168  }
1169  av_log(avctx, AV_LOG_DEBUG,
1170  "%s compression with %s texture (version %d.%d)\n",
1171  msgcomp, msgtext, version_major, version_minor);
1172 
1173  if (size != bytestream2_get_bytes_left(gbc)) {
1174  av_log(avctx, AV_LOG_ERROR,
1175  "Incomplete or invalid file (header %d, left %u).\n",
1177  return AVERROR_INVALIDDATA;
1178  }
1179 
1180  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
1181  ret = av_reallocp(&ctx->tex_data, ctx->tex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1182  if (ret < 0)
1183  return ret;
1184 
1185  if (ctx->ctex_size) {
1186  int i;
1187 
1188  ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
1189  ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
1190  ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
1191  ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
1192 
1193  ret = av_reallocp(&ctx->ctex_data, ctx->ctex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1194  if (ret < 0)
1195  return ret;
1196  for (i = 0; i < 4; i++) {
1197  ret = av_reallocp(&ctx->op_data[i], ctx->op_size[i]);
1198  if (ret < 0)
1199  return ret;
1200  }
1201  }
1202 
1203  /* Decompress texture out of the intermediate compression. */
1204  ret = decompress_tex(avctx);
1205  if (ret < 0)
1206  return ret;
1207  {
1208  int w_block = avctx->coded_width / ctx->texture_block_w;
1209  int h_block = avctx->coded_height / ctx->texture_block_h;
1210  if (w_block * h_block * ctx->tex_step > ctx->tex_size * 8LL)
1211  return AVERROR_INVALIDDATA;
1212  }
1213 
1214  tframe.f = data;
1215  ret = ff_thread_get_buffer(avctx, &tframe, 0);
1216  if (ret < 0)
1217  return ret;
1218 
1219  /* Now decompress the texture with the standard functions. */
1220  avctx->execute2(avctx, decompress_texture_thread,
1221  tframe.f, NULL, ctx->slice_count);
1222 
1223  /* Frame is ready to be output. */
1224  tframe.f->pict_type = AV_PICTURE_TYPE_I;
1225  tframe.f->key_frame = 1;
1226  *got_frame = 1;
1227 
1228  return avpkt->size;
1229 }
1230 
1231 static int dxv_init(AVCodecContext *avctx)
1232 {
1233  DXVContext *ctx = avctx->priv_data;
1234  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1235 
1236  if (ret < 0) {
1237  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
1238  avctx->width, avctx->height);
1239  return ret;
1240  }
1241 
1242  /* Codec requires 16x16 alignment. */
1243  avctx->coded_width = FFALIGN(avctx->width, 16);
1244  avctx->coded_height = FFALIGN(avctx->height, 16);
1245 
1246  ff_texturedsp_init(&ctx->texdsp);
1247 
1248  return 0;
1249 }
1250 
1251 static int dxv_close(AVCodecContext *avctx)
1252 {
1253  DXVContext *ctx = avctx->priv_data;
1254 
1255  av_freep(&ctx->tex_data);
1256  av_freep(&ctx->ctex_data);
1257  av_freep(&ctx->op_data[0]);
1258  av_freep(&ctx->op_data[1]);
1259  av_freep(&ctx->op_data[2]);
1260  av_freep(&ctx->op_data[3]);
1261 
1262  return 0;
1263 }
1264 
1266  .name = "dxv",
1267  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
1268  .type = AVMEDIA_TYPE_VIDEO,
1269  .id = AV_CODEC_ID_DXV,
1270  .init = dxv_init,
1271  .decode = dxv_decode,
1272  .close = dxv_close,
1273  .priv_data_size = sizeof(DXVContext),
1274  .capabilities = AV_CODEC_CAP_DR1 |
1277  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
1279 };
AVCodec
AVCodec.
Definition: avcodec.h:3481
stride
int stride
Definition: mace.c:144
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
DXVContext::tex_funct
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:60
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:2193
dxv_decompress_yg10
static int dxv_decompress_yg10(AVCodecContext *avctx)
Definition: dxv.c:849
elements
static const ElemCat * elements[ELEMENT_COUNT]
Definition: signature.h:566
GetByteContext
Definition: bytestream.h:33
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
DXVContext::ctex_data
uint8_t * ctex_data
Definition: dxv.c:40
extract_component
static int extract_component(int yo0, int yo1, int code)
Definition: dxv.c:82
fill_optable
static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
Definition: dxv.c:387
ff_clz
#define ff_clz
Definition: intmath.h:142
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
internal.h
AVCOL_SPC_YCOCG
@ AVCOL_SPC_YCOCG
Definition: pixfmt.h:506
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
table
static const uint16_t table[]
Definition: prosumer.c:206
data
const char data[16]
Definition: mxf.c:91
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
Definition: pixfmt.h:497
TextureDSPContext
Definition: texturedsp.h:45
dxv_init
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:1231
DXVContext::gbc
GetByteContext gbc
Definition: dxv.c:37
OpcodeTable
Definition: dxv.c:337
yao_subblock
static void yao_subblock(uint8_t *dst, uint8_t *yo_indices, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:141
thread.h
ThreadFrame::f
AVFrame * f
Definition: thread.h:35
DXVContext::ctex_size
int64_t ctex_size
Definition: dxv.c:45
DXVContext::tex_data
uint8_t * tex_data
Definition: dxv.c:39
bytestream2_get_bytes_left
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
CHECKPOINT
#define CHECKPOINT(x)
Definition: dxv.c:256
dxv_decompress_ycg6
static int dxv_decompress_ycg6(AVCodecContext *avctx)
Definition: dxv.c:833
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
texturedsp.h
dstp
BYTE * dstp
Definition: avisynth_c.h:908
dxv_decompress_lzf
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:1023
decompress_texture_thread
static int decompress_texture_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb)
Definition: dxv.c:193
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:2824
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
DXVContext::op_data
uint8_t * op_data[4]
Definition: dxv.c:50
tab2
const int16_t * tab2
Definition: mace.c:144
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:1753
DXVContext::ctex_step
int ctex_step
Definition: dxv.c:43
dxv_decompress_cgo
static int dxv_decompress_cgo(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data, int *oindex, int op_size, uint8_t **dstp, int *statep, uint8_t **tab0, uint8_t **tab1, int offset)
Definition: dxv.c:495
src
#define src
Definition: vp8dsp.c:254
tab1
const int16_t * tab1
Definition: mace.c:144
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
state
static struct @313 state
check
#define check(x, y, S, v)
Definition: motion_est_template.c:404
mask
static const uint16_t mask[17]
Definition: lzw.c:38
fill_ltable
static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
Definition: dxv.c:343
get_opcodes
static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
Definition: dxv.c:428
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:78
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
bits
uint8_t bits
Definition: vp3data.h:202
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_texturedsp_init
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:637
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:90
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
dxv_close
static int dxv_close(AVCodecContext *avctx)
Definition: dxv.c:1251
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
arg
const char * arg
Definition: jacosubdec.c:66
if
if(ret)
Definition: filter_design.txt:179
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1037
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:206
dxv_decompress_dxt1
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition: dxv.c:288
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
yao_block
static int yao_block(uint8_t *plane0, ptrdiff_t stride0, uint8_t *plane3, ptrdiff_t stride1, const uint8_t *block)
Definition: dxv.c:174
mathops.h
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:964
DXVContext::ctexture_block_w
int ctexture_block_w
Definition: dxv.c:56
DXVContext::tex_step
int tex_step
Definition: dxv.c:42
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
cocg_block
static int cocg_block(uint8_t *plane0, ptrdiff_t stride0, uint8_t *plane1, ptrdiff_t stride1, const uint8_t *block)
Definition: dxv.c:111
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
ff_dxv_decoder
AVCodec ff_dxv_decoder
Definition: dxv.c:1265
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
AVPacket::size
int size
Definition: avcodec.h:1478
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
AV_CODEC_ID_DXV
@ AV_CODEC_ID_DXV
Definition: avcodec.h:409
size
int size
Definition: twinvq_data.h:11134
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:163
ff_lzf_uncompress
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
Definition: lzf.c:40
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: common.h:367
DXVContext::op_size
int64_t op_size[4]
Definition: dxv.c:51
AV_RL24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:89
val
const char const char void * val
Definition: avisynth_c.h:863
OpcodeTable::val2
uint8_t val2
Definition: dxv.c:340
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: avcodec.h:1041
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
DXVContext
Definition: dxv.c:35
DXVContext::tex_rat
int tex_rat
Definition: dxv.c:41
flag
#define flag(name)
Definition: cbs_av1.c:557
OpcodeTable::next
int16_t next
Definition: dxv.c:338
decompress_indices
static void decompress_indices(uint8_t *dst, const uint8_t *src)
Definition: dxv.c:66
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
dxv_decompress_yo
static int dxv_decompress_yo(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data, int max_op_size)
Definition: dxv.c:791
AVCodecContext::height
int height
Definition: avcodec.h:1738
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
avcodec.h
tag
uint32_t tag
Definition: movenc.c:1496
ret
ret
Definition: filter_design.txt:187
dxv_decode
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:1041
DXVContext::tex_funct_planar
int(* tex_funct_planar[2])(uint8_t *plane0, ptrdiff_t stride0, uint8_t *plane1, ptrdiff_t stride1, const uint8_t *block)
Definition: dxv.c:61
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
DXVContext::tex_size
int64_t tex_size
Definition: dxv.c:44
DXVContext::ctexture_block_h
int ctexture_block_h
Definition: dxv.c:57
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:790
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
probe
static int probe(const AVProbeData *p)
Definition: act.c:36
dxv_decompress_opcodes
static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
Definition: dxv.c:470
ThreadFrame
Definition: thread.h:34
OpcodeTable::val1
uint8_t val1
Definition: dxv.c:339
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1753
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
DXVContext::slice_count
int slice_count
Definition: dxv.c:48
DXVContext::texture_block_h
int texture_block_h
Definition: dxv.c:54
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
bytestream.h
imgutils.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
yo_block
static int yo_block(uint8_t *dst, ptrdiff_t stride, uint8_t *unused0, ptrdiff_t unused1, const uint8_t *block)
Definition: dxv.c:160
DXVContext::texture_block_w
int texture_block_w
Definition: dxv.c:53
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
dxv_decompress_dxt5
static int dxv_decompress_dxt5(AVCodecContext *avctx)
Definition: dxv.c:866
dxv_decompress_cocg
static int dxv_decompress_cocg(DXVContext *ctx, GetByteContext *gb, uint8_t *tex_data, int tex_size, uint8_t *op_data0, uint8_t *op_data1, int max_op_size0, int max_op_size1)
Definition: dxv.c:735
av_image_check_size
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:282
dxv_decompress_raw
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:1029
int
int
Definition: ffmpeg_filter.c:191
lzf.h
AVCodecContext::execute2
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition: avcodec.h:2884
DXVContext::texdsp
TextureDSPContext texdsp
Definition: dxv.c:36