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 #include "libavutil/imgutils.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/mem.h"
32 #include "huffyuvdsp.h"
37 typedef struct YLCContext {
41 uint8_t *bitstream_bits;
43 int bitstream_bits_size;
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);
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)
72 bits[*pos] = (~pfx) & ((1 << FFMAX(pl, 1)) - 1);
73 lens[*pos] = FFMAX(pl, 1);
74 xlat[*pos] = s + (pl == 0);
79 get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
82 get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
87 static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
93 int cur_node, i, j, pos = 0;
97 for (i = 0; i < 256; i++) {
98 nodes[i].count = table[i];
110 int first_node = cur_node;
111 int second_node = cur_node;
114 nodes[cur_node].count = -1;
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;
122 first_node = second_node;
123 second_node = new_node;
127 } while (new_node != cur_node);
129 if (first_node == cur_node)
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;
144 } while (cur_node - 256 == j);
146 get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
148 return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
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,
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,
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,
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,
279 static int decode_frame(AVCodecContext *avctx,
280 void *data, int *got_frame,
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;
293 if (avpkt->size <= 16)
294 return AVERROR_INVALIDDATA;
296 if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
297 AV_RL32(buf + 4) != 0)
298 return AVERROR_INVALIDDATA;
300 toffset = AV_RL32(buf + 8);
301 if (toffset < 16 || toffset >= avpkt->size)
302 return AVERROR_INVALIDDATA;
304 boffset = AV_RL32(buf + 12);
305 if (toffset >= boffset || boffset >= avpkt->size)
306 return AVERROR_INVALIDDATA;
308 if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
311 av_fast_malloc(&s->table_bits, &s->table_bits_size,
312 boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
314 return AVERROR(ENOMEM);
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)
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);
331 ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]);
334 ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
337 ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
340 ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
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);
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)
358 for (y = 0; y < avctx->height; y++) {
359 memset(dst, 0, avctx->width * 2);
360 dst += p->linesize[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;
369 if (get_bits1(&gb)) {
370 int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
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];
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);
385 dst += iy * p->linesize[0];
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;
401 dst[x + 2] = y1 + y2;
406 dst += p->linesize[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];
415 L[2] = dst[x + 3] + L[2];
418 dst += p->linesize[0];
420 for (y = 1; y < avctx->height; y++) {
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];
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];
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];
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];
440 TL[2] = dst[x + 3 - p->linesize[0]];
442 dst += p->linesize[0];
445 p->pict_type = AV_PICTURE_TYPE_I;
453 static int init_thread_copy(AVCodecContext *avctx)
455 YLCContext *s = avctx->priv_data;
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;
470 static av_cold int decode_end(AVCodecContext *avctx)
472 YLCContext *s = avctx->priv_data;
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;
486 AVCodec ff_ylc_decoder = {
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),
493 .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
495 .decode = decode_frame,
496 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
497 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,