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 if(p->data[0])
00150 avctx->release_buffer(avctx, p);
00151
00152 p->reference = 1;
00153 p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00154 if (avctx->reget_buffer(avctx, p)) {
00155 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00156 return -1;
00157 }
00158
00159 start = 48;
00160
00161 if (start >= buf_size) {
00162 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
00163 return AVERROR_INVALIDDATA;
00164 }
00165
00166 s->decode_delta = buf[18];
00167
00168
00169 #ifndef ALT_BITSTREAM_READER_LE
00170 for (i = 0; i < buf_size; i++)
00171 buf[i] = av_reverse[buf[i]];
00172 #endif
00173
00174 init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
00175
00176 if (s->decode_delta) {
00177 ir2_decode_plane(s, avctx->width, avctx->height,
00178 s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
00179
00180 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
00181 s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
00182 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
00183 s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
00184 } else {
00185 ir2_decode_plane_inter(s, avctx->width, avctx->height,
00186 s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
00187
00188 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
00189 s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
00190 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
00191 s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
00192 }
00193
00194 *picture= *(AVFrame*)&s->picture;
00195 *data_size = sizeof(AVPicture);
00196
00197 return buf_size;
00198 }
00199
00200 static av_cold int ir2_decode_init(AVCodecContext *avctx){
00201 Ir2Context * const ic = avctx->priv_data;
00202 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
00203
00204 ic->avctx = avctx;
00205
00206 avctx->pix_fmt= PIX_FMT_YUV410P;
00207
00208 ir2_vlc.table = vlc_tables;
00209 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
00210 #ifdef ALT_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 indeo2_decoder = {
00234 "indeo2",
00235 AVMEDIA_TYPE_VIDEO,
00236 CODEC_ID_INDEO2,
00237 sizeof(Ir2Context),
00238 ir2_decode_init,
00239 NULL,
00240 ir2_decode_end,
00241 ir2_decode_frame,
00242 CODEC_CAP_DR1,
00243 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
00244 };