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)
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  bytestream2_seek(gb, data_start + op_offset + skip0 - 12, SEEK_SET);
759  if (op_size1 > max_op_size1)
760  return AVERROR_INVALIDDATA;
761  skip1 = dxv_decompress_opcodes(gb, op_data1, op_size1);
762  if (skip1 < 0)
763  return skip1;
764  bytestream2_seek(gb, data_start, SEEK_SET);
765 
766  AV_WL32(dst, bytestream2_get_le32(gb));
767  AV_WL32(dst + 4, bytestream2_get_le32(gb));
768  AV_WL32(dst + 8, bytestream2_get_le32(gb));
769  AV_WL32(dst + 12, bytestream2_get_le32(gb));
770 
771  tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
772  tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
773  tab2[0x9E3779B1 * AV_RL16(dst + 8) >> 24] = dst + 8;
774  tab3[0x9E3779B1 * (AV_RL32(dst + 10) & 0xFFFFFF) >> 24] = dst + 10;
775  dst += 16;
776  while (dst + 10 < tex_data + tex_size) {
777  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data0, &oi0, op_size0,
778  &dst, &state0, tab0, tab1, 8);
779  if (ret < 0)
780  return ret;
781  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data1, &oi1, op_size1,
782  &dst, &state1, tab2, tab3, 8);
783  if (ret < 0)
784  return ret;
785  }
786 
787  bytestream2_seek(gb, data_start + op_offset + skip0 + skip1 - 12, SEEK_SET);
788 
789  return 0;
790 }
791 
793  uint8_t *tex_data, int tex_size,
794  uint8_t *op_data, int max_op_size)
795 {
796  int op_offset = bytestream2_get_le32(gb);
797  unsigned op_size = bytestream2_get_le32(gb);
798  int data_start = bytestream2_tell(gb);
799  uint8_t *dst, *table0[256] = { 0 }, *table1[256] = { 0 };
800  int ret, state = 0, skip, oi = 0, v, vv;
801 
802  dst = tex_data;
803  bytestream2_skip(gb, op_offset - 8);
804  if (op_size > max_op_size)
805  return AVERROR_INVALIDDATA;
806  skip = dxv_decompress_opcodes(gb, op_data, op_size);
807  if (skip < 0)
808  return skip;
809  bytestream2_seek(gb, data_start, SEEK_SET);
810 
811  v = bytestream2_get_le32(gb);
812  AV_WL32(dst, v);
813  vv = bytestream2_get_le32(gb);
814  table0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
815  AV_WL32(dst + 4, vv);
816  table1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
817  dst += 8;
818 
819  while (dst < tex_data + tex_size) {
820  ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data, &oi, op_size,
821  &dst, &state, table0, table1, 0);
822  if (ret < 0)
823  return ret;
824  }
825 
826  bytestream2_seek(gb, data_start + op_offset + skip - 8, SEEK_SET);
827 
828  return 0;
829 }
830 
832 {
833  DXVContext *ctx = avctx->priv_data;
834  GetByteContext *gb = &ctx->gbc;
835  int ret;
836 
837  ret = dxv_decompress_yo(ctx, gb, ctx->tex_data, ctx->tex_size,
838  ctx->op_data[0], ctx->op_size[0]);
839  if (ret < 0)
840  return ret;
841 
842  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
843  ctx->op_data[1], ctx->op_data[2],
844  ctx->op_size[1], ctx->op_size[2]);
845 }
846 
848 {
849  DXVContext *ctx = avctx->priv_data;
850  GetByteContext *gb = &ctx->gbc;
851  int ret;
852 
853  ret = dxv_decompress_cocg(ctx, gb, ctx->tex_data, ctx->tex_size,
854  ctx->op_data[0], ctx->op_data[3],
855  ctx->op_size[0], ctx->op_size[3]);
856  if (ret < 0)
857  return ret;
858 
859  return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
860  ctx->op_data[1], ctx->op_data[2],
861  ctx->op_size[1], ctx->op_size[2]);
862 }
863 
865 {
866  DXVContext *ctx = avctx->priv_data;
867  GetByteContext *gbc = &ctx->gbc;
868  uint32_t value, op;
869  int idx, prev, state = 0;
870  int pos = 4;
871  int run = 0;
872  int probe, check;
873 
874  /* Copy the first four elements */
875  AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
876  AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
877  AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
878  AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
879 
880  /* Process input until the whole texture has been filled */
881  while (pos + 2 <= ctx->tex_size / 4) {
882  if (run) {
883  run--;
884 
885  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
886  AV_WL32(ctx->tex_data + 4 * pos, prev);
887  pos++;
888  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
889  AV_WL32(ctx->tex_data + 4 * pos, prev);
890  pos++;
891  } else {
892  if (bytestream2_get_bytes_left(gbc) < 1)
893  return AVERROR_INVALIDDATA;
894  if (state == 0) {
895  value = bytestream2_get_le32(gbc);
896  state = 16;
897  }
898  op = value & 0x3;
899  value >>= 2;
900  state--;
901 
902  switch (op) {
903  case 0:
904  /* Long copy */
905  check = bytestream2_get_byte(gbc) + 1;
906  if (check == 256) {
907  do {
908  probe = bytestream2_get_le16(gbc);
909  check += probe;
910  } while (probe == 0xFFFF);
911  }
912  while (check && pos + 4 <= ctx->tex_size / 4) {
913  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
914  AV_WL32(ctx->tex_data + 4 * pos, prev);
915  pos++;
916 
917  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
918  AV_WL32(ctx->tex_data + 4 * pos, prev);
919  pos++;
920 
921  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
922  AV_WL32(ctx->tex_data + 4 * pos, prev);
923  pos++;
924 
925  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
926  AV_WL32(ctx->tex_data + 4 * pos, prev);
927  pos++;
928 
929  check--;
930  }
931 
932  /* Restart (or exit) the loop */
933  continue;
934  break;
935  case 1:
936  /* Load new run value */
937  run = bytestream2_get_byte(gbc);
938  if (run == 255) {
939  do {
940  probe = bytestream2_get_le16(gbc);
941  run += probe;
942  } while (probe == 0xFFFF);
943  }
944 
945  /* Copy two dwords from previous data */
946  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
947  AV_WL32(ctx->tex_data + 4 * pos, prev);
948  pos++;
949 
950  prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
951  AV_WL32(ctx->tex_data + 4 * pos, prev);
952  pos++;
953  break;
954  case 2:
955  /* Copy two dwords from a previous index */
956  idx = 8 + bytestream2_get_le16(gbc);
957  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
958  return AVERROR_INVALIDDATA;
959  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
960  AV_WL32(ctx->tex_data + 4 * pos, prev);
961  pos++;
962 
963  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
964  AV_WL32(ctx->tex_data + 4 * pos, prev);
965  pos++;
966  break;
967  case 3:
968  /* Copy two dwords from input */
969  prev = bytestream2_get_le32(gbc);
970  AV_WL32(ctx->tex_data + 4 * pos, prev);
971  pos++;
972 
973  prev = bytestream2_get_le32(gbc);
974  AV_WL32(ctx->tex_data + 4 * pos, prev);
975  pos++;
976  break;
977  }
978  }
979 
980  CHECKPOINT(4);
981  if (pos + 2 > ctx->tex_size / 4)
982  return AVERROR_INVALIDDATA;
983 
984  /* Copy two elements from a previous offset or from the input buffer */
985  if (op) {
986  if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
987  return AVERROR_INVALIDDATA;
988  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
989  AV_WL32(ctx->tex_data + 4 * pos, prev);
990  pos++;
991 
992  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
993  AV_WL32(ctx->tex_data + 4 * pos, prev);
994  pos++;
995  } else {
996  CHECKPOINT(4);
997 
998  if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
999  return AVERROR_INVALIDDATA;
1000  if (op)
1001  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1002  else
1003  prev = bytestream2_get_le32(gbc);
1004  AV_WL32(ctx->tex_data + 4 * pos, prev);
1005  pos++;
1006 
1007  CHECKPOINT(4);
1008 
1009  if (op)
1010  prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1011  else
1012  prev = bytestream2_get_le32(gbc);
1013  AV_WL32(ctx->tex_data + 4 * pos, prev);
1014  pos++;
1015  }
1016  }
1017 
1018  return 0;
1019 }
1020 
1022 {
1023  DXVContext *ctx = avctx->priv_data;
1024  return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
1025 }
1026 
1028 {
1029  DXVContext *ctx = avctx->priv_data;
1030  GetByteContext *gbc = &ctx->gbc;
1031 
1032  if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
1033  return AVERROR_INVALIDDATA;
1034 
1035  bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
1036  return 0;
1037 }
1038 
1039 static int dxv_decode(AVCodecContext *avctx, void *data,
1040  int *got_frame, AVPacket *avpkt)
1041 {
1042  DXVContext *ctx = avctx->priv_data;
1043  ThreadFrame tframe;
1044  GetByteContext *gbc = &ctx->gbc;
1045  int (*decompress_tex)(AVCodecContext *avctx);
1046  const char *msgcomp, *msgtext;
1047  uint32_t tag;
1048  int version_major, version_minor = 0;
1049  int size = 0, old_type = 0;
1050  int ret;
1051 
1052  bytestream2_init(gbc, avpkt->data, avpkt->size);
1053 
1054  ctx->texture_block_h = 4;
1055  ctx->texture_block_w = 4;
1056 
1057  avctx->pix_fmt = AV_PIX_FMT_RGBA;
1058  avctx->colorspace = AVCOL_SPC_RGB;
1059 
1060  ctx->tex_funct = NULL;
1061  ctx->tex_funct_planar[0] = NULL;
1062  ctx->tex_funct_planar[1] = NULL;
1063 
1064  tag = bytestream2_get_le32(gbc);
1065  switch (tag) {
1066  case MKBETAG('D', 'X', 'T', '1'):
1067  decompress_tex = dxv_decompress_dxt1;
1068  ctx->tex_funct = ctx->texdsp.dxt1_block;
1069  ctx->tex_rat = 8;
1070  ctx->tex_step = 8;
1071  msgcomp = "DXTR1";
1072  msgtext = "DXT1";
1073  break;
1074  case MKBETAG('D', 'X', 'T', '5'):
1075  decompress_tex = dxv_decompress_dxt5;
1076  ctx->tex_funct = ctx->texdsp.dxt5_block;
1077  ctx->tex_rat = 4;
1078  ctx->tex_step = 16;
1079  msgcomp = "DXTR5";
1080  msgtext = "DXT5";
1081  break;
1082  case MKBETAG('Y', 'C', 'G', '6'):
1083  decompress_tex = dxv_decompress_ycg6;
1084  ctx->tex_funct_planar[0] = yo_block;
1085  ctx->tex_funct_planar[1] = cocg_block;
1086  ctx->tex_rat = 8;
1087  ctx->tex_step = 32;
1088  ctx->ctex_step = 16;
1089  msgcomp = "YOCOCG6";
1090  msgtext = "YCG6";
1091  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1092  ctx->texture_block_h = 4;
1093  ctx->texture_block_w = 16;
1094  ctx->ctexture_block_h = 4;
1095  ctx->ctexture_block_w = 4;
1096  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1097  avctx->colorspace = AVCOL_SPC_YCOCG;
1098  break;
1099  case MKBETAG('Y', 'G', '1', '0'):
1100  decompress_tex = dxv_decompress_yg10;
1101  ctx->tex_funct_planar[0] = yao_block;
1102  ctx->tex_funct_planar[1] = cocg_block;
1103  ctx->tex_rat = 4;
1104  ctx->tex_step = 64;
1105  ctx->ctex_step = 16;
1106  msgcomp = "YAOCOCG10";
1107  msgtext = "YG10";
1108  ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1109  ctx->texture_block_h = 4;
1110  ctx->texture_block_w = 16;
1111  ctx->ctexture_block_h = 4;
1112  ctx->ctexture_block_w = 4;
1113  avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
1114  avctx->colorspace = AVCOL_SPC_YCOCG;
1115  break;
1116  default:
1117  /* Old version does not have a real header, just size and type. */
1118  size = tag & 0x00FFFFFF;
1119  old_type = tag >> 24;
1120  version_major = (old_type & 0x0F) - 1;
1121 
1122  if (old_type & 0x80) {
1123  msgcomp = "RAW";
1124  decompress_tex = dxv_decompress_raw;
1125  } else {
1126  msgcomp = "LZF";
1127  decompress_tex = dxv_decompress_lzf;
1128  }
1129 
1130  if (old_type & 0x40) {
1131  msgtext = "DXT5";
1132 
1133  ctx->tex_funct = ctx->texdsp.dxt5_block;
1134  ctx->tex_step = 16;
1135  } else if (old_type & 0x20 || version_major == 1) {
1136  msgtext = "DXT1";
1137 
1138  ctx->tex_funct = ctx->texdsp.dxt1_block;
1139  ctx->tex_step = 8;
1140  } else {
1141  av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
1142  return AVERROR_INVALIDDATA;
1143  }
1144  ctx->tex_rat = 1;
1145  break;
1146  }
1147 
1148  ctx->slice_count = av_clip(avctx->thread_count, 1,
1149  avctx->coded_height / FFMAX(ctx->texture_block_h,
1150  ctx->ctexture_block_h));
1151 
1152  /* New header is 12 bytes long. */
1153  if (!old_type) {
1154  version_major = bytestream2_get_byte(gbc) - 1;
1155  version_minor = bytestream2_get_byte(gbc);
1156 
1157  /* Encoder copies texture data when compression is not advantageous. */
1158  if (bytestream2_get_byte(gbc)) {
1159  msgcomp = "RAW";
1160  ctx->tex_rat = 1;
1161  decompress_tex = dxv_decompress_raw;
1162  }
1163 
1164  bytestream2_skip(gbc, 1); // unknown
1165  size = bytestream2_get_le32(gbc);
1166  }
1167  av_log(avctx, AV_LOG_DEBUG,
1168  "%s compression with %s texture (version %d.%d)\n",
1169  msgcomp, msgtext, version_major, version_minor);
1170 
1171  if (size != bytestream2_get_bytes_left(gbc)) {
1172  av_log(avctx, AV_LOG_ERROR,
1173  "Incomplete or invalid file (header %d, left %u).\n",
1174  size, bytestream2_get_bytes_left(gbc));
1175  return AVERROR_INVALIDDATA;
1176  }
1177 
1178  ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
1180  if (ret < 0)
1181  return ret;
1182 
1183  if (ctx->ctex_size) {
1184  int i;
1185 
1186  ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
1187  ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
1188  ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
1189  ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
1190 
1192  if (ret < 0)
1193  return ret;
1194  for (i = 0; i < 4; i++) {
1195  ret = av_reallocp(&ctx->op_data[i], ctx->op_size[i]);
1196  if (ret < 0)
1197  return ret;
1198  }
1199  }
1200 
1201  /* Decompress texture out of the intermediate compression. */
1202  ret = decompress_tex(avctx);
1203  if (ret < 0)
1204  return ret;
1205  {
1206  int w_block = avctx->coded_width / ctx->texture_block_w;
1207  int h_block = avctx->coded_height / ctx->texture_block_h;
1208  if (w_block * h_block * ctx->tex_step > ctx->tex_size * 8LL)
1209  return AVERROR_INVALIDDATA;
1210  }
1211 
1212  tframe.f = data;
1213  ret = ff_thread_get_buffer(avctx, &tframe, 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  tframe.f, NULL, ctx->slice_count);
1220 
1221  /* Frame is ready to be output. */
1222  tframe.f->pict_type = AV_PICTURE_TYPE_I;
1223  tframe.f->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  .name = "dxv",
1265  .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
1266  .type = AVMEDIA_TYPE_VIDEO,
1267  .id = AV_CODEC_ID_DXV,
1268  .init = dxv_init,
1269  .decode = dxv_decode,
1270  .close = dxv_close,
1271  .priv_data_size = sizeof(DXVContext),
1272  .capabilities = AV_CODEC_CAP_DR1 |
1275  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
1277 };
#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
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:863
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int(* dxt5_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:51
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
uint8_t val2
Definition: dxv.c:340
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1753
int ctex_step
Definition: dxv.c:43
misc image utilities
AVFrame * f
Definition: thread.h:35
Texture block (4x4) module.
int size
Definition: avcodec.h:1478
int ctexture_block_w
Definition: dxv.c:56
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition: dxv.c:288
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
static int dxv_decompress_ycg6(AVCodecContext *avctx)
Definition: dxv.c:831
uint8_t run
Definition: svq3.c:206
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3477
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
Definition: pixfmt.h:497
static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
Definition: dxv.c:428
int64_t ctex_size
Definition: dxv.c:45
#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
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
uint8_t * tex_data
Definition: dxv.c:39
static int dxv_decompress_dxt5(AVCodecContext *avctx)
Definition: dxv.c:864
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
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
int64_t tex_size
Definition: dxv.c:44
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
static int yao_block(uint8_t *plane0, ptrdiff_t stride0, uint8_t *plane3, ptrdiff_t stride1, const uint8_t *block)
Definition: dxv.c:174
Multithreading support functions.
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
#define CHECKPOINT(x)
Definition: dxv.c:256
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
int16_t next
Definition: dxv.c:338
uint8_t * data
Definition: avcodec.h:1477
const uint8_t * buffer
Definition: bytestream.h:34
uint32_t tag
Definition: movenc.c:1496
static int dxv_decompress_yg10(AVCodecContext *avctx)
Definition: dxv.c:847
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:792
ptrdiff_t size
Definition: opengl_enc.c:100
static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
Definition: dxv.c:343
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
static const uint16_t table[]
Definition: prosumer.c:206
TextureDSPContext texdsp
Definition: dxv.c:36
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
Definition: lzf.c:40
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int decompress_texture_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb)
Definition: dxv.c:193
static const uint16_t mask[17]
Definition: lzw.c:38
BYTE * dstp
Definition: avisynth_c.h:908
uint8_t val1
Definition: dxv.c:339
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
AVCodec ff_dxv_decoder
Definition: dxv.c:1263
GetByteContext gbc
Definition: dxv.c:37
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
const char * arg
Definition: jacosubdec.c:66
static int dxv_close(AVCodecContext *avctx)
Definition: dxv.c:1249
const char * name
Name of the codec implementation.
Definition: avcodec.h:3484
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:87
uint8_t bits
Definition: vp3data.h:202
#define FFMAX(a, b)
Definition: common.h:94
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1037
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition: dxv.c:1021
Definition: dxv.c:35
static int yo_block(uint8_t *dst, ptrdiff_t stride, uint8_t *unused0, ptrdiff_t unused1, const uint8_t *block)
Definition: dxv.c:160
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
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:637
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
#define ff_clz
Definition: intmath.h:142
int64_t op_size[4]
Definition: dxv.c:51
int width
picture width / height.
Definition: avcodec.h:1738
static const ElemCat * elements[ELEMENT_COUNT]
Definition: signature.h:566
static struct @313 state
int tex_rat
Definition: dxv.c:41
AVFormatContext * ctx
Definition: movenc.c:48
static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
Definition: dxv.c:470
static void decompress_indices(uint8_t *dst, const uint8_t *src)
Definition: dxv.c:66
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
int slice_count
Definition: dxv.c:48
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
int texture_block_h
Definition: dxv.c:54
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:2820
if(ret)
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: avcodec.h:1041
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
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:2880
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
Libavcodec external API header.
static int cocg_block(uint8_t *plane0, ptrdiff_t stride0, uint8_t *plane1, ptrdiff_t stride1, const uint8_t *block)
Definition: dxv.c:111
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
main external API structure.
Definition: avcodec.h:1565
static void yao_subblock(uint8_t *dst, uint8_t *yo_indices, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:141
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:206
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
const int16_t * tab1
Definition: mace.c:144
int coded_height
Definition: avcodec.h:1753
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:2189
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
static int dxv_init(AVCodecContext *avctx)
Definition: dxv.c:1229
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
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
static int probe(const AVProbeData *p)
Definition: act.c:36
int ctexture_block_h
Definition: dxv.c:57
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
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
int
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxv.c:1039
common internal api header.
#define flag(name)
Definition: cbs_av1.c:553
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
#define MKBETAG(a, b, c, d)
Definition: common.h:367
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:790
void * priv_data
Definition: avcodec.h:1592
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
int texture_block_w
Definition: dxv.c:53
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: dxv.c:60
#define av_freep(p)
static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
Definition: dxv.c:387
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
#define stride
static int extract_component(int yo0, int yo1, int code)
Definition: dxv.c:82
uint8_t * op_data[4]
Definition: dxv.c:50
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1454
uint8_t * ctex_data
Definition: dxv.c:40
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
for(j=16;j >0;--j)
const int16_t * tab2
Definition: mace.c:144
int tex_step
Definition: dxv.c:42
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition: dxv.c:1027
#define check(x, y, S, v)
static uint8_t tmp[11]
Definition: aes_ctr.c:26