Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/ylc.c
Line
Count
Source
1
/*
2
 * YUY2 Lossless Codec
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include <string.h>
22
23
57.4M
#define YLC_VLC_BITS 10
24
25
#include "libavutil/intreadwrite.h"
26
#include "libavutil/mem.h"
27
#include "libavutil/pixfmt.h"
28
#include "avcodec.h"
29
#include "bswapdsp.h"
30
#include "codec_internal.h"
31
#include "get_bits.h"
32
#include "thread.h"
33
#include "unary.h"
34
35
typedef struct YLCContext {
36
    VLC vlc[4];
37
    uint32_t table[256];
38
    uint8_t *buffer;
39
    int buffer_size;
40
    BswapDSPContext bdsp;
41
} YLCContext;
42
43
static av_cold int decode_init(AVCodecContext *avctx)
44
1.52k
{
45
1.52k
    YLCContext *s = avctx->priv_data;
46
47
1.52k
    avctx->pix_fmt = AV_PIX_FMT_YUYV422;
48
1.52k
    ff_bswapdsp_init(&s->bdsp);
49
50
1.52k
    return 0;
51
1.52k
}
52
53
typedef struct Node {
54
    int16_t  sym;
55
    uint32_t count;
56
    int16_t  l, r;
57
} Node;
58
59
static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
60
                           Node *nodes, int node,
61
                           uint32_t pfx, int pl, int *pos)
62
3.51M
{
63
3.51M
    int s;
64
65
3.51M
    s = nodes[node].sym;
66
3.51M
    if (s != -1) {
67
2.00M
        bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1);
68
2.00M
        lens[*pos] = FFMAX(pl, 1);
69
2.00M
        xlat[*pos] = s + (pl == 0);
70
2.00M
        (*pos)++;
71
2.00M
    } else {
72
1.50M
        pfx <<= 1;
73
1.50M
        pl++;
74
1.50M
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
75
1.50M
                       pos);
76
1.50M
        pfx |= 1;
77
1.50M
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
78
1.50M
                       pos);
79
1.50M
    }
80
3.51M
}
81
82
static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
83
505k
{
84
505k
    Node nodes[512];
85
505k
    uint32_t bits[256];
86
505k
    int16_t lens[256];
87
505k
    uint8_t xlat[256];
88
505k
    int cur_node, i, j, pos = 0;
89
90
505k
    ff_vlc_free(vlc);
91
92
129M
    for (i = 0; i < 256; i++) {
93
129M
        nodes[i].count = table[i];
94
129M
        nodes[i].sym   = i;
95
129M
        nodes[i].l     = i;
96
129M
        nodes[i].r     = i;
97
129M
    }
98
99
505k
    cur_node = 256;
100
505k
    j = 0;
101
524k
    do {
102
2.72M
        for (i = 0; ; i++) {
103
2.72M
            int new_node = j;
104
2.72M
            int first_node = cur_node;
105
2.72M
            int second_node = cur_node;
106
2.72M
            unsigned nd, st;
107
108
2.72M
            nodes[cur_node].count = -1;
109
110
785M
            do {
111
785M
                int val = nodes[new_node].count;
112
785M
                if (val && (val < nodes[first_node].count)) {
113
8.72M
                    if (val >= nodes[second_node].count) {
114
3.63M
                        first_node = new_node;
115
5.09M
                    } else {
116
5.09M
                        first_node = second_node;
117
5.09M
                        second_node = new_node;
118
5.09M
                    }
119
8.72M
                }
120
785M
                new_node += 1;
121
785M
            } while (new_node != cur_node);
122
123
2.72M
            if (first_node == cur_node)
124
518k
                break;
125
126
2.20M
            nd = nodes[second_node].count;
127
2.20M
            st = nodes[first_node].count;
128
2.20M
            nodes[second_node].count = 0;
129
2.20M
            nodes[first_node].count  = 0;
130
2.20M
            if (nd >= UINT32_MAX - st) {
131
6.34k
                av_log(avctx, AV_LOG_ERROR, "count overflow\n");
132
6.34k
                return AVERROR_INVALIDDATA;
133
6.34k
            }
134
2.20M
            nodes[cur_node].count = nd + st;
135
2.20M
            nodes[cur_node].sym = -1;
136
2.20M
            nodes[cur_node].l = first_node;
137
2.20M
            nodes[cur_node].r = second_node;
138
2.20M
            cur_node++;
139
2.20M
        }
140
518k
        j++;
141
518k
    } while (cur_node - 256 == j);
142
143
499k
    get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
144
145
499k
    return ff_vlc_init_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2,
146
499k
                              bits, 4, 4, xlat, 1, 1, 0);
147
505k
}
148
149
static const uint8_t table_y1[] = {
150
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
151
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
152
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
153
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
154
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
155
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
156
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
157
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
167
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
168
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
169
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
170
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
171
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
172
    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
173
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
174
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
175
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
176
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
177
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
178
    0x02, 0x00,
179
};
180
181
static const uint8_t table_u[] = {
182
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
183
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
184
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
186
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
187
    0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
188
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
190
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
192
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
193
    0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
194
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195
    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
198
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
199
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
201
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
203
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
204
    0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
205
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
206
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
207
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208
    0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
209
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
210
    0x01, 0x00,
211
};
212
213
static const uint8_t table_y2[] = {
214
    0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
215
    0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
216
    0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
217
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
218
    0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
219
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
220
    0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
221
    0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
222
    0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
223
    0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
224
    0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
225
    0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
226
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
227
    0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
228
    0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
229
    0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
230
    0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
231
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
232
    0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
233
    0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
234
    0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
235
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
236
    0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
237
    0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
238
    0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
239
    0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
240
    0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
241
    0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
242
    0x04, 0x00,
243
};
244
245
static const uint8_t table_v[] = {
246
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
247
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
248
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
249
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
250
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
251
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
252
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
253
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
254
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
255
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
256
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
257
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
258
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
259
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
260
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
261
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
262
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
263
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
264
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
265
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
266
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
267
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
268
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
269
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
270
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
271
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
272
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
273
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
274
    0x01, 0x00,
275
};
276
277
static int decode_frame(AVCodecContext *avctx, AVFrame *p,
278
                        int *got_frame, AVPacket *avpkt)
279
341k
{
280
341k
    int TL[4] = { 128, 128, 128, 128 };
281
341k
    int L[4]  = { 128, 128, 128, 128 };
282
341k
    YLCContext *s = avctx->priv_data;
283
341k
    const uint8_t *buf = avpkt->data;
284
341k
    int ret, x, y, toffset, boffset;
285
341k
    GetBitContext gb;
286
341k
    uint8_t *dst;
287
288
341k
    if (avpkt->size <= 16)
289
194k
        return AVERROR_INVALIDDATA;
290
291
147k
    if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
292
142k
        AV_RL32(buf + 4) != 0)
293
5.45k
        return AVERROR_INVALIDDATA;
294
295
141k
    toffset = AV_RL32(buf + 8);
296
141k
    if (toffset < 16 || toffset >= avpkt->size)
297
1.20k
        return AVERROR_INVALIDDATA;
298
299
140k
    boffset = AV_RL32(buf + 12);
300
140k
    if (toffset >= boffset || boffset >= avpkt->size)
301
1.62k
        return AVERROR_INVALIDDATA;
302
303
139k
    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
304
7.84k
        return ret;
305
306
131k
    av_fast_malloc(&s->buffer, &s->buffer_size,
307
131k
                   FFMAX(boffset - toffset, avpkt->size - boffset)
308
131k
                       + AV_INPUT_BUFFER_PADDING_SIZE);
309
131k
    if (!s->buffer)
310
0
        return AVERROR(ENOMEM);
311
312
131k
    memcpy(s->buffer, avpkt->data + toffset, boffset - toffset);
313
131k
    memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
314
131k
    s->bdsp.bswap_buf((uint32_t *) s->buffer,
315
131k
                      (uint32_t *) s->buffer,
316
131k
                      (boffset - toffset + 3) >> 2);
317
131k
    if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0)
318
0
        return ret;
319
320
630k
    for (int i = 0; i < 4; i++) {
321
129M
        for (x = 0; x < 256; x++) {
322
129M
            unsigned len = get_unary(&gb, 1, 31);
323
129M
            uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
324
325
129M
            s->table[x] = val;
326
129M
        }
327
328
505k
        ret = build_vlc(avctx, &s->vlc[i], s->table);
329
505k
        if (ret < 0)
330
6.57k
            return ret;
331
505k
    }
332
333
124k
    memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset);
334
124k
    memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
335
124k
    s->bdsp.bswap_buf((uint32_t *) s->buffer,
336
124k
                      (uint32_t *) s->buffer,
337
124k
                      (avpkt->size - boffset) >> 2);
338
124k
    if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0)
339
0
        return ret;
340
341
124k
    dst = p->data[0];
342
34.3M
    for (y = 0; y < avctx->height; y++) {
343
34.2M
        memset(dst, 0, avctx->width * 2);
344
34.2M
        dst += p->linesize[0];
345
34.2M
    }
346
347
124k
    dst = p->data[0];
348
383k
    for (y = 0; y < avctx->height; y++) {
349
23.3M
        for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
350
23.1M
            if (get_bits_left(&gb) <= 0)
351
3.15k
                return AVERROR_INVALIDDATA;
352
353
23.1M
            if (get_bits1(&gb)) {
354
11.8M
                int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3);
355
11.8M
                if (val < 0) {
356
229
                    return AVERROR_INVALIDDATA;
357
11.8M
                } else if (val < 0xE1) {
358
10.8M
                    dst[x    ] = table_y1[val];
359
10.8M
                    dst[x + 1] = table_u[val];
360
10.8M
                    dst[x + 2] = table_y2[val];
361
10.8M
                    dst[x + 3] = table_v[val];
362
10.8M
                    x += 4;
363
10.8M
                } else {
364
966k
                    int incr = (val - 0xDF) * 4;
365
966k
                    if (x + incr >= avctx->width * 2) {
366
232k
                        int iy = ((x + incr) / (avctx->width * 2));
367
232k
                        x  = (x + incr) % (avctx->width * 2);
368
232k
                        y += iy;
369
232k
                        dst += iy * p->linesize[0];
370
733k
                    } else {
371
733k
                        x += incr;
372
733k
                    }
373
966k
                }
374
11.8M
            } else {
375
11.2M
                int y1, y2, u, v;
376
377
11.2M
                y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
378
11.2M
                u  = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3);
379
11.2M
                y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
380
11.2M
                v  = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3);
381
11.2M
                if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
382
3.08k
                    return AVERROR_INVALIDDATA;
383
11.2M
                dst[x    ] = y1;
384
11.2M
                dst[x + 1] = u;
385
11.2M
                dst[x + 2] = y1 + y2;
386
11.2M
                dst[x + 3] = v;
387
11.2M
                x += 4;
388
11.2M
            }
389
23.1M
        }
390
258k
        dst += p->linesize[0];
391
258k
    }
392
393
118k
    dst = p->data[0];
394
6.10M
    for (x = 0; x < avctx->width * 2; x += 4) {
395
5.98M
        dst[x    ] =        dst[x    ] + L[0];
396
5.98M
        dst[x + 2] = L[0] = dst[x + 2] + L[0];
397
5.98M
        L[1] = dst[x + 1] + L[1];
398
5.98M
        dst[x + 1] = L[1];
399
5.98M
        L[2] = dst[x + 3] + L[2];
400
5.98M
        dst[x + 3] = L[2];
401
5.98M
    }
402
118k
    dst += p->linesize[0];
403
404
1.29M
    for (y = 1; y < avctx->height; y++) {
405
1.17M
        x = 0;
406
1.17M
        dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
407
1.17M
        dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
408
1.17M
        TL[0] = dst[x + 2 - p->linesize[0]];
409
1.17M
        L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
410
1.17M
        dst[x + 1] = L[1];
411
1.17M
        TL[1] = dst[x + 1 - p->linesize[0]];
412
1.17M
        L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
413
1.17M
        dst[x + 3] = L[2];
414
1.17M
        TL[2] = dst[x + 3 - p->linesize[0]];
415
11.6M
        for (x = 4; x < avctx->width * 2; x += 4) {
416
10.4M
            dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
417
10.4M
            dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
418
10.4M
            TL[0] = dst[x + 2 - p->linesize[0]];
419
10.4M
            L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
420
10.4M
            dst[x + 1] = L[1];
421
10.4M
            TL[1] = dst[x + 1 - p->linesize[0]];
422
10.4M
            L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
423
10.4M
            dst[x + 3] = L[2];
424
10.4M
            TL[2] = dst[x + 3 - p->linesize[0]];
425
10.4M
        }
426
1.17M
        dst += p->linesize[0];
427
1.17M
    }
428
429
118k
    *got_frame   = 1;
430
431
118k
    return avpkt->size;
432
124k
}
433
434
static av_cold int decode_end(AVCodecContext *avctx)
435
1.52k
{
436
1.52k
    YLCContext *s = avctx->priv_data;
437
438
7.62k
    for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++)
439
6.10k
        ff_vlc_free(&s->vlc[i]);
440
1.52k
    av_freep(&s->buffer);
441
1.52k
    s->buffer_size = 0;
442
443
1.52k
    return 0;
444
1.52k
}
445
446
const FFCodec ff_ylc_decoder = {
447
    .p.name         = "ylc",
448
    CODEC_LONG_NAME("YUY2 Lossless Codec"),
449
    .p.type         = AVMEDIA_TYPE_VIDEO,
450
    .p.id           = AV_CODEC_ID_YLC,
451
    .priv_data_size = sizeof(YLCContext),
452
    .init           = decode_init,
453
    .close          = decode_end,
454
    FF_CODEC_DECODE_CB(decode_frame),
455
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
456
};