00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "libavutil/intreadwrite.h"
00024 #include "dsputil.h"
00025 #include "get_bits.h"
00026 #include "avcodec.h"
00027
00028 typedef struct CLLCContext {
00029 DSPContext dsp;
00030 AVCodecContext *avctx;
00031
00032 uint8_t *swapped_buf;
00033 int swapped_buf_size;
00034 } CLLCContext;
00035
00036 static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc)
00037 {
00038 uint8_t symbols[256];
00039 uint8_t bits[256];
00040 uint16_t codes[256];
00041 int num_lens, num_codes, num_codes_sum, prefix;
00042 int i, j, count;
00043
00044 prefix = 0;
00045 count = 0;
00046 num_codes_sum = 0;
00047
00048 num_lens = get_bits(gb, 5);
00049
00050 for (i = 0; i < num_lens; i++) {
00051 num_codes = get_bits(gb, 9);
00052 num_codes_sum += num_codes;
00053
00054 if (num_codes_sum > 256) {
00055 vlc->table = NULL;
00056
00057 av_log(ctx->avctx, AV_LOG_ERROR,
00058 "Too many VLCs (%d) to be read.\n", num_codes_sum);
00059 return AVERROR_INVALIDDATA;
00060 }
00061
00062 for (j = 0; j < num_codes; j++) {
00063 symbols[count] = get_bits(gb, 8);
00064 bits[count] = i + 1;
00065 codes[count] = prefix++;
00066
00067 count++;
00068 }
00069
00070 prefix <<= 1;
00071 }
00072
00073 return ff_init_vlc_sparse(vlc, 7, count, bits, 1, 1,
00074 codes, 2, 2, symbols, 1, 1, 0);
00075 }
00076
00077
00078
00079
00080
00081 static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
00082 VLC *vlc, uint8_t *outbuf)
00083 {
00084 uint8_t *dst;
00085 int pred[4];
00086 int code;
00087 int i;
00088
00089 OPEN_READER(bits, gb);
00090
00091 dst = outbuf;
00092 pred[0] = top_left[0];
00093 pred[1] = top_left[1];
00094 pred[2] = top_left[2];
00095 pred[3] = top_left[3];
00096
00097 for (i = 0; i < ctx->avctx->width; i++) {
00098
00099 UPDATE_CACHE(bits, gb);
00100 GET_VLC(code, bits, gb, vlc[0].table, 7, 2);
00101
00102 pred[0] += code;
00103 dst[0] = pred[0];
00104
00105
00106 if (dst[0]) {
00107
00108 UPDATE_CACHE(bits, gb);
00109 GET_VLC(code, bits, gb, vlc[1].table, 7, 2);
00110
00111 pred[1] += code;
00112 dst[1] = pred[1];
00113
00114
00115 UPDATE_CACHE(bits, gb);
00116 GET_VLC(code, bits, gb, vlc[2].table, 7, 2);
00117
00118 pred[2] += code;
00119 dst[2] = pred[2];
00120
00121
00122 UPDATE_CACHE(bits, gb);
00123 GET_VLC(code, bits, gb, vlc[3].table, 7, 2);
00124
00125 pred[3] += code;
00126 dst[3] = pred[3];
00127 } else {
00128 dst[1] = 0;
00129 dst[2] = 0;
00130 dst[3] = 0;
00131 }
00132
00133 dst += 4;
00134 }
00135
00136 CLOSE_READER(bits, gb);
00137
00138 dst -= 4 * ctx->avctx->width;
00139 top_left[0] = dst[0];
00140
00141
00142 if (top_left[0]) {
00143 top_left[1] = dst[1];
00144 top_left[2] = dst[2];
00145 top_left[3] = dst[3];
00146 }
00147
00148 return 0;
00149 }
00150
00151 static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
00152 int *top_left, VLC *vlc, uint8_t *outbuf)
00153 {
00154 uint8_t *dst;
00155 int pred, code;
00156 int i;
00157
00158 OPEN_READER(bits, gb);
00159
00160 dst = outbuf;
00161 pred = *top_left;
00162
00163
00164 for (i = 0; i < ctx->avctx->width; i++) {
00165 UPDATE_CACHE(bits, gb);
00166 GET_VLC(code, bits, gb, vlc->table, 7, 2);
00167
00168 pred += code;
00169 dst[0] = pred;
00170 dst += 3;
00171 }
00172
00173 CLOSE_READER(bits, gb);
00174
00175
00176 *top_left = dst[-3 * ctx->avctx->width];
00177
00178 return 0;
00179 }
00180
00181 static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
00182 {
00183 AVCodecContext *avctx = ctx->avctx;
00184 uint8_t *dst;
00185 int pred[4];
00186 int ret;
00187 int i, j;
00188 VLC vlc[4];
00189
00190 pred[0] = 0;
00191 pred[1] = 0x80;
00192 pred[2] = 0x80;
00193 pred[3] = 0x80;
00194
00195 dst = pic->data[0];
00196
00197 skip_bits(gb, 16);
00198
00199
00200 for (i = 0; i < 4; i++) {
00201 ret = read_code_table(ctx, gb, &vlc[i]);
00202 if (ret < 0) {
00203 for (j = 0; j <= i; j++)
00204 ff_free_vlc(&vlc[j]);
00205
00206 av_log(ctx->avctx, AV_LOG_ERROR,
00207 "Could not read code table %d.\n", i);
00208 return ret;
00209 }
00210 }
00211
00212
00213 for (i = 0; i < avctx->height; i++) {
00214 read_argb_line(ctx, gb, pred, vlc, dst);
00215
00216 dst += pic->linesize[0];
00217 }
00218
00219 for (i = 0; i < 4; i++)
00220 ff_free_vlc(&vlc[i]);
00221
00222 return 0;
00223 }
00224
00225 static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
00226 {
00227 AVCodecContext *avctx = ctx->avctx;
00228 uint8_t *dst;
00229 int pred[3];
00230 int ret;
00231 int i, j;
00232 VLC vlc[3];
00233
00234 pred[0] = 0x80;
00235 pred[1] = 0x80;
00236 pred[2] = 0x80;
00237
00238 dst = pic->data[0];
00239
00240 skip_bits(gb, 16);
00241
00242
00243 for (i = 0; i < 3; i++) {
00244 ret = read_code_table(ctx, gb, &vlc[i]);
00245 if (ret < 0) {
00246 for (j = 0; j <= i; j++)
00247 ff_free_vlc(&vlc[j]);
00248
00249 av_log(ctx->avctx, AV_LOG_ERROR,
00250 "Could not read code table %d.\n", i);
00251 return ret;
00252 }
00253 }
00254
00255
00256 for (i = 0; i < avctx->height; i++) {
00257 for (j = 0; j < 3; j++)
00258 read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
00259
00260 dst += pic->linesize[0];
00261 }
00262
00263 for (i = 0; i < 3; i++)
00264 ff_free_vlc(&vlc[i]);
00265
00266 return 0;
00267 }
00268
00269 static int cllc_decode_frame(AVCodecContext *avctx, void *data,
00270 int *got_picture_ptr, AVPacket *avpkt)
00271 {
00272 CLLCContext *ctx = avctx->priv_data;
00273 AVFrame *pic = avctx->coded_frame;
00274 uint8_t *src = avpkt->data;
00275 uint32_t info_tag, info_offset;
00276 int data_size;
00277 GetBitContext gb;
00278 int coding_type, ret;
00279
00280 if (pic->data[0])
00281 avctx->release_buffer(avctx, pic);
00282
00283 pic->reference = 0;
00284
00285
00286 info_offset = 0;
00287 info_tag = AV_RL32(src);
00288 if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
00289 info_offset = AV_RL32(src + 4);
00290 if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
00291 av_log(avctx, AV_LOG_ERROR,
00292 "Invalid INFO header offset: 0x%08X is too large.\n",
00293 info_offset);
00294 return AVERROR_INVALIDDATA;
00295 }
00296
00297 info_offset += 8;
00298 src += info_offset;
00299
00300 av_log(avctx, AV_LOG_DEBUG, "Skipping INFO chunk.\n");
00301 }
00302
00303 data_size = (avpkt->size - info_offset) & ~1;
00304
00305
00306 av_fast_padded_malloc(&ctx->swapped_buf,
00307 &ctx->swapped_buf_size, data_size);
00308 if (!ctx->swapped_buf) {
00309 av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
00310 return AVERROR(ENOMEM);
00311 }
00312
00313
00314 ctx->dsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
00315 data_size / 2);
00316
00317 init_get_bits(&gb, ctx->swapped_buf, data_size * 8);
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 coding_type = (AV_RL32(src) >> 8) & 0xFF;
00328 av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
00329
00330 switch (coding_type) {
00331 case 1:
00332 case 2:
00333 avctx->pix_fmt = PIX_FMT_RGB24;
00334 avctx->bits_per_raw_sample = 8;
00335
00336 ret = avctx->get_buffer(avctx, pic);
00337 if (ret < 0) {
00338 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
00339 return ret;
00340 }
00341
00342 ret = decode_rgb24_frame(ctx, &gb, pic);
00343 if (ret < 0)
00344 return ret;
00345
00346 break;
00347 case 3:
00348 avctx->pix_fmt = PIX_FMT_ARGB;
00349 avctx->bits_per_raw_sample = 8;
00350
00351 ret = avctx->get_buffer(avctx, pic);
00352 if (ret < 0) {
00353 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
00354 return ret;
00355 }
00356
00357 ret = decode_argb_frame(ctx, &gb, pic);
00358 if (ret < 0)
00359 return ret;
00360
00361 break;
00362 default:
00363 av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
00364 return AVERROR_INVALIDDATA;
00365 }
00366
00367 pic->key_frame = 1;
00368 pic->pict_type = AV_PICTURE_TYPE_I;
00369
00370 *got_picture_ptr = 1;
00371 *(AVFrame *)data = *pic;
00372
00373 return avpkt->size;
00374 }
00375
00376 static av_cold int cllc_decode_close(AVCodecContext *avctx)
00377 {
00378 CLLCContext *ctx = avctx->priv_data;
00379
00380 if (avctx->coded_frame->data[0])
00381 avctx->release_buffer(avctx, avctx->coded_frame);
00382
00383 av_freep(&avctx->coded_frame);
00384 av_freep(&ctx->swapped_buf);
00385
00386 return 0;
00387 }
00388
00389 static av_cold int cllc_decode_init(AVCodecContext *avctx)
00390 {
00391 CLLCContext *ctx = avctx->priv_data;
00392
00393
00394 ctx->avctx = avctx;
00395 ctx->swapped_buf = NULL;
00396 ctx->swapped_buf_size = 0;
00397
00398 ff_dsputil_init(&ctx->dsp, avctx);
00399
00400 avctx->coded_frame = avcodec_alloc_frame();
00401 if (!avctx->coded_frame) {
00402 av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
00403 return AVERROR(ENOMEM);
00404 }
00405
00406 return 0;
00407 }
00408
00409 AVCodec ff_cllc_decoder = {
00410 .name = "cllc",
00411 .type = AVMEDIA_TYPE_VIDEO,
00412 .id = AV_CODEC_ID_CLLC,
00413 .priv_data_size = sizeof(CLLCContext),
00414 .init = cllc_decode_init,
00415 .decode = cllc_decode_frame,
00416 .close = cllc_decode_close,
00417 .capabilities = CODEC_CAP_DR1,
00418 .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
00419 };