Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/dxtory.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Dxtory decoder
3
 *
4
 * Copyright (c) 2011 Konstantin Shishkov
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 <inttypes.h>
24
25
#include "libavutil/common.h"
26
#include "libavutil/intreadwrite.h"
27
28
#define BITSTREAM_READER_LE
29
#include "avcodec.h"
30
#include "bytestream.h"
31
#include "codec_internal.h"
32
#include "get_bits.h"
33
#include "unary.h"
34
#include "thread.h"
35
36
static int64_t get_raw_size(enum AVPixelFormat fmt, int width, int height)
37
117k
{
38
117k
    switch (fmt) {
39
1.59k
    case AV_PIX_FMT_RGB555LE:
40
107k
    case AV_PIX_FMT_RGB565LE:
41
107k
        return width * height * 2LL;
42
0
    case AV_PIX_FMT_RGB24:
43
1.00k
    case AV_PIX_FMT_BGR24:
44
2.49k
    case AV_PIX_FMT_YUV444P:
45
2.49k
        return width * height * 3LL;
46
4.42k
    case AV_PIX_FMT_YUV420P:
47
4.42k
        return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 1) * AV_CEIL_RSHIFT(height, 1);
48
3.73k
    case AV_PIX_FMT_YUV410P:
49
3.73k
        return (int64_t)(width * height) + 2 * AV_CEIL_RSHIFT(width, 2) * AV_CEIL_RSHIFT(height, 2);
50
117k
    }
51
52
0
    return 0;
53
117k
}
54
55
static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip)
56
223k
{
57
223k
    if (!vflip)
58
16.6k
        return;
59
60
206k
    switch (pic->format) {
61
1.20k
    case AV_PIX_FMT_YUV444P:
62
1.20k
        pic->data[1] += (avctx->height - 1) * pic->linesize[1];
63
1.20k
        pic->linesize[1] = -pic->linesize[1];
64
1.20k
        pic->data[2] += (avctx->height - 1) * pic->linesize[2];
65
1.20k
        pic->linesize[2] = -pic->linesize[2];
66
1.80k
    case AV_PIX_FMT_RGB555LE:
67
203k
    case AV_PIX_FMT_RGB565LE:
68
204k
    case AV_PIX_FMT_BGR24:
69
204k
    case AV_PIX_FMT_RGB24:
70
204k
        pic->data[0] += (avctx->height - 1) * pic->linesize[0];
71
204k
        pic->linesize[0] = -pic->linesize[0];
72
204k
        break;
73
1.92k
    case AV_PIX_FMT_YUV410P:
74
1.92k
        pic->data[0] += (avctx->height - 1) * pic->linesize[0];
75
1.92k
        pic->linesize[0] = -pic->linesize[0];
76
1.92k
        pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[1];
77
1.92k
        pic->linesize[1] = -pic->linesize[1];
78
1.92k
        pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[2];
79
1.92k
        pic->linesize[2] = -pic->linesize[2];
80
1.92k
        break;
81
345
    case AV_PIX_FMT_YUV420P:
82
345
        pic->data[0] += (avctx->height - 1) * pic->linesize[0];
83
345
        pic->linesize[0] = -pic->linesize[0];
84
345
        pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[1];
85
345
        pic->linesize[1] = -pic->linesize[1];
86
345
        pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[2];
87
345
        pic->linesize[2] = -pic->linesize[2];
88
345
        break;
89
206k
    }
90
206k
}
91
92
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
93
                                const uint8_t *src, int src_size,
94
                                int id, int bpp, uint32_t vflipped)
95
108k
{
96
108k
    int h;
97
108k
    uint8_t *dst;
98
108k
    int ret;
99
100
108k
    if (src_size < get_raw_size(id, avctx->width, avctx->height)) {
101
3.69k
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
102
3.69k
        return AVERROR_INVALIDDATA;
103
3.69k
    }
104
105
104k
    avctx->pix_fmt = id;
106
104k
    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
107
2.64k
        return ret;
108
109
101k
    do_vflip(avctx, pic, vflipped);
110
111
101k
    dst = pic->data[0];
112
204k
    for (h = 0; h < avctx->height; h++) {
113
102k
        memcpy(dst, src, avctx->width * bpp);
114
102k
        src += avctx->width * bpp;
115
102k
        dst += pic->linesize[0];
116
102k
    }
117
118
101k
    do_vflip(avctx, pic, vflipped);
119
120
101k
    return 0;
121
104k
}
122
123
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
124
                                const uint8_t *src, int src_size,
