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"
36 typedef struct YLCContext {
40 uint8_t *bitstream_bits;
42 int bitstream_bits_size;
46 static av_cold int decode_init(AVCodecContext *avctx)
48 YLCContext *s = avctx->priv_data;
50 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
51 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) & ((1 << 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];
109 int first_node = cur_node;
110 int second_node = cur_node;
113 nodes[cur_node].count = -1;
116 int val = nodes[new_node].count;
117 if (val && (val < nodes[first_node].count)) {
118 if (val >= nodes[second_node].count) {
119 first_node = new_node;
121 first_node = second_node;
122 second_node = new_node;
126 } while (new_node != cur_node);
128 if (first_node == cur_node)
131 nd = nodes[second_node].count;
132 st = nodes[first_node].count;
133 nodes[second_node].count = 0;
134 nodes[first_node].count = 0;
135 nodes[cur_node].count = nd + st;
136 nodes[cur_node].sym = -1;
137 nodes[cur_node].n0 = cur_node;
138 nodes[cur_node].l = first_node;
139 nodes[cur_node].r = second_node;
143 } while (cur_node - 256 == j);
145 get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
147 return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
150 static const uint8_t table_y1[] = {
151 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
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, 0xFF, 0xFF, 0xFF,
157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 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, 0x01,
168 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x02, 0x02, 0x02, 0x02,
174 0x02, 0x02, 0x02, 0x02, 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,
182 static const uint8_t table_u[] = {
183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
187 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
188 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
190 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
194 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
196 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
200 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
201 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
204 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
205 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
206 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
207 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
210 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
214 static const uint8_t table_y2[] = {
215 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
216 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
217 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
218 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
219 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
220 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
221 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
222 0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
223 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
224 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
225 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
226 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
227 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
228 0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
229 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
230 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
231 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
232 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
233 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
234 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
235 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
236 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
237 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
238 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
239 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
240 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
241 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
242 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
246 static const uint8_t table_v[] = {
247 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
248 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
249 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
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,
278 static int decode_frame(AVCodecContext *avctx,
279 void *data, int *got_frame,
282 int TL[4] = { 128, 128, 128, 128 };
283 int L[4] = { 128, 128, 128, 128 };
284 YLCContext *s = avctx->priv_data;
285 const uint8_t *buf = avpkt->data;
286 int ret, x, y, toffset, boffset;
287 AVFrame * const p = data;
291 if (avpkt->size <= 16)
292 return AVERROR_INVALIDDATA;
294 if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
295 AV_RL32(buf + 4) != 0)
296 return AVERROR_INVALIDDATA;
298 toffset = AV_RL32(buf + 8);
299 if (toffset < 16 || toffset >= avpkt->size)
300 return AVERROR_INVALIDDATA;
302 boffset = AV_RL32(buf + 12);
303 if (toffset >= boffset || boffset >= avpkt->size)
304 return AVERROR_INVALIDDATA;
306 if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
309 av_fast_malloc(&s->table_bits, &s->table_bits_size,
310 boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
312 return AVERROR(ENOMEM);
314 memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
315 memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
316 s->bdsp.bswap_buf((uint32_t *) s->table_bits,
317 (uint32_t *) s->table_bits,
318 (boffset - toffset + 3) >> 2);
319 if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
322 for (x = 0; x < 1024; x++) {
323 unsigned len = get_unary(&gb, 1, 31);
324 uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
329 ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]);
332 ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
335 ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
338 ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
342 av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
343 avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
344 if (!s->bitstream_bits)
345 return AVERROR(ENOMEM);
347 memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
348 memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
349 s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
350 (uint32_t *) s->bitstream_bits,
351 (avpkt->size - boffset) >> 2);
352 if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
356 for (y = 0; y < avctx->height; y++) {
357 memset(dst, 0, avctx->width * 2);
358 dst += p->linesize[0];
362 for (y = 0; y < avctx->height; y++) {
363 for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
364 if (get_bits_left(&gb) <= 0)
365 return AVERROR_INVALIDDATA;
367 if (get_bits1(&gb)) {
368 int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
370 return AVERROR_INVALIDDATA;
371 } else if (val < 0xE1) {
372 dst[x ] = table_y1[val];
373 dst[x + 1] = table_u[val];
374 dst[x + 2] = table_y2[val];
375 dst[x + 3] = table_v[val];
378 int incr = (val - 0xDF) * 4;
379 if (x + incr >= avctx->width * 2) {
380 int iy = ((x + incr) / (avctx->width * 2));
381 x = (x + incr) % (avctx->width * 2);
383 dst += iy * p->linesize[0];
391 y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
392 u = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
393 y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
394 v = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3);
395 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
396 return AVERROR_INVALIDDATA;
399 dst[x + 2] = y1 + y2;
404 dst += p->linesize[0];
408 for (x = 0; x < avctx->width * 2; x += 4) {
409 dst[x ] = dst[x ] + L[0];
410 dst[x + 2] = L[0] = dst[x + 2] + L[0];
411 L[1] = dst[x + 1] + L[1];
413 L[2] = dst[x + 3] + L[2];
416 dst += p->linesize[0];
418 for (y = 1; y < avctx->height; y++) {
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];
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];
428 TL[2] = dst[x + 3 - p->linesize[0]];
429 for (x = 4; x < avctx->width * 2; x += 4) {
430 dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
431 dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
432 TL[0] = dst[x + 2 - p->linesize[0]];
433 L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
435 TL[1] = dst[x + 1 - p->linesize[0]];
436 L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
438 TL[2] = dst[x + 3 - p->linesize[0]];
440 dst += p->linesize[0];
443 p->pict_type = AV_PICTURE_TYPE_I;
450 static av_cold int decode_end(AVCodecContext *avctx)
452 YLCContext *s = avctx->priv_data;
454 ff_free_vlc(&s->vlc[0]);
455 ff_free_vlc(&s->vlc[1]);
456 ff_free_vlc(&s->vlc[2]);
457 ff_free_vlc(&s->vlc[3]);
462 AVCodec ff_ylc_decoder = {
464 .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
465 .type = AVMEDIA_TYPE_VIDEO,
466 .id = AV_CODEC_ID_YLC,
467 .priv_data_size = sizeof(YLCContext),
470 .decode = decode_frame,
471 .capabilities = AV_CODEC_CAP_DR1,