• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "codec_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 
read_code_table(CLLCContext * ctx,GetBitContext * gb,VLC * vlc)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  */
read_argb_line(CLLCContext * ctx,GetBitContext * gb,int * top_left,VLC * vlc,uint8_t * outbuf)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 
read_rgb24_component_line(CLLCContext * ctx,GetBitContext * gb,int * top_left,VLC * vlc,uint8_t * outbuf)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 
read_yuv_component_line(CLLCContext * ctx,GetBitContext * gb,int * top_left,VLC * vlc,uint8_t * outbuf,int is_chroma)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 
decode_argb_frame(CLLCContext * ctx,GetBitContext * gb,AVFrame * pic)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 
decode_rgb24_frame(CLLCContext * ctx,GetBitContext * gb,AVFrame * pic)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 
decode_yuv_frame(CLLCContext * ctx,GetBitContext * gb,AVFrame * pic)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 
cllc_decode_frame(AVCodecContext * avctx,AVFrame * pic,int * got_picture_ptr,AVPacket * avpkt)358 static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic,
359                              int *got_picture_ptr, AVPacket *avpkt)
360 {
361     CLLCContext *ctx = avctx->priv_data;
362     const uint8_t *src = avpkt->data;
363     uint32_t info_tag, info_offset;
364     int data_size;
365     GetBitContext gb;
366     int coding_type, ret;
367 
368     if (avpkt->size < 4 + 4) {
369         av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
370         return AVERROR_INVALIDDATA;
371     }
372 
373     info_offset = 0;
374     info_tag    = AV_RL32(src);
375     if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
376         info_offset = AV_RL32(src + 4);
377         if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
378             av_log(avctx, AV_LOG_ERROR,
379                    "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
380                    info_offset);
381             return AVERROR_INVALIDDATA;
382         }
383         ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
384 
385         info_offset += 8;
386         src         += info_offset;
387     }
388 
389     data_size = (avpkt->size - info_offset) & ~1;
390 
391     /* Make sure our bswap16'd buffer is big enough */
392     av_fast_padded_malloc(&ctx->swapped_buf,
393                           &ctx->swapped_buf_size, data_size);
394     if (!ctx->swapped_buf) {
395         av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
396         return AVERROR(ENOMEM);
397     }
398 
399     /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
400     ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
401                           data_size / 2);
402 
403     if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
404         return ret;
405 
406     /*
407      * Read in coding type. The types are as follows:
408      *
409      * 0 - YUY2
410      * 1 - BGR24 (Triples)
411      * 2 - BGR24 (Quads)
412      * 3 - BGRA
413      */
414     coding_type = (AV_RL32(src) >> 8) & 0xFF;
415     av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
416 
417     if(get_bits_left(&gb) < avctx->height * avctx->width)
418         return AVERROR_INVALIDDATA;
419 
420     switch (coding_type) {
421     case 0:
422         avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
423         avctx->bits_per_raw_sample = 8;
424 
425         if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
426             return ret;
427 
428         ret = decode_yuv_frame(ctx, &gb, pic);
429         if (ret < 0)
430             return ret;
431 
432         break;
433     case 1:
434     case 2:
435         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
436         avctx->bits_per_raw_sample = 8;
437 
438         if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
439             return ret;
440 
441         ret = decode_rgb24_frame(ctx, &gb, pic);
442         if (ret < 0)
443             return ret;
444 
445         break;
446     case 3:
447         avctx->pix_fmt             = AV_PIX_FMT_ARGB;
448         avctx->bits_per_raw_sample = 8;
449 
450         if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
451             return ret;
452 
453         ret = decode_argb_frame(ctx, &gb, pic);
454         if (ret < 0)
455             return ret;
456 
457         break;
458     default:
459         av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
460         return AVERROR_INVALIDDATA;
461     }
462 
463     pic->key_frame = 1;
464     pic->pict_type = AV_PICTURE_TYPE_I;
465 
466     *got_picture_ptr = 1;
467 
468     return avpkt->size;
469 }
470 
cllc_decode_close(AVCodecContext * avctx)471 static av_cold int cllc_decode_close(AVCodecContext *avctx)
472 {
473     CLLCContext *ctx = avctx->priv_data;
474 
475     av_freep(&ctx->swapped_buf);
476 
477     return 0;
478 }
479 
cllc_decode_init(AVCodecContext * avctx)480 static av_cold int cllc_decode_init(AVCodecContext *avctx)
481 {
482     CLLCContext *ctx = avctx->priv_data;
483 
484     /* Initialize various context values */
485     ctx->avctx            = avctx;
486     ctx->swapped_buf      = NULL;
487     ctx->swapped_buf_size = 0;
488 
489     ff_bswapdsp_init(&ctx->bdsp);
490 
491     return 0;
492 }
493 
494 const FFCodec ff_cllc_decoder = {
495     .p.name         = "cllc",
496     .p.long_name    = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
497     .p.type         = AVMEDIA_TYPE_VIDEO,
498     .p.id           = AV_CODEC_ID_CLLC,
499     .priv_data_size = sizeof(CLLCContext),
500     .init           = cllc_decode_init,
501     FF_CODEC_DECODE_CB(cllc_decode_frame),
502     .close          = cllc_decode_close,
503     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
504     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
505 };
506