GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/ylc.c Lines: 0 202 0.0 %
Date: 2020-10-23 17:01:47 Branches: 0 84 0.0 %

Line Branch Exec 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 <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#define YLC_VLC_BITS 10
26
27
#include "libavutil/imgutils.h"
28
#include "libavutil/internal.h"
29
#include "libavutil/intreadwrite.h"
30
#include "libavutil/mem.h"
31
#include "avcodec.h"
32
#include "bswapdsp.h"
33
#include "get_bits.h"
34
#include "huffyuvdsp.h"
35
#include "internal.h"
36
#include "thread.h"
37
#include "unary.h"
38
39
typedef struct YLCContext {
40
    VLC vlc[4];
41
    uint32_t table[1024];
42
    uint8_t *table_bits;
43
    uint8_t *bitstream_bits;
44
    int table_bits_size;
45
    int bitstream_bits_size;
46
    BswapDSPContext bdsp;
47
} YLCContext;
48
49
static av_cold int decode_init(AVCodecContext *avctx)
50
{
51
    YLCContext *s = avctx->priv_data;
52
53
    avctx->pix_fmt = AV_PIX_FMT_YUYV422;
54
    ff_bswapdsp_init(&s->bdsp);
55
56
    return 0;
57
}
58
59
typedef struct Node {
60
    int16_t  sym;
61
    int16_t  n0;
62
    uint32_t count;
63
    int16_t  l, r;
64
} Node;
65
66
static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
67
                           Node *nodes, int node,
68
                           uint32_t pfx, int pl, int *pos)
69
{
70
    int s;
71
72
    s = nodes[node].sym;
73
    if (s != -1) {
74
        bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1);
75
        lens[*pos] = FFMAX(pl, 1);
76
        xlat[*pos] = s + (pl == 0);
77
        (*pos)++;
78
    } else {
79
        pfx <<= 1;
80
        pl++;
81
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
82
                       pos);
83
        pfx |= 1;
84
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
85
                       pos);
86
    }
87
}
88
89
static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
90
{
91
    Node nodes[512];
92
    uint32_t bits[256];
93
    int16_t lens[256];
94
    uint8_t xlat[256];
95
    int cur_node, i, j, pos = 0;
96
97
    ff_free_vlc(vlc);
98
99
    for (i = 0; i < 256; i++) {
100
        nodes[i].count = table[i];
101
        nodes[i].sym   = i;
102
        nodes[i].n0    = -2;
103
        nodes[i].l     = i;
104
        nodes[i].r     = i;
105
    }
106
107
    cur_node = 256;
108
    j = 0;
109
    do {
110
        for (i = 0; ; i++) {
111
            int new_node = j;
112
            int first_node = cur_node;
113
            int second_node = cur_node;
114
            unsigned nd, st;
115
116
            nodes[cur_node].count = -1;
117
118
            do {
119
                int val = nodes[new_node].count;
120
                if (val && (val < nodes[first_node].count)) {
121
                    if (val >= nodes[second_node].count) {
122
                        first_node = new_node;
123
                    } else {
124
                        first_node = second_node;
125
                        second_node = new_node;
126
                    }
127
                }
128
                new_node += 1;
129
            } while (new_node != cur_node);
130
131
            if (first_node == cur_node)
132
                break;
133
134
            nd = nodes[second_node].count;
135
            st = nodes[first_node].count;
136
            nodes[second_node].count = 0;
137
            nodes[first_node].count  = 0;
138
            if (nd >= UINT32_MAX - st) {
139
                av_log(avctx, AV_LOG_ERROR, "count overflow\n");
140
                return AVERROR_INVALIDDATA;
141
            }
142
            nodes[cur_node].count = nd + st;
143
            nodes[cur_node].sym = -1;
144
            nodes[cur_node].n0 = cur_node;
145
            nodes[cur_node].l = first_node;
146
            nodes[cur_node].r = second_node;
147
            cur_node++;
148
        }
149
        j++;
150
    } while (cur_node - 256 == j);
151
152
    get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
153
154
    return ff_init_vlc_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2,
155
                              bits, 4, 4, xlat, 1, 1, 0);
