xref: /third_party/ffmpeg/libavcodec/dxv.c (revision cabdff1a)
1/*
2 * Resolume DXV decoder
3 * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
4 * Copyright (C) 2018 Paul B Mahol
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <stdint.h>
24
25#include "libavutil/imgutils.h"
26
27#include "mathops.h"
28#include "avcodec.h"
29#include "bytestream.h"
30#include "codec_internal.h"
31#include "lzf.h"
32#include "texturedsp.h"
33#include "thread.h"
34
35typedef struct DXVContext {
36    TextureDSPContext texdsp;
37    GetByteContext gbc;
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 */
48    int slice_count;
49
50    uint8_t *op_data[4]; // Opcodes
51    int64_t op_size[4];  // Opcodes size
52
53    int texture_block_w;
54    int texture_block_h;
55
56    int ctexture_block_w;
57    int ctexture_block_h;
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
66static 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
82static 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
111static 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
141static 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
160static 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
174static 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
193static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
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
288static int dxv_decompress_dxt1(AVCodecContext *avctx)
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
337typedef struct OpcodeTable {
338    int16_t next;
339    uint8_t val1;
340    uint8_t val2;
341} OpcodeTable;
342
343static 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
387static 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
428static 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
470static 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
495static int dxv_decompress_cgo(DXVContext *ctx, GetByteContext *gb,
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 {
719done:
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
735static int dxv_decompress_cocg(DXVContext *ctx, GetByteContext *gb,
736                               uint8_t *tex_data, int tex_size,
737                               uint8_t *op_data0, uint8_t *op_data1,
738                               int max_op_size0, int max_op_size1)
739{
740    uint8_t *dst, *tab2[256] = { 0 }, *tab0[256] = { 0 }, *tab3[256] = { 0 }, *tab1[256] = { 0 };
741    int op_offset = bytestream2_get_le32(gb);
742    unsigned op_size0 = bytestream2_get_le32(gb);
743    unsigned op_size1 = bytestream2_get_le32(gb);
744    int data_start = bytestream2_tell(gb);
745    int skip0, skip1, oi0 = 0, oi1 = 0;
746    int ret, state0 = 0, state1 = 0;
747
748    if (op_offset < 12 || op_offset - 12 > bytestream2_get_bytes_left(gb))
749        return AVERROR_INVALIDDATA;
750
751    dst = tex_data;
752    bytestream2_skip(gb, op_offset - 12);
753    if (op_size0 > max_op_size0)
754        return AVERROR_INVALIDDATA;
755    skip0 = dxv_decompress_opcodes(gb, op_data0, op_size0);
756    if (skip0 < 0)
757        return skip0;
758    if (op_size1 > max_op_size1)
759        return AVERROR_INVALIDDATA;
760    skip1 = dxv_decompress_opcodes(gb, op_data1, op_size1);
761    if (skip1 < 0)
762        return skip1;
763    bytestream2_seek(gb, data_start, SEEK_SET);
764
765    AV_WL32(dst, bytestream2_get_le32(gb));
766    AV_WL32(dst + 4, bytestream2_get_le32(gb));
767    AV_WL32(dst + 8, bytestream2_get_le32(gb));
768    AV_WL32(dst + 12, bytestream2_get_le32(gb));
769
770    tab0[0x9E3779B1 * AV_RL16(dst) >> 24] = dst;
771    tab1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
772    tab2[0x9E3779B1 * AV_RL16(dst + 8) >> 24] = dst + 8;
773    tab3[0x9E3779B1 * (AV_RL32(dst + 10) & 0xFFFFFF) >> 24] = dst + 10;
774    dst += 16;
775    while (dst + 10 < tex_data + tex_size) {
776        ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data0, &oi0, op_size0,
777                                 &dst, &state0, tab0, tab1, 8);
778        if (ret < 0)
779            return ret;
780        ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data1, &oi1, op_size1,
781                                 &dst, &state1, tab2, tab3, 8);
782        if (ret < 0)
783            return ret;
784    }
785
786    bytestream2_seek(gb, data_start - 12 + op_offset + skip0 + skip1, SEEK_SET);
787
788    return 0;
789}
790
791static int dxv_decompress_yo(DXVContext *ctx, GetByteContext *gb,
792                             uint8_t *tex_data, int tex_size,
793                             uint8_t *op_data, int max_op_size)
794{
795    int op_offset = bytestream2_get_le32(gb);
796    unsigned op_size = bytestream2_get_le32(gb);
797    int data_start = bytestream2_tell(gb);
798    uint8_t *dst, *table0[256] = { 0 }, *table1[256] = { 0 };
799    int ret, state = 0, skip, oi = 0, v, vv;
800
801    if (op_offset < 8 || op_offset - 8 > bytestream2_get_bytes_left(gb))
802        return AVERROR_INVALIDDATA;
803
804    dst = tex_data;
805    bytestream2_skip(gb, op_offset - 8);
806    if (op_size > max_op_size)
807        return AVERROR_INVALIDDATA;
808    skip = dxv_decompress_opcodes(gb, op_data, op_size);
809    if (skip < 0)
810        return skip;
811    bytestream2_seek(gb, data_start, SEEK_SET);
812
813    v = bytestream2_get_le32(gb);
814    AV_WL32(dst, v);
815    vv = bytestream2_get_le32(gb);
816    table0[0x9E3779B1 * (uint16_t)v >> 24] = dst;
817    AV_WL32(dst + 4, vv);
818    table1[0x9E3779B1 * (AV_RL32(dst + 2) & 0xFFFFFF) >> 24] = dst + 2;
819    dst += 8;
820
821    while (dst < tex_data + tex_size) {
822        ret = dxv_decompress_cgo(ctx, gb, tex_data, tex_size, op_data, &oi, op_size,
823                                 &dst, &state, table0, table1, 0);
824        if (ret < 0)
825            return ret;
826    }
827
828    bytestream2_seek(gb, data_start + op_offset + skip - 8, SEEK_SET);
829
830    return 0;
831}
832
833static int dxv_decompress_ycg6(AVCodecContext *avctx)
834{
835    DXVContext *ctx = avctx->priv_data;
836    GetByteContext *gb = &ctx->gbc;
837    int ret;
838
839    ret = dxv_decompress_yo(ctx, gb, ctx->tex_data, ctx->tex_size,
840                            ctx->op_data[0], ctx->op_size[0]);
841    if (ret < 0)
842        return ret;
843
844    return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
845                               ctx->op_data[1], ctx->op_data[2],
846                               ctx->op_size[1], ctx->op_size[2]);
847}
848
849static int dxv_decompress_yg10(AVCodecContext *avctx)
850{
851    DXVContext *ctx = avctx->priv_data;
852    GetByteContext *gb = &ctx->gbc;
853    int ret;
854
855    ret = dxv_decompress_cocg(ctx, gb, ctx->tex_data, ctx->tex_size,
856                              ctx->op_data[0], ctx->op_data[3],
857                              ctx->op_size[0], ctx->op_size[3]);
858    if (ret < 0)
859        return ret;
860
861    return dxv_decompress_cocg(ctx, gb, ctx->ctex_data, ctx->ctex_size,
862                               ctx->op_data[1], ctx->op_data[2],
863                               ctx->op_size[1], ctx->op_size[2]);
864}
865
866static int dxv_decompress_dxt5(AVCodecContext *avctx)
867{
868    DXVContext *ctx = avctx->priv_data;
869    GetByteContext *gbc = &ctx->gbc;
870    uint32_t value, op, prev;
871    int idx, state = 0;
872    int pos = 4;
873    int run = 0;
874    int probe, check;
875
876    /* Copy the first four elements */
877    AV_WL32(ctx->tex_data +  0, bytestream2_get_le32(gbc));
878    AV_WL32(ctx->tex_data +  4, bytestream2_get_le32(gbc));
879    AV_WL32(ctx->tex_data +  8, bytestream2_get_le32(gbc));
880    AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
881
882    /* Process input until the whole texture has been filled */
883    while (pos + 2 <= ctx->tex_size / 4) {
884        if (run) {
885            run--;
886
887            prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
888            AV_WL32(ctx->tex_data + 4 * pos, prev);
889            pos++;
890            prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
891            AV_WL32(ctx->tex_data + 4 * pos, prev);
892            pos++;
893        } else {
894            if (bytestream2_get_bytes_left(gbc) < 1)
895                return AVERROR_INVALIDDATA;
896            if (state == 0) {
897                value = bytestream2_get_le32(gbc);
898                state = 16;
899            }
900            op = value & 0x3;
901            value >>= 2;
902            state--;
903
904            switch (op) {
905            case 0:
906                /* Long copy */
907                check = bytestream2_get_byte(gbc) + 1;
908                if (check == 256) {
909                    do {
910                        probe = bytestream2_get_le16(gbc);
911                        check += probe;
912                    } while (probe == 0xFFFF);
913                }
914                while (check && pos + 4 <= ctx->tex_size / 4) {
915                    prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
916                    AV_WL32(ctx->tex_data + 4 * pos, prev);
917                    pos++;
918
919                    prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
920                    AV_WL32(ctx->tex_data + 4 * pos, prev);
921                    pos++;
922
923                    prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
924                    AV_WL32(ctx->tex_data + 4 * pos, prev);
925                    pos++;
926
927                    prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
928                    AV_WL32(ctx->tex_data + 4 * pos, prev);
929                    pos++;
930
931                    check--;
932                }
933
934                /* Restart (or exit) the loop */
935                continue;
936                break;
937            case 1:
938                /* Load new run value */
939                run = bytestream2_get_byte(gbc);
940                if (run == 255) {
941                    do {
942                        probe = bytestream2_get_le16(gbc);
943                        run += probe;
944                    } while (probe == 0xFFFF);
945                }
946
947                /* Copy two dwords from previous data */
948                prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
949                AV_WL32(ctx->tex_data + 4 * pos, prev);
950                pos++;
951
952                prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
953                AV_WL32(ctx->tex_data + 4 * pos, prev);
954                pos++;
955                break;
956            case 2:
957                /* Copy two dwords from a previous index */
958                idx = 8 + bytestream2_get_le16(gbc);
959                if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
960                    return AVERROR_INVALIDDATA;
961                prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
962                AV_WL32(ctx->tex_data + 4 * pos, prev);
963                pos++;
964
965                prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
966                AV_WL32(ctx->tex_data + 4 * pos, prev);
967                pos++;
968                break;
969            case 3:
970                /* Copy two dwords from input */
971                prev = bytestream2_get_le32(gbc);
972                AV_WL32(ctx->tex_data + 4 * pos, prev);
973                pos++;
974
975                prev = bytestream2_get_le32(gbc);
976                AV_WL32(ctx->tex_data + 4 * pos, prev);
977                pos++;
978                break;
979            }
980        }
981
982        CHECKPOINT(4);
983        if (pos + 2 > ctx->tex_size / 4)
984            return AVERROR_INVALIDDATA;
985
986        /* Copy two elements from a previous offset or from the input buffer */
987        if (op) {
988            if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)
989                return AVERROR_INVALIDDATA;
990            prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
991            AV_WL32(ctx->tex_data + 4 * pos, prev);
992            pos++;
993
994            prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
995            AV_WL32(ctx->tex_data + 4 * pos, prev);
996            pos++;
997        } else {
998            CHECKPOINT(4);
999
1000            if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4))
1001                return AVERROR_INVALIDDATA;
1002            if (op)
1003                prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1004            else
1005                prev = bytestream2_get_le32(gbc);
1006            AV_WL32(ctx->tex_data + 4 * pos, prev);
1007            pos++;
1008
1009            CHECKPOINT(4);
1010
1011            if (op)
1012                prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
1013            else
1014                prev = bytestream2_get_le32(gbc);
1015            AV_WL32(ctx->tex_data + 4 * pos, prev);
1016            pos++;
1017        }
1018    }
1019
1020    return 0;
1021}
1022
1023static int dxv_decompress_lzf(AVCodecContext *avctx)
1024{
1025    DXVContext *ctx = avctx->priv_data;
1026    return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
1027}
1028
1029static int dxv_decompress_raw(AVCodecContext *avctx)
1030{
1031    DXVContext *ctx = avctx->priv_data;
1032    GetByteContext *gbc = &ctx->gbc;
1033
1034    if (bytestream2_get_bytes_left(gbc) < ctx->tex_size)
1035        return AVERROR_INVALIDDATA;
1036
1037    bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size);
1038    return 0;
1039}
1040
1041static int dxv_decode(AVCodecContext *avctx, AVFrame *frame,
1042                      int *got_frame, AVPacket *avpkt)
1043{
1044    DXVContext *ctx = avctx->priv_data;
1045    GetByteContext *gbc = &ctx->gbc;
1046    int (*decompress_tex)(AVCodecContext *avctx);
1047    const char *msgcomp, *msgtext;
1048    uint32_t tag;
1049    int version_major, version_minor = 0;
1050    int size = 0, old_type = 0;
1051    int ret;
1052
1053    bytestream2_init(gbc, avpkt->data, avpkt->size);
1054
1055    ctx->texture_block_h = 4;
1056    ctx->texture_block_w = 4;
1057
1058    avctx->pix_fmt = AV_PIX_FMT_RGBA;
1059    avctx->colorspace = AVCOL_SPC_RGB;
1060
1061    ctx->tex_funct = NULL;
1062    ctx->tex_funct_planar[0] = NULL;
1063    ctx->tex_funct_planar[1] = NULL;
1064
1065    tag = bytestream2_get_le32(gbc);
1066    switch (tag) {
1067    case MKBETAG('D', 'X', 'T', '1'):
1068        decompress_tex = dxv_decompress_dxt1;
1069        ctx->tex_funct = ctx->texdsp.dxt1_block;
1070        ctx->tex_rat   = 8;
1071        ctx->tex_step  = 8;
1072        msgcomp = "DXTR1";
1073        msgtext = "DXT1";
1074        break;
1075    case MKBETAG('D', 'X', 'T', '5'):
1076        decompress_tex = dxv_decompress_dxt5;
1077        ctx->tex_funct = ctx->texdsp.dxt5_block;
1078        ctx->tex_rat   = 4;
1079        ctx->tex_step  = 16;
1080        msgcomp = "DXTR5";
1081        msgtext = "DXT5";
1082        break;
1083    case MKBETAG('Y', 'C', 'G', '6'):
1084        decompress_tex = dxv_decompress_ycg6;
1085        ctx->tex_funct_planar[0] = yo_block;
1086        ctx->tex_funct_planar[1] = cocg_block;
1087        ctx->tex_rat   = 8;
1088        ctx->tex_step  = 32;
1089        ctx->ctex_step = 16;
1090        msgcomp = "YOCOCG6";
1091        msgtext = "YCG6";
1092        ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1093        ctx->texture_block_h = 4;
1094        ctx->texture_block_w = 16;
1095        ctx->ctexture_block_h = 4;
1096        ctx->ctexture_block_w = 4;
1097        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1098        avctx->colorspace = AVCOL_SPC_YCOCG;
1099        break;
1100    case MKBETAG('Y', 'G', '1', '0'):
1101        decompress_tex = dxv_decompress_yg10;
1102        ctx->tex_funct_planar[0] = yao_block;
1103        ctx->tex_funct_planar[1] = cocg_block;
1104        ctx->tex_rat   = 4;
1105        ctx->tex_step  = 64;
1106        ctx->ctex_step = 16;
1107        msgcomp = "YAOCOCG10";
1108        msgtext = "YG10";
1109        ctx->ctex_size = avctx->coded_width * avctx->coded_height / 4;
1110        ctx->texture_block_h = 4;
1111        ctx->texture_block_w = 16;
1112        ctx->ctexture_block_h = 4;
1113        ctx->ctexture_block_w = 4;
1114        avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
1115        avctx->colorspace = AVCOL_SPC_YCOCG;
1116        break;
1117    default:
1118        /* Old version does not have a real header, just size and type. */
1119        size = tag & 0x00FFFFFF;
1120        old_type = tag >> 24;
1121        version_major = (old_type & 0x0F) - 1;
1122
1123        if (old_type & 0x80) {
1124            msgcomp = "RAW";
1125            decompress_tex = dxv_decompress_raw;
1126        } else {
1127            msgcomp = "LZF";
1128            decompress_tex = dxv_decompress_lzf;
1129        }
1130
1131        if (old_type & 0x40) {
1132            msgtext = "DXT5";
1133
1134            ctx->tex_funct = ctx->texdsp.dxt5_block;
1135            ctx->tex_step  = 16;
1136        } else if (old_type & 0x20 || version_major == 1) {
1137            msgtext = "DXT1";
1138
1139            ctx->tex_funct = ctx->texdsp.dxt1_block;
1140            ctx->tex_step  = 8;
1141        } else {
1142            av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag);
1143            return AVERROR_INVALIDDATA;
1144        }
1145        ctx->tex_rat = 1;
1146        break;
1147    }
1148
1149    ctx->slice_count = av_clip(avctx->thread_count, 1,
1150                               avctx->coded_height / FFMAX(ctx->texture_block_h,
1151                                                           ctx->ctexture_block_h));
1152
1153    /* New header is 12 bytes long. */
1154    if (!old_type) {
1155        version_major = bytestream2_get_byte(gbc) - 1;
1156        version_minor = bytestream2_get_byte(gbc);
1157
1158        /* Encoder copies texture data when compression is not advantageous. */
1159        if (bytestream2_get_byte(gbc)) {
1160            msgcomp = "RAW";
1161            ctx->tex_rat = 1;
1162            decompress_tex = dxv_decompress_raw;
1163        }
1164
1165        bytestream2_skip(gbc, 1); // unknown
1166        size = bytestream2_get_le32(gbc);
1167    }
1168    av_log(avctx, AV_LOG_DEBUG,
1169           "%s compression with %s texture (version %d.%d)\n",
1170           msgcomp, msgtext, version_major, version_minor);
1171
1172    if (size != bytestream2_get_bytes_left(gbc)) {
1173        av_log(avctx, AV_LOG_ERROR,
1174               "Incomplete or invalid file (header %d, left %u).\n",
1175               size, bytestream2_get_bytes_left(gbc));
1176        return AVERROR_INVALIDDATA;
1177    }
1178
1179    ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
1180    ret = av_reallocp(&ctx->tex_data, ctx->tex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1181    if (ret < 0)
1182        return ret;
1183
1184    if (ctx->ctex_size) {
1185        int i;
1186
1187        ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16;
1188        ctx->op_size[1] = avctx->coded_width * avctx->coded_height / 32;
1189        ctx->op_size[2] = avctx->coded_width * avctx->coded_height / 32;
1190        ctx->op_size[3] = avctx->coded_width * avctx->coded_height / 16;
1191
1192        ret = av_reallocp(&ctx->ctex_data, ctx->ctex_size + AV_INPUT_BUFFER_PADDING_SIZE);
1193        if (ret < 0)
1194            return ret;
1195        for (i = 0; i < 4; i++) {
1196            ret = av_reallocp(&ctx->op_data[i], ctx->op_size[i]);
1197            if (ret < 0)
1198                return ret;
1199        }
1200    }
1201
1202    /* Decompress texture out of the intermediate compression. */
1203    ret = decompress_tex(avctx);
1204    if (ret < 0)
1205        return ret;
1206    {
1207        int w_block = avctx->coded_width / ctx->texture_block_w;
1208        int h_block = avctx->coded_height / ctx->texture_block_h;
1209        if (w_block * h_block * ctx->tex_step > ctx->tex_size * 8LL)
1210            return AVERROR_INVALIDDATA;
1211    }
1212
1213    ret = ff_thread_get_buffer(avctx, frame, 0);
1214    if (ret < 0)
1215        return ret;
1216
1217    /* Now decompress the texture with the standard functions. */
1218    avctx->execute2(avctx, decompress_texture_thread,
1219                    frame, NULL, ctx->slice_count);
1220
1221    /* Frame is ready to be output. */
1222    frame->pict_type = AV_PICTURE_TYPE_I;
1223    frame->key_frame = 1;
1224    *got_frame = 1;
1225
1226    return avpkt->size;
1227}
1228
1229static 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
1249static 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
1263const FFCodec ff_dxv_decoder = {
1264    .p.name         = "dxv",
1265    .p.long_name    = NULL_IF_CONFIG_SMALL("Resolume DXV"),
1266    .p.type         = AVMEDIA_TYPE_VIDEO,
1267    .p.id           = AV_CODEC_ID_DXV,
1268    .init           = dxv_init,
1269    FF_CODEC_DECODE_CB(dxv_decode),
1270    .close          = dxv_close,
1271    .priv_data_size = sizeof(DXVContext),
1272    .p.capabilities = AV_CODEC_CAP_DR1 |
1273                      AV_CODEC_CAP_SLICE_THREADS |
1274                      AV_CODEC_CAP_FRAME_THREADS,
1275    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
1276                      FF_CODEC_CAP_INIT_CLEANUP,
1277};
1278