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