125
                                uint32_t vflipped)
126
3.73k
{
127
3.73k
    int h, w;
128
3.73k
    uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
129
3.73k
    int height, width, hmargin, vmargin;
130
3.73k
    int huvborder;
131
3.73k
    int ret;
132
133
3.73k
    if (src_size < get_raw_size(AV_PIX_FMT_YUV410P, avctx->width, avctx->height)) {
134
778
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
135
778
        return AVERROR_INVALIDDATA;
136
778
    }
137
138
2.95k
    avctx->pix_fmt = AV_PIX_FMT_YUV410P;
139
2.95k
    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
140
804
        return ret;
141
142
2.14k
    do_vflip(avctx, pic, vflipped);
143
144
2.14k
    height = avctx->height & ~3;
145
2.14k
    width  = avctx->width  & ~3;
146
2.14k
    hmargin = avctx->width  - width;
147
2.14k
    vmargin = avctx->height - height;
148
2.14k
    huvborder = AV_CEIL_RSHIFT(avctx->width, 2) - 1;
149
150
2.14k
    Y1 = pic->data[0];
151
2.14k
    Y2 = pic->data[0] + pic->linesize[0];
152
2.14k
    Y3 = pic->data[0] + pic->linesize[0] * 2;
153
2.14k
    Y4 = pic->data[0] + pic->linesize[0] * 3;
154
2.14k
    U  = pic->data[1];
155
2.14k
    V  = pic->data[2];
156
146k
    for (h = 0; h < height; h += 4) {
157
162k
        for (w = 0; w < width; w += 4) {
158
18.3k
            AV_COPY32U(Y1 + w, src);
159
18.3k
            AV_COPY32U(Y2 + w, src + 4);
160
18.3k
            AV_COPY32U(Y3 + w, src + 8);
161
18.3k
            AV_COPY32U(Y4 + w, src + 12);
162
18.3k
            U[w >> 2] = src[16] + 0x80;
163
18.3k
            V[w >> 2] = src[17] + 0x80;
164
18.3k
            src += 18;
165
18.3k
        }
166
144k
        if (hmargin) {
167
288k
            for (w = 0; w < hmargin; w++) {
168
144k
                Y1[width + w] = src[w];
169
144k
                Y2[width + w] = src[w + hmargin * 1];
170
144k
                Y3[width + w] = src[w + hmargin * 2];
171
144k
                Y4[width + w] = src[w + hmargin * 3];
172
144k
            }
173
144k
            src += 4 * hmargin;
174
144k
            U[huvborder] = src[0] + 0x80;
175
144k
            V[huvborder] = src[1] + 0x80;
176
144k
            src += 2;
177
144k
        }
178
144k
        Y1 += pic->linesize[0] * 4;
179
144k
        Y2 += pic->linesize[0] * 4;
180
144k
        Y3 += pic->linesize[0] * 4;
181
144k
        Y4 += pic->linesize[0] * 4;
182
144k
        U  += pic->linesize[1];
183
144k
        V  += pic->linesize[2];
184
144k
    }
185
186
2.14k
    if (vmargin) {
187
42.6k
        for (w = 0; w < width; w += 4) {
188
40.8k
            AV_COPY32U(Y1 + w, src);
189
40.8k
            if (vmargin > 1)
190
40.8k
                AV_COPY32U(Y2 + w, src + 4);
191
40.8k
            if (vmargin > 2)
192
40.8k
                AV_COPY32U(Y3 + w, src + 8);
193
40.8k
            src += 4 * vmargin;
194
40.8k
            U[w >> 2] = src[0] + 0x80;
195
40.8k
            V[w >> 2] = src[1] + 0x80;
196
40.8k
            src += 2;
197
40.8k
        }
198
1.74k
        if (hmargin) {
199
3.53k
            for (w = 0; w < hmargin; w++) {
200
2.01k
                AV_COPY32U(Y1 + w, src);
201
2.01k
                if (vmargin > 1)
202
2.01k
                    AV_COPY32U(Y2 + w, src + 4);
203
2.01k
                if (vmargin > 2)
204
2.01k
                    AV_COPY32U(Y3 + w, src + 8);
205
2.01k
                src += 4 * vmargin;
206
2.01k
            }
207
1.52k
            U[huvborder] = src[0] + 0x80;
208
1.52k
            V[huvborder] = src[1] + 0x80;
209
1.52k
            src += 2;
210
1.52k
        }
211
1.74k
    }
212
213
2.14k
    do_vflip(avctx, pic, vflipped);
214
215
2.14k
    return 0;
216
2.95k
}
217
218
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
219
                                const uint8_t *src, int src_size,
