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