156
}
157
158
static const uint8_t table_y1[] = {
159
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
160
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
161
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
162
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
163
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
164
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
165
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
166
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
170
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
176
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
177
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
178
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
179
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
180
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
181
    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
182
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
183
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
184
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
185
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
186
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
187
    0x02, 0x00,
188
};
189
190
static const uint8_t table_u[] = {
191
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
192
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
193
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
195
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
196
    0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
197
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
198
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
199
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
201
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
202
    0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
203
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
204
    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
207
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
208
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
209
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
210
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
212
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
213
    0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
214
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
215
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
216
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217
    0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
218
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
219
    0x01, 0x00,
220
};
221
222
static const uint8_t table_y2[] = {
223
    0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
224
    0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
225
    0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
226
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
227
    0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
228
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
229
    0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
230
    0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
231
    0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
232
    0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
233
    0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
234
    0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
235
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
236
    0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
237
    0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
238
    0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
239
    0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
240
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
241
    0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
242
    0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
243
    0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
244
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
245
    0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
246
    0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
247
    0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
248
    0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
249
    0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
250
    0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
251
    0x04, 0x00,
252
};
253
254
static const uint8_t table_v[] = {
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, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
275
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
276
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
277
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
278
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
279
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
280
    0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
281
    0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
282
    0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
283
    0x01, 0x00,
284
};
285
286
static int decode_frame(AVCodecContext *avctx,
287
                        void *data, int *got_frame,
288
                        AVPacket *avpkt)
289
{
290
    int TL[4] = { 128, 128, 128, 128 };
291
    int L[4]  = { 128, 128, 128, 128 };
292
    YLCContext *s = avctx->priv_data;
293
    ThreadFrame frame = { .f = data };
294
    const uint8_t *buf = avpkt->data;
295
    int ret, x, y, toffset, boffset;
296
    AVFrame * const p = data;
297
    GetBitContext gb;
298
    uint8_t *dst;
299
300
    if (avpkt->size <= 16)
301
        return AVERROR_INVALIDDATA;
302
303
    if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
304
        AV_RL32(buf + 4) != 0)
305
        return AVERROR_INVALIDDATA;
306
307
    toffset = AV_RL32(buf + 8);
308
    if (toffset < 16 || toffset >= avpkt->size)
309
        return AVERROR_INVALIDDATA;
310
311
    boffset = AV_RL32(buf + 12);
312
    if (toffset >= boffset || boffset >= avpkt->size)
313
        return AVERROR_INVALIDDATA;
314
315
    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
316
        return ret;
317
318
    av_fast_malloc(&s->table_bits, &s->table_bits_size,
319
                   boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
320
    if (!s->table_bits)
321
        return AVERROR(ENOMEM);
322
323
    memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
324
    memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
325
    s->bdsp.bswap_buf((uint32_t *) s->table_bits,
326
                      (uint32_t *) s->table_bits,
327
                      (boffset - toffset + 3) >> 2);
328
    if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
329
        return ret;
330
331
    for (x = 0; x < 1024; x++) {
332
        unsigned len = get_unary(&gb, 1, 31);
333
        uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
334
335
        s->table[x] = val;
336
    }
337
338
    ret = build_vlc(avctx, &s->vlc[0], &s->table[0  ]);
339
    if (ret < 0)
340
        return ret;
341
    ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
342
    if (ret < 0)
343
        return ret;
344
    ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
345
    if (ret < 0)
346
        return ret;
347
    ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
348
    if (ret < 0)
349
        return ret;
350
351
    av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
352
                   avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
353
    if (!s->bitstream_bits)
354
        return AVERROR(ENOMEM);
355
356
    memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
357
    memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
358
    s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
359
                      (uint32_t *) s->bitstream_bits,
360
                      (avpkt->size - boffset) >> 2);
361
    if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
362
        return ret;
363
364
    dst = p->data[0];
365
    for (y = 0; y < avctx->height; y++) {
366
        memset(dst, 0, avctx->width * 2);
367
        dst += p->linesize[0];
368
    }
369
370
    dst = p->data[0];
