blob: 7df6e69f2aff53ad7871dc9cf8882d5b47ae09a6 [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 *
Mans Rullgard2912e872011-03-18 17:35:105 * This file is part of Libav.
Diego Biurrunb78e7192006-10-07 15:30:466 *
Mans Rullgard2912e872011-03-18 17:35:107 * Libav 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 *
Mans Rullgard2912e872011-03-18 17:35:1012 * Libav 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
Mans Rullgard2912e872011-03-18 17:35:1018 * License along with Libav; 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;
Anton Khirnov79d501a2013-11-09 09:14:4637 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,
52 int stride, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:4753{
54 int i;
55 int j;
56 int out = 0;
57 int c;
58 int t;
Diego Biurrun115329f2005-12-17 18:14:3859
Anton Khirnovc04c64c2012-11-17 07:11:3060 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:1961 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:0462
Michael Niedermayer856dbbf2005-04-20 09:42:4763 /* first line contain absolute values, other lines contain deltas */
Anton Khirnovc04c64c2012-11-17 07:11:3064 while (out < width) {
Michael Niedermayer856dbbf2005-04-20 09:42:4765 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3066 if (c >= 0x80) { /* we have a run */
Michael Niedermayer8b39f752005-04-20 10:16:1967 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3068 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1969 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4770 for (i = 0; i < c * 2; i++)
71 dst[out++] = 0x80;
72 } else { /* copy two values from table */
73 dst[out++] = table[c * 2];
74 dst[out++] = table[(c * 2) + 1];
75 }
76 }
77 dst += stride;
Diego Biurrun115329f2005-12-17 18:14:3878
Anton Khirnovc04c64c2012-11-17 07:11:3079 for (j = 1; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:4780 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:3081 while (out < width) {
Michael Niedermayer856dbbf2005-04-20 09:42:4782 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3083 if (c >= 0x80) { /* we have a skip */
Michael Niedermayer8b39f752005-04-20 10:16:1984 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3085 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1986 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4787 for (i = 0; i < c * 2; i++) {
88 dst[out] = dst[out - stride];
89 out++;
90 }
91 } else { /* add two deltas from table */
Anton Khirnovc04c64c2012-11-17 07:11:3092 t = dst[out - stride] + (table[c * 2] - 128);
93 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:4794 dst[out] = t;
95 out++;
Anton Khirnovc04c64c2012-11-17 07:11:3096 t = dst[out - stride] + (table[(c * 2) + 1] - 128);
97 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:4798 dst[out] = t;
99 out++;
100 }
101 }
102 dst += stride;
103 }
Michael Niedermayerf707a5e2005-04-20 09:52:04104 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47105}
106
Anton Khirnovc04c64c2012-11-17 07:11:30107static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
108 int stride, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:47109{
110 int j;
111 int out = 0;
112 int c;
113 int t;
Michael Niedermayerf707a5e2005-04-20 09:52:04114
Anton Khirnovc04c64c2012-11-17 07:11:30115 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:19116 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:04117
Anton Khirnovc04c64c2012-11-17 07:11:30118 for (j = 0; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:47119 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:30120 while (out < width) {
Michael Niedermayer856dbbf2005-04-20 09:42:47121 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:30122 if (c >= 0x80) { /* we have a skip */
123 c -= 0x7F;
Michael Niedermayer856dbbf2005-04-20 09:42:47124 out += c * 2;
125 } else { /* add two deltas from table */
Anton Khirnovc04c64c2012-11-17 07:11:30126 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
127 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47128 dst[out] = t;
129 out++;
Anton Khirnovc04c64c2012-11-17 07:11:30130 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
131 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47132 dst[out] = t;
133 out++;
134 }
135 }
136 dst += stride;
137 }
Michael Niedermayerf707a5e2005-04-20 09:52:04138 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47139}
140
Diego Biurrun115329f2005-12-17 18:14:38141static int ir2_decode_frame(AVCodecContext *avctx,
Anton Khirnovdf9b9562012-11-13 18:35:22142 void *data, int *got_frame,
Thilo Borgmann7a00bba2009-04-07 15:59:50143 AVPacket *avpkt)
Michael Niedermayer856dbbf2005-04-20 09:42:47144{
Michael Niedermayer856dbbf2005-04-20 09:42:47145 Ir2Context * const s = avctx->priv_data;
Anton Khirnovc04c64c2012-11-17 07:11:30146 const uint8_t *buf = avpkt->data;
147 int buf_size = avpkt->size;
148 AVFrame *picture = data;
Anton Khirnov79d501a2013-11-09 09:14:46149 AVFrame * const p = s->picture;
Anton Khirnov6ea2c9a2012-11-17 07:06:19150 int start, ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47151
Anton Khirnov759001c2012-11-21 20:34:46152 if ((ret = ff_reget_buffer(avctx, p)) < 0) {
Michael Niedermayer856dbbf2005-04-20 09:42:47153 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
Anton Khirnov6ea2c9a2012-11-17 07:06:19154 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47155 }
156
Alex Converseb7ce4f12011-09-09 20:26:49157 start = 48; /* hardcoded for now */
158
159 if (start >= buf_size) {
160 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
161 return AVERROR_INVALIDDATA;
162 }
163
Michael Niedermayer856dbbf2005-04-20 09:42:47164 s->decode_delta = buf[18];
Diego Biurrun115329f2005-12-17 18:14:38165
Michael Niedermayer856dbbf2005-04-20 09:42:47166 /* decide whether frame uses deltas or not */
Diego Biurrunaaf47bc2011-12-22 15:33:31167#ifndef BITSTREAM_READER_LE
Michael Niedermayer856dbbf2005-04-20 09:42:47168 for (i = 0; i < buf_size; i++)
Diego Biurrund5c62122012-10-11 16:50:30169 buf[i] = ff_reverse[buf[i]];
Michael Niedermayeref56de32005-05-11 01:50:46170#endif
Michael Niedermayer856dbbf2005-04-20 09:42:47171
Alex Converse68ca3302011-09-09 20:24:19172 init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
Michael Niedermayer856dbbf2005-04-20 09:42:47173
174 if (s->decode_delta) { /* intraframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40175 if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46176 p->data[0], p->linesize[0],
Anton Khirnov7b1fbd42012-11-17 07:08:40177 ir2_luma_table)) < 0)
178 return ret;
179
Michael Niedermayer856dbbf2005-04-20 09:42:47180 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40181 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46182 p->data[2], p->linesize[2],
Anton Khirnov7b1fbd42012-11-17 07:08:40183 ir2_luma_table)) < 0)
184 return ret;
185 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46186 p->data[1], p->linesize[1],
Anton Khirnov7b1fbd42012-11-17 07:08:40187 ir2_luma_table)) < 0)
188 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47189 } else { /* interframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40190 if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46191 p->data[0], p->linesize[0],
Anton Khirnov7b1fbd42012-11-17 07:08:40192 ir2_luma_table)) < 0)
193 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47194 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40195 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46196 p->data[2], p->linesize[2],
Anton Khirnov7b1fbd42012-11-17 07:08:40197 ir2_luma_table)) < 0)
198 return ret;
199 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46200 p->data[1], p->linesize[1],
Anton Khirnov7b1fbd42012-11-17 07:08:40201 ir2_luma_table)) < 0)
202 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47203 }
204
Anton Khirnov79d501a2013-11-09 09:14:46205 if ((ret = av_frame_ref(picture, p)) < 0)
Anton Khirnov759001c2012-11-21 20:34:46206 return ret;
207
Anton Khirnovdf9b9562012-11-13 18:35:22208 *got_frame = 1;
Michael Niedermayer856dbbf2005-04-20 09:42:47209
210 return buf_size;
211}
212
Anton Khirnovc04c64c2012-11-17 07:11:30213static av_cold int ir2_decode_init(AVCodecContext *avctx)
214{
Michael Niedermayer856dbbf2005-04-20 09:42:47215 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkovbd4110f2009-04-17 14:09:56216 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
Michael Niedermayer856dbbf2005-04-20 09:42:47217
218 ic->avctx = avctx;
219
Anton Khirnov716d4132012-10-06 10:10:34220 avctx->pix_fmt= AV_PIX_FMT_YUV410P;
Diego Biurrun115329f2005-12-17 18:14:38221
Anton Khirnov79d501a2013-11-09 09:14:46222 ic->picture = av_frame_alloc();
223 if (!ic->picture)
224 return AVERROR(ENOMEM);
Anton Khirnov3b199d22013-02-13 07:50:04225
Kostya Shishkovbd4110f2009-04-17 14:09:56226 ir2_vlc.table = vlc_tables;
227 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
Diego Biurrunaaf47bc2011-12-22 15:33:31228#ifdef BITSTREAM_READER_LE
Michael Niedermayer856dbbf2005-04-20 09:42:47229 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 | INIT_VLC_LE);
Michael Niedermayeref56de32005-05-11 01:50:46232#else
Christian Lohmaierc11aac62007-06-04 11:03:24233 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
234 &ir2_codes[0][1], 4, 2,
Kostya Shishkovbd4110f2009-04-17 14:09:56235 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
Michael Niedermayeref56de32005-05-11 01:50:46236#endif
Diego Biurrun115329f2005-12-17 18:14:38237
Michael Niedermayer856dbbf2005-04-20 09:42:47238 return 0;
239}
240
Anton Khirnovc04c64c2012-11-17 07:11:30241static av_cold int ir2_decode_end(AVCodecContext *avctx)
242{
Kostya Shishkov6d924b52009-10-14 05:28:24243 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkov6d924b52009-10-14 05:28:24244
Anton Khirnov79d501a2013-11-09 09:14:46245 av_frame_free(&ic->picture);
Kostya Shishkov6d924b52009-10-14 05:28:24246
247 return 0;
248}
249
Diego Elio Pettenòd36beb32011-01-25 21:40:11250AVCodec ff_indeo2_decoder = {
Anton Khirnovec6402b2011-07-17 10:54:31251 .name = "indeo2",
Diego Biurrunb2bed932013-10-03 20:57:53252 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
Anton Khirnovec6402b2011-07-17 10:54:31253 .type = AVMEDIA_TYPE_VIDEO,
Anton Khirnov36ef5362012-08-05 09:11:04254 .id = AV_CODEC_ID_INDEO2,
Anton Khirnovec6402b2011-07-17 10:54:31255 .priv_data_size = sizeof(Ir2Context),
256 .init = ir2_decode_init,
257 .close = ir2_decode_end,
258 .decode = ir2_decode_frame,
259 .capabilities = CODEC_CAP_DR1,
Michael Niedermayer856dbbf2005-04-20 09:42:47260};