220
                                uint32_t vflipped)
221
4.42k
{
222
4.42k
    int h, w;
223
4.42k
    uint8_t *Y1, *Y2, *U, *V;
224
4.42k
    int height, width, hmargin, vmargin;
225
4.42k
    int huvborder;
226
4.42k
    int ret;
227
228
4.42k
    if (src_size < get_raw_size(AV_PIX_FMT_YUV420P, avctx->width, avctx->height)) {
229
781
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
230
781
        return AVERROR_INVALIDDATA;
231
781
    }
232
233
3.64k
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
234
3.64k
    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
235
762
        return ret;
236
237
2.88k
    do_vflip(avctx, pic, vflipped);
238
239
2.88k
    height = avctx->height & ~1;
240
2.88k
    width  = avctx->width  & ~1;
241
2.88k
    hmargin = avctx->width  - width;
242
2.88k
    vmargin = avctx->height - height;
243
2.88k
    huvborder = AV_CEIL_RSHIFT(avctx->width, 1) - 1;
244
245
2.88k
    Y1 = pic->data[0];
246
2.88k
    Y2 = pic->data[0] + pic->linesize[0];
247
2.88k
    U  = pic->data[1];
248
2.88k
    V  = pic->data[2];
249
159k
    for (h = 0; h < height; h += 2) {
250
263k
        for (w = 0; w < width; w += 2) {
251
107k
            AV_COPY16(Y1 + w, src);
252
107k
            AV_COPY16(Y2 + w, src + 2);
253
107k
            U[w >> 1] = src[4] + 0x80;
254
107k
            V[w >> 1] = src[5] + 0x80;
255
107k
            src += 6;
256
107k
        }
257
156k
        if (hmargin) {
258
156k
            Y1[width + 1] = src[0];
259
156k
            Y2[width + 1] = src[1];
260
156k
            U[huvborder] = src[2] + 0x80;
261
156k
            V[huvborder] = src[3] + 0x80;
262
156k
            src += 4;
263
156k
        }
264
156k
        Y1 += pic->linesize[0] * 2;
265
156k
        Y2 += pic->linesize[0] * 2;
266
156k
        U  += pic->linesize[1];
267
156k
        V  += pic->linesize[2];
268
156k
    }
269
270
2.88k
    if (vmargin) {
271
20.0k
        for (w = 0; w < width; w += 2) {
272
17.6k
            AV_COPY16U(Y1 + w, src);
273
17.6k
            U[w >> 1] = src[0] + 0x80;
274
17.6k
            V[w >> 1] = src[1] + 0x80;
275
17.6k
            src += 4;
276
17.6k
        }
277
2.33k
        if (hmargin) {
278
2.10k
            Y1[w] = src[0];
279
2.10k
            U[huvborder] = src[1] + 0x80;
280
2.10k
            V[huvborder] = src[2] + 0x80;
281
2.10k
            src += 3;
282
2.10k
        }
283
2.33k
    }
284
285
2.88k
    do_vflip(avctx, pic, vflipped);
286
287
2.88k
    return 0;
288
3.64k
}
289
290
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
291
                                const uint8_t *src, int src_size,
292
                                uint32_t vflipped)
