blob: 8b47b59f79c52e1caa414618b7c6e49095d16eab [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 Biurrund5c62122012-10-11 16:50:3027#include "libavutil/attributes.h"
Andreas Rheinhardt0d71ac32020-11-15 21:48:3528#include "libavutil/thread.h"
Diego Biurrunb6686622016-06-04 13:07:3029
30#define BITSTREAM_READER_LE
Michael Niedermayer856dbbf2005-04-20 09:42:4731#include "avcodec.h"
Andreas Rheinhardta688f3c2022-03-16 17:18:2832#include "codec_internal.h"
Stefano Sabatini9106a692009-04-13 16:20:2633#include "get_bits.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4734#include "indeo2data.h"
Anton Khirnov759001c2012-11-21 20:34:4635#include "internal.h"
Diego Biurrund5c62122012-10-11 16:50:3036#include "mathops.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4737
38typedef struct Ir2Context{
39 AVCodecContext *avctx;
Paul B Mahol451b2ca2013-07-26 14:58:4440 AVFrame *picture;
Michael Niedermayer856dbbf2005-04-20 09:42:4741 GetBitContext gb;
42 int decode_delta;
43} Ir2Context;
44
45#define CODE_VLC_BITS 14
46static VLC ir2_vlc;
47
48/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */
49static inline int ir2_get_code(GetBitContext *gb)
50{
Andreas Rheinhardtf25dde02020-11-01 03:16:2551 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1);
Michael Niedermayer856dbbf2005-04-20 09:42:4752}
Michael Niedermayer856dbbf2005-04-20 09:42:4753
Anton Khirnovc04c64c2012-11-17 07:11:3054static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:2255 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:4756{
57 int i;
58 int j;
59 int out = 0;
Diego Biurrun115329f2005-12-17 18:14:3860
Michael Niedermayer4ef27d42019-03-17 20:39:5761 if ((width & 1) || width * height / (2*(IR2_CODES - 0x7F)) > get_bits_left(&ctx->gb))
Anton Khirnov6ea2c9a2012-11-17 07:06:1962 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:0463
Michael Niedermayer856dbbf2005-04-20 09:42:4764 /* first line contain absolute values, other lines contain deltas */
Anton Khirnovc04c64c2012-11-17 07:11:3065 while (out < width) {
Reimar Döffingerc2c27e92014-10-18 13:28:0366 int c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3067 if (c >= 0x80) { /* we have a run */
Michael Niedermayer8b39f752005-04-20 10:16:1968 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3069 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1970 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4771 for (i = 0; i < c * 2; i++)
72 dst[out++] = 0x80;
73 } else { /* copy two values from table */
Michael Niedermayer159fb8f2017-05-08 22:02:2274 if (c <= 0)
75 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4776 dst[out++] = table[c * 2];
77 dst[out++] = table[(c * 2) + 1];
78 }
79 }
Kostya Shishkov422e14f2014-06-25 18:28:2280 dst += pitch;
Diego Biurrun115329f2005-12-17 18:14:3881
Anton Khirnovc04c64c2012-11-17 07:11:3082 for (j = 1; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:4783 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:3084 while (out < width) {
Michael Niedermayer52939a22019-07-31 22:50:2185 int c;
86 if (get_bits_left(&ctx->gb) <= 0)
87 return AVERROR_INVALIDDATA;
88 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3089 if (c >= 0x80) { /* we have a skip */
Michael Niedermayer8b39f752005-04-20 10:16:1990 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3091 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1992 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4793 for (i = 0; i < c * 2; i++) {
Kostya Shishkov422e14f2014-06-25 18:28:2294 dst[out] = dst[out - pitch];
Michael Niedermayer856dbbf2005-04-20 09:42:4795 out++;
96 }
97 } else { /* add two deltas from table */
Michael Niedermayer159fb8f2017-05-08 22:02:2298 int t;
99 if (c <= 0)
100 return AVERROR_INVALIDDATA;
101 t = dst[out - pitch] + (table[c * 2] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:30102 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47103 dst[out] = t;
104 out++;
Kostya Shishkov422e14f2014-06-25 18:28:22105 t = dst[out - pitch] + (table[(c * 2) + 1] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:30106 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47107 dst[out] = t;
108 out++;
109 }
110 }
Kostya Shishkov422e14f2014-06-25 18:28:22111 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47112 }
Michael Niedermayerf707a5e2005-04-20 09:52:04113 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47114}
115
Anton Khirnovc04c64c2012-11-17 07:11:30116static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:22117 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:47118{
119 int j;
120 int out = 0;
121 int c;
122 int t;
Michael Niedermayerf707a5e2005-04-20 09:52:04123
Anton Khirnovc04c64c2012-11-17 07:11:30124 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:19125 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:04126
Anton Khirnovc04c64c2012-11-17 07:11:30127 for (j = 0; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:47128 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:30129 while (out < width) {
Michael Niedermayer52939a22019-07-31 22:50:21130 if (get_bits_left(&ctx->gb) <= 0)
131 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:47132 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:30133 if (c >= 0x80) { /* we have a skip */
134 c -= 0x7F;
Michael Niedermayer856dbbf2005-04-20 09:42:47135 out += c * 2;
136 } else { /* add two deltas from table */
Michael Niedermayer159fb8f2017-05-08 22:02:22137 if (c <= 0)
138 return AVERROR_INVALIDDATA;
Anton Khirnovc04c64c2012-11-17 07:11:30139 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
140 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47141 dst[out] = t;
142 out++;
Anton Khirnovc04c64c2012-11-17 07:11:30143 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
144 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47145 dst[out] = t;
146 out++;
147 }
148 }
Kostya Shishkov422e14f2014-06-25 18:28:22149 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47150 }
Michael Niedermayerf707a5e2005-04-20 09:52:04151 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47152}
153
Andreas Rheinhardtce7dbd02022-03-30 19:33:24154static int ir2_decode_frame(AVCodecContext *avctx, AVFrame *picture,
155 int *got_frame, AVPacket *avpkt)
Michael Niedermayer856dbbf2005-04-20 09:42:47156{
157 Ir2Context * const s = avctx->priv_data;
Anton Khirnovc04c64c2012-11-17 07:11:30158 const uint8_t *buf = avpkt->data;
159 int buf_size = avpkt->size;
Paul B Mahol451b2ca2013-07-26 14:58:44160 AVFrame * const p = s->picture;
Anton Khirnov6ea2c9a2012-11-17 07:06:19161 int start, ret;
Luca Barbato73f3c8f2016-02-23 00:58:19162 int ltab, ctab;
Michael Niedermayer856dbbf2005-04-20 09:42:47163
James Almer9ea6d212019-08-30 14:37:25164 if ((ret = ff_reget_buffer(avctx, p, 0)) < 0)
Anton Khirnov6ea2c9a2012-11-17 07:06:19165 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47166
Alex Converseb7ce4f12011-09-09 20:26:49167 start = 48; /* hardcoded for now */
168
169 if (start >= buf_size) {
170 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
171 return AVERROR_INVALIDDATA;
172 }
173
Michael Niedermayer856dbbf2005-04-20 09:42:47174 s->decode_delta = buf[18];
Diego Biurrun115329f2005-12-17 18:14:38175
Michael Niedermayer856dbbf2005-04-20 09:42:47176 /* decide whether frame uses deltas or not */
Michael Niedermayer856dbbf2005-04-20 09:42:47177
Paul B Mahol484cc662015-12-20 20:31:55178 if ((ret = init_get_bits8(&s->gb, buf + start, buf_size - start)) < 0)
179 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47180
Luca Barbato73f3c8f2016-02-23 00:58:19181 ltab = buf[0x22] & 3;
182 ctab = buf[0x22] >> 2;
Michael Niedermayer9ffe44c2016-08-19 11:07:14183
184 if (ctab > 3) {
185 av_log(avctx, AV_LOG_ERROR, "ctab %d is invalid\n", ctab);
186 return AVERROR_INVALIDDATA;
187 }
188
Michael Niedermayer856dbbf2005-04-20 09:42:47189 if (s->decode_delta) { /* intraframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40190 if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46191 p->data[0], p->linesize[0],
Luca Barbato73f3c8f2016-02-23 00:58:19192 ir2_delta_table[ltab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40193 return ret;
194
Michael Niedermayer856dbbf2005-04-20 09:42:47195 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40196 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46197 p->data[2], p->linesize[2],
Luca Barbato73f3c8f2016-02-23 00:58:19198 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40199 return ret;
200 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46201 p->data[1], p->linesize[1],
Luca Barbato73f3c8f2016-02-23 00:58:19202 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40203 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47204 } else { /* interframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40205 if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46206 p->data[0], p->linesize[0],
Luca Barbato73f3c8f2016-02-23 00:58:19207 ir2_delta_table[ltab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40208 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47209 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40210 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46211 p->data[2], p->linesize[2],
Luca Barbato73f3c8f2016-02-23 00:58:19212 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40213 return ret;
214 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46215 p->data[1], p->linesize[1],
Luca Barbato73f3c8f2016-02-23 00:58:19216 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40217 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47218 }
219
Anton Khirnov79d501a2013-11-09 09:14:46220 if ((ret = av_frame_ref(picture, p)) < 0)
Anton Khirnov759001c2012-11-21 20:34:46221 return ret;
222
Anton Khirnovdf9b9562012-11-13 18:35:22223 *got_frame = 1;
Michael Niedermayer856dbbf2005-04-20 09:42:47224
225 return buf_size;
226}
227
Andreas Rheinhardt0d71ac32020-11-15 21:48:35228static av_cold void ir2_init_static(void)
229{
230 INIT_VLC_STATIC_FROM_LENGTHS(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
231 &ir2_tab[0][1], 2, &ir2_tab[0][0], 2, 1,
232 0, INIT_VLC_OUTPUT_LE, 1 << CODE_VLC_BITS);
233}
234
Anton Khirnovc04c64c2012-11-17 07:11:30235static av_cold int ir2_decode_init(AVCodecContext *avctx)
236{
Andreas Rheinhardt0d71ac32020-11-15 21:48:35237 static AVOnce init_static_once = AV_ONCE_INIT;
Michael Niedermayer856dbbf2005-04-20 09:42:47238 Ir2Context * const ic = avctx->priv_data;
Michael Niedermayer856dbbf2005-04-20 09:42:47239
240 ic->avctx = avctx;
241
Anton Khirnov716d4132012-10-06 10:10:34242 avctx->pix_fmt= AV_PIX_FMT_YUV410P;
Diego Biurrun115329f2005-12-17 18:14:38243
Paul B Mahol451b2ca2013-07-26 14:58:44244 ic->picture = av_frame_alloc();
245 if (!ic->picture)
246 return AVERROR(ENOMEM);
Anton Khirnov3b199d22013-02-13 07:50:04247
Andreas Rheinhardt0d71ac32020-11-15 21:48:35248 ff_thread_once(&init_static_once, ir2_init_static);
Diego Biurrun115329f2005-12-17 18:14:38249
Michael Niedermayer856dbbf2005-04-20 09:42:47250 return 0;
251}
252
Anton Khirnovc04c64c2012-11-17 07:11:30253static av_cold int ir2_decode_end(AVCodecContext *avctx)
254{
Kostya Shishkov6d924b52009-10-14 05:28:24255 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkov6d924b52009-10-14 05:28:24256
Paul B Mahol451b2ca2013-07-26 14:58:44257 av_frame_free(&ic->picture);
Kostya Shishkov6d924b52009-10-14 05:28:24258
259 return 0;
260}
261
Andreas Rheinhardt20f97272022-03-16 20:09:54262const FFCodec ff_indeo2_decoder = {
263 .p.name = "indeo2",
264 .p.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
265 .p.type = AVMEDIA_TYPE_VIDEO,
266 .p.id = AV_CODEC_ID_INDEO2,
Anton Khirnovec6402b2011-07-17 10:54:31267 .priv_data_size = sizeof(Ir2Context),
268 .init = ir2_decode_init,
269 .close = ir2_decode_end,
270 .decode = ir2_decode_frame,
Andreas Rheinhardt20f97272022-03-16 20:09:54271 .p.capabilities = AV_CODEC_CAP_DR1,
Andreas Rheinhardt0d71ac32020-11-15 21:48:35272 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
Michael Niedermayer856dbbf2005-04-20 09:42:47273};