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