293
1.49k
{
294
1.49k
    int h, w;
295
1.49k
    uint8_t *Y, *U, *V;
296
1.49k
    int ret;
297
298
1.49k
    if (src_size < get_raw_size(AV_PIX_FMT_YUV444P, avctx->width, avctx->height)) {
299
370
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
300
370
        return AVERROR_INVALIDDATA;
301
370
    }
302
303
1.12k
    avctx->pix_fmt = AV_PIX_FMT_YUV444P;
304
1.12k
    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
305
468
        return ret;
306
307
654
    do_vflip(avctx, pic, vflipped);
308
309
654
    Y = pic->data[0];
310
654
    U = pic->data[1];
311
654
    V = pic->data[2];
312
11.6k
    for (h = 0; h < avctx->height; h++) {
313
163k
        for (w = 0; w < avctx->width; w++) {
314
152k
            Y[w] = *src++;
315
152k
            U[w] = *src++ ^ 0x80;
316
152k
            V[w] = *src++ ^ 0x80;
317
152k
        }
318
11.0k
        Y += pic->linesize[0];
319
11.0k
        U += pic->linesize[1];
320
11.0k
        V += pic->linesize[2];
321
11.0k
    }
322
323
654
    do_vflip(avctx, pic, vflipped);
324
325
654
    return 0;
326
1.12k
}
327
328
static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
329
static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
330
static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
331
332
static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
333
42.2M
{
334
42.2M
    uint8_t c, val;
335
336
42.2M
    c = get_unary(gb, 0, 8);
337
42.2M
    if (!c) {
338
37.1M
        val = get_bits(gb, 8);
339
37.1M
        memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
340
37.1M
    } else {
341
5.06M
        val = lru[c - 1];
342
5.06M
        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
343
5.06M
    }
344
42.2M
    lru[0] = val;
345
346
42.2M
    return val;
347
42.2M
}
348
349
static int check_slice_size(AVCodecContext *avctx,
350
                            const uint8_t *src, int src_size,
351
                            int slice_size, int off)
352
9.41k
{
353
9.41k
    int cur_slice_size;
354
355
9.41k
    if (slice_size > src_size - off) {
356
2.07k
        av_log(avctx, AV_LOG_ERROR,
357
2.07k
               "invalid slice size %d (only %d bytes left)\n",
358
2.07k
               slice_size, src_size - off);
359
2.07k
        return AVERROR_INVALIDDATA;
360
2.07k
    }
361
7.33k
    if (slice_size <= 16) {
362
0
        av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n",
363
0
               slice_size);
364
0
        return AVERROR_INVALIDDATA;
365
0
    }
366
367
7.33k
    cur_slice_size = AV_RL32(src + off);
368
7.33k
    if (cur_slice_size != slice_size - 16) {
369
7.09k
        av_log(avctx, AV_LOG_ERROR,
370
7.09k
               "Slice sizes mismatch: got %d instead of %d\n",
371
7.09k
               cur_slice_size, slice_size - 16);
372
7.09k
    }
373
374
7.33k
    return 0;
375
7.33k
}
376
377
static int load_buffer(AVCodecContext *avctx,
378
                       const uint8_t *src, int src_size,
379
                       GetByteContext *gb,
380
                       int *nslices, int *off)
381
11.5k
{
382
11.5k
    bytestream2_init(gb, src, src_size);
383
11.5k
    *nslices = bytestream2_get_le16(gb);
384
11.5k
    *off = FFALIGN(*nslices * 4 + 2, 16);
385
11.5k
    if (src_size < *off) {
386
3.59k
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
387
3.59k
        return AVERROR_INVALIDDATA;
388
3.59k
    }
389
390
7.95k
    if (!*nslices) {
391
257
        avpriv_request_sample(avctx, "%d slices for %dx%d", *nslices,
392
257
                              avctx->width, avctx->height);
393
257
        return AVERROR_PATCHWELCOME;
394
257
    }
395
396
7.69k
    return 0;
397
7.95k
}
398
399
static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
400
                                     int bits)
401
6.42M
{
402
6.42M
    uint8_t c, val;
403
404
6.42M
    c = get_unary(gb, 0, bits);
405
6.42M
    if (!c) {
406
5.82M
        val = get_bits(gb, bits);
407
5.82M
        memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
408
5.82M
    } else {
409
597k
        val = lru[c - 1];
410
597k
        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
411
597k
    }
412
6.42M
    lru[0] = val;
413
414
6.42M
    return val;
415
6.42M
}
416
417
typedef int (*decode_slice_func)(GetBitContext *gb, AVFrame *frame,
418
                                 int line, int height, uint8_t lru[3][8]);
419
420
typedef void (*setup_lru_func)(uint8_t lru[3][8]);
421
422
static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
423
                            const uint8_t *src, int src_size,
424
                            decode_slice_func decode_slice,
