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 };