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
23 #define YLC_VLC_BITS 10
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/pixfmt.h"
30 #include "codec_internal.h"
35 typedef struct YLCContext
{
43 static av_cold
int decode_init(AVCodecContext
*avctx
)
45 YLCContext
*s
= avctx
->priv_data
;
47 avctx
->pix_fmt
= AV_PIX_FMT_YUYV422
;
48 ff_bswapdsp_init(&s
->bdsp
);
59 static void get_tree_codes(uint32_t *bits
, int16_t *lens
, uint8_t *xlat
,
60 Node
*nodes
, int node
,
61 uint32_t pfx
, int pl
, int *pos
)
67 bits
[*pos
] = (~pfx
) & ((1ULL << FFMAX(pl
, 1)) - 1);
68 lens
[*pos
] = FFMAX(pl
, 1);
69 xlat
[*pos
] = s
+ (pl
== 0);
74 get_tree_codes(bits
, lens
, xlat
, nodes
, nodes
[node
].l
, pfx
, pl
,
77 get_tree_codes(bits
, lens
, xlat
, nodes
, nodes
[node
].r
, pfx
, pl
,
82 static int build_vlc(AVCodecContext
*avctx
, VLC
*vlc
, const uint32_t *table
)
88 int cur_node
, i
, j
, pos
= 0;
92 for (i
= 0; i
< 256; i
++) {
93 nodes
[i
].count
= table
[i
];
104 int first_node
= cur_node
;
105 int second_node
= cur_node
;
108 nodes
[cur_node
].count
= -1;
111 int val
= nodes
[new_node
].count
;
112 if (val
&& (val
< nodes
[first_node
].count
)) {
113 if (val
>= nodes
[second_node
].count
) {
114 first_node
= new_node
;
116 first_node
= second_node
;
117 second_node
= new_node
;
121 } while (new_node
!= cur_node
);
123 if (first_node
== cur_node
)
126 nd
= nodes
[second_node
].count
;
127 st
= nodes
[first_node
].count
;
128 nodes
[second_node
].count
= 0;
129 nodes
[first_node
].count
= 0;
130 if (nd
>= UINT32_MAX
- st
) {
131 av_log(avctx
, AV_LOG_ERROR
, "count overflow\n");
132 return AVERROR_INVALIDDATA
;
134 nodes
[cur_node
].count
= nd
+ st
;
135 nodes
[cur_node
].sym
= -1;
136 nodes
[cur_node
].l
= first_node
;
137 nodes
[cur_node
].r
= second_node
;
141 } while (cur_node
- 256 == j
);
143 get_tree_codes(bits
, lens
, xlat
, nodes
, cur_node
- 1, 0, 0, &pos
);
145 return ff_vlc_init_sparse(vlc
, YLC_VLC_BITS
, pos
, lens
, 2, 2,
146 bits
, 4, 4, xlat
, 1, 1, 0);
149 static const uint8_t table_y1
[] = {
150 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
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, 0xFF, 0xFF, 0xFF,
156 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 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, 0x01,
167 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x02, 0x02, 0x02, 0x02,
173 0x02, 0x02, 0x02, 0x02, 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,
181 static const uint8_t table_u
[] = {
182 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
186 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
187 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
188 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
194 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
198 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
199 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
203 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
204 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
205 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
206 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
209 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
213 static const uint8_t table_y2
[] = {
214 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
215 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
216 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
217 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
218 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
219 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
220 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
221 0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
222 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
223 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
224 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
225 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
226 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
227 0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
228 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
229 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
230 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
231 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
232 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
233 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
234 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
235 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
236 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
237 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
238 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
239 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
240 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
241 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
245 static const uint8_t table_v
[] = {
246 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
247 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
248 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
249 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
250 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
251 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
252 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
253 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
254 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
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,
277 static int decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
278 int *got_frame
, AVPacket
*avpkt
)
280 int TL
[4] = { 128, 128, 128, 128 };
281 int L
[4] = { 128, 128, 128, 128 };
282 YLCContext
*s
= avctx
->priv_data
;
283 const uint8_t *buf
= avpkt
->data
;
284 int ret
, x
, y
, toffset
, boffset
;
288 if (avpkt
->size
<= 16)
289 return AVERROR_INVALIDDATA
;
291 if (AV_RL32(buf
) != MKTAG('Y', 'L', 'C', '0') ||
292 AV_RL32(buf
+ 4) != 0)
293 return AVERROR_INVALIDDATA
;
295 toffset
= AV_RL32(buf
+ 8);
296 if (toffset
< 16 || toffset
>= avpkt
->size
)
297 return AVERROR_INVALIDDATA
;
299 boffset
= AV_RL32(buf
+ 12);
300 if (toffset
>= boffset
|| boffset
>= avpkt
->size
)
301 return AVERROR_INVALIDDATA
;
303 if ((ret
= ff_thread_get_buffer(avctx
, p
, 0)) < 0)
306 av_fast_malloc(&s
->buffer
, &s
->buffer_size
,
307 FFMAX(boffset
- toffset
, avpkt
->size
- boffset
)
308 + AV_INPUT_BUFFER_PADDING_SIZE
);
310 return AVERROR(ENOMEM
);
312 memcpy(s
->buffer
, avpkt
->data
+ toffset
, boffset
- toffset
);
313 memset(s
->buffer
+ boffset
- toffset
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
314 s
->bdsp
.bswap_buf((uint32_t *) s
->buffer
,
315 (uint32_t *) s
->buffer
,
316 (boffset
- toffset
+ 3) >> 2);
317 if ((ret
= init_get_bits8(&gb
, s
->buffer
, boffset
- toffset
)) < 0)
320 for (int i
= 0; i
< 4; i
++) {
321 for (x
= 0; x
< 256; x
++) {
322 unsigned len
= get_unary(&gb
, 1, 31);
323 uint32_t val
= ((1U << len
) - 1) + get_bits_long(&gb
, len
);
328 ret
= build_vlc(avctx
, &s
->vlc
[i
], s
->table
);
333 memcpy(s
->buffer
, avpkt
->data
+ boffset
, avpkt
->size
- boffset
);
334 memset(s
->buffer
+ avpkt
->size
- boffset
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
335 s
->bdsp
.bswap_buf((uint32_t *) s
->buffer
,
336 (uint32_t *) s
->buffer
,
337 (avpkt
->size
- boffset
) >> 2);
338 if ((ret
= init_get_bits8(&gb
, s
->buffer
, avpkt
->size
- boffset
)) < 0)
342 for (y
= 0; y
< avctx
->height
; y
++) {
343 memset(dst
, 0, avctx
->width
* 2);
344 dst
+= p
->linesize
[0];
348 for (y
= 0; y
< avctx
->height
; y
++) {
349 for (x
= 0; x
< avctx
->width
* 2 && y
< avctx
->height
;) {
350 if (get_bits_left(&gb
) <= 0)
351 return AVERROR_INVALIDDATA
;
353 if (get_bits1(&gb
)) {
354 int val
= get_vlc2(&gb
, s
->vlc
[0].table
, YLC_VLC_BITS
, 3);
356 return AVERROR_INVALIDDATA
;
357 } else if (val
< 0xE1) {
358 dst
[x
] = table_y1
[val
];
359 dst
[x
+ 1] = table_u
[val
];
360 dst
[x
+ 2] = table_y2
[val
];
361 dst
[x
+ 3] = table_v
[val
];
364 int incr
= (val
- 0xDF) * 4;
365 if (x
+ incr
>= avctx
->width
* 2) {
366 int iy
= ((x
+ incr
) / (avctx
->width
* 2));
367 x
= (x
+ incr
) % (avctx
->width
* 2);
369 dst
+= iy
* p
->linesize
[0];
377 y1
= get_vlc2(&gb
, s
->vlc
[1].table
, YLC_VLC_BITS
, 3);
378 u
= get_vlc2(&gb
, s
->vlc
[2].table
, YLC_VLC_BITS
, 3);
379 y2
= get_vlc2(&gb
, s
->vlc
[1].table
, YLC_VLC_BITS
, 3);
380 v
= get_vlc2(&gb
, s
->vlc
[3].table
, YLC_VLC_BITS
, 3);
381 if (y1
< 0 || y2
< 0 || u
< 0 || v
< 0)
382 return AVERROR_INVALIDDATA
;
385 dst
[x
+ 2] = y1
+ y2
;
390 dst
+= p
->linesize
[0];
394 for (x
= 0; x
< avctx
->width
* 2; x
+= 4) {
395 dst
[x
] = dst
[x
] + L
[0];
396 dst
[x
+ 2] = L
[0] = dst
[x
+ 2] + L
[0];
397 L
[1] = dst
[x
+ 1] + L
[1];
399 L
[2] = dst
[x
+ 3] + L
[2];
402 dst
+= p
->linesize
[0];
404 for (y
= 1; y
< avctx
->height
; y
++) {
406 dst
[x
] = dst
[x
] + L
[0] + dst
[x
+ 0 - p
->linesize
[0]] - TL
[0];
407 dst
[x
+ 2] = L
[0] = dst
[x
+ 2] + L
[0] + dst
[x
+ 2 - p
->linesize
[0]] - TL
[0];
408 TL
[0] = dst
[x
+ 2 - p
->linesize
[0]];
409 L
[1] = dst
[x
+ 1] + L
[1] + dst
[x
+ 1 - p
->linesize
[0]] - TL
[1];
411 TL
[1] = dst
[x
+ 1 - p
->linesize
[0]];
412 L
[2] = dst
[x
+ 3] + L
[2] + dst
[x
+ 3 - p
->linesize
[0]] - TL
[2];
414 TL
[2] = dst
[x
+ 3 - p
->linesize
[0]];
415 for (x
= 4; x
< avctx
->width
* 2; x
+= 4) {
416 dst
[x
] = dst
[x
] + L
[0] + dst
[x
+ 0 - p
->linesize
[0]] - TL
[0];
417 dst
[x
+ 2] = L
[0] = dst
[x
+ 2] + L
[0] + dst
[x
+ 2 - p
->linesize
[0]] - TL
[0];
418 TL
[0] = dst
[x
+ 2 - p
->linesize
[0]];
419 L
[1] = dst
[x
+ 1] + L
[1] + dst
[x
+ 1 - p
->linesize
[0]] - TL
[1];
421 TL
[1] = dst
[x
+ 1 - p
->linesize
[0]];
422 L
[2] = dst
[x
+ 3] + L
[2] + dst
[x
+ 3 - p
->linesize
[0]] - TL
[2];
424 TL
[2] = dst
[x
+ 3 - p
->linesize
[0]];
426 dst
+= p
->linesize
[0];
434 static av_cold
int decode_end(AVCodecContext
*avctx
)
436 YLCContext
*s
= avctx
->priv_data
;
438 for (int i
= 0; i
< FF_ARRAY_ELEMS(s
->vlc
); i
++)
439 ff_vlc_free(&s
->vlc
[i
]);
440 av_freep(&s
->buffer
);
446 const FFCodec ff_ylc_decoder
= {
448 CODEC_LONG_NAME("YUY2 Lossless Codec"),
449 .p
.type
= AVMEDIA_TYPE_VIDEO
,
450 .p
.id
= AV_CODEC_ID_YLC
,
451 .priv_data_size
= sizeof(YLCContext
),
454 FF_CODEC_DECODE_CB(decode_frame
),
455 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
,