indeo2.c 6.5 KB
Newer Older
1
/*
D
Diego Biurrun 已提交
2
 * Intel Indeo 2 codec
3 4
 * Copyright (c) 2005 Konstantin Shishkov
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22 23 24 25
/**
 * @file indeo2.c
 * Intel Indeo 2 decoder.
 */
26
#define ALT_BITSTREAM_READER_LE
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include "avcodec.h"
#include "bitstream.h"
#include "indeo2data.h"

typedef struct Ir2Context{
    AVCodecContext *avctx;
    AVFrame picture;
    GetBitContext gb;
    int decode_delta;
} Ir2Context;

#define CODE_VLC_BITS 14
static VLC ir2_vlc;

/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */
static inline int ir2_get_code(GetBitContext *gb)
{
M
Michael Niedermayer 已提交
44
    return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
45 46
}

M
Michael Niedermayer 已提交
47
static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
48 49 50 51 52 53 54
                             const uint8_t *table)
{
    int i;
    int j;
    int out = 0;
    int c;
    int t;
55

M
Michael Niedermayer 已提交
56 57 58
    if(width&1)
        return -1;

59 60 61
    /* first line contain absolute values, other lines contain deltas */
    while (out < width){
        c = ir2_get_code(&ctx->gb);
M
Michael Niedermayer 已提交
62 63
        if(c >= 0x80) { /* we have a run */
            c -= 0x7F;
M
Michael Niedermayer 已提交
64 65
            if(out + c*2 > width)
                return -1;
66 67 68 69 70 71 72 73
            for (i = 0; i < c * 2; i++)
                dst[out++] = 0x80;
        } else { /* copy two values from table */
            dst[out++] = table[c * 2];
            dst[out++] = table[(c * 2) + 1];
        }
    }
    dst += stride;
74

75 76 77 78
    for (j = 1; j < height; j++){
        out = 0;
        while (out < width){
            c = ir2_get_code(&ctx->gb);
M
Michael Niedermayer 已提交
79 80
            if(c >= 0x80) { /* we have a skip */
                c -= 0x7F;
M
Michael Niedermayer 已提交
81 82
                if(out + c*2 > width)
                    return -1;
83 84 85 86 87 88
                for (i = 0; i < c * 2; i++) {
                    dst[out] = dst[out - stride];
                    out++;
                }
            } else { /* add two deltas from table */
                t = dst[out - stride] + (table[c * 2] - 128);
89
                t= av_clip_uint8(t);
90 91 92
                dst[out] = t;
                out++;
                t = dst[out - stride] + (table[(c * 2) + 1] - 128);
93
                t= av_clip_uint8(t);
94 95 96 97 98 99
                dst[out] = t;
                out++;
            }
        }
        dst += stride;
    }
M
Michael Niedermayer 已提交
100
    return 0;
101 102
}

M
Michael Niedermayer 已提交
103
static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
104 105 106 107 108 109
                             const uint8_t *table)
{
    int j;
    int out = 0;
    int c;
    int t;
M
Michael Niedermayer 已提交
110 111 112 113

    if(width&1)
        return -1;

114 115 116 117
    for (j = 0; j < height; j++){
        out = 0;
        while (out < width){
            c = ir2_get_code(&ctx->gb);
M
Michael Niedermayer 已提交
118 119
            if(c >= 0x80) { /* we have a skip */
                c -= 0x7F;
120 121
                out += c * 2;
            } else { /* add two deltas from table */
122
                t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
123
                t= av_clip_uint8(t);
124 125
                dst[out] = t;
                out++;
126
                t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
127
                t= av_clip_uint8(t);
128 129 130 131 132 133
                dst[out] = t;
                out++;
            }
        }
        dst += stride;
    }
M
Michael Niedermayer 已提交
134
    return 0;
135 136
}

137
static int ir2_decode_frame(AVCodecContext *avctx,
138
                        void *data, int *data_size,
M
consts  
Michael Niedermayer 已提交
139
                        const uint8_t *buf, int buf_size)
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
{
    Ir2Context * const s = avctx->priv_data;
    AVFrame *picture = data;
    AVFrame * const p= (AVFrame*)&s->picture;
    int start;

    if(p->data[0])
        avctx->release_buffer(avctx, p);

    p->reference = 1;
    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
    if (avctx->reget_buffer(avctx, p)) {
        av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
        return -1;
    }

    s->decode_delta = buf[18];
157

158
    /* decide whether frame uses deltas or not */
159
#ifndef ALT_BITSTREAM_READER_LE
160 161
    for (i = 0; i < buf_size; i++)
        buf[i] = ff_reverse[buf[i]];
162
#endif
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
    start = 48; /* hardcoded for now */

    init_get_bits(&s->gb, buf + start, buf_size - start);

    if (s->decode_delta) { /* intraframe */
        ir2_decode_plane(s, avctx->width, avctx->height,
                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
        /* swapped U and V */
        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
    } else { /* interframe */
        ir2_decode_plane_inter(s, avctx->width, avctx->height,
                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
        /* swapped U and V */
        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
    }

    *picture= *(AVFrame*)&s->picture;
    *data_size = sizeof(AVPicture);

    return buf_size;
}

static int ir2_decode_init(AVCodecContext *avctx){
    Ir2Context * const ic = avctx->priv_data;

    ic->avctx = avctx;

    avctx->pix_fmt= PIX_FMT_YUV410P;
197

198
    if (!ir2_vlc.table)
199
#ifdef ALT_BITSTREAM_READER_LE
200 201
        init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
                 &ir2_codes[0][1], 4, 2,
202
                 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);
203
#else
204 205
        init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
                 &ir2_codes[0][1], 4, 2,
206
                 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC);
207
#endif
208

209 210 211 212 213 214 215 216 217 218 219 220 221 222
    return 0;
}

AVCodec indeo2_decoder = {
    "indeo2",
    CODEC_TYPE_VIDEO,
    CODEC_ID_INDEO2,
    sizeof(Ir2Context),
    ir2_decode_init,
    NULL,
    NULL,
    ir2_decode_frame,
    CODEC_CAP_DR1,
};