425
                            setup_lru_func setup_lru,
426
                            enum AVPixelFormat fmt,
427
                            uint32_t vflipped)
428
11.5k
{
429
11.5k
    GetByteContext gb, gb_check;
430
11.5k
    GetBitContext  gb2;
431
11.5k
    int nslices, slice, line = 0;
432
11.5k
    uint32_t off, slice_size;
433
11.5k
    uint64_t off_check;
434
11.5k
    uint8_t lru[3][8];
435
11.5k
    int ret;
436
437
11.5k
    ret = load_buffer(avctx, src, src_size, &gb, &nslices, &off);
438
11.5k
    if (ret < 0)
439
3.85k
        return ret;
440
441
7.69k
    off_check = off;
442
7.69k
    gb_check = gb;
443
127k
    for (slice = 0; slice < nslices; slice++) {
444
120k
        slice_size = bytestream2_get_le32(&gb_check);
445
446
120k
        if (slice_size <= 16 + (avctx->height * avctx->width / (8 * nslices)))
447
631
            return AVERROR_INVALIDDATA;
448
120k
        off_check += slice_size;
449
120k
    }
450
451
7.06k
    if (off_check - avctx->discard_damaged_percentage*off_check/100 > src_size)
452
497
        return AVERROR_INVALIDDATA;
453
454
6.57k
    avctx->pix_fmt = fmt;
455
6.57k
    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
456
1.22k
        return ret;
457
458
5.34k
    do_vflip(avctx, pic, vflipped);
459
460
12.6k
    for (slice = 0; slice < nslices; slice++) {
461
9.41k
        slice_size = bytestream2_get_le32(&gb);
462
463
9.41k
        setup_lru(lru);
464
465
9.41k
        ret = check_slice_size(avctx, src, src_size, slice_size, off);
466
9.41k
        if (ret < 0)
467
2.07k
            return ret;
468
469
7.33k
        if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
470
0
            return ret;
471
472
7.33k
        line += decode_slice(&gb2, pic, line, avctx->height - line, lru);
473
474
7.33k
        off += slice_size;
475
7.33k
    }
476
477
3.27k
    if (avctx->height - line) {
478
1.68k
        avpriv_request_sample(avctx, "Not enough slice data available");
479
1.68k
    }
480
481
3.27k
    do_vflip(avctx, pic, vflipped);
482
483
3.27k
    return 0;
484
5.34k
}
485
486
av_always_inline
487
static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame,
488
                                int line, int left, uint8_t lru[3][8],
489
                                int is_565)
490
2.21k
{
491
2.21k
    int x, y;
492
2.21k
    int r, g, b;
493
2.21k
    int width    = frame->width;
494
2.21k
    int stride   = frame->linesize[0];
495
2.21k
    uint8_t *dst = frame->data[0] + stride * line;
496
497
1.15M
    for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
498
3.29M
        for (x = 0; x < width; x++) {
499
2.14M
            b = decode_sym_565(gb, lru[0], 5);
500
2.14M
            g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
501
2.14M
            r = decode_sym_565(gb, lru[2], 5);
502
2.14M
            dst[x * 3 + 0] = (r << 3) | (r >> 2);
503
2.14M
            dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
504
2.14M
            dst[x * 3 + 2] = (b << 3) | (b >> 2);
505
2.14M
        }
506
507
1.15M
        dst += stride;
508
1.15M
    }
509
510
2.21k
    return y;
511
2.21k
}
512
513
static void setup_lru_555(uint8_t lru[3][8])
514
2.08k
{
515
2.08k
    memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
516
2.08k
    memcpy(lru[1], def_lru_555, 8 * sizeof(*def_lru));
517
2.08k
    memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
518
2.08k
}
519
520
static void setup_lru_565(uint8_t lru[3][8])
521
765
{
522
765
    memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
523
765
    memcpy(lru[1], def_lru_565, 8 * sizeof(*def_lru));
524
765
    memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
525
765
}
526
527
static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame,
528
                                int line, int left, uint8_t lru[3][8])
529
1.76k
{
530
1.76k
    return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0);
531
1.76k
}
532
533
static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame,
534
                                int line, int left, uint8_t lru[3][8])
535
451
{
536
451
    return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1);
537
451
}
538
539
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
540
                                const uint8_t *src, int src_size, int is_565,
