]> git.sesse.net Git - ffmpeg/blob - libavcodec/ylc.c
Merge commit '5846b496f0a1dd5be4ef714622940674305ec00f'
[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 "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 #if HAVE_THREADS
457 static int init_thread_copy(AVCodecContext *avctx)
458 {
459     YLCContext *s = avctx->priv_data;
460
461     memset(&s->vlc[0], 0, sizeof(VLC));
462     memset(&s->vlc[1], 0, sizeof(VLC));
463     memset(&s->vlc[2], 0, sizeof(VLC));
464     memset(&s->vlc[3], 0, sizeof(VLC));
465     s->table_bits = NULL;
466     s->table_bits_size = 0;
467     s->bitstream_bits = NULL;
468     s->bitstream_bits_size = 0;
469
470     return 0;
471 }
472 #endif
473
474 static av_cold int decode_end(AVCodecContext *avctx)
475 {
476     YLCContext *s = avctx->priv_data;
477
478     ff_free_vlc(&s->vlc[0]);
479     ff_free_vlc(&s->vlc[1]);
480     ff_free_vlc(&s->vlc[2]);
481     ff_free_vlc(&s->vlc[3]);
482     av_freep(&s->table_bits);
483     s->table_bits_size = 0;
484     av_freep(&s->bitstream_bits);
485     s->bitstream_bits_size = 0;
486
487     return 0;
488 }
489
490 AVCodec ff_ylc_decoder = {
491     .name           = "ylc",
492     .long_name      = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
493     .type           = AVMEDIA_TYPE_VIDEO,
494     .id             = AV_CODEC_ID_YLC,
495     .priv_data_size = sizeof(YLCContext),
496     .init           = decode_init,
497     .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
498     .close          = decode_end,
499     .decode         = decode_frame,
500     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
501     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
502 };