4 * This file is part of FFmpeg.
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.
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.
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
25 #define YLC_VLC_BITS 10
27 #include "libavutil/imgutils.h"
28 #include "libavutil/internal.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/mem.h"
34 #include "huffyuvdsp.h"
39 typedef struct YLCContext {
47 static av_cold int decode_init(AVCodecContext *avctx)
49 YLCContext *s = avctx->priv_data;
51 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
52 ff_bswapdsp_init(&s->bdsp);
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)
71 bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1);
72 lens[*pos] = FFMAX(pl, 1);
73 xlat[*pos] = s + (pl == 0);
78 get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
81 get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
86 static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
92 int cur_node, i, j, pos = 0;
96 for (i = 0; i < 256; i++) {
97 nodes[i].count = table[i];
108 int first_node = cur_node;
109 int second_node = cur_node;
112 nodes[cur_node].count = -1;
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;
120 first_node = second_node;
121 second_node = new_node;
125 } while (new_node != cur_node);
127 if (first_node == cur_node)
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;
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;
145 } while (cur_node - 256 == j);
147 get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
149 return ff_init_vlc_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2,
150 bits, 4, 4, xlat, 1, 1, 0);
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,
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,
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,
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,
281 static int decode_frame(AVCodecContext *avctx,
282 void *data, int *got_frame,
285 int TL[4] = { 128, 128, 128, 128 };
286 int L[4] = { 128, 128, 128, 128 };
287 YLCContext *s = avctx->priv_data;
288 ThreadFrame frame = { .f = data };
289 const uint8_t *buf = avpkt->data;
290 int ret, x, y, toffset, boffset;
291 AVFrame * const p = data;
295 if (avpkt->size <= 16)
296 return AVERROR_INVALIDDATA;
298 if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
299 AV_RL32(buf + 4) != 0)
300 return AVERROR_INVALIDDATA;
302 toffset = AV_RL32(buf + 8);
303 if (toffset < 16 || toffset >= avpkt->size)
304 return AVERROR_INVALIDDATA;
306 boffset = AV_RL32(buf + 12);
307 if (toffset >= boffset || boffset >= avpkt->size)
308 return AVERROR_INVALIDDATA;
310 if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
313 av_fast_malloc(&s->buffer, &s->buffer_size,
314 FFMAX(boffset - toffset, avpkt->size - boffset)
315 + AV_INPUT_BUFFER_PADDING_SIZE);
317 return AVERROR(ENOMEM);
319 memcpy(s->buffer, avpkt->data + toffset, boffset - toffset);
320 memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
321 s->bdsp.bswap_buf((uint32_t *) s->buffer,
322 (uint32_t *) s->buffer,
323 (boffset - toffset + 3) >> 2);
324 if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0)
327 for (int i = 0; i < 4; i++) {
328 for (x = 0; x < 256; x++) {
329 unsigned len = get_unary(&gb, 1, 31);
330 uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
335 ret = build_vlc(avctx, &s->vlc[i], s->table);
340 memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset);
341 memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
342 s->bdsp.bswap_buf((uint32_t *) s->buffer,
343 (uint32_t *) s->buffer,
344 (avpkt->size - boffset) >> 2);
345 if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0)
349 for (y = 0; y < avctx->height; y++) {
350 memset(dst, 0, avctx->width * 2);
351 dst += p->linesize[0];
355 for (y = 0; y < avctx->height; y++) {
356 for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
357 if (get_bits_left(&gb) <= 0)
358 return AVERROR_INVALIDDATA;
360 if (get_bits1(&gb)) {
361 int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3);
363 return AVERROR_INVALIDDATA;
364 } else if (val < 0xE1) {
365 dst[x ] = table_y1[val];
366 dst[x + 1] = table_u[val];
367 dst[x + 2] = table_y2[val];
368 dst[x + 3] = table_v[val];
371 int incr = (val - 0xDF) * 4;
372 if (x + incr >= avctx->width * 2) {
373 int iy = ((x + incr) / (avctx->width * 2));
374 x = (x + incr) % (avctx->width * 2);
376 dst += iy * p->linesize[0];
384 y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
385 u = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3);
386 y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
387 v = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3);
388 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
389 return AVERROR_INVALIDDATA;
392 dst[x + 2] = y1 + y2;
397 dst += p->linesize[0];
401 for (x = 0; x < avctx->width * 2; x += 4) {
402 dst[x ] = dst[x ] + L[0];
403 dst[x + 2] = L[0] = dst[x + 2] + L[0];
404 L[1] = dst[x + 1] + L[1];
406 L[2] = dst[x + 3] + L[2];
409 dst += p->linesize[0];
411 for (y = 1; y < avctx->height; y++) {
413 dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
414 dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
415 TL[0] = dst[x + 2 - p->linesize[0]];
416 L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
418 TL[1] = dst[x + 1 - p->linesize[0]];
419 L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
421 TL[2] = dst[x + 3 - p->linesize[0]];
422 for (x = 4; x < avctx->width * 2; x += 4) {
423 dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
424 dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
425 TL[0] = dst[x + 2 - p->linesize[0]];
426 L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
428 TL[1] = dst[x + 1 - p->linesize[0]];
429 L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
431 TL[2] = dst[x + 3 - p->linesize[0]];
433 dst += p->linesize[0];
436 p->pict_type = AV_PICTURE_TYPE_I;
443 static av_cold int decode_end(AVCodecContext *avctx)
445 YLCContext *s = avctx->priv_data;
447 for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++)
448 ff_free_vlc(&s->vlc[i]);
449 av_freep(&s->buffer);
455 const AVCodec ff_ylc_decoder = {
457 .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
458 .type = AVMEDIA_TYPE_VIDEO,
459 .id = AV_CODEC_ID_YLC,
460 .priv_data_size = sizeof(YLCContext),
463 .decode = decode_frame,
464 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
465 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,