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 "codec_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;
339  uint8_t val1;
340  uint8_t val2;
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, prev;
871  int idx, 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 
1042  int *got_frame, AVPacket *avpkt)
1043 {
1044  DXVContext *ctx = avctx->priv_data;
1045  GetByteContext *gbc = &ctx->gbc;
1046  int (*decompress_tex)(AVCodecContext *avctx);
1047  const char *msgcomp, *msgtext;
1048  uint32_t tag;
1049  int version_major, version_minor = 0;
1050  int size = 0, old_type = 0;
1051  int ret;
1052 
1053  bytestream2_init(gbc, avpkt->data, avpkt->size);
1054 
1055  ctx->texture_block_h = 4;
1056  ctx->texture_block_w = 4;
1057 
1058  avctx->pix_fmt = AV_PIX_FMT_RGBA;
1059  avctx->colorspace = AVCOL_SPC_RGB;
1060 
1061  ctx->tex_funct = NULL;
1062  ctx->tex_funct_planar[0] = NULL;
1063  ctx->tex_funct_planar[1] = NULL;
1064 
1065  tag = bytestream2_get_le32(gbc);
1066  switch (tag) {
1067  case MKBETAG('D', 'X', 'T', '1'):
1068  decompress_tex = dxv_decompress_dxt1;
1069  ctx->tex_funct = ctx->texdsp.dxt1_block;
1070  ctx->tex_rat = 8;
1071  ctx->tex_step = 8;
1072  msgcomp = "DXTR1";
1073  msgtext = "DXT1";
1074  break;
1075  case MKBETAG('D', 'X', 'T', '5'):
1076  decompress_tex = dxv_decompress_dxt5;
1077  ctx->tex_funct = ctx->texdsp.dxt5_block;
1078  ctx->tex_rat = 4;
1079  ctx->tex_step = 16;
1080  msgcomp = "DXTR5";
1081  msgtext = "DXT5";
1082  break;
1083  case MKBETAG('Y', 'C', 'G', '6'):
1084  decompress_tex = dxv_decompress_ycg6;
1085  ctx->tex_funct_planar[0] = yo_block;
1086  ctx->tex_funct_planar[1] = cocg_block;
1087  ctx->tex_rat = 8;
1088  ctx->tex_step = 32;
1089  ctx->ctex_step = 16;
1090  msgcomp = "YOCOCG6";
1091  msgtext = "YCG6";
1092  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1093  ctx->texture_block_h = 4;
1094  ctx->texture_block_w = 16;
1095  ctx->ctexture_block_h = 4;
1096  ctx->ctexture_block_w = 4;
1097  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1098  avctx->colorspace = AVCOL_SPC_YCOCG;
1099  break;
1100  case MKBETAG('Y', 'G', '1', '0'):
1101  decompress_tex = dxv_decompress_yg10;
1102  ctx->tex_funct_planar[0] = yao_block;
1103  ctx->tex_funct_planar[1] = cocg_block;
1104  ctx->tex_rat = 4;
1105  ctx->tex_step = 64;
1106  ctx->ctex_step = 16;
1107  msgcomp = "YAOCOCG10";
1108  msgtext = "YG10";
1109  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1110  ctx->texture_block_h = 4;
1111  ctx->texture_block_w = 16;
1112  ctx->ctexture_block_h = 4;
1113  ctx->ctexture_block_w = 4;
1114  avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
1115  avctx->colorspace = AVCOL_SPC_YCOCG;
1116  break;
1117  default:
1118  /* Old version does not have a real header, just size and type. */
1119  size = tag & 0x00FFFFFF;
1120  old_type = tag >> 24;
1121  version_major = (old_type & 0x0F) - 1;
1122 
1123  if (old_type & 0x80) {
1124  msgcomp = "RAW";
1125  decompress_tex = dxv_decompress_raw;
1126  } else {
1127  msgcomp = "LZF";
1128  decompress_tex = dxv_decompress_lzf;
1129  }
1130 
1131  if (old_type & 0x40) {
1132  msgtext = "DXT5";
1133 
1134  ctx->tex_funct = ctx->texdsp.dxt5_block;
1135  ctx->tex_step = 16;
1136  } else if (old_type & 0x20 || version_major == 1) {
1137  msgtext = "DXT1";
1138 
1139  ctx->tex_funct = ctx->texdsp.dxt1_block;
1140  ctx->tex_step = 8;
1141  } else {
1142  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
1143  return AVERROR_INVALIDDATA;
1144  }
1145  ctx->tex_rat = 1;
1146  break;
1147  }
1148 
1149  ctx->slice_count = av_clip(avctx->thread_count, 1,
1150  avctx->coded_height / FFMAX(ctx->texture_block_h,
1151  ctx->ctexture_block_h));
1152 
1153  /* New header is 12 bytes long. */
1154  if (!old_type) {
1155  version_major = bytestream2_get_byte(gbc) - 1;
1156  version_minor = bytestream2_get_byte(gbc);
1157 
1158  /* Encoder copies texture data when compression is not advantageous. */
1159  if (bytestream2_get_byte(gbc)) {
1160  msgcomp = "RAW";
1161  ctx->tex_rat = 1;
1162  decompress_tex = dxv_decompress_raw;
1163  }
1164 
1165  bytestream2_skip(gbc, 1); // unknown
1166  size = bytestream2_get_le32(gbc);
1167  }
1168  av_log(avctx, AV_LOG_DEBUG,
1169  "%s compression with %s texture (version %d.%d)\n",
1170  msgcomp, msgtext, version_major, version_minor);
1171 
1172  if (size != bytestream2_get_bytes_left(gbc)) {
1173  av_log(avctx, AV_LOG_ERROR,
1174  "Incomplete or invalid file (header %d, left %u).\n",
1176  return AVERROR_INVALIDDATA;
1177  }
1178 
1179  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
1180  ret = av_reallocp(&ctx->tex_data, ctx->tex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1181  if (ret < 0)
1182  return ret;
1183 
1184  if (ctx->ctex_size) {
1185  int i;
1186 
1187  ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
1188  ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
1189  ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
1190  ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
1191 
1192  ret = av_reallocp(&ctx->ctex_data, ctx->ctex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1193  if (ret < 0)
1194  return ret;
1195  for (i = 0; i < 4; i++) {
1196  ret = av_reallocp(&ctx->op_data[i], ctx->op_size[i]);
1197  if (ret < 0)
1198  return ret;
1199  }
1200  }
1201 
1202  /* Decompress texture out of the intermediate compression. */
1203  ret = decompress_tex(avctx);
1204  if (ret < 0)
1205  return ret;
1206  {
1207  int w_block = avctx->coded_width / ctx->texture_block_w;
1208  int h_block = avctx->coded_height / ctx->texture_block_h;
1209  if (w_block * h_block * ctx->tex_step > ctx->tex_size * 8LL)
1210  return AVERROR_INVALIDDATA;
1211  }
1212 
1213  ret = ff_thread_get_buffer(avctx, frame, 0);
1214  if (ret < 0)
1215  return ret;
1216 
1217  /* Now decompress the texture with the standard functions. */
1218  avctx->execute2(avctx, decompress_texture_thread,
1219  frame, NULL, ctx->slice_count);
1220 
1221  /* Frame is ready to be output. */
1222  frame->pict_type = AV_PICTURE_TYPE_I;
1223  frame->key_frame = 1;
1224  *got_frame = 1;
1225 
1226  return avpkt->size;
1227 }
1228 
1229 static int dxv_init(AVCodecContext *avctx)
1230 {
1231  DXVContext *ctx = avctx->priv_data;
1232  int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1233 
1234  if (ret < 0) {
1235  av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
1236  avctx->width, avctx->height);
1237  return ret;
1238  }
1239 
1240  /* Codec requires 16x16 alignment. */
1241  avctx->coded_width = FFALIGN(avctx->width, 16);
1242  avctx->coded_height = FFALIGN(avctx->height, 16);
1243 
1244  ff_texturedsp_init(&ctx->texdsp);
1245 
1246  return 0;
1247 }
1248 
1249 static int dxv_close(AVCodecContext *avctx)
1250 {
1251  DXVContext *ctx = avctx->priv_data;
1252 
1253  av_freep(&ctx->tex_data);
1254  av_freep(&ctx->ctex_data);
1255  av_freep(&ctx->op_data[0]);
1256  av_freep(&ctx->op_data[1]);
1257  av_freep(&ctx->op_data[2]);
1258  av_freep(&ctx->op_data[3]);
1259 
1260  return 0;
1261 }
1262 
1264  .p.name = "dxv",
1265  .p.long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
1266  .p.type = AVMEDIA_TYPE_VIDEO,
1267  .p.id = AV_CODEC_ID_DXV,
1268  .init = dxv_init,
1270  .close = dxv_close,
1271  .priv_data_size = sizeof(DXVContext),
1272  .p.capabilities = AV_CODEC_CAP_DR1 |
1275  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
1277 };
av_clip
#define av_clip
Definition: common.h:95
DXVContext::tex_funct
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:60
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: codec_internal.h:39
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:966
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:262
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
dxv_decode
static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:1041
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:212
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AVCOL_SPC_YCOCG
@ AVCOL_SPC_YCOCG
Definition: pixfmt.h:535
AVPacket::data
uint8_t * data
Definition: packet.h:374
table
static const uint16_t table[]
Definition: prosumer.c:206
half
static uint8_t half(int a, int b)
Definition: mobiclip.c:541
FFCodec
Definition: codec_internal.h:112
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:526
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
TextureDSPContext
Definition: texturedsp.h:47
dxv_init
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:1229
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
DXVContext::ctex_size
int64_t ctex_size
Definition: dxv.c:45
DXVContext::tex_data
uint8_t * tex_data
Definition: dxv.c:39
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:168
texturedsp.h
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
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:1463
ff_thread_get_buffer
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames. The frames must then be freed with ff_thread_release_buffer(). Otherwise decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
val
static double val(void *priv, double ch)
Definition: aeval.c:77
DXVContext::op_data
uint8_t * op_data[4]
Definition: dxv.c:50
tab2
const int16_t * tab2
Definition: mace.c:145
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:577
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
tab1
const int16_t * tab1
Definition: mace.c:145
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
check
#define check(x, y, S, v)
Definition: motion_est_template.c:405
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
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:254
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:76
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
bits
uint8_t bits
Definition: vp3data.h:141
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
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:94
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:1249
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:67
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: codec.h:113
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:205
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:267
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_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
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:117
codec_internal.h
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_CODEC_ID_DXV
@ AV_CODEC_ID_DXV
Definition: codec_id.h:241
size
int size
Definition: twinvq_data.h:10344
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:186
state
static struct @327 state
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
ff_lzf_uncompress
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
Definition: lzf.c:40
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:93
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: codec.h:117
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:553
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:269
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_dxv_decoder
const FFCodec ff_dxv_decoder
Definition: dxv.c:1263
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
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: codec_internal.h:31
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
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:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
avcodec.h
stride
#define stride
Definition: h264pred_template.c:537
tag
uint32_t tag
Definition: movenc.c:1646
ret
ret
Definition: filter_design.txt:187
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
pos
unsigned int pos
Definition: spdifenc.c:412
DXVContext::ctexture_block_h
int ctexture_block_h
Definition: dxv.c:57
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
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:92
AVCodecContext
main external API structure.
Definition: avcodec.h:389
probe
static int probe(const AVProbeData *p)
Definition: act.c:38
dxv_decompress_opcodes
static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
Definition: dxv.c:470
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:577
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:78
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
d
d
Definition: ffmpeg_filter.c:153
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
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:137
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:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
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:318
dxv_decompress_raw
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:1029
int
int
Definition: ffmpeg_filter.c:153
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:1533
DXVContext::texdsp
TextureDSPContext texdsp
Definition: dxv.c:36