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