/src/ffmpeg/libavcodec/cllc.c
Line | Count | Source (jump to first uncovered line) |
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 "libavutil/mem.h" |
27 | | #include "bswapdsp.h" |
28 | | #include "canopus.h" |
29 | | #include "get_bits.h" |
30 | | #include "avcodec.h" |
31 | | #include "codec_internal.h" |
32 | | #include "thread.h" |
33 | | |
34 | 216k | #define VLC_BITS 7 |
35 | 108k | #define VLC_DEPTH 2 |
36 | | |
37 | | |
38 | | typedef struct CLLCContext { |
39 | | AVCodecContext *avctx; |
40 | | BswapDSPContext bdsp; |
41 | | |
42 | | uint8_t *swapped_buf; |
43 | | int swapped_buf_size; |
44 | | } CLLCContext; |
45 | | |
46 | | static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) |
47 | 108k | { |
48 | 108k | uint8_t symbols[256]; |
49 | 108k | uint8_t bits[256]; |
50 | 108k | int num_lens, num_codes, num_codes_sum; |
51 | 108k | int i, j, count; |
52 | | |
53 | 108k | count = 0; |
54 | 108k | num_codes_sum = 0; |
55 | | |
56 | 108k | num_lens = get_bits(gb, 5); |
57 | | |
58 | 108k | if (num_lens > VLC_BITS * VLC_DEPTH) { |
59 | 764 | av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens); |
60 | 764 | return AVERROR_INVALIDDATA; |
61 | 764 | } |
62 | | |
63 | 133k | for (i = 0; i < num_lens; i++) { |
64 | 26.3k | num_codes = get_bits(gb, 9); |
65 | 26.3k | num_codes_sum += num_codes; |
66 | | |
67 | 26.3k | if (num_codes_sum > 256) { |
68 | 842 | av_log(ctx->avctx, AV_LOG_ERROR, |
69 | 842 | "Too many VLCs (%d) to be read.\n", num_codes_sum); |
70 | 842 | return AVERROR_INVALIDDATA; |
71 | 842 | } |
72 | | |
73 | 278k | for (j = 0; j < num_codes; j++) { |
74 | 253k | symbols[count] = get_bits(gb, 8); |
75 | 253k | bits[count] = i + 1; |
76 | | |
77 | 253k | count++; |
78 | 253k | } |
79 | 25.5k | } |
80 | | |
81 | 107k | return ff_vlc_init_from_lengths(vlc, VLC_BITS, count, bits, 1, |
82 | 107k | symbols, 1, 1, 0, 0, ctx->avctx); |
83 | 108k | } |
84 | | |
85 | | /* |
86 | | * Unlike the RGB24 read/restore, which reads in a component at a time, |
87 | | * ARGB read/restore reads in ARGB quads. |
88 | | */ |
89 | | static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, |
90 | | VLC *vlc, uint8_t *outbuf) |
91 | 1.26M | { |
92 | 1.26M | uint8_t *dst; |
93 | 1.26M | int pred[4]; |
94 | 1.26M | int code; |
95 | 1.26M | int i; |
96 | | |
97 | 1.26M | OPEN_READER(bits, gb); |
98 | | |
99 | 1.26M | dst = outbuf; |
100 | 1.26M | pred[0] = top_left[0]; |
101 | 1.26M | pred[1] = top_left[1]; |
102 | 1.26M | pred[2] = top_left[2]; |
103 | 1.26M | pred[3] = top_left[3]; |
104 | | |
105 | 39.0M | for (i = 0; i < ctx->avctx->width; i++) { |
106 | | /* Always get the alpha component */ |
107 | 37.7M | UPDATE_CACHE(bits, gb); |
108 | 37.7M | GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH); |
109 | | |
110 | 37.7M | pred[0] += code; |
111 | 37.7M | dst[0] = pred[0]; |
112 | | |
113 | | /* Skip the components if they are entirely transparent */ |
114 | 37.7M | if (dst[0]) { |
115 | | /* Red */ |
116 | 37.5M | UPDATE_CACHE(bits, gb); |
117 | 37.5M | GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH); |
118 | | |
119 | 37.5M | pred[1] += code; |
120 | 37.5M | dst[1] = pred[1]; |
121 | | |
122 | | /* Green */ |
123 | 37.5M | UPDATE_CACHE(bits, gb); |
124 | 37.5M | GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH); |
125 | | |
126 | 37.5M | pred[2] += code; |
127 | 37.5M | dst[2] = pred[2]; |
128 | | |
129 | | /* Blue */ |
130 | 37.5M | UPDATE_CACHE(bits, gb); |
131 | 37.5M | GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH); |
132 | | |
133 | 37.5M | pred[3] += code; |
134 | 37.5M | dst[3] = pred[3]; |
135 | 37.5M | } else { |
136 | 217k | dst[1] = 0; |
137 | 217k | dst[2] = 0; |
138 | 217k | dst[3] = 0; |
139 | 217k | } |
140 | | |
141 | 37.7M | dst += 4; |
142 | 37.7M | } |
143 | | |
144 | 1.26M | CLOSE_READER(bits, gb); |
145 | | |
146 | 1.26M | top_left[0] = outbuf[0]; |
147 | | |
148 | | /* Only stash components if they are not transparent */ |
149 | 1.26M | if (top_left[0]) { |
150 | 1.25M | top_left[1] = outbuf[1]; |
151 | 1.25M | top_left[2] = outbuf[2]; |
152 | 1.25M | top_left[3] = outbuf[3]; |
153 | 1.25M | } |
154 | | |
155 | 1.26M | return 0; |
156 | 1.26M | } |
157 | | |
158 | | static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, |
159 | | int *top_left, VLC *vlc, uint8_t *outbuf) |
160 | 3.17M | { |
161 | 3.17M | uint8_t *dst; |
162 | 3.17M | int pred, code; |
163 | 3.17M | int i; |
164 | | |
165 | 3.17M | OPEN_READER(bits, gb); |
166 | | |
167 | 3.17M | dst = outbuf; |
168 | 3.17M | pred = *top_left; |
169 | | |
170 | | /* Simultaneously read and restore the line */ |
171 | 50.8M | for (i = 0; i < ctx->avctx->width; i++) { |
172 | 47.6M | UPDATE_CACHE(bits, gb); |
173 | 47.6M | GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH); |
174 | | |
175 | 47.6M | pred += code; |
176 | 47.6M | dst[0] = pred; |
177 | 47.6M | dst += 3; |
178 | 47.6M | } |
179 | | |
180 | 3.17M | CLOSE_READER(bits, gb); |
181 | | |
182 | | /* Stash the first pixel */ |
183 | 3.17M | *top_left = outbuf[0]; |
184 | | |
185 | 3.17M | return 0; |
186 | 3.17M | } |
187 | | |
188 | | static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, |
189 | | int *top_left, VLC *vlc, uint8_t *outbuf, |
190 | | int is_chroma) |
191 | 3.83M | { |
192 | 3.83M | int pred, code; |
193 | 3.83M | int i; |
194 | | |
195 | 3.83M | OPEN_READER(bits, gb); |
196 | | |
197 | 3.83M | pred = *top_left; |
198 | | |
199 | | /* Simultaneously read and restore the line */ |
200 | 59.3M | for (i = 0; i < ctx->avctx->width >> is_chroma; i++) { |
201 | 55.5M | UPDATE_CACHE(bits, gb); |
202 | 55.5M | GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH); |
203 | | |
204 | 55.5M | pred += code; |
205 | 55.5M | outbuf[i] = pred; |
206 | 55.5M | } |
207 | | |
208 | 3.83M | CLOSE_READER(bits, gb); |
209 | | |
210 | | /* Stash the first pixel */ |
211 | 3.83M | *top_left = outbuf[0]; |
212 | | |
213 | 3.83M | return 0; |
214 | 3.83M | } |
215 | | |
216 | | static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
217 | 1.88k | { |
218 | 1.88k | AVCodecContext *avctx = ctx->avctx; |
219 | 1.88k | uint8_t *dst; |
220 | 1.88k | int pred[4]; |
221 | 1.88k | int ret; |
222 | 1.88k | int i, j; |
223 | 1.88k | VLC vlc[4]; |
224 | | |
225 | 1.88k | pred[0] = 0; |
226 | 1.88k | pred[1] = 0x80; |
227 | 1.88k | pred[2] = 0x80; |
228 | 1.88k | pred[3] = 0x80; |
229 | | |
230 | 1.88k | dst = pic->data[0]; |
231 | | |
232 | 1.88k | skip_bits(gb, 16); |
233 | | |
234 | | /* Read in code table for each plane */ |
235 | 7.40k | for (i = 0; i < 4; i++) { |
236 | 6.34k | ret = read_code_table(ctx, gb, &vlc[i]); |
237 | 6.34k | if (ret < 0) { |
238 | 2.12k | for (j = 0; j < i; j++) |
239 | 1.29k | ff_vlc_free(&vlc[j]); |
240 | | |
241 | 829 | av_log(ctx->avctx, AV_LOG_ERROR, |
242 | 829 | "Could not read code table %d.\n", i); |
243 | 829 | return ret; |
244 | 829 | } |
245 | 6.34k | } |
246 | | |
247 | | /* Read in and restore every line */ |
248 | 1.26M | for (i = 0; i < avctx->height; i++) { |
249 | 1.26M | read_argb_line(ctx, gb, pred, vlc, dst); |
250 | | |
251 | 1.26M | dst += pic->linesize[0]; |
252 | 1.26M | } |
253 | | |
254 | 5.28k | for (i = 0; i < 4; i++) |
255 | 4.22k | ff_vlc_free(&vlc[i]); |
256 | | |
257 | 1.05k | return 0; |
258 | 1.88k | } |
259 | | |
260 | | static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
261 | 33.3k | { |
262 | 33.3k | AVCodecContext *avctx = ctx->avctx; |
263 | 33.3k | uint8_t *dst; |
264 | 33.3k | int pred[3]; |
265 | 33.3k | int ret; |
266 | 33.3k | int i, j; |
267 | 33.3k | VLC vlc[3]; |
268 | | |
269 | 33.3k | pred[0] = 0x80; |
270 | 33.3k | pred[1] = 0x80; |
271 | 33.3k | pred[2] = 0x80; |
272 | | |
273 | 33.3k | dst = pic->data[0]; |
274 | | |
275 | 33.3k | skip_bits(gb, 16); |
276 | | |
277 | | /* Read in code table for each plane */ |
278 | 131k | for (i = 0; i < 3; i++) { |
279 | 98.7k | ret = read_code_table(ctx, gb, &vlc[i]); |
280 | 98.7k | if (ret < 0) { |
281 | 1.91k | for (j = 0; j < i; j++) |
282 | 901 | ff_vlc_free(&vlc[j]); |
283 | | |
284 | 1.01k | av_log(ctx->avctx, AV_LOG_ERROR, |
285 | 1.01k | "Could not read code table %d.\n", i); |
286 | 1.01k | return ret; |
287 | 1.01k | } |
288 | 98.7k | } |
289 | | |
290 | | /* Read in and restore every line */ |
291 | 1.08M | for (i = 0; i < avctx->height; i++) { |
292 | 4.23M | for (j = 0; j < 3; j++) |
293 | 3.17M | read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]); |
294 | | |
295 | 1.05M | dst += pic->linesize[0]; |
296 | 1.05M | } |
297 | | |
298 | 129k | for (i = 0; i < 3; i++) |
299 | 96.8k | ff_vlc_free(&vlc[i]); |
300 | | |
301 | 32.2k | return 0; |
302 | 33.3k | } |
303 | | |
304 | | static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) |
305 | 3.00k | { |
306 | 3.00k | AVCodecContext *avctx = ctx->avctx; |
307 | 3.00k | uint8_t block; |
308 | 3.00k | uint8_t *dst[3]; |
309 | 3.00k | int pred[3]; |
310 | 3.00k | int ret; |
311 | 3.00k | int i, j; |
312 | 3.00k | VLC vlc[2]; |
313 | | |
314 | 3.00k | pred[0] = 0x80; |
315 | 3.00k | pred[1] = 0x80; |
316 | 3.00k | pred[2] = 0x80; |
317 | | |
318 | 3.00k | dst[0] = pic->data[0]; |
319 | 3.00k | dst[1] = pic->data[1]; |
320 | 3.00k | dst[2] = pic->data[2]; |
321 | | |
322 | 3.00k | skip_bits(gb, 8); |
323 | | |
324 | 3.00k | block = get_bits(gb, 8); |
325 | 3.00k | if (block) { |
326 | 689 | avpriv_request_sample(ctx->avctx, "Blocked YUV"); |
327 | 689 | return AVERROR_PATCHWELCOME; |
328 | 689 | } |
329 | | |
330 | | /* Read in code table for luma and chroma */ |
331 | 4.95k | for (i = 0; i < 2; i++) { |
332 | 3.82k | ret = read_code_table(ctx, gb, &vlc[i]); |
333 | 3.82k | if (ret < 0) { |
334 | 1.57k | for (j = 0; j < i; j++) |
335 | 388 | ff_vlc_free(&vlc[j]); |
336 | | |
337 | 1.18k | av_log(ctx->avctx, AV_LOG_ERROR, |
338 | 1.18k | "Could not read code table %d.\n", i); |
339 | 1.18k | return ret; |
340 | 1.18k | } |
341 | 3.82k | } |
342 | | |
343 | | /* Read in and restore every line */ |
344 | 1.27M | for (i = 0; i < avctx->height; i++) { |
345 | 1.27M | read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */ |
346 | 1.27M | read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */ |
347 | 1.27M | read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */ |
348 | | |
349 | 5.10M | for (j = 0; j < 3; j++) |
350 | 3.83M | dst[j] += pic->linesize[j]; |
351 | 1.27M | } |
352 | | |
353 | 3.38k | for (i = 0; i < 2; i++) |
354 | 2.25k | ff_vlc_free(&vlc[i]); |
355 | | |
356 | 1.12k | return 0; |
357 | 2.31k | } |
358 | | |
359 | | static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic, |
360 | | int *got_picture_ptr, AVPacket *avpkt) |
361 | 466k | { |
362 | 466k | CLLCContext *ctx = avctx->priv_data; |
363 | 466k | const uint8_t *src = avpkt->data; |
364 | 466k | uint32_t info_tag, info_offset; |
365 | 466k | int data_size; |
366 | 466k | GetBitContext gb; |
367 | 466k | int coding_type, ret; |
368 | | |
369 | 466k | if (avpkt->size < 4 + 4) { |
370 | 379k | av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); |
371 | 379k | return AVERROR_INVALIDDATA; |
372 | 379k | } |
373 | | |
374 | 86.5k | info_offset = 0; |
375 | 86.5k | info_tag = AV_RL32(src); |
376 | 86.5k | if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
377 | 9.04k | info_offset = AV_RL32(src + 4); |
378 | 9.04k | if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) { |
379 | 737 | av_log(avctx, AV_LOG_ERROR, |
380 | 737 | "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", |
381 | 737 | info_offset); |
382 | 737 | return AVERROR_INVALIDDATA; |
383 | 737 | } |
384 | 8.30k | ff_canopus_parse_info_tag(avctx, src + 8, info_offset); |
385 | | |
386 | 8.30k | info_offset += 8; |
387 | 8.30k | src += info_offset; |
388 | 8.30k | } |
389 | | |
390 | 85.8k | data_size = (avpkt->size - info_offset) & ~1; |
391 | | |
392 | | /* Make sure our bswap16'd buffer is big enough */ |
393 | 85.8k | av_fast_padded_malloc(&ctx->swapped_buf, |
394 | 85.8k | &ctx->swapped_buf_size, data_size); |
395 | 85.8k | if (!ctx->swapped_buf) { |
396 | 0 | av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n"); |
397 | 0 | return AVERROR(ENOMEM); |
398 | 0 | } |
399 | | |
400 | | /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */ |
401 | 85.8k | ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src, |
402 | 85.8k | data_size / 2); |
403 | | |
404 | 85.8k | if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0) |
405 | 0 | return ret; |
406 | | |
407 | | /* |
408 | | * Read in coding type. The types are as follows: |
409 | | * |
410 | | * 0 - YUY2 |
411 | | * 1 - BGR24 (Triples) |
412 | | * 2 - BGR24 (Quads) |
413 | | * 3 - BGRA |
414 | | */ |
415 | 85.8k | coding_type = (AV_RL32(src) >> 8) & 0xFF; |
416 | 85.8k | av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type); |
417 | | |
418 | 85.8k | if(get_bits_left(&gb) < avctx->height * avctx->width) |
419 | 35.9k | return AVERROR_INVALIDDATA; |
420 | | |
421 | 49.8k | switch (coding_type) { |
422 | 10.3k | case 0: |
423 | 10.3k | avctx->pix_fmt = AV_PIX_FMT_YUV422P; |
424 | 10.3k | avctx->bits_per_raw_sample = 8; |
425 | | |
426 | 10.3k | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
427 | 7.35k | return ret; |
428 | | |
429 | 3.00k | ret = decode_yuv_frame(ctx, &gb, pic); |
430 | 3.00k | if (ret < 0) |
431 | 1.87k | return ret; |
432 | | |
433 | 1.12k | break; |
434 | 1.37k | case 1: |
435 | 35.8k | case 2: |
436 | 35.8k | avctx->pix_fmt = AV_PIX_FMT_RGB24; |
437 | 35.8k | avctx->bits_per_raw_sample = 8; |
438 | | |
439 | 35.8k | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
440 | 2.58k | return ret; |
441 | | |
442 | 33.3k | ret = decode_rgb24_frame(ctx, &gb, pic); |
443 | 33.3k | if (ret < 0) |
444 | 1.01k | return ret; |
445 | | |
446 | 32.2k | break; |
447 | 32.2k | case 3: |
448 | 2.26k | avctx->pix_fmt = AV_PIX_FMT_ARGB; |
449 | 2.26k | avctx->bits_per_raw_sample = 8; |
450 | | |
451 | 2.26k | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
452 | 382 | return ret; |
453 | | |
454 | 1.88k | ret = decode_argb_frame(ctx, &gb, pic); |
455 | 1.88k | if (ret < 0) |
456 | 829 | return ret; |
457 | | |
458 | 1.05k | break; |
459 | 1.30k | default: |
460 | 1.30k | av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type); |
461 | 1.30k | return AVERROR_INVALIDDATA; |
462 | 49.8k | } |
463 | | |
464 | 34.4k | *got_picture_ptr = 1; |
465 | | |
466 | 34.4k | return avpkt->size; |
467 | 49.8k | } |
468 | | |
469 | | static av_cold int cllc_decode_close(AVCodecContext *avctx) |
470 | 1.73k | { |
471 | 1.73k | CLLCContext *ctx = avctx->priv_data; |
472 | | |
473 | 1.73k | av_freep(&ctx->swapped_buf); |
474 | | |
475 | 1.73k | return 0; |
476 | 1.73k | } |
477 | | |
478 | | static av_cold int cllc_decode_init(AVCodecContext *avctx) |
479 | 1.73k | { |
480 | 1.73k | CLLCContext *ctx = avctx->priv_data; |
481 | | |
482 | | /* Initialize various context values */ |
483 | 1.73k | ctx->avctx = avctx; |
484 | 1.73k | ctx->swapped_buf = NULL; |
485 | 1.73k | ctx->swapped_buf_size = 0; |
486 | | |
487 | 1.73k | ff_bswapdsp_init(&ctx->bdsp); |
488 | | |
489 | 1.73k | return 0; |
490 | 1.73k | } |
491 | | |
492 | | const FFCodec ff_cllc_decoder = { |
493 | | .p.name = "cllc", |
494 | | CODEC_LONG_NAME("Canopus Lossless Codec"), |
495 | | .p.type = AVMEDIA_TYPE_VIDEO, |
496 | | .p.id = AV_CODEC_ID_CLLC, |
497 | | .priv_data_size = sizeof(CLLCContext), |
498 | | .init = cllc_decode_init, |
499 | | FF_CODEC_DECODE_CB(cllc_decode_frame), |
500 | | .close = cllc_decode_close, |
501 | | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, |
502 | | }; |