]> git.sesse.net Git - ffmpeg/blob - libavcodec/ylc.c
Merge commit '5b1b495c8d21600eac694d50f428654a3125e217'
[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 #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 "unary.h"
35
36 typedef struct YLCContext {
37     VLC vlc[4];
38     uint32_t table[1024];
39     uint8_t *table_bits;
40     uint8_t *bitstream_bits;
41     int table_bits_size;
42     int bitstream_bits_size;
43     BswapDSPContext bdsp;
44 } YLCContext;
45
46 static av_cold int decode_init(AVCodecContext *avctx)
47 {
48     YLCContext *s = avctx->priv_data;
49
50     avctx->pix_fmt = AV_PIX_FMT_YUYV422;
51     ff_bswapdsp_init(&s->bdsp);
52
53     return 0;
54 }
55
56 typedef struct Node {
57     int16_t  sym;
58     int16_t  n0;
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) & ((1 << 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].n0    = -2;
100         nodes[i].l     = i;
101         nodes[i].r     = i;
102     }
103
104     cur_node = 256;
105     j = 0;
106     do {
107         for (i = 0; ; i++) {
108             int new_node = j;
109             int first_node = cur_node;
110             int second_node = cur_node;
111             int nd, st;
112
113             nodes[cur_node].count = -1;
114
115             do {
116                 int val = nodes[new_node].count;
117                 if (val && (val < nodes[first_node].count)) {
118                     if (val >= nodes[second_node].count) {
119                         first_node = new_node;
120                     } else {
121                         first_node = second_node;
122                         second_node = new_node;
123                     }
124                 }
125                 new_node += 1;
126             } while (new_node != cur_node);
127
128             if (first_node == cur_node)
129                 break;
130
131             nd = nodes[second_node].count;
132             st = nodes[first_node].count;
133             nodes[second_node].count = 0;
134             nodes[first_node].count  = 0;
135             nodes[cur_node].count = nd + st;
136             nodes[cur_node].sym = -1;
137             nodes[cur_node].n0 = cur_node;
138             nodes[cur_node].l = first_node;
139             nodes[cur_node].r = second_node;
140             cur_node++;
141         }
142         j++;
143     } while (cur_node - 256 == j);
144
145     get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
146
147     return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
148 }
149
150 static const uint8_t table_y1[] = {
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, 0xFE, 0xFE, 0xFE,
156     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
162     0xFF, 0xFF, 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, 0x00,
167     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x01, 0x01, 0x01,
173     0x01, 0x01, 0x01, 0x01, 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, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
179     0x02, 0x00,
180 };
181
182 static const uint8_t table_u[] = {
183     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
185     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
187     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
188     0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
189     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
190     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
191     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
193     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
194     0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
196     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
200     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
201     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
202     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
204     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
205     0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
206     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
207     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
208     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
210     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
211     0x01, 0x00,
212 };
213
214 static const uint8_t table_y2[] = {
215     0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
216     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
217     0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
218     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
219     0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
220     0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
221     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
222     0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
223     0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
224     0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
225     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
226     0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
227     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
228     0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
229     0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
230     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
231     0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
232     0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
233     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
234     0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
235     0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
236     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
237     0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
238     0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
239     0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
240     0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
241     0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
242     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
243     0x04, 0x00,
244 };
245
246 static const uint8_t table_v[] = {
247     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
248     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
249     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
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, 0x00,
276 };
277
278 static int decode_frame(AVCodecContext *avctx,
279                         void *data, int *got_frame,
280                         AVPacket *avpkt)
281 {
282     int TL[4] = { 128, 128, 128, 128 };
283     int L[4]  = { 128, 128, 128, 128 };
284     YLCContext *s = avctx->priv_data;
285     const uint8_t *buf = avpkt->data;
286     int ret, x, y, toffset, boffset;
287     AVFrame * const p = data;
288     GetBitContext gb;
289     uint8_t *dst;
290
291     if (avpkt->size <= 16)
292         return AVERROR_INVALIDDATA;
293
294     if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
295         AV_RL32(buf + 4) != 0)
296         return AVERROR_INVALIDDATA;
297
298     toffset = AV_RL32(buf + 8);
299     if (toffset < 16 || toffset >= avpkt->size)
300         return AVERROR_INVALIDDATA;
301
302     boffset = AV_RL32(buf + 12);
303     if (toffset >= boffset || boffset >= avpkt->size)
304         return AVERROR_INVALIDDATA;
305
306     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
307         return ret;
308
309     av_fast_malloc(&s->table_bits, &s->table_bits_size,
310                    boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
311     if (!s->table_bits)
312         return AVERROR(ENOMEM);
313
314     memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
315     memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
316     s->bdsp.bswap_buf((uint32_t *) s->table_bits,
317                       (uint32_t *) s->table_bits,
318                       (boffset - toffset + 3) >> 2);
319     if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
320         return ret;
321
322     for (x = 0; x < 1024; x++) {
323         unsigned len = get_unary(&gb, 1, 31);
324         uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
325
326         s->table[x] = val;
327     }
328
329     ret = build_vlc(avctx, &s->vlc[0], &s->table[0  ]);
330     if (ret < 0)
331         return ret;
332     ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
333     if (ret < 0)
334         return ret;
335     ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
336     if (ret < 0)
337         return ret;
338     ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
339     if (ret < 0)
340         return ret;
341
342     av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
343                    avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
344     if (!s->bitstream_bits)
345         return AVERROR(ENOMEM);
346
347     memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
348     memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
349     s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
350                       (uint32_t *) s->bitstream_bits,
351                       (avpkt->size - boffset) >> 2);
352     if ((ret = init_get_bits8(&gb, s->bitstream_bits, 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, s->vlc[0].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, s->vlc[1].bits, 3);
392                 u  = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
393                 y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
394                 v  = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].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
459     return 0;
460 }
461
462 AVCodec ff_ylc_decoder = {
463     .name           = "ylc",
464     .long_name      = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
465     .type           = AVMEDIA_TYPE_VIDEO,
466     .id             = AV_CODEC_ID_YLC,
467     .priv_data_size = sizeof(YLCContext),
468     .init           = decode_init,
469     .close          = decode_end,
470     .decode         = decode_frame,
471     .capabilities   = AV_CODEC_CAP_DR1,
472 };