371
    for (y = 0; y < avctx->height; y++) {
372
        for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
373
            if (get_bits_left(&gb) <= 0)
374
                return AVERROR_INVALIDDATA;
375
376
            if (get_bits1(&gb)) {
377
                int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3);
378
                if (val < 0) {
379
                    return AVERROR_INVALIDDATA;
380
                } else if (val < 0xE1) {
381
                    dst[x    ] = table_y1[val];
382
                    dst[x + 1] = table_u[val];
383
                    dst[x + 2] = table_y2[val];
384
                    dst[x + 3] = table_v[val];
385
                    x += 4;
386
                } else {
387
                    int incr = (val - 0xDF) * 4;
388
                    if (x + incr >= avctx->width * 2) {
389
                        int iy = ((x + incr) / (avctx->width * 2));
390
                        x  = (x + incr) % (avctx->width * 2);
391
                        y += iy;
392
                        dst += iy * p->linesize[0];
393
                    } else {
394
                        x += incr;
395
                    }
396
                }
397
            } else {
398
                int y1, y2, u, v;
399
400
                y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
401
                u  = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3);
402
                y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
403
                v  = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3);
404
                if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
405
                    return AVERROR_INVALIDDATA;
406
                dst[x    ] = y1;
407
                dst[x + 1] = u;
408
                dst[x + 2] = y1 + y2;
409
                dst[x + 3] = v;
410
                x += 4;
411
            }
412
        }
413
        dst += p->linesize[0];
414
    }
415
416
    dst = p->data[0];
417
    for (x = 0; x < avctx->width * 2; x += 4) {
418
        dst[x    ] =        dst[x    ] + L[0];
419
        dst[x + 2] = L[0] = dst[x + 2] + L[0];
420
        L[1] = dst[x + 1] + L[1];
421
        dst[x + 1] = L[1];
422
        L[2] = dst[x + 3] + L[2];
423
        dst[x + 3] = L[2];
424
    }
425
    dst += p->linesize[0];
426
427
    for (y = 1; y < avctx->height; y++) {
428
        x = 0;
429
        dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
430
        dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
431
        TL[0] = dst[x + 2 - p->linesize[0]];
432
        L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
433
        dst[x + 1] = L[1];
434
        TL[1] = dst[x + 1 - p->linesize[0]];
435
        L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
436
        dst[x + 3] = L[2];
437
        TL[2] = dst[x + 3 - p->linesize[0]];
438
        for (x = 4; x < avctx->width * 2; x += 4) {
439
            dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
440
            dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
441
            TL[0] = dst[x + 2 - p->linesize[0]];
442
            L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
443
            dst[x + 1] = L[1];
444
            TL[1] = dst[x + 1 - p->linesize[0]];
445
            L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
446
            dst[x + 3] = L[2];
447
            TL[2] = dst[x + 3 - p->linesize[0]];
448
        }
449
        dst += p->linesize[0];
450
    }
451
452
    p->pict_type = AV_PICTURE_TYPE_I;
453
    p->key_frame = 1;
454
    *got_frame   = 1;
455
456
    return avpkt->size;
457
}
458
459
static av_cold int decode_end(AVCodecContext *avctx)
460
{
461
    YLCContext *s = avctx->priv_data;
462
463
    ff_free_vlc(&s->vlc[0]);
464
    ff_free_vlc(&s->vlc[1]);
465
    ff_free_vlc(&s->vlc[2]);
466
    ff_free_vlc(&s->vlc[3]);
467
    av_freep(&s->table_bits);
468
    s->table_bits_size = 0;
469
    av_freep(&s->bitstream_bits);
470
    s->bitstream_bits_size = 0;
471
472
    return 0;
473
}
474
475
AVCodec ff_ylc_decoder = {
476
    .name           = "ylc",
477
    .long_name      = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
478
    .type           = AVMEDIA_TYPE_VIDEO,
479
    .id             = AV_CODEC_ID_YLC,
480
    .priv_data_size = sizeof(YLCContext),
481
    .init           = decode_init,
482
    .close          = decode_end,
483
    .decode         = decode_frame,
484
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
485
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
486
};