541
                                uint32_t vflipped)
542
4.49k
{
543
4.49k
    enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
544
4.49k
    if (is_565)
545
1.44k
        return dxtory_decode_v2(avctx, pic, src, src_size,
546
1.44k
                                dx2_decode_slice_565,
547
1.44k
                                setup_lru_565,
548
1.44k
                                fmt, vflipped);
549
3.05k
    else
550
3.05k
        return dxtory_decode_v2(avctx, pic, src, src_size,
551
3.05k
                                dx2_decode_slice_555,
552
3.05k
                                setup_lru_555,
553
3.05k
                                fmt, vflipped);
554
4.49k
}
555
556
static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
557
                                int line, int left, uint8_t lru[3][8])
558
366
{
559
366
    int x, y;
560
366
    int width    = frame->width;
561
366
    int stride   = frame->linesize[0];
562
366
    uint8_t *dst = frame->data[0] + stride * line;
563
564
388k
    for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
565
1.64M
        for (x = 0; x < width; x++) {
566
1.25M
            dst[x * 3 + 0] = decode_sym(gb, lru[0]);
567
1.25M
            dst[x * 3 + 1] = decode_sym(gb, lru[1]);
568
1.25M
            dst[x * 3 + 2] = decode_sym(gb, lru[2]);
569
1.25M
        }
570
571
387k
        dst += stride;
572
387k
    }
573
574
366
    return y;
575
366
}
576
577
static void default_setup_lru(uint8_t lru[3][8])
578
6.56k
{
579
6.56k
    int i;
580
581
26.2k
    for (i = 0; i < 3; i++)
582
19.6k
        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
583
6.56k
}
584
585
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
586
                                const uint8_t *src, int src_size,
587
                                uint32_t vflipped)
588
988
{
589
988
    return dxtory_decode_v2(avctx, pic, src, src_size,
590
988
                            dx2_decode_slice_rgb,
591
988
                            default_setup_lru,
592
988
                            AV_PIX_FMT_BGR24, vflipped);
593
988
}
594
595
static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
596
                                int line, int left,
597
                                uint8_t lru[3][8])
598
2.32k
{
599
2.32k
    int x, y, i, j;
600
2.32k
    int width   = frame->width;
601
602
2.32k
    int ystride = frame->linesize[0];
603
2.32k
    int ustride = frame->linesize[1];
604
2.32k
    int vstride = frame->linesize[2];
605
606
2.32k
    uint8_t *Y  = frame->data[0] + ystride * line;
607
2.32k
    uint8_t *U  = frame->data[1] + (ustride >> 2) * line;
608
2.32k
    uint8_t *V  = frame->data[2] + (vstride >> 2) * line;
609
610
2.32k
    int h, w, hmargin, vmargin;
611
2.32k
    int huvborder;
612
613
2.32k
    h = frame->height & ~3;
614
2.32k
    w = frame->width  & ~3;
615
2.32k
    hmargin = frame->width  - w;
616
2.32k
    vmargin = frame->height - h;
617
2.32k
    huvborder = AV_CEIL_RSHIFT(frame->width, 2) - 1;
618
619
421k
    for (y = 0; y < left - 3 && get_bits_left(gb) >= 18 * w / 4 + hmargin * 4 + (!!hmargin * 2); y += 4) {
620
586k
        for (x = 0; x < w; x += 4) {
621
840k
            for (j = 0; j < 4; j++)
622
3.36M
                for (i = 0; i < 4; i++)
623
2.68M
                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
624
168k
            U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
625
168k
            V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
626
168k
        }
627
418k
        if (hmargin) {
628
2.08M
            for (j = 0; j < 4; j++)
629
3.54M
                for (i = 0; i < hmargin; i++)
630
1.88M
                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
631
417k
            U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
632
417k
            V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
633
417k
        }
634
635
418k
        Y += ystride * 4;
636
418k
        U += ustride;
637
418k
        V += vstride;
638
418k
    }
639
640
2.32k
    if (vmargin && y + vmargin == left) {
641
1.16M
        for (x = 0; x < width; x += 4) {
642
2.35M
            for (j = 0; j < vmargin; j++)
643
5.92M
                for (i = 0; i < 4; i++)
644
4.74M
                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
645
1.16M
            U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
646
1.16M
            V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
647
1.16M
        }
648
1.39k
        if (hmargin) {
649
3.75k
            for (j = 0; j < vmargin; j++) {
650
9.26k
                for (i = 0; i < hmargin; i++)
651
6.67k
                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
652
2.59k
            }
653
1.15k
            U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
654
1.15k
            V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
655
1.15k
        }
656
657
1.39k
        y += vmargin;
658
1.39k
    }
659
660
2.32k
    return y;
661
2.32k
}
662
663
664
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
665
                                const uint8_t *src, int src_size,
