blob: 39735c2e4b5a1d1b71a16fe5eea15a09c64b6c5f [file] [log] [blame]
Michael Niedermayer856dbbf2005-04-20 09:42:471/*
Diego Biurrun02c15922006-09-15 13:53:262 * Intel Indeo 2 codec
Michael Niedermayer856dbbf2005-04-20 09:42:473 * Copyright (c) 2005 Konstantin Shishkov
4 *
Diego Biurrunb78e7192006-10-07 15:30:465 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
Michael Niedermayer856dbbf2005-04-20 09:42:478 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
Diego Biurrunb78e7192006-10-07 15:30:4610 * version 2.1 of the License, or (at your option) any later version.
Michael Niedermayer856dbbf2005-04-20 09:42:4711 *
Diego Biurrunb78e7192006-10-07 15:30:4612 * FFmpeg is distributed in the hope that it will be useful,
Michael Niedermayer856dbbf2005-04-20 09:42:4713 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
Diego Biurrunb78e7192006-10-07 15:30:4618 * License along with FFmpeg; if not, write to the Free Software
Diego Biurrun5509bff2006-01-12 22:43:2619 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Michael Niedermayer856dbbf2005-04-20 09:42:4720 */
Diego Biurrun115329f2005-12-17 18:14:3821
Michael Niedermayer856dbbf2005-04-20 09:42:4722/**
Diego Biurrunba87f082010-04-20 14:45:3423 * @file
Michael Niedermayer856dbbf2005-04-20 09:42:4724 * Intel Indeo 2 decoder.
25 */
Diego Biurrund5c62122012-10-11 16:50:3026
Diego Biurrunaaf47bc2011-12-22 15:33:3127#define BITSTREAM_READER_LE
Diego Biurrund5c62122012-10-11 16:50:3028#include "libavutil/attributes.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4729#include "avcodec.h"
Stefano Sabatini9106a692009-04-13 16:20:2630#include "get_bits.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4731#include "indeo2data.h"
Anton Khirnov759001c2012-11-21 20:34:4632#include "internal.h"
Diego Biurrund5c62122012-10-11 16:50:3033#include "mathops.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4734
35typedef struct Ir2Context{
36 AVCodecContext *avctx;
Paul B Mahol451b2ca2013-07-26 14:58:4437 AVFrame *picture;
Michael Niedermayer856dbbf2005-04-20 09:42:4738 GetBitContext gb;
39 int decode_delta;
40} Ir2Context;
41
42#define CODE_VLC_BITS 14
43static VLC ir2_vlc;
44
45/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */
46static inline int ir2_get_code(GetBitContext *gb)
47{
Michael Niedermayer8b39f752005-04-20 10:16:1948 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
Michael Niedermayer856dbbf2005-04-20 09:42:4749}
Michael Niedermayer856dbbf2005-04-20 09:42:4750
Anton Khirnovc04c64c2012-11-17 07:11:3051static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:2252 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:4753{
54 int i;
55 int j;
56 int out = 0;
Diego Biurrun115329f2005-12-17 18:14:3857
Anton Khirnovc04c64c2012-11-17 07:11:3058 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:1959 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:0460
Michael Niedermayer856dbbf2005-04-20 09:42:4761 /* first line contain absolute values, other lines contain deltas */
Anton Khirnovc04c64c2012-11-17 07:11:3062 while (out < width) {
Reimar Döffingerc2c27e92014-10-18 13:28:0363 int c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3064 if (c >= 0x80) { /* we have a run */
Michael Niedermayer8b39f752005-04-20 10:16:1965 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3066 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1967 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4768 for (i = 0; i < c * 2; i++)
69 dst[out++] = 0x80;
70 } else { /* copy two values from table */
71 dst[out++] = table[c * 2];
72 dst[out++] = table[(c * 2) + 1];
73 }
74 }
Kostya Shishkov422e14f2014-06-25 18:28:2275 dst += pitch;
Diego Biurrun115329f2005-12-17 18:14:3876
Anton Khirnovc04c64c2012-11-17 07:11:3077 for (j = 1; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:4778 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:3079 while (out < width) {
Reimar Döffingerc2c27e92014-10-18 13:28:0380 int c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3081 if (c >= 0x80) { /* we have a skip */
Michael Niedermayer8b39f752005-04-20 10:16:1982 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3083 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1984 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4785 for (i = 0; i < c * 2; i++) {
Kostya Shishkov422e14f2014-06-25 18:28:2286 dst[out] = dst[out - pitch];
Michael Niedermayer856dbbf2005-04-20 09:42:4787 out++;
88 }
89 } else { /* add two deltas from table */
Reimar Döffingerc2c27e92014-10-18 13:28:0390 int t = dst[out - pitch] + (table[c * 2] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:3091 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:4792 dst[out] = t;
93 out++;
Kostya Shishkov422e14f2014-06-25 18:28:2294 t = dst[out - pitch] + (table[(c * 2) + 1] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:3095 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:4796 dst[out] = t;
97 out++;
98 }
99 }
Kostya Shishkov422e14f2014-06-25 18:28:22100 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47101 }
Michael Niedermayerf707a5e2005-04-20 09:52:04102 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47103}
104
Anton Khirnovc04c64c2012-11-17 07:11:30105static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:22106 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:47107{
108 int j;
109 int out = 0;
110 int c;
111 int t;
Michael Niedermayerf707a5e2005-04-20 09:52:04112
Anton Khirnovc04c64c2012-11-17 07:11:30113 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:19114 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:04115
Anton Khirnovc04c64c2012-11-17 07:11:30116 for (j = 0; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:47117 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:30118 while (out < width) {
Michael Niedermayer856dbbf2005-04-20 09:42:47119 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:30120 if (c >= 0x80) { /* we have a skip */
121 c -= 0x7F;
Michael Niedermayer856dbbf2005-04-20 09:42:47122 out += c * 2;
123 } else { /* add two deltas from table */
Anton Khirnovc04c64c2012-11-17 07:11:30124 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
125 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47126 dst[out] = t;
127 out++;
Anton Khirnovc04c64c2012-11-17 07:11:30128 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
129 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47130 dst[out] = t;
131 out++;
132 }
133 }
Kostya Shishkov422e14f2014-06-25 18:28:22134 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47135 }
Michael Niedermayerf707a5e2005-04-20 09:52:04136 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47137}
138
Diego Biurrun115329f2005-12-17 18:14:38139static int ir2_decode_frame(AVCodecContext *avctx,
Anton Khirnovdf9b9562012-11-13 18:35:22140 void *data, int *got_frame,
Thilo Borgmann7a00bba2009-04-07 15:59:50141 AVPacket *avpkt)
Michael Niedermayer856dbbf2005-04-20 09:42:47142{
143 Ir2Context * const s = avctx->priv_data;
Anton Khirnovc04c64c2012-11-17 07:11:30144 const uint8_t *buf = avpkt->data;
145 int buf_size = avpkt->size;
146 AVFrame *picture = data;
Paul B Mahol451b2ca2013-07-26 14:58:44147 AVFrame * const p = s->picture;
Anton Khirnov6ea2c9a2012-11-17 07:06:19148 int start, ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47149
Clément Bœsch1ec94b02013-03-12 07:41:53150 if ((ret = ff_reget_buffer(avctx, p)) < 0)
Anton Khirnov6ea2c9a2012-11-17 07:06:19151 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47152
Alex Converseb7ce4f12011-09-09 20:26:49153 start = 48; /* hardcoded for now */
154
155 if (start >= buf_size) {
156 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
157 return AVERROR_INVALIDDATA;
158 }
159
Michael Niedermayer856dbbf2005-04-20 09:42:47160 s->decode_delta = buf[18];
Diego Biurrun115329f2005-12-17 18:14:38161
Michael Niedermayer856dbbf2005-04-20 09:42:47162 /* decide whether frame uses deltas or not */
Diego Biurrunaaf47bc2011-12-22 15:33:31163#ifndef BITSTREAM_READER_LE
Michael Niedermayer856dbbf2005-04-20 09:42:47164 for (i = 0; i < buf_size; i++)
Diego Biurrund5c62122012-10-11 16:50:30165 buf[i] = ff_reverse[buf[i]];
Michael Niedermayeref56de32005-05-11 01:50:46166#endif
Michael Niedermayer856dbbf2005-04-20 09:42:47167
Alex Converse68ca3302011-09-09 20:24:19168 init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
Michael Niedermayer856dbbf2005-04-20 09:42:47169
170 if (s->decode_delta) { /* intraframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40171 if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46172 p->data[0], p->linesize[0],
Anton Khirnov7b1fbd42012-11-17 07:08:40173 ir2_luma_table)) < 0)
174 return ret;
175
Michael Niedermayer856dbbf2005-04-20 09:42:47176 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40177 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46178 p->data[2], p->linesize[2],
Anton Khirnov7b1fbd42012-11-17 07:08:40179 ir2_luma_table)) < 0)
180 return ret;
181 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46182 p->data[1], p->linesize[1],
Anton Khirnov7b1fbd42012-11-17 07:08:40183 ir2_luma_table)) < 0)
184 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47185 } else { /* interframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40186 if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46187 p->data[0], p->linesize[0],
Anton Khirnov7b1fbd42012-11-17 07:08:40188 ir2_luma_table)) < 0)
189 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47190 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40191 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46192 p->data[2], p->linesize[2],
Anton Khirnov7b1fbd42012-11-17 07:08:40193 ir2_luma_table)) < 0)
194 return ret;
195 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46196 p->data[1], p->linesize[1],
Anton Khirnov7b1fbd42012-11-17 07:08:40197 ir2_luma_table)) < 0)
198 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47199 }
200
Anton Khirnov79d501a2013-11-09 09:14:46201 if ((ret = av_frame_ref(picture, p)) < 0)
Anton Khirnov759001c2012-11-21 20:34:46202 return ret;
203
Anton Khirnovdf9b9562012-11-13 18:35:22204 *got_frame = 1;
Michael Niedermayer856dbbf2005-04-20 09:42:47205
206 return buf_size;
207}
208
Anton Khirnovc04c64c2012-11-17 07:11:30209static av_cold int ir2_decode_init(AVCodecContext *avctx)
210{
Michael Niedermayer856dbbf2005-04-20 09:42:47211 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkovbd4110f2009-04-17 14:09:56212 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
Michael Niedermayer856dbbf2005-04-20 09:42:47213
214 ic->avctx = avctx;
215
Anton Khirnov716d4132012-10-06 10:10:34216 avctx->pix_fmt= AV_PIX_FMT_YUV410P;
Diego Biurrun115329f2005-12-17 18:14:38217
Paul B Mahol451b2ca2013-07-26 14:58:44218 ic->picture = av_frame_alloc();
219 if (!ic->picture)
220 return AVERROR(ENOMEM);
Anton Khirnov3b199d22013-02-13 07:50:04221
Kostya Shishkovbd4110f2009-04-17 14:09:56222 ir2_vlc.table = vlc_tables;
223 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
Diego Biurrunaaf47bc2011-12-22 15:33:31224#ifdef BITSTREAM_READER_LE
Michael Niedermayer856dbbf2005-04-20 09:42:47225 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
226 &ir2_codes[0][1], 4, 2,
Kostya Shishkovbd4110f2009-04-17 14:09:56227 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
Michael Niedermayeref56de32005-05-11 01:50:46228#else
Christian Lohmaierc11aac62007-06-04 11:03:24229 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
230 &ir2_codes[0][1], 4, 2,
Kostya Shishkovbd4110f2009-04-17 14:09:56231 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
Michael Niedermayeref56de32005-05-11 01:50:46232#endif
Diego Biurrun115329f2005-12-17 18:14:38233
Michael Niedermayer856dbbf2005-04-20 09:42:47234 return 0;
235}
236
Anton Khirnovc04c64c2012-11-17 07:11:30237static av_cold int ir2_decode_end(AVCodecContext *avctx)
238{
Kostya Shishkov6d924b52009-10-14 05:28:24239 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkov6d924b52009-10-14 05:28:24240
Paul B Mahol451b2ca2013-07-26 14:58:44241 av_frame_free(&ic->picture);
Kostya Shishkov6d924b52009-10-14 05:28:24242
243 return 0;
244}
245
Diego Elio Pettenòe7e2df22011-01-25 21:40:11246AVCodec ff_indeo2_decoder = {
Anton Khirnovec6402b2011-07-17 10:54:31247 .name = "indeo2",
Diego Biurrunb2bed932013-10-03 20:57:53248 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
Anton Khirnovec6402b2011-07-17 10:54:31249 .type = AVMEDIA_TYPE_VIDEO,
Anton Khirnov36ef5362012-08-05 09:11:04250 .id = AV_CODEC_ID_INDEO2,
Anton Khirnovec6402b2011-07-17 10:54:31251 .priv_data_size = sizeof(Ir2Context),
252 .init = ir2_decode_init,
253 .close = ir2_decode_end,
254 .decode = ir2_decode_frame,
255 .capabilities = CODEC_CAP_DR1,
Michael Niedermayer856dbbf2005-04-20 09:42:47256};