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 "codec_internal.h"
34 #include "get_bits.h"
35 #include "huffyuvdsp.h"
36 #include "thread.h"
37 #include "unary.h"
38 
39 typedef struct YLCContext {
40     VLC vlc[4];
41     uint32_t table[256];
42     uint8_t *buffer;
43     int buffer_size;
44     BswapDSPContext bdsp;
45 } YLCContext;
46 
decode_init(AVCodecContext *avctx)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 
get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos)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 
build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)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 
decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)281 static int decode_frame(AVCodecContext *avctx, AVFrame *p,
282                         int *got_frame, AVPacket *avpkt)
283 {
284     int TL[4] = { 128, 128, 128, 128 };
285     int L[4]  = { 128, 128, 128, 128 };
286     YLCContext *s = avctx->priv_data;
287     const uint8_t *buf = avpkt->data;
288     int ret, x, y, toffset, boffset;
289     GetBitContext gb;
290     uint8_t *dst;
291 
292     if (avpkt->size <= 16)
293         return AVERROR_INVALIDDATA;
294 
295     if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
296         AV_RL32(buf + 4) != 0)
297         return AVERROR_INVALIDDATA;
298 
299     toffset = AV_RL32(buf + 8);
300     if (toffset < 16 || toffset >= avpkt->size)
301         return AVERROR_INVALIDDATA;
302 
303     boffset = AV_RL32(buf + 12);
304     if (toffset >= boffset || boffset >= avpkt->size)
305         return AVERROR_INVALIDDATA;
306 
307     if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
308         return ret;
309 
310     av_fast_malloc(&s->buffer, &s->buffer_size,
311                    FFMAX(boffset - toffset, avpkt->size - boffset)
312                        + AV_INPUT_BUFFER_PADDING_SIZE);
313     if (!s->buffer)
314         return AVERROR(ENOMEM);
315 
316     memcpy(s->buffer, avpkt->data + toffset, boffset - toffset);
317     memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
318     s->bdsp.bswap_buf((uint32_t *) s->buffer,
319                       (uint32_t *) s->buffer,
320                       (boffset - toffset + 3) >> 2);
321     if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0)
322         return ret;
323 
324     for (int i = 0; i < 4; i++) {
325         for (x = 0; x < 256; x++) {
326             unsigned len = get_unary(&gb, 1, 31);
327             uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
328 
329             s->table[x] = val;
330         }
331 
332         ret = build_vlc(avctx, &s->vlc[i], s->table);
333         if (ret < 0)
334             return ret;
335     }
336 
337     memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset);
338     memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
339     s->bdsp.bswap_buf((uint32_t *) s->buffer,
340                       (uint32_t *) s->buffer,
341                       (avpkt->size - boffset) >> 2);
342     if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0)
343         return ret;
344 
345     dst = p->data[0];
346     for (y = 0; y < avctx->height; y++) {
347         memset(dst, 0, avctx->width * 2);
348         dst += p->linesize[0];
349     }
350 
351     dst = p->data[0];
352     for (y = 0; y < avctx->height; y++) {
353         for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
354             if (get_bits_left(&gb) <= 0)
355                 return AVERROR_INVALIDDATA;
356 
357             if (get_bits1(&gb)) {
358                 int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3);
359                 if (val < 0) {
360                     return AVERROR_INVALIDDATA;
361                 } else if (val < 0xE1) {
362                     dst[x    ] = table_y1[val];
363                     dst[x + 1] = table_u[val];
364                     dst[x + 2] = table_y2[val];
365                     dst[x + 3] = table_v[val];
366                     x += 4;
367                 } else {
368                     int incr = (val - 0xDF) * 4;
369                     if (x + incr >= avctx->width * 2) {
370                         int iy = ((x + incr) / (avctx->width * 2));
371                         x  = (x + incr) % (avctx->width * 2);
372                         y += iy;
373                         dst += iy * p->linesize[0];
374                     } else {
375                         x += incr;
376                     }
377                 }
378             } else {
379                 int y1, y2, u, v;
380 
381                 y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
382                 u  = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3);
383                 y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
384                 v  = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3);
385                 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
386                     return AVERROR_INVALIDDATA;
387                 dst[x    ] = y1;
388                 dst[x + 1] = u;
389                 dst[x + 2] = y1 + y2;
390                 dst[x + 3] = v;
391                 x += 4;
392             }
393         }
394         dst += p->linesize[0];
395     }
396 
397     dst = p->data[0];
398     for (x = 0; x < avctx->width * 2; x += 4) {
399         dst[x    ] =        dst[x    ] + L[0];
400         dst[x + 2] = L[0] = dst[x + 2] + L[0];
401         L[1] = dst[x + 1] + L[1];
402         dst[x + 1] = L[1];
403         L[2] = dst[x + 3] + L[2];
404         dst[x + 3] = L[2];
405     }
406     dst += p->linesize[0];
407 
408     for (y = 1; y < avctx->height; y++) {
409         x = 0;
410         dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
411         dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
412         TL[0] = dst[x + 2 - p->linesize[0]];
413         L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
414         dst[x + 1] = L[1];
415         TL[1] = dst[x + 1 - p->linesize[0]];
416         L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
417         dst[x + 3] = L[2];
418         TL[2] = dst[x + 3 - p->linesize[0]];
419         for (x = 4; x < avctx->width * 2; x += 4) {
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         }
430         dst += p->linesize[0];
431     }
432 
433     p->pict_type = AV_PICTURE_TYPE_I;
434     p->key_frame = 1;
435     *got_frame   = 1;
436 
437     return avpkt->size;
438 }
439 
decode_end(AVCodecContext *avctx)440 static av_cold int decode_end(AVCodecContext *avctx)
441 {
442     YLCContext *s = avctx->priv_data;
443 
444     for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++)
445         ff_free_vlc(&s->vlc[i]);
446     av_freep(&s->buffer);
447     s->buffer_size = 0;
448 
449     return 0;
450 }
451 
452 const FFCodec ff_ylc_decoder = {
453     .p.name         = "ylc",
454     .p.long_name    = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
455     .p.type         = AVMEDIA_TYPE_VIDEO,
456     .p.id           = AV_CODEC_ID_YLC,
457     .priv_data_size = sizeof(YLCContext),
458     .init           = decode_init,
459     .close          = decode_end,
460     FF_CODEC_DECODE_CB(decode_frame),
461     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
462     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
463 };
464