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