FFmpeg
Loading...
Searching...
No Matches
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
26#include "libavutil/imgutils.h"
27#include "libavutil/mem.h"
28
29#include "avcodec.h"
30#include "bytestream.h"
31#include "codec_internal.h"
32#include "dxv.h"
33#include "lzf.h"
34#include "texturedsp.h"
35#include "thread.h"
36
37typedef struct DXVContext {
40
41 uint8_t *tex_data; // Compressed texture
42 unsigned tex_data_size;
43 uint8_t *ctex_data; // Compressed chroma texture
45
46 size_t tex_size; // Texture size
47 int64_t ctex_size; // Chroma texture size
48
49 uint8_t *op_data[4]; // Opcodes
50 unsigned op_data_size[4];
51 int64_t op_size[4]; // Opcodes size
53
54/* This scheme addresses already decoded elements depending on 2-bit status:
55 * 0 -> copy new element
56 * 1 -> copy one element from position -x
57 * 2 -> copy one element from position -(get_byte() + 2) * x
58 * 3 -> copy one element from position -(get_16le() + 0x102) * x
59 * x is always 2 for dxt1 and 4 for dxt5. */
60#define CHECKPOINT(x) \
61 do { \
62 if (state == 0) { \
63 if (bytestream2_get_bytes_left(gbc) < 4) \
64 return AVERROR_INVALIDDATA; \
65 value = bytestream2_get_le32(gbc); \
66 state = 16; \
67 } \
68 op = value & 0x3; \
69 value >>= 2; \
70 state--; \
71 switch (op) { \
72 case 1: \
73 idx = x; \
74 break; \
75 case 2: \
76 idx = (bytestream2_get_byte(gbc) + 2) * x; \
77 if (idx > pos) { \
78 av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
79 return AVERROR_INVALIDDATA; \
80 } \
81 break; \
82 case 3: \
83 idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
84 if (idx > pos) { \
85 av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); \
86 return AVERROR_INVALIDDATA; \
87 } \
88 break; \
89 } \
90 } while(0)
91
93{
94 DXVContext *ctx = avctx->priv_data;
95 GetByteContext *gbc = &ctx->gbc;
96 uint32_t value, prev, op;
97 int idx = 0, state = 0;
98 int pos = 2;
99
100 /* Copy the first two elements */
101 AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
102 AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
103
104 /* Process input until the whole texture has been filled */
105 while (pos + 2 <= ctx->tex_size / 4) {
106 CHECKPOINT(2);
107
108 /* Copy two elements from a previous offset or from the input buffer */
109 if (op) {
110 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
111 AV_WL32(ctx->tex_data + 4 * pos, prev);
112 pos++;
113
114 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
115 AV_WL32(ctx->tex_data + 4 * pos, prev);
116 pos++;
117 } else {
118 CHECKPOINT(2);
119
120 if (op)
121 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
122 else
123 prev = bytestream2_get_le32(gbc);
124 AV_WL32(ctx->tex_data + 4 * pos, prev);
125 pos++;
126
127 CHECKPOINT(2);
128
129 if (op)
130 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
131 else
132 prev = bytestream2_get_le32(gbc);
133 AV_WL32(ctx->tex_data + 4 * pos, prev);
134 pos++;
135 }
136 }
137
138 return 0;
139}
140
141typedef struct OpcodeTable {
142 int16_t next;
143 uint8_t val1;
144 uint8_t val2;
146
147static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
148{
149 unsigned half = 512, bits = 1023, left = 1024, input, mask;
150 int value, counter = 0, rshift = 10, lshift = 30;
151
152 mask = bytestream2_get_le32(gb) >> 2;
153 while (left) {
154 if (counter >= 256)
155 return AVERROR_INVALIDDATA;
156 value = bits & mask;
157 left -= bits & mask;
158 mask >>= rshift;
159 lshift -= rshift;
160 table[counter++] = value;
161 if (lshift < 16) {
162 if (bytestream2_get_bytes_left(gb) <= 0)
163 return AVERROR_INVALIDDATA;
164
165 input = bytestream2_get_le16(gb);
166 mask += input << lshift;
167 lshift += 16;
168 }
169 if (left < half) {
170 half >>= 1;
171 bits >>= 1;
172 rshift--;
173 }
174 }
175
176 for (; !table[counter - 1]; counter--)
177 if (counter <= 0)
178 return AVERROR_INVALIDDATA;
179
180 *nb_elements = counter;
181
182 if (counter < 256)
183 memset(&table[counter], 0, 4 * (256 - counter));
184
185 if (lshift >= 16)
186 bytestream2_seek(gb, -2, SEEK_CUR);
187
188 return 0;
189}
190
191static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
192{
193 unsigned table2[256] = { 0 };
194 unsigned x = 0;
195 int val0, val1, i, j = 2, k = 0;
196
197 table2[0] = table0[0];
198 for (i = 0; i < nb_elements - 1; i++, table2[i] = val0) {
199 val0 = table0[i + 1] + table2[i];
200 }
201
202 if (!table2[0]) {
203 do {
204 k++;
205 } while (!table2[k]);
206 }
207
208 j = 2;
209 for (i = 1024; i > 0; i--) {
210 for (table1[x].val1 = k; k < 256 && j > table2[k]; k++);
211 x = (x - 383) & 0x3FF;
212 j++;
213 }
214
215 if (nb_elements > 0)
216 memcpy(&table2[0], table0, 4 * nb_elements);
217
218 for (i = 0; i < 1024; i++) {
219 val0 = table1[i].val1;
220 val1 = table2[val0];
221 table2[val0]++;
222 x = 31 - ff_clz(val1);
223 if (x > 10)
224 return AVERROR_INVALIDDATA;
225 table1[i].val2 = 10 - x;
226 table1[i].next = (val1 << table1[i].val2) - 1024;
227 }
228
229 return 0;
230}
231
232static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
233{
234 OpcodeTable optable[1024];
235 int sum, x, val, lshift, rshift, ret, i, idx;
236 int64_t size_in_bits;
237 unsigned endoffset, newoffset, offset;
238 unsigned next;
239 const uint8_t *src = gb->buffer;
240
241 ret = fill_optable(table, optable, nb_elements);
242 if (ret < 0)
243 return ret;
244
245 size_in_bits = bytestream2_get_le32(gb);
246 endoffset = ((size_in_bits + 7) >> 3) - 4;
247 if ((int)endoffset <= 0 || bytestream2_get_bytes_left(gb) < endoffset)
248 return AVERROR_INVALIDDATA;
249
250 offset = endoffset;
251 next = AV_RL32(src + endoffset);
252 rshift = (((size_in_bits & 0xFF) - 1) & 7) + 15;
253 lshift = 32 - rshift;
254 idx = (next >> rshift) & 0x3FF;
255 for (i = 0; i < op_size; i++) {
256 dst[i] = optable[idx].val1;
257 val = optable[idx].val2;
258 sum = val + lshift;
259 x = (next << lshift) >> 1 >> (31 - val);
260 newoffset = offset - (sum >> 3);
261 lshift = sum & 7;
262 idx = x + optable[idx].next;
263 offset = newoffset;
264 if (offset > endoffset)
265 return AVERROR_INVALIDDATA;
266 next = AV_RL32(src + offset);
267 }
268
269 bytestream2_skip(gb, (size_in_bits + 7 >> 3) - 4);
270
271 return 0;
272}
273
274static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
275{
276 int pos = bytestream2_tell(gb);
277 int flag = bytestream2_peek_byte(gb);
278
279 if ((flag & 3) == 0) {
280 bytestream2_skip(gb, 1);
281 int read_size = bytestream2_get_buffer(gb, dstp, op_size);
282 if (read_size != op_size)
283 return AVERROR_INVALIDDATA;
284 } else if ((flag & 3) == 1) {
285 bytestream2_skip(gb, 1);
286 memset(dstp, bytestream2_get_byte(gb), op_size);
287 } else {
288 uint32_t table[256];
289 int ret, elements = 0;
290
291 ret = fill_ltable(gb, table, &elements);
292 if (ret < 0)
293 return ret;
294 ret = get_opcodes(gb, table, dstp, op_size, elements);
295 if (ret < 0)
296 return ret;
297 }
298 return bytestream2_tell(gb) - pos;
299}
300
302 uint8_t *tex_data, int tex_size,
303 uint8_t *op_data, int *oindex,
304 int op_size,
305 uint8_t **dstp, int *statep,
306 uint8_t **tab0, uint8_t **tab1,
307 int offset)
308{
309 uint8_t *dst = *dstp;
310 uint8_t *tptr0, *tptr1, *tptr3;
311 int oi = *oindex;
312 int state = *statep;
313 int opcode, v, vv;
314
315 if (state <= 0) {
316 if (oi >= op_size)
317 return AVERROR_INVALIDDATA;
318 opcode = op_data[oi++];
319 if (!opcode) {
320 v = bytestream2_get_byte(gb);
321 if (v == 255) {
322 do {
323 if (bytestream2_get_bytes_left(gb) <= 0)
324 return AVERROR_INVALIDDATA;
325 opcode = bytestream2_get_le16(gb);
326 v += opcode;
327 } while (opcode == 0xFFFF);
328 }
329 AV_WL32(dst, AV_RL32(dst - (8 + offset)));
330 AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
331 state = v + 4;
332 goto done;
333 }
334
335 switch (opcode) {
336 case 1:
337 AV_WL32(dst, AV_RL32(dst - (8 + offset)));
338 AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
339 break;
340 case 2:
341 vv = (8 + offset) * (bytestream2_get_le16(gb) + 1);
342 if (vv < 0 || vv > dst - tex_data)
343 return AVERROR_INVALIDDATA;
344 tptr0 = dst - vv;
345 v = AV_RL32(tptr0);
346 AV_WL32(dst, AV_RL32(tptr0));
347 AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
348 tab0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
349 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
350 break;
351 case 3:
352 AV_WL32(dst, bytestream2_get_le32(gb));
353 AV_WL32(dst + 4, bytestream2_get_le32(gb));
354 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
355 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
356 break;
357 case 4:
358 tptr3 = tab1[bytestream2_get_byte(gb)];
359 if (!tptr3)
360 return AVERROR_INVALIDDATA;
361 AV_WL16(dst, bytestream2_get_le16(gb));
362 AV_WL16(dst + 2, AV_RL16(tptr3));
363 dst[4] = tptr3[2];
364 AV_WL16(dst + 5, bytestream2_get_le16(gb));
365 dst[7] = bytestream2_get_byte(gb);
366 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
367 break;
368 case 5:
369 tptr3 = tab1[bytestream2_get_byte(gb)];
370 if (!tptr3)
371 return AVERROR_INVALIDDATA;
372 AV_WL16(dst, bytestream2_get_le16(gb));
373 AV_WL16(dst + 2, bytestream2_get_le16(gb));
374 dst[4] = bytestream2_get_byte(gb);
375 AV_WL16(dst + 5, AV_RL16(tptr3));
376 dst[7] = tptr3[2];
377 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
378 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
379 break;
380 case 6:
381 tptr0 = tab1[bytestream2_get_byte(gb)];
382 if (!tptr0)
383 return AVERROR_INVALIDDATA;
384 tptr1 = tab1[bytestream2_get_byte(gb)];
385 if (!tptr1)
386 return AVERROR_INVALIDDATA;
387 AV_WL16(dst, bytestream2_get_le16(gb));
388 AV_WL16(dst + 2, AV_RL16(tptr0));
389 dst[4] = tptr0[2];
390 AV_WL16(dst + 5, AV_RL16(tptr1));
391 dst[7] = tptr1[2];
392 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
393 break;
394 case 7:
395 v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
396 if (v < 0 || v > dst - tex_data)
397 return AVERROR_INVALIDDATA;
398 tptr0 = dst - v;
399 AV_WL16(dst, bytestream2_get_le16(gb));
400 AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
401 AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
402 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
403 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
404 break;
405 case 8:
406 tptr1 = tab0[bytestream2_get_byte(gb)];
407 if (!tptr1)
408 return AVERROR_INVALIDDATA;
409 AV_WL16(dst, AV_RL16(tptr1));
410 AV_WL16(dst + 2, bytestream2_get_le16(gb));
411 AV_WL32(dst + 4, bytestream2_get_le32(gb));
412 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
413 break;
414 case 9:
415 tptr1 = tab0[bytestream2_get_byte(gb)];
416 if (!tptr1)
417 return AVERROR_INVALIDDATA;
418 tptr3 = tab1[bytestream2_get_byte(gb)];
419 if (!tptr3)
420 return AVERROR_INVALIDDATA;
421 AV_WL16(dst, AV_RL16(tptr1));
422 AV_WL16(dst + 2, AV_RL16(tptr3));
423 dst[4] = tptr3[2];
424 AV_WL16(dst + 5, bytestream2_get_le16(gb));
425 dst[7] = bytestream2_get_byte(gb);
426 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
427 break;
428 case 10:
429 tptr1 = tab0[bytestream2_get_byte(gb)];
430 if (!tptr1)
431 return AVERROR_INVALIDDATA;
432 tptr3 = tab1[bytestream2_get_byte(gb)];
433 if (!tptr3)
434 return AVERROR_INVALIDDATA;
435 AV_WL16(dst, AV_RL16(tptr1));
436 AV_WL16(dst + 2, bytestream2_get_le16(gb));
437 dst[4] = bytestream2_get_byte(gb);
438 AV_WL16(dst + 5, AV_RL16(tptr3));
439 dst[7] = tptr3[2];
440 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
441 break;
442 case 11:
443 tptr0 = tab0[bytestream2_get_byte(gb)];
444 if (!tptr0)
445 return AVERROR_INVALIDDATA;
446 tptr3 = tab1[bytestream2_get_byte(gb)];
447 if (!tptr3)
448 return AVERROR_INVALIDDATA;
449 tptr1 = tab1[bytestream2_get_byte(gb)];
450 if (!tptr1)
451 return AVERROR_INVALIDDATA;
452 AV_WL16(dst, AV_RL16(tptr0));
453 AV_WL16(dst + 2, AV_RL16(tptr3));
454 dst[4] = tptr3[2];
455 AV_WL16(dst + 5, AV_RL16(tptr1));
456 dst[7] = tptr1[2];
457 break;
458 case 12:
459 tptr1 = tab0[bytestream2_get_byte(gb)];
460 if (!tptr1)
461 return AVERROR_INVALIDDATA;
462 v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
463 if (v < 0 || v > dst - tex_data)
464 return AVERROR_INVALIDDATA;
465 tptr0 = dst - v;
466 AV_WL16(dst, AV_RL16(tptr1));
467 AV_WL16(dst + 2, AV_RL16(tptr0 + 2));
468 AV_WL32(dst + 4, AV_RL32(tptr0 + 4));
469 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
470 break;
471 case 13:
472 AV_WL16(dst, AV_RL16(dst - (8 + offset)));
473 AV_WL16(dst + 2, bytestream2_get_le16(gb));
474 AV_WL32(dst + 4, bytestream2_get_le32(gb));
475 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
476 break;
477 case 14:
478 tptr3 = tab1[bytestream2_get_byte(gb)];
479 if (!tptr3)
480 return AVERROR_INVALIDDATA;
481 AV_WL16(dst, AV_RL16(dst - (8 + offset)));
482 AV_WL16(dst + 2, AV_RL16(tptr3));
483 dst[4] = tptr3[2];
484 AV_WL16(dst + 5, bytestream2_get_le16(gb));
485 dst[7] = bytestream2_get_byte(gb);
486 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
487 break;
488 case 15:
489 tptr3 = tab1[bytestream2_get_byte(gb)];
490 if (!tptr3)
491 return AVERROR_INVALIDDATA;
492 AV_WL16(dst, AV_RL16(dst - (8 + offset)));
493 AV_WL16(dst + 2, bytestream2_get_le16(gb));
494 dst[4] = bytestream2_get_byte(gb);
495 AV_WL16(dst + 5, AV_RL16(tptr3));
496 dst[7] = tptr3[2];
497 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
498 break;
499 case 16:
500 tptr3 = tab1[bytestream2_get_byte(gb)];
501 if (!tptr3)
502 return AVERROR_INVALIDDATA;
503 tptr1 = tab1[bytestream2_get_byte(gb)];
504 if (!tptr1)
505 return AVERROR_INVALIDDATA;
506 AV_WL16(dst, AV_RL16(dst - (8 + offset)));
507 AV_WL16(dst + 2, AV_RL16(tptr3));
508 dst[4] = tptr3[2];
509 AV_WL16(dst + 5, AV_RL16(tptr1));
510 dst[7] = tptr1[2];
511 break;
512 case 17:
513 v = (8 + offset) * (bytestream2_get_le16(gb) + 1);
514 if (v < 0 || v > dst - tex_data)
515 return AVERROR_INVALIDDATA;
516 AV_WL16(dst, AV_RL16(dst - (8 + offset)));
517 AV_WL16(dst + 2, AV_RL16(&dst[-v + 2]));
518 AV_WL32(dst + 4, AV_RL32(&dst[-v + 4]));
519 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFFu) >> 24] = dst + 2;
520 break;
521 default:
522 break;
523 }
524 } else {
525done:
526 AV_WL32(dst, AV_RL32(dst - (8 + offset)));
527 AV_WL32(dst + 4, AV_RL32(dst - (4 + offset)));
528 state--;
529 }
530 if (dst - tex_data + 8 > tex_size)
531 return AVERROR_INVALIDDATA;
532 dst += 8;
533
534 *oindex = oi;
535 *dstp = dst;
536 *statep = state;
537
538 return 0;
539}
540
542 uint8_t *tex_data, int tex_size,
543 uint8_t *op_data0, uint8_t *op_data1,
544 int max_op_size0, int max_op_size1)
545{
546 uint8_t *dst, *tab2[256] = { 0 }, *tab0[256] = { 0 }, *tab3[256] = { 0 }, *tab1[256] = { 0 };
547 int op_offset = bytestream2_get_le32(gb);
548 unsigned op_size0 = bytestream2_get_le32(gb);
549 unsigned op_size1 = bytestream2_get_le32(gb);
550 int data_start = bytestream2_tell(gb);
551 int skip0, skip1, oi0 = 0, oi1 = 0;
552 int ret, state0 = 0, state1 = 0;
553
554 if (op_offset < 12 || op_offset - 12 > bytestream2_get_bytes_left(gb))
555 return AVERROR_INVALIDDATA;
556
557 dst = tex_data;
558 bytestream2_skip(gb, op_offset - 12);
559 if (op_size0 > max_op_size0)
560 return AVERROR_INVALIDDATA;
561 skip0 = dxv_decompress_opcodes(gb, op_data0, op_size0);
562 if (skip0 < 0)
563 return skip0;
564 if (op_size1 > max_op_size1)
565 return AVERROR_INVALIDDATA;
566 skip1 = dxv_decompress_opcodes(gb, op_data1, op_size1);
567 if (skip1 < 0)
568 return skip1;
569 bytestream2_seek(gb, data_start, SEEK_SET);
570
571 AV_WL32(dst, bytestream2_get_le32(gb));
572 AV_WL32(dst + 4, bytestream2_get_le32(gb));
573 AV_WL32(dst + 8, bytestream2_get_le32(gb));
574 AV_WL32(dst + 12, bytestream2_get_le32(gb));
575
576 tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
577 tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
578 tab2[0x9E3779B1 * AV_RL16(dst + 8) >> 24] = dst + 8;
579 tab3[0x9E3779B1 * (AV_RL32(dst + 10) & 0xFFFFFF) >> 24] = dst + 10;
580 dst += 16;
581 while (dst + 10 < tex_data + tex_size) {
582 ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data0, &oi0, op_size0,
583 &dst, &state0, tab0, tab1, 8);
584 if (ret < 0)
585 return ret;
586 ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data1, &oi1, op_size1,
587 &dst, &state1, tab2, tab3, 8);
588 if (ret < 0)
589 return ret;
590 }
591
592 bytestream2_seek(gb, data_start - 12 + op_offset + skip0 + skip1, SEEK_SET);
593
594 return 0;
595}
596
598 uint8_t *tex_data, int tex_size,
599 uint8_t *op_data, int max_op_size)
600{
601 int op_offset = bytestream2_get_le32(gb);
602 unsigned op_size = bytestream2_get_le32(gb);
603 int data_start = bytestream2_tell(gb);
604 uint8_t *dst, *table0[256] = { 0 }, *table1[256] = { 0 };
605 int ret, state = 0, skip, oi = 0, v, vv;
606
607 if (op_offset < 8 || op_offset - 8 > bytestream2_get_bytes_left(gb))
608 return AVERROR_INVALIDDATA;
609
610 dst = tex_data;
611 bytestream2_skip(gb, op_offset - 8);
612 if (op_size > max_op_size)
613 return AVERROR_INVALIDDATA;
614 skip = dxv_decompress_opcodes(gb, op_data, op_size);
615 if (skip < 0)
616 return skip;
617 bytestream2_seek(gb, data_start, SEEK_SET);
618
619 v = bytestream2_get_le32(gb);
620 AV_WL32(dst, v);
621 vv = bytestream2_get_le32(gb);
622 table0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
623 AV_WL32(dst + 4, vv);
624 table1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
625 dst += 8;
626
627 while (dst < tex_data + tex_size) {
628 ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data, &oi, op_size,
629 &dst, &state, table0, table1, 0);
630 if (ret < 0)
631 return ret;
632 }
633
634 bytestream2_seek(gb, data_start + op_offset + skip - 8, SEEK_SET);
635
636 return 0;
637}
638
640{
641 DXVContext *ctx = avctx->priv_data;
642 GetByteContext *gb = &ctx->gbc;
643 int ret;
644
645 ret = dxv_decompress_yo(ctx, gb, ctx->tex_data, ctx->tex_size,
646 ctx->op_data[0], ctx->op_size[0]);
647 if (ret < 0)
648 return ret;
649
650 return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
651 ctx->op_data[1], ctx->op_data[2],
652 ctx->op_size[1], ctx->op_size[2]);
653}
654
656{
657 DXVContext *ctx = avctx->priv_data;
658 GetByteContext *gb = &ctx->gbc;
659 int ret;
660
661 ret = dxv_decompress_cocg(ctx, gb, ctx->tex_data, ctx->tex_size,
662 ctx->op_data[0], ctx->op_data[3],
663 ctx->op_size[0], ctx->op_size[3]);
664 if (ret < 0)
665 return ret;
666
667 return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
668 ctx->op_data[1], ctx->op_data[2],
669 ctx->op_size[1], ctx->op_size[2]);
670}
671
673{
674 DXVContext *ctx = avctx->priv_data;
675 GetByteContext *gbc = &ctx->gbc;
676 uint32_t value, op, prev;
677 int idx, state = 0;
678 int pos = 4;
679 int run = 0;
680 int probe, check;
681
682 /* Copy the first four elements */
683 AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
684 AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
685 AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
686 AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
687
688 /* Process input until the whole texture has been filled */
689 while (pos + 2 <= ctx->tex_size / 4) {
690 if (run) {
691 run--;
692
693 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
694 AV_WL32(ctx->tex_data + 4 * pos, prev);
695 pos++;
696 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
697 AV_WL32(ctx->tex_data + 4 * pos, prev);
698 pos++;
699 } else {
700 if (bytestream2_get_bytes_left(gbc) < 1)
701 return AVERROR_INVALIDDATA;
702 if (state == 0) {
703 value = bytestream2_get_le32(gbc);
704 state = 16;
705 }
706 op = value & 0x3;
707 value >>= 2;
708 state--;
709
710 switch (op) {
711 case 0:
712 /* Long copy */
713 check = bytestream2_get_byte(gbc) + 1;
714 if (check == 256) {
715 do {
716 probe = bytestream2_get_le16(gbc);
717 check += probe;
718 } while (probe == 0xFFFF);
719 }
720 while (check && pos + 4 <= ctx->tex_size / 4) {
721 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
722 AV_WL32(ctx->tex_data + 4 * pos, prev);
723 pos++;
724
725 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
726 AV_WL32(ctx->tex_data + 4 * pos, prev);
727 pos++;
728
729 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
730 AV_WL32(ctx->tex_data + 4 * pos, prev);
731 pos++;
732
733 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
734 AV_WL32(ctx->tex_data + 4 * pos, prev);
735 pos++;
736
737 check--;
738 }
739
740 /* Restart (or exit) the loop */
741 continue;
742 break;
743 case 1:
744 /* Load new run value */
745 run = bytestream2_get_byte(gbc);
746 if (run == 255) {
747 do {
748 probe = bytestream2_get_le16(gbc);
749 run += probe;
750 } while (probe == 0xFFFF);
751 }
752
753 /* Copy two dwords from previous data */
754 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
755 AV_WL32(ctx->tex_data + 4 * pos, prev);
756 pos++;
757
758 prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
759 AV_WL32(ctx->tex_data + 4 * pos, prev);
760 pos++;
761 break;
762 case 2:
763 /* Copy two dwords from a previous index */
764 idx = 8 + 4 * bytestream2_get_le16(gbc);
765 if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
766 return AVERROR_INVALIDDATA;
767 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
768 AV_WL32(ctx->tex_data + 4 * pos, prev);
769 pos++;
770
771 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
772 AV_WL32(ctx->tex_data + 4 * pos, prev);
773 pos++;
774 break;
775 case 3:
776 /* Copy two dwords from input */
777 prev = bytestream2_get_le32(gbc);
778 AV_WL32(ctx->tex_data + 4 * pos, prev);
779 pos++;
780
781 prev = bytestream2_get_le32(gbc);
782 AV_WL32(ctx->tex_data + 4 * pos, prev);
783 pos++;
784 break;
785 }
786 }
787
788 CHECKPOINT(4);
789 if (pos + 2 > ctx->tex_size / 4)
790 return AVERROR_INVALIDDATA;
791
792 /* Copy two elements from a previous offset or from the input buffer */
793 if (op) {
794 if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
795 return AVERROR_INVALIDDATA;
796 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
797 AV_WL32(ctx->tex_data + 4 * pos, prev);
798 pos++;
799
800 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
801 AV_WL32(ctx->tex_data + 4 * pos, prev);
802 pos++;
803 } else {
804 CHECKPOINT(4);
805
806 if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
807 return AVERROR_INVALIDDATA;
808 if (op)
809 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
810 else
811 prev = bytestream2_get_le32(gbc);
812 AV_WL32(ctx->tex_data + 4 * pos, prev);
813 pos++;
814
815 CHECKPOINT(4);
816
817 if (op)
818 prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
819 else
820 prev = bytestream2_get_le32(gbc);
821 AV_WL32(ctx->tex_data + 4 * pos, prev);
822 pos++;
823 }
824 }
825
826 return 0;
827}
828
830{
831 DXVContext *ctx = avctx->priv_data;
832 unsigned old_size = ctx->tex_data_size;
833 int ret = ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size, &ctx->tex_data_size);
834 old_size = FFMAX(old_size, ctx->tex_size);
835 if (ctx->tex_data_size > old_size)
836 memset(ctx->tex_data + old_size, 0, ctx->tex_data_size - old_size);
837 return ret;
838}
839
841{
842 DXVContext *ctx = avctx->priv_data;
843 GetByteContext *gbc = &ctx->gbc;
844
845 if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
846 return AVERROR_INVALIDDATA;
847
848 bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
849 return 0;
850}
851
853 int *got_frame, AVPacket *avpkt)
854{
855 DXVContext *ctx = avctx->priv_data;
856 GetByteContext *gbc = &ctx->gbc;
857 TextureDSPThreadContext texdsp_ctx, ctexdsp_ctx;
858 int (*decompress_tex)(AVCodecContext *avctx);
859 const char *msgcomp, *msgtext;
860 uint32_t tag;
861 int version_major, version_minor = 0;
862 int size = 0, old_type = 0;
863 int ret;
864
865 bytestream2_init(gbc, avpkt->data, avpkt->size);
866
867 avctx->pix_fmt = AV_PIX_FMT_RGBA;
868 avctx->colorspace = AVCOL_SPC_RGB;
869
870 tag = bytestream2_get_le32(gbc);
871 switch (tag) {
872 case DXV_FMT_DXT1:
873 decompress_tex = dxv_decompress_dxt1;
874 texdsp_ctx.tex_funct = ctx->texdsp.dxt1_block;
875 texdsp_ctx.tex_ratio = 8;
876 texdsp_ctx.raw_ratio = 16;
877 msgcomp = "DXTR1";
878 msgtext = "DXT1";
879 break;
880 case DXV_FMT_DXT5:
881 decompress_tex = dxv_decompress_dxt5;
882 /* DXV misnomers DXT5, alpha is premultiplied so use DXT4 instead */
883 texdsp_ctx.tex_funct = ctx->texdsp.dxt4_block;
884 texdsp_ctx.tex_ratio = 16;
885 texdsp_ctx.raw_ratio = 16;
886 msgcomp = "DXTR5";
887 msgtext = "DXT5";
888 break;
889 case DXV_FMT_YCG6:
890 decompress_tex = dxv_decompress_ycg6;
891 texdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
892 texdsp_ctx.tex_ratio = 8;
893 texdsp_ctx.raw_ratio = 4;
894 ctexdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
895 ctexdsp_ctx.tex_ratio = 16;
896 ctexdsp_ctx.raw_ratio = 4;
897 msgcomp = "YOCOCG6";
898 msgtext = "YCG6";
901 break;
902 case DXV_FMT_YG10:
903 decompress_tex = dxv_decompress_yg10;
904 texdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
905 texdsp_ctx.tex_ratio = 16;
906 texdsp_ctx.raw_ratio = 4;
907 ctexdsp_ctx.tex_funct = ctx->texdsp.rgtc1u_gray_block;
908 ctexdsp_ctx.tex_ratio = 16;
909 ctexdsp_ctx.raw_ratio = 4;
910 msgcomp = "YAOCOCG10";
911 msgtext = "YG10";
914 break;
915 default:
916 /* Old version does not have a real header, just size and type. */
917 size = tag & 0x00FFFFFF;
918 old_type = tag >> 24;
919 version_major = (old_type & 0x0F) - 1;
920
921 if (old_type & 0x80) {
922 msgcomp = "RAW";
923 decompress_tex = dxv_decompress_raw;
924 } else {
925 msgcomp = "LZF";
926 decompress_tex = dxv_decompress_lzf;
927 }
928
929 if (old_type & 0x40) {
931 msgtext = "DXT5";
932
933 texdsp_ctx.tex_funct = ctx->texdsp.dxt4_block;
934 texdsp_ctx.tex_ratio = 16;
935 texdsp_ctx.raw_ratio = 16;
936 } else if (old_type & 0x20 || version_major == 1) {
938 msgtext = "DXT1";
939
940 texdsp_ctx.tex_funct = ctx->texdsp.dxt1_block;
941 texdsp_ctx.tex_ratio = 8;
942 texdsp_ctx.raw_ratio = 16;
943 } else {
944 av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
945 return AVERROR_INVALIDDATA;
946 }
947 break;
948 }
949 if (avctx->coded_height / 2 / TEXTURE_BLOCK_H < 1)
950 return AVERROR_INVALIDDATA;
951
952 texdsp_ctx.slice_count = av_clip(avctx->thread_count, 1,
954 ctexdsp_ctx.slice_count = av_clip(avctx->thread_count, 1,
955 avctx->coded_height / 2 / TEXTURE_BLOCK_H);
956
957 /* New header is 12 bytes long. */
958 if (!old_type) {
959 version_major = bytestream2_get_byte(gbc) - 1;
960 version_minor = bytestream2_get_byte(gbc);
961
962 /* Encoder copies texture data when compression is not advantageous. */
963 if (bytestream2_get_byte(gbc)) {
964 msgcomp = "RAW";
965 decompress_tex = dxv_decompress_raw;
966 }
967
968 bytestream2_skip(gbc, 1); // unknown
969 size = bytestream2_get_le32(gbc);
970 }
971 av_log(avctx, AV_LOG_DEBUG,
972 "%s compression with %s texture (version %d.%d)\n",
973 msgcomp, msgtext, version_major, version_minor);
974
975 if (size != bytestream2_get_bytes_left(gbc)) {
976 av_log(avctx, AV_LOG_ERROR,
977 "Incomplete or invalid file (header %d, left %u).\n",
979 return AVERROR_INVALIDDATA;
980 }
981
982 ctx->tex_size = avctx->coded_width / (texdsp_ctx.raw_ratio / (avctx->pix_fmt == AV_PIX_FMT_RGBA ? 4 : 1)) *
984 texdsp_ctx.tex_ratio;
985 unsigned old_size = ctx->tex_data_size;
986 void *ptr = av_fast_realloc(ctx->tex_data, &ctx->tex_data_size, ctx->tex_size + AV_INPUT_BUFFER_PADDING_SIZE);
987 if (!ptr)
988 return AVERROR(ENOMEM);
989 ctx->tex_data = ptr;
990
991 if (ctx->tex_data_size > old_size)
992 memset(ctx->tex_data + old_size, 0, ctx->tex_data_size - old_size);
993
994 if (avctx->pix_fmt != AV_PIX_FMT_RGBA) {
995 int i;
996
997 ctx->ctex_size = avctx->coded_width / 2 / ctexdsp_ctx.raw_ratio *
998 avctx->coded_height / 2 / TEXTURE_BLOCK_H *
999 ctexdsp_ctx.tex_ratio;
1000
1001 ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
1002 ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
1003 ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
1004 ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
1005
1006 old_size = ctx->ctex_data_size;
1007 ptr = av_fast_realloc(ctx->ctex_data, &ctx->ctex_data_size, ctx->ctex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1008 if (!ptr)
1009 return AVERROR(ENOMEM);
1010 ctx->ctex_data = ptr;
1011 if (old_size < ctx->ctex_data_size)
1012 memset(ctx->ctex_data + old_size, 0, ctx->ctex_data_size - old_size);
1013
1014 for (i = 0; i < 4; i++) {
1015 old_size = ctx->op_data_size[i];
1016 ptr = av_fast_realloc(ctx->op_data[i], &ctx->op_data_size[i], ctx->op_size[i]);
1017 if (!ptr)
1018 return AVERROR(ENOMEM);
1019 ctx->op_data[i] = ptr;
1020 }
1021 }
1022
1023 /* Decompress texture out of the intermediate compression. */
1024 ret = decompress_tex(avctx);
1025 if (ret < 0)
1026 return ret;
1027
1028 ret = ff_thread_get_buffer(avctx, frame, 0);
1029 if (ret < 0)
1030 return ret;
1031
1032 texdsp_ctx.width = avctx->coded_width;
1033 texdsp_ctx.height = avctx->coded_height;
1034 ctexdsp_ctx.width = avctx->coded_width / 2;
1035 ctexdsp_ctx.height = avctx->coded_height / 2;
1036 switch (tag) {
1037 case DXV_FMT_YG10:
1038 /* BC5 texture with alpha in the second half of each block */
1039 texdsp_ctx.tex_data.in = ctx->tex_data + texdsp_ctx.tex_ratio / 2;
1040 texdsp_ctx.frame_data.out = frame->data[3];
1041 texdsp_ctx.stride = frame->linesize[3];
1042 ret = ff_texturedsp_exec_decompress_threads(avctx, &texdsp_ctx);
1043 if (ret < 0)
1044 return ret;
1046 case DXV_FMT_YCG6:
1047 /* BC5 texture with Co in the first half of each block and Cg in the second */
1048 ctexdsp_ctx.tex_data.in = ctx->ctex_data;
1049 ctexdsp_ctx.frame_data.out = frame->data[2];
1050 ctexdsp_ctx.stride = frame->linesize[2];
1051 ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx);
1052 if (ret < 0)
1053 return ret;
1054 ctexdsp_ctx.tex_data.in = ctx->ctex_data + ctexdsp_ctx.tex_ratio / 2;
1055 ctexdsp_ctx.frame_data.out = frame->data[1];
1056 ctexdsp_ctx.stride = frame->linesize[1];
1057 ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx);
1058 if (ret < 0)
1059 return ret;
1061 case DXV_FMT_DXT1:
1062 case DXV_FMT_DXT5:
1063 /* For DXT1 and DXT5, self explanatory
1064 * For YCG6, BC4 texture for Y
1065 * For YG10, BC5 texture with Y in the first half of each block */
1066 texdsp_ctx.tex_data.in = ctx->tex_data;
1067 texdsp_ctx.frame_data.out = frame->data[0];
1068 texdsp_ctx.stride = frame->linesize[0];
1069 ret = ff_texturedsp_exec_decompress_threads(avctx, &texdsp_ctx);
1070 if (ret < 0)
1071 return ret;
1072 break;
1073 }
1074
1075 /* Frame is ready to be output. */
1076 *got_frame = 1;
1077
1078 return avpkt->size;
1079}
1080
1082{
1083 DXVContext *ctx = avctx->priv_data;
1084 int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1085
1086 if (ret < 0) {
1087 av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
1088 avctx->width, avctx->height);
1089 return ret;
1090 }
1091
1092 /* Codec is based on 4x4 blocks, but in practice width is aligned to 16 */
1093 avctx->coded_width = FFALIGN(avctx->width, 16);
1094 avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
1095
1096 ff_texturedsp_init(&ctx->texdsp);
1097
1098 return 0;
1099}
1100
1102{
1103 DXVContext *ctx = avctx->priv_data;
1104
1105 av_freep(&ctx->tex_data);
1106 ctx->tex_data_size = 0;
1107
1108 av_freep(&ctx->ctex_data);
1109 ctx->ctex_data_size = 0;
1110
1111 av_freep(&ctx->op_data[0]);
1112 av_freep(&ctx->op_data[1]);
1113 av_freep(&ctx->op_data[2]);
1114 av_freep(&ctx->op_data[3]);
1115 memset(ctx->op_data_size, 0, sizeof(ctx->op_data_size));
1116
1117 return 0;
1118}
1119
1121 .p.name = "dxv",
1122 CODEC_LONG_NAME("Resolume DXV"),
1123 .p.type = AVMEDIA_TYPE_VIDEO,
1124 .p.id = AV_CODEC_ID_DXV,
1125 .init = dxv_init,
1127 .close = dxv_close,
1128 .priv_data_size = sizeof(DXVContext),
1129 .p.capabilities = AV_CODEC_CAP_DR1 |
1132 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1133};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static int probe(const AVProbeData *p)
Definition act.c:39
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_dxv_decoder
Definition dxv.c:1120
static AVFormatContext * ctx
Libavcodec external API header.
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition bytestream.h:212
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
#define flag(name)
Definition cbs_h264.c:60
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define av_clip
Definition common.h:100
long long int64_t
Definition coverity.c:34
static AVFrame * frame
static int dxv_decompress_yg10(AVCodecContext *avctx)
Definition dxv.c:655
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:301
static int dxv_decompress_dxt1(AVCodecContext *avctx)
Definition dxv.c:92
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:541
static av_cold int dxv_init(AVCodecContext *avctx)
Definition dxv.c:1081
static int fill_optable(unsigned *table0, OpcodeTable *table1, int nb_elements)
Definition dxv.c:191
static int dxv_decompress_dxt5(AVCodecContext *avctx)
Definition dxv.c:672
static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op_size, int nb_elements)
Definition dxv.c:232
static int dxv_decompress_raw(AVCodecContext *avctx)
Definition dxv.c:840
static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition dxv.c:852
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:597
static int dxv_decompress_ycg6(AVCodecContext *avctx)
Definition dxv.c:639
static int fill_ltable(GetByteContext *gb, uint32_t *table, int *nb_elements)
Definition dxv.c:147
static av_cold int dxv_close(AVCodecContext *avctx)
Definition dxv.c:1101
#define CHECKPOINT(x)
Definition dxv.c:60
static int dxv_decompress_opcodes(GetByteContext *gb, void *dstp, size_t op_size)
Definition dxv.c:274
static int dxv_decompress_lzf(AVCodecContext *avctx)
Definition dxv.c:829
@ DXV_FMT_DXT5
Definition dxv.h:29
@ DXV_FMT_YG10
Definition dxv.h:31
@ DXV_FMT_YCG6
Definition dxv.h:30
@ DXV_FMT_DXT1
Definition dxv.h:28
double value
Definition eval.c:102
static struct @346255127015250356166251341105367306144006377143 state
static const uint8_t bits[8]
Definition fastaudio.c:100
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition codec.h:102
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition codec.h:98
@ AV_CODEC_ID_DXV
Definition codec_id.h:240
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define ff_clz
Definition intmath.h:141
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
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
misc image utilities
#define AV_WL32(p, v)
#define AV_RL32(p)
#define AV_RL16(p)
#define AV_WL16(p, v)
unsigned offset
Definition libaomenc.c:763
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
Multithreading API for decoders.
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_cold
Definition attributes.h:117
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned *allocated_size)
Decompress LZF data into *buf, reallocating it as needed.
Definition lzf.c:55
static const uint16_t mask[17]
Definition lzw.c:38
const int16_t * tab2
Definition mace.c:145
const int16_t * tab1
Definition mace.c:145
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
static uint8_t half(int a, int b)
Definition mobiclip.c:540
#define check(x, y, S, v)
uint32_t tag
Definition movenc.c:2073
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ AVCOL_SPC_YCOCG
Definition pixfmt.h:716
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition pixfmt.h:707
static const uint16_t table[]
Definition prosumer.c:203
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
static const ElemCat * elements[ELEMENT_COUNT]
Definition signature.h:565
unsigned int pos
Definition spdifenc.c:431
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
uint8_t * tex_data
Definition dxv.c:41
uint8_t * ctex_data
Definition dxv.c:43
int64_t ctex_size
Definition dxv.c:47
uint8_t * op_data[4]
Definition dxv.c:49
TextureDSPContext texdsp
Definition dxv.c:38
size_t tex_size
Definition dxv.c:46
unsigned ctex_data_size
Definition dxv.c:44
unsigned tex_data_size
Definition dxv.c:42
unsigned op_data_size[4]
Definition dxv.c:50
int64_t op_size[4]
Definition dxv.c:51
GetByteContext gbc
Definition dxv.c:39
const uint8_t * buffer
Definition bytestream.h:34
uint8_t val1
Definition dxv.c:143
int16_t next
Definition dxv.c:142
uint8_t val2
Definition dxv.c:144
union TextureDSPThreadContext::@274301011315177304000236374320052224260127200145 frame_data
int(* tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition texturedsp.h:85
const uint8_t * in
Definition texturedsp.h:71
union TextureDSPThreadContext::@343301224315114336214156165306265310104165221120 tex_data
uint8_t run
Definition svq3.c:207
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition texturedsp.c:640
Texture block (4x4) module.
int ff_texturedsp_exec_decompress_threads(struct AVCodecContext *avctx, TextureDSPThreadContext *ctx)
#define TEXTURE_BLOCK_H
Definition texturedsp.h:43
int size