666
                                uint32_t vflipped)
667
2.78k
{
668
2.78k
    return dxtory_decode_v2(avctx, pic, src, src_size,
669
2.78k
                            dx2_decode_slice_410,
670
2.78k
                            default_setup_lru,
671
2.78k
                            AV_PIX_FMT_YUV410P, vflipped);
672
2.78k
}
673
674
static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
675
                                int line, int left,
676
                                uint8_t lru[3][8])
677
1.99k
{
678
1.99k
    int x, y;
679
680
1.99k
    int width    = frame->width;
681
682
1.99k
    int ystride = frame->linesize[0];
683
1.99k
    int ustride = frame->linesize[1];
684
1.99k
    int vstride = frame->linesize[2];
685
686
1.99k
    uint8_t *Y  = frame->data[0] + ystride * line;
687
1.99k
    uint8_t *U  = frame->data[1] + (ustride >> 1) * line;
688
1.99k
    uint8_t *V  = frame->data[2] + (vstride >> 1) * line;
689
690
1.99k
    int h, w, hmargin, vmargin;
691
1.99k
    int huvborder;
692
693
1.99k
    h = frame->height & ~1;
694
1.99k
    w = frame->width  & ~1;
695
1.99k
    hmargin = frame->width  - w;
696
1.99k
    vmargin = frame->height - h;
697
1.99k
    huvborder = AV_CEIL_RSHIFT(frame->width, 1) - 1;
698
699
1.34M
    for (y = 0; y < left - 1 && get_bits_left(gb) >= 3 * w + hmargin * 4; y += 2) {
700
2.18M
        for (x = 0; x < w; x += 2) {
701
847k
            Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
702
847k
            Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
703
847k
            Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
704
847k
            Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
705
847k
            U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
706
847k
            V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
707
847k
        }
708
1.34M
        if (hmargin) {
709
1.32M
            Y[x + 0 * ystride] = decode_sym(gb, lru[0]);
710
1.32M
            Y[x + 1 * ystride] = decode_sym(gb, lru[0]);
711
1.32M
            U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
712
1.32M
            V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
713
1.32M
        }
714
715
1.34M
        Y += ystride * 2;
716
1.34M
        U += ustride;
717
1.34M
        V += vstride;
718
1.34M
    }
719
720
1.99k
    if (vmargin) {
721
3.69M
        for (x = 0; x < width; x += 2) {
722
3.68M
            Y[x + 0]  = decode_sym(gb, lru[0]);
723
3.68M
            U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
724
3.68M
            V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
725
3.68M
        }
726
1.67k
        if (hmargin) {
727
1.40k
            Y[x]         = decode_sym(gb, lru[0]);
728
1.40k
            U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
729
1.40k
            V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
730
1.40k
        }
731
1.67k
    }
732
733
1.99k
    return y;
734
1.99k
}
735
736
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
737
                                const uint8_t *src, int src_size,
738
                                uint32_t vflipped)
739
2.04k
{
740
2.04k
    return dxtory_decode_v2(avctx, pic, src, src_size,
741
2.04k
                            dx2_decode_slice_420,
742
2.04k
                            default_setup_lru,
743
2.04k
                            AV_PIX_FMT_YUV420P, vflipped);
744
2.04k
}
745
746
static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
747
                                int line, int left,
748
                                uint8_t lru[3][8])
