blob: 80b049861ec56a8022f2740f1992dac9a2bbee62
1 | /* |
2 | * Canopus Lossless Codec decoder |
3 | * |
4 | * Copyright (c) 2012-2013 Derek Buitenhuis |
5 | * |
6 | * This file is part of FFmpeg. |
7 | * |
8 | * FFmpeg is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU Lesser General Public |
10 | * License as published by the Free Software Foundation; either |
11 | * version 2.1 of the License, or (at your option) any later version. |
12 | * |
13 | * FFmpeg is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * Lesser General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU Lesser General Public |
19 | * License along with FFmpeg; if not, write to the Free Software |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | */ |
22 | |
23 | #include <inttypes.h> |
24 | |
25 | #include "libavutil/intreadwrite.h" |
26 | #include "bswapdsp.h" |
27 | #include "canopus.h" |
28 | #include "get_bits.h" |
29 | #include "avcodec.h" |
30 | #include "internal.h" |
31 | |
32 | typedef struct CLLCContext { |
33 | AVCodecContext *avctx; |
34 | BswapDSPContext bdsp; |
35 | |
36 | uint8_t *swapped_buf; |
37 | int swapped_buf_size; |
38 | } CLLCContext; |
39 | |
40 | static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) |
41 | { |
42 | uint8_t symbols[256]; |
43 | uint8_t bits[256]; |
44 | uint16_t codes[256]; |
45 | int num_lens, num_codes, num_codes_sum, prefix; |
46 | int i, j, count; |
47 | |
48 | prefix = 0; |
49 | count = 0; |
50 | num_codes_sum = 0; |
51 | |
52 | num_lens = get_bits(gb, 5); |
53 | |
54 | for (i = 0; i < num_lens; i++) { |
55 | num_codes = get_bits(gb, 9); |
56 | num_codes_sum += num_codes; |
57 | |
58 | if (num_codes_sum > 256) { |
59 | vlc->table = NULL; |
60 | |
61 | av_log(ctx->avctx, AV_LOG_ERROR, |
62 | "Too many VLCs (%d) to be read.\n", num_codes_sum); |
63 | return AVERROR_INVALIDDATA; |
64 | } |
65 | |
66 | for (j = 0; j < num_codes; j++) { |
67 | symbols[count] = get_bits(gb, 8); |
68 | bits[count] = i + 1; |
69 | codes[count] = prefix++; |
70 | |
71 | count++; |
72 | } |
73 | |
74 | prefix <<= 1; |
75 | } |
76 | |
77 | return ff_init_vlc_sparse(vlc, 7, count, bits, 1, 1, |
78 | codes, 2, 2, symbols, 1, 1, 0); |
79 | } |
80 | |
81 | /* |
82 | * Unlike the RGB24 read/restore, which reads in a component at a time, |
83 | * ARGB read/restore reads in ARGB quads. |
84 | */ |
85 | static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, |
86 | VLC *vlc, uint8_t *outbuf) |
87 | { |
88 | uint8_t *dst; |
89 | int pred[4]; |
90 | int code; |
91 | int i; |
92 | |
93 | OPEN_READER(bits, gb); |
94 | |
95 | dst = outbuf; |
96 | pred[0] = top_left[0]; |
97 | pred[1] = top_left[1]; |
98 | pred[2] = top_left[2]; |
99 | pred[3] = top_left[3]; |
100 | |
101 | for (i = 0; i < ctx->avctx->width; i++) { |
102 | /* Always get the alpha component */ |
103 | UPDATE_CACHE(bits, gb); |
104 | GET_VLC(code, bits, gb, vlc[0].table, 7, 2); |
105 | |
106 | pred[0] += code; |
107 | dst[0] = pred[0]; |
108 | |
109 | /* Skip the components if they are entirely transparent */ |
110 | if (dst[0]) { |
111 | /* Red */ |
112 | UPDATE_CACHE(bits, gb); |
113 | GET_VLC(code, bits, gb, vlc[1].table, 7, 2); |
114 | |
115 | pred[1] += code; |
116 | dst[1] = pred[1]; |
117 | |
118 | /* Green */ |
119 | UPDATE_CACHE(bits, gb); |
120 | GET_VLC(code, bits, gb, vlc[2].table, 7, 2); |
121 | |
122 | pred[2] += code; |
123 | dst[2] = pred[2]; |
124 | |
125 | /* Blue */ |
126 | UPDATE_CACHE(bits, gb); |
127 | GET_VLC(code, bits, gb, vlc[3].table, 7, 2); |
128 | |
129 | pred[3] += code; |
130 | dst[3] = pred[3]; |
131 | } else { |
132 | dst[1] = 0; |
133 | dst[2] = 0; |
134 | dst[3] = 0; |
135 | } |
136 | |
137 | dst += 4; |
138 | } |
139 | |
140 | CLOSE_READER(bits, gb); |
141 | |
142 | top_left[0] = outbuf[0]; |
143 | |
144 | /* Only stash components if they are not transparent */ |
145 | if (top_left[0]) { |
146 | top_left[1] = outbuf[1]; |
147 | top_left[2] = outbuf[2]; |
148 | top_left[3] = outbuf[3]; |
149 | } |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, |
155 | int *top_left, VLC *vlc, uint8_t *outbuf) |
156 | { |
157 | uint8_t *dst; |
158 | int pred, code; |
159 | int i; |
160 | |
161 | OPEN_READER(bits, gb); |
162 | |
163 | dst = outbuf; |
164 | pred = *top_left; |
165 | |
166 | /* Simultaneously read and restore the line */ |
167 | for (i = 0; i < ctx->avctx->width; i++) { |
168 | UPDATE_CACHE(bits, gb); |
169 | GET_VLC(code, bits, gb, vlc->table, 7, 2); |
170 | |
171 | pred += code; |
172 | dst[0] = pred; |
173 | dst += 3; |
174 | } |
175 | |
176 | CLOSE_READER(bits, gb); |
177 | |
178 | /* Stash the first pixel */ |
179 | *top_left = outbuf[0]; |
180 | |
181 | return 0; |
182 | } |
183 | |
184 | static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, |
185 | int *top_left, VLC *vlc, uint8_t *outbuf, |
186 | int is_chroma) |
187 | { |
188 | int pred, code; |
189 | int i; |
190 | |
191 | OPEN_READER(bits, gb); |
192 | |
193 | pred = *top_left; |
194 | |
195 | /* Simultaneously read and restore the line */ |
196 | for (i = 0; i < ctx->avctx->width >> is_chroma; i++) { |
197 | UPDATE_CACHE(bits, gb); |
198 | GET_VLC(code, bits, gb, vlc->table, 7, 2); |
199 | |
200 | pred += code; |
201 | outbuf[i] = pred; |
202 | } |
203 | |
204 | CLOSE_READER(bits, gb); |
205 | |
206 | /* Stash the first pixel */ |
207 | *top_left = outbuf[0]; |
208 | |
209 | return 0; |
210 | } |
211 | |
212 | static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
213 | { |
214 | AVCodecContext *avctx = ctx->avctx; |
215 | uint8_t *dst; |
216 | int pred[4]; |
217 | int ret; |
218 | int i, j; |
219 | VLC vlc[4]; |
220 | |
221 | pred[0] = 0; |
222 | pred[1] = 0x80; |
223 | pred[2] = 0x80; |
224 | pred[3] = 0x80; |
225 | |
226 | dst = pic->data[0]; |
227 | |
228 | skip_bits(gb, 16); |
229 | |
230 | /* Read in code table for each plane */ |
231 | for (i = 0; i < 4; i++) { |
232 | ret = read_code_table(ctx, gb, &vlc[i]); |
233 | if (ret < 0) { |
234 | for (j = 0; j <= i; j++) |
235 | ff_free_vlc(&vlc[j]); |
236 | |
237 | av_log(ctx->avctx, AV_LOG_ERROR, |
238 | "Could not read code table %d.\n", i); |
239 | return ret; |
240 | } |
241 | } |
242 | |
243 | /* Read in and restore every line */ |
244 | for (i = 0; i < avctx->height; i++) { |
245 | read_argb_line(ctx, gb, pred, vlc, dst); |
246 | |
247 | dst += pic->linesize[0]; |
248 | } |
249 | |
250 | for (i = 0; i < 4; i++) |
251 | ff_free_vlc(&vlc[i]); |
252 | |
253 | return 0; |
254 | } |
255 | |
256 | static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
257 | { |
258 | AVCodecContext *avctx = ctx->avctx; |
259 | uint8_t *dst; |
260 | int pred[3]; |
261 | int ret; |
262 | int i, j; |
263 | VLC vlc[3]; |
264 | |
265 | pred[0] = 0x80; |
266 | pred[1] = 0x80; |
267 | pred[2] = 0x80; |
268 | |
269 | dst = pic->data[0]; |
270 | |
271 | skip_bits(gb, 16); |
272 | |
273 | /* Read in code table for each plane */ |
274 | for (i = 0; i < 3; i++) { |
275 | ret = read_code_table(ctx, gb, &vlc[i]); |
276 | if (ret < 0) { |
277 | for (j = 0; j <= i; j++) |
278 | ff_free_vlc(&vlc[j]); |
279 | |
280 | av_log(ctx->avctx, AV_LOG_ERROR, |
281 | "Could not read code table %d.\n", i); |
282 | return ret; |
283 | } |
284 | } |
285 | |
286 | /* Read in and restore every line */ |
287 | for (i = 0; i < avctx->height; i++) { |
288 | for (j = 0; j < 3; j++) |
289 | read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]); |
290 | |
291 | dst += pic->linesize[0]; |
292 | } |
293 | |
294 | for (i = 0; i < 3; i++) |
295 | ff_free_vlc(&vlc[i]); |
296 | |
297 | return 0; |
298 | } |
299 | |
300 | static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
301 | { |
302 | AVCodecContext *avctx = ctx->avctx; |
303 | uint8_t block; |
304 | uint8_t *dst[3]; |
305 | int pred[3]; |
306 | int ret; |
307 | int i, j; |
308 | VLC vlc[2]; |
309 | |
310 | pred[0] = 0x80; |
311 | pred[1] = 0x80; |
312 | pred[2] = 0x80; |
313 | |
314 | dst[0] = pic->data[0]; |
315 | dst[1] = pic->data[1]; |
316 | dst[2] = pic->data[2]; |
317 | |
318 | skip_bits(gb, 8); |
319 | |
320 | block = get_bits(gb, 8); |
321 | if (block) { |
322 | avpriv_request_sample(ctx->avctx, "Blocked YUV"); |
323 | return AVERROR_PATCHWELCOME; |
324 | } |
325 | |
326 | /* Read in code table for luma and chroma */ |
327 | for (i = 0; i < 2; i++) { |
328 | ret = read_code_table(ctx, gb, &vlc[i]); |
329 | if (ret < 0) { |
330 | for (j = 0; j <= i; j++) |
331 | ff_free_vlc(&vlc[j]); |
332 | |
333 | av_log(ctx->avctx, AV_LOG_ERROR, |
334 | "Could not read code table %d.\n", i); |
335 | return ret; |
336 | } |
337 | } |
338 | |
339 | /* Read in and restore every line */ |
340 | for (i = 0; i < avctx->height; i++) { |
341 | read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */ |
342 | read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */ |
343 | read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */ |
344 | |
345 | for (j = 0; j < 3; j++) |
346 | dst[j] += pic->linesize[j]; |
347 | } |
348 | |
349 | for (i = 0; i < 2; i++) |
350 | ff_free_vlc(&vlc[i]); |
351 | |
352 | return 0; |
353 | } |
354 | |
355 | static int cllc_decode_frame(AVCodecContext *avctx, void *data, |
356 | int *got_picture_ptr, AVPacket *avpkt) |
357 | { |
358 | CLLCContext *ctx = avctx->priv_data; |
359 | AVFrame *pic = data; |
360 | uint8_t *src = avpkt->data; |
361 | uint32_t info_tag, info_offset; |
362 | int data_size; |
363 | GetBitContext gb; |
364 | int coding_type, ret; |
365 | |
366 | if (avpkt->size < 4 + 4) { |
367 | av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); |
368 | return AVERROR_INVALIDDATA; |
369 | } |
370 | |
371 | info_offset = 0; |
372 | info_tag = AV_RL32(src); |
373 | if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
374 | info_offset = AV_RL32(src + 4); |
375 | if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) { |
376 | av_log(avctx, AV_LOG_ERROR, |
377 | "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", |
378 | info_offset); |
379 | return AVERROR_INVALIDDATA; |
380 | } |
381 | ff_canopus_parse_info_tag(avctx, src + 8, info_offset); |
382 | |
383 | info_offset += 8; |
384 | src += info_offset; |
385 | } |
386 | |
387 | data_size = (avpkt->size - info_offset) & ~1; |
388 | |
389 | /* Make sure our bswap16'd buffer is big enough */ |
390 | av_fast_padded_malloc(&ctx->swapped_buf, |
391 | &ctx->swapped_buf_size, data_size); |
392 | if (!ctx->swapped_buf) { |
393 | av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n"); |
394 | return AVERROR(ENOMEM); |
395 | } |
396 | |
397 | /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */ |
398 | ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src, |
399 | data_size / 2); |
400 | |
401 | if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0) |
402 | return ret; |
403 | |
404 | /* |
405 | * Read in coding type. The types are as follows: |
406 | * |
407 | * 0 - YUY2 |
408 | * 1 - BGR24 (Triples) |
409 | * 2 - BGR24 (Quads) |
410 | * 3 - BGRA |
411 | */ |
412 | coding_type = (AV_RL32(src) >> 8) & 0xFF; |
413 | av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type); |
414 | |
415 | switch (coding_type) { |
416 | case 0: |
417 | avctx->pix_fmt = AV_PIX_FMT_YUV422P; |
418 | avctx->bits_per_raw_sample = 8; |
419 | |
420 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
421 | return ret; |
422 | |
423 | ret = decode_yuv_frame(ctx, &gb, pic); |
424 | if (ret < 0) |
425 | return ret; |
426 | |
427 | break; |
428 | case 1: |
429 | case 2: |
430 | avctx->pix_fmt = AV_PIX_FMT_RGB24; |
431 | avctx->bits_per_raw_sample = 8; |
432 | |
433 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
434 | return ret; |
435 | |
436 | ret = decode_rgb24_frame(ctx, &gb, pic); |
437 | if (ret < 0) |
438 | return ret; |
439 | |
440 | break; |
441 | case 3: |
442 | avctx->pix_fmt = AV_PIX_FMT_ARGB; |
443 | avctx->bits_per_raw_sample = 8; |
444 | |
445 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
446 | return ret; |
447 | |
448 | ret = decode_argb_frame(ctx, &gb, pic); |
449 | if (ret < 0) |
450 | return ret; |
451 | |
452 | break; |
453 | default: |
454 | av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type); |
455 | return AVERROR_INVALIDDATA; |
456 | } |
457 | |
458 | pic->key_frame = 1; |
459 | pic->pict_type = AV_PICTURE_TYPE_I; |
460 | |
461 | *got_picture_ptr = 1; |
462 | |
463 | return avpkt->size; |
464 | } |
465 | |
466 | static av_cold int cllc_decode_close(AVCodecContext *avctx) |
467 | { |
468 | CLLCContext *ctx = avctx->priv_data; |
469 | |
470 | av_freep(&ctx->swapped_buf); |
471 | |
472 | return 0; |
473 | } |
474 | |
475 | static av_cold int cllc_decode_init(AVCodecContext *avctx) |
476 | { |
477 | CLLCContext *ctx = avctx->priv_data; |
478 | |
479 | /* Initialize various context values */ |
480 | ctx->avctx = avctx; |
481 | ctx->swapped_buf = NULL; |
482 | ctx->swapped_buf_size = 0; |
483 | |
484 | ff_bswapdsp_init(&ctx->bdsp); |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | AVCodec ff_cllc_decoder = { |
490 | .name = "cllc", |
491 | .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"), |
492 | .type = AVMEDIA_TYPE_VIDEO, |
493 | .id = AV_CODEC_ID_CLLC, |
494 | .priv_data_size = sizeof(CLLCContext), |
495 | .init = cllc_decode_init, |
496 | .decode = cllc_decode_frame, |
497 | .close = cllc_decode_close, |
498 | .capabilities = AV_CODEC_CAP_DR1, |
499 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
500 | }; |
501 |