]> git.sesse.net Git - ffmpeg/blob - libavcodec/cllc.c
Canopus Lossless decoder
[ffmpeg] / libavcodec / cllc.c
1 /*
2  * Canopus Lossless Codec decoder
3  *
4  * Copyright (c) 2012 Derek Buitenhuis
5  *
6  * This file is part of Libav.
7  *
8  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavutil/intreadwrite.h"
24 #include "dsputil.h"
25 #include "get_bits.h"
26 #include "avcodec.h"
27
28 typedef struct CLLCContext {
29     DSPContext dsp;
30     AVCodecContext *avctx;
31
32     uint8_t *swapped_buf;
33     int      swapped_buf_size;
34 } CLLCContext;
35
36 static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc)
37 {
38     uint8_t symbols[256];
39     uint8_t bits[256];
40     uint16_t codes[256];
41     int num_lens, num_codes, num_codes_sum, prefix;
42     int i, j, count;
43
44     prefix        = 0;
45     count         = 0;
46     num_codes_sum = 0;
47
48     num_lens = get_bits(gb, 5);
49
50     for (i = 0; i < num_lens; i++) {
51         num_codes      = get_bits(gb, 9);
52         num_codes_sum += num_codes;
53
54         if (num_codes_sum > 256) {
55             vlc->table = NULL;
56
57             av_log(ctx->avctx, AV_LOG_ERROR,
58                    "Too many VLCs (%d) to be read.\n", num_codes_sum);
59             return AVERROR_INVALIDDATA;
60         }
61
62         for (j = 0; j < num_codes; j++) {
63             symbols[count] = get_bits(gb, 8);
64             bits[count]    = i + 1;
65             codes[count]   = prefix++;
66
67             count++;
68         }
69
70         prefix <<= 1;
71     }
72
73     return ff_init_vlc_sparse(vlc, 7, count, bits, 1, 1,
74                               codes, 2, 2, symbols, 1, 1, 0);
75 }
76
77 static int read_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
78                      VLC *vlc, uint8_t *outbuf)
79 {
80     uint8_t *dst;
81     int pred, code;
82     int i;
83
84     OPEN_READER(bits, gb);
85
86     dst  = outbuf;
87     pred = *top_left;
88
89     /* Simultaneously read and restore the line */
90     for (i = 0; i < ctx->avctx->width; i++) {
91         UPDATE_CACHE(bits, gb);
92         GET_VLC(code, bits, gb, vlc->table, 7, 2);
93
94         pred  += code;
95         dst[0] = pred;
96         dst   += 3;
97     }
98
99     CLOSE_READER(bits, gb);
100
101     /* Stash the first pixel */
102     *top_left = dst[-3 * ctx->avctx->width];
103
104     return 0;
105 }
106
107 static int decode_bgr24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
108 {
109     AVCodecContext *avctx = ctx->avctx;
110     uint8_t *dst;
111     int pred[3];
112     int ret;
113     int i, j;
114     VLC vlc[3];
115
116     pred[0] = 0x80;
117     pred[1] = 0x80;
118     pred[2] = 0x80;
119
120     dst = pic->data[0];
121
122     skip_bits(gb, 16);
123
124     /* Read in code table for each plane */
125     for (i = 0; i < 3; i++) {
126         ret = read_code_table(ctx, gb, &vlc[i]);
127         if (ret < 0) {
128             for (j = 0; j <= i; j++)
129                 ff_free_vlc(&vlc[j]);
130
131             av_log(ctx->avctx, AV_LOG_ERROR,
132                    "Could not read code table %d.\n", i);
133             return ret;
134         }
135     }
136
137     /* Read in and restore every line */
138     for (i = 0; i < avctx->height; i++) {
139         for (j = 0; j < 3; j++)
140             read_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
141
142         dst += pic->linesize[0];
143     }
144
145     for (i = 0; i < 3; i++)
146         ff_free_vlc(&vlc[i]);
147
148     return 0;
149 }
150
151 static int cllc_decode_frame(AVCodecContext *avctx, void *data,
152                              int *got_picture_ptr, AVPacket *avpkt)
153 {
154     CLLCContext *ctx = avctx->priv_data;
155     AVFrame *pic = avctx->coded_frame;
156     uint8_t *src = avpkt->data;
157     uint8_t *swapped_buf_new;
158     uint32_t info_tag, info_offset;
159     GetBitContext gb;
160     int coding_type, ret;
161
162     if (pic->data[0])
163         avctx->release_buffer(avctx, pic);
164
165     pic->reference = 0;
166
167     /* Make sure our bswap16'd buffer is big enough */
168     swapped_buf_new = av_fast_realloc(ctx->swapped_buf,
169                                       &ctx->swapped_buf_size, avpkt->size);
170     if (!swapped_buf_new) {
171         av_log(avctx, AV_LOG_ERROR, "Could not realloc swapped buffer.\n");
172         return AVERROR(ENOMEM);
173     }
174     ctx->swapped_buf = swapped_buf_new;
175
176     /* Skip the INFO header if present */
177     info_offset = 0;
178     info_tag    = AV_RL32(src);
179     if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
180         info_offset = AV_RL32(src + 4);
181         if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
182             av_log(avctx, AV_LOG_ERROR,
183                    "Invalid INFO header offset: 0x%08X is too large.\n",
184                    info_offset);
185             return AVERROR_INVALIDDATA;
186         }
187
188         info_offset += 8;
189         src         += info_offset;
190
191         av_log(avctx, AV_LOG_DEBUG, "Skipping INFO chunk.\n");
192     }
193
194     /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
195     ctx->dsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
196                          (avpkt->size - info_offset) / 2);
197
198     init_get_bits(&gb, ctx->swapped_buf, (avpkt->size - info_offset) * 8);
199
200     /*
201      * Read in coding type. The types are as follows:
202      *
203      * 0 - YUY2
204      * 1 - BGR24 (Triples)
205      * 2 - BGR24 (Quads)
206      * 3 - BGRA
207      */
208     coding_type = (AV_RL32(src) >> 8) & 0xFF;
209     av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
210
211     switch (coding_type) {
212     case 1:
213         avctx->pix_fmt             = PIX_FMT_RGB24;
214         avctx->bits_per_raw_sample = 8;
215
216         ret = avctx->get_buffer(avctx, pic);
217         if (ret < 0) {
218             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
219             return ret;
220         }
221
222         ret = decode_bgr24_frame(ctx, &gb, pic);
223         if (ret < 0)
224             return ret;
225
226         break;
227     default:
228         av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d\n.", coding_type);
229         return AVERROR_INVALIDDATA;
230     }
231
232     pic->key_frame = 1;
233     pic->pict_type = AV_PICTURE_TYPE_I;
234
235     *got_picture_ptr = 1;
236     *(AVFrame *)data = *pic;
237
238     return avpkt->size;
239 }
240
241 static av_cold int cllc_decode_close(AVCodecContext *avctx)
242 {
243     CLLCContext *ctx = avctx->priv_data;
244
245     if (avctx->coded_frame->data[0])
246         avctx->release_buffer(avctx, avctx->coded_frame);
247
248     av_freep(&avctx->coded_frame);
249     av_freep(&ctx->swapped_buf);
250
251     return 0;
252 }
253
254 static av_cold int cllc_decode_init(AVCodecContext *avctx)
255 {
256     CLLCContext *ctx = avctx->priv_data;
257
258     /* Initialize various context values */
259     ctx->avctx            = avctx;
260     ctx->swapped_buf      = NULL;
261     ctx->swapped_buf_size = 0;
262
263     ff_dsputil_init(&ctx->dsp, avctx);
264
265     avctx->coded_frame = avcodec_alloc_frame();
266     if (!avctx->coded_frame) {
267         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
268         return AVERROR(ENOMEM);
269     }
270
271     return 0;
272 }
273
274 AVCodec ff_cllc_decoder = {
275     .name           = "cllc",
276     .type           = AVMEDIA_TYPE_VIDEO,
277     .id             = CODEC_ID_CLLC,
278     .priv_data_size = sizeof(CLLCContext),
279     .init           = cllc_decode_init,
280     .decode         = cllc_decode_frame,
281     .close          = cllc_decode_close,
282     .capabilities   = CODEC_CAP_DR1,
283     .long_name      = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
284 };