749
432
{
750
432
    int x, y;
751
752
432
    int width   = frame->width;
753
754
432
    int ystride = frame->linesize[0];
755
432
    int ustride = frame->linesize[1];
756
432
    int vstride = frame->linesize[2];
757
758
432
    uint8_t *Y  = frame->data[0] + ystride * line;
759
432
    uint8_t *U  = frame->data[1] + ustride * line;
760
432
    uint8_t *V  = frame->data[2] + vstride * line;
761
762
213k
    for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
763
1.60M
        for (x = 0; x < width; x++) {
764
1.39M
            Y[x] = decode_sym(gb, lru[0]);
765
1.39M
            U[x] = decode_sym(gb, lru[1]) ^ 0x80;
766
1.39M
            V[x] = decode_sym(gb, lru[2]) ^ 0x80;
767
1.39M
        }
768
769
213k
        Y += ystride;
770
213k
        U += ustride;
771
213k
        V += vstride;
772
213k
    }
773
774
432
    return y;
775
432
}
776
777
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
778
                                const uint8_t *src, int src_size,
779
                                uint32_t vflipped)
780
1.23k
{
781
1.23k
    return dxtory_decode_v2(avctx, pic, src, src_size,
782
1.23k
                            dx2_decode_slice_444,
783
1.23k
                            default_setup_lru,
784
1.23k
                            AV_PIX_FMT_YUV444P, vflipped);
785
1.23k
}
786
787
static int decode_frame(AVCodecContext *avctx, AVFrame *pic,
788
                        int *got_frame, AVPacket *avpkt)
789
357k
{
790
357k
    const uint8_t *src = avpkt->data;
791
357k
    uint32_t type;
792
357k
    int vflipped, ret;
793
794
357k
    if (avpkt->size < 16) {
795
214k
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
796
214k
        return AVERROR_INVALIDDATA;
797
214k
    }
798
799
142k
    type = AV_RB32(src);
800
142k
    vflipped = !!(type & 0x20);
801
802
142k
    switch (type) {
803
563
    case 0x01000021:
804
1.00k
    case 0x01000001:
805
1.00k
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
806
1.00k
                                   AV_PIX_FMT_BGR24, 3, vflipped);
807
1.00k
        break;
808
252
    case 0x01000029:
809
988
    case 0x01000009:
810
988
        ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped);
811
988
        break;
812
571
    case 0x02000021:
813
4.42k
    case 0x02000001:
814
4.42k
        ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
815
4.42k
        break;
816
300
    case 0x02000029:
817
2.04k
    case 0x02000009:
818
2.04k
        ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
819
2.04k
        break;
820
1.41k
    case 0x03000021:
821
3.73k
    case 0x03000001:
822
3.73k
        ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
823
3.73k
        break;
824
615
    case 0x03000029:
825
2.78k
    case 0x03000009:
826
2.78k
        ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
827
2.78k
        break;
828
969
    case 0x04000021:
829
1.49k
    case 0x04000001:
830
1.49k
        ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
831
1.49k
        break;
832
246
    case 0x04000029:
833
1.23k
    case 0x04000009:
834
1.23k
        ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
835
1.23k
        break;
836
105k
    case 0x17000021:
837
105k
    case 0x17000001:
838
105k
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
839
105k
                                   AV_PIX_FMT_RGB565LE, 2, vflipped);
840
105k
        break;
841
216
    case 0x17000029:
842
1.44k
    case 0x17000009:
843
1.44k
        ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped);
844
1.44k
        break;
845
638
    case 0x18000021:
846
850
    case 0x19000021:
847
1.18k
    case 0x18000001:
848
1.59k
    case 0x19000001:
849
1.59k
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
850
1.59k
                                   AV_PIX_FMT_RGB555LE, 2, vflipped);
851
1.59k
        break;
852
330
    case 0x18000029:
853
587
    case 0x19000029:
854
2.53k
    case 0x18000009:
855
3.05k
    case 0x19000009:
856
3.05k
        ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped);
857
3.05k
        break;
858
13.0k
    default:
859
13.0k
        avpriv_request_sample(avctx, "Frame header %"PRIX32, type);
860
13.0k
        return AVERROR_PATCHWELCOME;
861
142k
    }
862
863
129k
    if (ret)
864
18.5k
        return ret;
865
866
110k
    *got_frame = 1;
867
868
110k
    return avpkt->size;
869
129k
}
870
871
const FFCodec ff_dxtory_decoder = {
872
    .p.name         = "dxtory",
873
    CODEC_LONG_NAME("Dxtory"),
874
    .p.type         = AVMEDIA_TYPE_VIDEO,
875
    .p.id           = AV_CODEC_ID_DXTORY,
876
    FF_CODEC_DECODE_CB(decode_frame),
877
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
878
};