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 "bitstream.h"
00029 #include "indeo2data.h"
00030
00031 typedef struct Ir2Context{
00032 AVCodecContext *avctx;
00033 AVFrame picture;
00034 GetBitContext gb;
00035 int decode_delta;
00036 } Ir2Context;
00037
00038 #define CODE_VLC_BITS 14
00039 static VLC ir2_vlc;
00040
00041
00042 static inline int ir2_get_code(GetBitContext *gb)
00043 {
00044 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
00045 }
00046
00047 static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
00048 const uint8_t *table)
00049 {
00050 int i;
00051 int j;
00052 int out = 0;
00053 int c;
00054 int t;
00055
00056 if(width&1)
00057 return -1;
00058
00059
00060 while (out < width){
00061 c = ir2_get_code(&ctx->gb);
00062 if(c >= 0x80) {
00063 c -= 0x7F;
00064 if(out + c*2 > width)
00065 return -1;
00066 for (i = 0; i < c * 2; i++)
00067 dst[out++] = 0x80;
00068 } else {
00069 dst[out++] = table[c * 2];
00070 dst[out++] = table[(c * 2) + 1];
00071 }
00072 }
00073 dst += stride;
00074
00075 for (j = 1; j < height; j++){
00076 out = 0;
00077 while (out < width){
00078 c = ir2_get_code(&ctx->gb);
00079 if(c >= 0x80) {
00080 c -= 0x7F;
00081 if(out + c*2 > width)
00082 return -1;
00083 for (i = 0; i < c * 2; i++) {
00084 dst[out] = dst[out - stride];
00085 out++;
00086 }
00087 } else {
00088 t = dst[out - stride] + (table[c * 2] - 128);
00089 t= av_clip_uint8(t);
00090 dst[out] = t;
00091 out++;
00092 t = dst[out - stride] + (table[(c * 2) + 1] - 128);
00093 t= av_clip_uint8(t);
00094 dst[out] = t;
00095 out++;
00096 }
00097 }
00098 dst += stride;
00099 }
00100 return 0;
00101 }
00102
00103 static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
00104 const uint8_t *table)
00105 {
00106 int j;
00107 int out = 0;
00108 int c;
00109 int t;
00110
00111 if(width&1)
00112 return -1;
00113
00114 for (j = 0; j < height; j++){
00115 out = 0;
00116 while (out < width){
00117 c = ir2_get_code(&ctx->gb);
00118 if(c >= 0x80) {
00119 c -= 0x7F;
00120 out += c * 2;
00121 } else {
00122 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
00123 t= av_clip_uint8(t);
00124 dst[out] = t;
00125 out++;
00126 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
00127 t= av_clip_uint8(t);
00128 dst[out] = t;
00129 out++;
00130 }
00131 }
00132 dst += stride;
00133 }
00134 return 0;
00135 }
00136
00137 static int ir2_decode_frame(AVCodecContext *avctx,
00138 void *data, int *data_size,
00139 const uint8_t *buf, int buf_size)
00140 {
00141 Ir2Context * const s = avctx->priv_data;
00142 AVFrame *picture = data;
00143 AVFrame * const p= (AVFrame*)&s->picture;
00144 int start;
00145
00146 if(p->data[0])
00147 avctx->release_buffer(avctx, p);
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] = ff_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
00200 ic->avctx = avctx;
00201
00202 avctx->pix_fmt= PIX_FMT_YUV410P;
00203
00204 if (!ir2_vlc.table)
00205 #ifdef ALT_BITSTREAM_READER_LE
00206 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
00207 &ir2_codes[0][1], 4, 2,
00208 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);
00209 #else
00210 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
00211 &ir2_codes[0][1], 4, 2,
00212 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC);
00213 #endif
00214
00215 return 0;
00216 }
00217
00218 AVCodec indeo2_decoder = {
00219 "indeo2",
00220 CODEC_TYPE_VIDEO,
00221 CODEC_ID_INDEO2,
00222 sizeof(Ir2Context),
00223 ir2_decode_init,
00224 NULL,
00225 NULL,
00226 ir2_decode_frame,
00227 CODEC_CAP_DR1,
00228 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
00229 };