00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #define BITSTREAM_READER_LE
00028 #include "libavutil/attributes.h"
00029 #include "avcodec.h"
00030 #include "get_bits.h"
00031 #include "indeo2data.h"
00032 #include "mathops.h"
00033
00034 typedef struct Ir2Context{
00035 AVCodecContext *avctx;
00036 AVFrame picture;
00037 GetBitContext gb;
00038 int decode_delta;
00039 } Ir2Context;
00040
00041 #define CODE_VLC_BITS 14
00042 static VLC ir2_vlc;
00043
00044
00045 static inline int ir2_get_code(GetBitContext *gb)
00046 {
00047 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
00048 }
00049
00050 static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
00051 const uint8_t *table)
00052 {
00053 int i;
00054 int j;
00055 int out = 0;
00056 int c;
00057 int t;
00058
00059 if(width&1)
00060 return -1;
00061
00062
00063 while (out < width){
00064 c = ir2_get_code(&ctx->gb);
00065 if(c >= 0x80) {
00066 c -= 0x7F;
00067 if(out + c*2 > width)
00068 return -1;
00069 for (i = 0; i < c * 2; i++)
00070 dst[out++] = 0x80;
00071 } else {
00072 dst[out++] = table[c * 2];
00073 dst[out++] = table[(c * 2) + 1];
00074 }
00075 }
00076 dst += stride;
00077
00078 for (j = 1; j < height; j++){
00079 out = 0;
00080 while (out < width){
00081 c = ir2_get_code(&ctx->gb);
00082 if(c >= 0x80) {
00083 c -= 0x7F;
00084 if(out + c*2 > width)
00085 return -1;
00086 for (i = 0; i < c * 2; i++) {
00087 dst[out] = dst[out - stride];
00088 out++;
00089 }
00090 } else {
00091 t = dst[out - stride] + (table[c * 2] - 128);
00092 t= av_clip_uint8(t);
00093 dst[out] = t;
00094 out++;
00095 t = dst[out - stride] + (table[(c * 2) + 1] - 128);
00096 t= av_clip_uint8(t);
00097 dst[out] = t;
00098 out++;
00099 }
00100 }
00101 dst += stride;
00102 }
00103 return 0;
00104 }
00105
00106 static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
00107 const uint8_t *table)
00108 {
00109 int j;
00110 int out = 0;
00111 int c;
00112 int t;
00113
00114 if(width&1)
00115 return -1;
00116
00117 for (j = 0; j < height; j++){
00118 out = 0;
00119 while (out < width){
00120 c = ir2_get_code(&ctx->gb);
00121 if(c >= 0x80) {
00122 c -= 0x7F;
00123 out += c * 2;
00124 } else {
00125 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
00126 t= av_clip_uint8(t);
00127 dst[out] = t;
00128 out++;
00129 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
00130 t= av_clip_uint8(t);
00131 dst[out] = t;
00132 out++;
00133 }
00134 }
00135 dst += stride;
00136 }
00137 return 0;
00138 }
00139
00140 static int ir2_decode_frame(AVCodecContext *avctx,
00141 void *data, int *got_frame,
00142 AVPacket *avpkt)
00143 {
00144 const uint8_t *buf = avpkt->data;
00145 int buf_size = avpkt->size;
00146 Ir2Context * const s = avctx->priv_data;
00147 AVFrame *picture = data;
00148 AVFrame * const p = &s->picture;
00149 int start;
00150
00151 p->reference = 3;
00152 p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00153 if (avctx->reget_buffer(avctx, p)) {
00154 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00155 return -1;
00156 }
00157
00158 start = 48;
00159
00160 if (start >= buf_size) {
00161 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
00162 return AVERROR_INVALIDDATA;
00163 }
00164
00165 s->decode_delta = buf[18];
00166
00167
00168 #ifndef BITSTREAM_READER_LE
00169 for (i = 0; i < buf_size; i++)
00170 buf[i] = ff_reverse[buf[i]];
00171 #endif
00172
00173 init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
00174
00175 if (s->decode_delta) {
00176 ir2_decode_plane(s, avctx->width, avctx->height,
00177 s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
00178
00179 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
00180 s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
00181 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
00182 s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
00183 } else {
00184 ir2_decode_plane_inter(s, avctx->width, avctx->height,
00185 s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
00186
00187 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
00188 s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
00189 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
00190 s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
00191 }
00192
00193 *picture = s->picture;
00194 *got_frame = 1;
00195
00196 return buf_size;
00197 }
00198
00199 static av_cold int ir2_decode_init(AVCodecContext *avctx){
00200 Ir2Context * const ic = avctx->priv_data;
00201 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
00202
00203 avcodec_get_frame_defaults(&ic->picture);
00204 ic->avctx = avctx;
00205
00206 avctx->pix_fmt= AV_PIX_FMT_YUV410P;
00207
00208 ir2_vlc.table = vlc_tables;
00209 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
00210 #ifdef BITSTREAM_READER_LE
00211 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
00212 &ir2_codes[0][1], 4, 2,
00213 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
00214 #else
00215 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
00216 &ir2_codes[0][1], 4, 2,
00217 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
00218 #endif
00219
00220 return 0;
00221 }
00222
00223 static av_cold int ir2_decode_end(AVCodecContext *avctx){
00224 Ir2Context * const ic = avctx->priv_data;
00225 AVFrame *pic = &ic->picture;
00226
00227 if (pic->data[0])
00228 avctx->release_buffer(avctx, pic);
00229
00230 return 0;
00231 }
00232
00233 AVCodec ff_indeo2_decoder = {
00234 .name = "indeo2",
00235 .type = AVMEDIA_TYPE_VIDEO,
00236 .id = AV_CODEC_ID_INDEO2,
00237 .priv_data_size = sizeof(Ir2Context),
00238 .init = ir2_decode_init,
00239 .close = ir2_decode_end,
00240 .decode = ir2_decode_frame,
00241 .capabilities = CODEC_CAP_DR1,
00242 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
00243 };