02162a37e7fbd9ed41c88ca1ce43cc22044a2627
[ffmpeg.git] / 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 "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) & ((1 << 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             int 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             nodes[cur_node].count = nd + st;
137             nodes[cur_node].sym = -1;
138             nodes[cur_node].n0 = cur_node;
139             nodes[cur_node].l = first_node;
140             nodes[cur_node].r = second_node;
141             cur_node++;
142         }
143         j++;
144     } while (cur_node - 256 == j);
145
146     get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
147
148     return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
149 }
150
151 static const uint8_t table_y1[] = {
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, 0xFE, 0xFE, 0xFE,
157     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
163     0xFF, 0xFF, 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, 0x00,
168     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x01, 0x01, 0x01,
174     0x01, 0x01, 0x01, 0x01, 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, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
180     0x02, 0x00,
181 };
182
183 static const uint8_t table_u[] = {
184     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
186     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
188     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
189     0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
190     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
191     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
192     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
194     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
195     0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
196     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
197     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
200     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
201     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
202     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
203     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
205     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
206     0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
207     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
208     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
209     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
211     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
212     0x01, 0x00,
213 };
214
215 static const uint8_t table_y2[] = {
216     0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
217     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
218     0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
219     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
220     0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
221     0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
222     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
223     0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
224     0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
225     0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
226     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
227     0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
228     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
229     0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
230     0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
231     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
232     0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
233     0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
234     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
235     0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
236     0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
237     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
238     0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
239     0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
240     0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
241     0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
242     0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
243     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
244     0x04, 0x00,
245 };
246
247 static const uint8_t table_v[] = {
248     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
249     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
250     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
251     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
252     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
253     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
254     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
255     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
256     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
257     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
258     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
259     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
260     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
261     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
262     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
263     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
264     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
265     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
266     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
267     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
268     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
269     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
270     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
271     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
272     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
273     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
274     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
275     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
276     0x01, 0x00,
277 };
278
279 static int decode_frame(AVCodecContext *avctx,
280                         void *data, int *got_frame,
281                         AVPacket *avpkt)
282 {
283     int TL[4] = { 128, 128, 128, 128 };
284     int L[4]  = { 128, 128, 128, 128 };
285     YLCContext *s = avctx->priv_data;
286     ThreadFrame frame = { .f = data };
287     const uint8_t *buf = avpkt->data;
288     int ret, x, y, toffset, boffset;
289     AVFrame * const p = data;
290     GetBitContext gb;
291     uint8_t *dst;
292
293     if (avpkt->size <= 16)
294         return AVERROR_INVALIDDATA;
295
296     if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
297         AV_RL32(buf + 4) != 0)
298         return AVERROR_INVALIDDATA;
299
300     toffset = AV_RL32(buf + 8);
301     if (toffset < 16 || toffset >= avpkt->size)
302         return AVERROR_INVALIDDATA;
303
304     boffset = AV_RL32(buf + 12);
305     if (toffset >= boffset || boffset >= avpkt->size)
306         return AVERROR_INVALIDDATA;
307
308     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
309         return ret;
310
311     av_fast_malloc(&s->table_bits, &s->table_bits_size,
312                    boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
313     if (!s->table_bits)
314         return AVERROR(ENOMEM);
315
316     memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
317     memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
318     s->bdsp.bswap_buf((uint32_t *) s->table_bits,
319                       (uint32_t *) s->table_bits,
320                       (boffset - toffset + 3) >> 2);
321     if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
322         return ret;
323
324     for (x = 0; x < 1024; x++) {
325         unsigned len = get_unary(&gb, 1, 31);
326         uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
327
328         s->table[x] = val;
329     }
330
331     ret = build_vlc(avctx, &s->vlc[0], &s->table[0  ]);
332     if (ret < 0)
333         return ret;
334     ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
335     if (ret < 0)
336         return ret;
337     ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
338     if (ret < 0)
339         return ret;
340     ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
341     if (ret < 0)
342         return ret;
343
344     av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
345                    avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
346     if (!s->bitstream_bits)
347         return AVERROR(ENOMEM);
348
349     memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
350     memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
351     s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
352                       (uint32_t *) s->bitstream_bits,
353                       (avpkt->size - boffset) >> 2);
354     if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
355         return ret;
356
357     dst = p->data[0];
358     for (y = 0; y < avctx->height; y++) {
359         memset(dst, 0, avctx->width * 2);
360         dst += p->linesize[0];
361     }
362
363     dst = p->data[0];
364     for (y = 0; y < avctx->height; y++) {
365         for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
366             if (get_bits_left(&gb) <= 0)
367                 return AVERROR_INVALIDDATA;
368
369             if (get_bits1(&gb)) {
370                 int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
371                 if (val < 0) {
372                     return AVERROR_INVALIDDATA;
373                 } else if (val < 0xE1) {
374                     dst[x    ] = table_y1[val];
375                     dst[x + 1] = table_u[val];
376                     dst[x + 2] = table_y2[val];
377                     dst[x + 3] = table_v[val];
378                     x += 4;
379                 } else {
380                     int incr = (val - 0xDF) * 4;
381                     if (x + incr >= avctx->width * 2) {
382                         int iy = ((x + incr) / (avctx->width * 2));
383                         x  = (x + incr) % (avctx->width * 2);
384                         y += iy;
385                         dst += iy * p->linesize[0];
386                     } else {
387                         x += incr;
388                     }
389                 }
390             } else {
391                 int y1, y2, u, v;
392
393                 y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
394                 u  = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
395                 y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
396                 v  = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3);
397                 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
398                     return AVERROR_INVALIDDATA;
399                 dst[x    ] = y1;
400                 dst[x + 1] = u;
401                 dst[x + 2] = y1 + y2;
402                 dst[x + 3] = v;
403                 x += 4;
404             }
405         }
406         dst += p->linesize[0];
407     }
408
409     dst = p->data[0];
410     for (x = 0; x < avctx->width * 2; x += 4) {
411         dst[x    ] =        dst[x    ] + L[0];
412         dst[x + 2] = L[0] = dst[x + 2] + L[0];
413         L[1] = dst[x + 1] + L[1];
414         dst[x + 1] = L[1];
415         L[2] = dst[x + 3] + L[2];
416         dst[x + 3] = L[2];
417     }
418     dst += p->linesize[0];
419
420     for (y = 1; y < avctx->height; y++) {
421         x = 0;
422         dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
423         dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
424         TL[0] = dst[x + 2 - p->linesize[0]];
425         L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
426         dst[x + 1] = L[1];
427         TL[1] = dst[x + 1 - p->linesize[0]];
428         L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
429         dst[x + 3] = L[2];
430         TL[2] = dst[x + 3 - p->linesize[0]];
431         for (x = 4; x < avctx->width * 2; x += 4) {
432             dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
433             dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
434             TL[0] = dst[x + 2 - p->linesize[0]];
435             L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
436             dst[x + 1] = L[1];
437             TL[1] = dst[x + 1 - p->linesize[0]];
438             L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
439             dst[x + 3] = L[2];
440             TL[2] = dst[x + 3 - p->linesize[0]];
441         }
442         dst += p->linesize[0];
443     }
444
445     p->pict_type = AV_PICTURE_TYPE_I;
446     p->key_frame = 1;
447     *got_frame   = 1;
448
449     return avpkt->size;
450 }
451
452 #if HAVE_THREADS
453 static int init_thread_copy(AVCodecContext *avctx)
454 {
455     YLCContext *s = avctx->priv_data;
456
457     memset(&s->vlc[0], 0, sizeof(VLC));
458     memset(&s->vlc[1], 0, sizeof(VLC));
459     memset(&s->vlc[2], 0, sizeof(VLC));
460     memset(&s->vlc[3], 0, sizeof(VLC));
461     s->table_bits = NULL;
462     s->table_bits_size = 0;
463     s->bitstream_bits = NULL;
464     s->bitstream_bits_size = 0;
465
466     return 0;
467 }
468 #endif
469
470 static av_cold int decode_end(AVCodecContext *avctx)
471 {
472     YLCContext *s = avctx->priv_data;
473
474     ff_free_vlc(&s->vlc[0]);
475     ff_free_vlc(&s->vlc[1]);
476     ff_free_vlc(&s->vlc[2]);
477     ff_free_vlc(&s->vlc[3]);
478     av_freep(&s->table_bits);
479     s->table_bits_size = 0;
480     av_freep(&s->bitstream_bits);
481     s->bitstream_bits_size = 0;
482
483     return 0;
484 }
485
486 AVCodec ff_ylc_decoder = {
487     .name           = "ylc",
488     .long_name      = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
489     .type           = AVMEDIA_TYPE_VIDEO,
490     .id             = AV_CODEC_ID_YLC,
491     .priv_data_size = sizeof(YLCContext),
492     .init           = decode_init,
493     .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
494     .close          = decode_end,
495     .decode         = decode_frame,
496     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
497     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
498 };