blob: 6878ab7cb66960947451b48a80683e1bcd3878af [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"
Andreas Rheinhardte2c24e62022-08-24 18:49:2533#include "decode.h"
Stefano Sabatini9106a692009-04-13 16:20:2634#include "get_bits.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4735#include "indeo2data.h"
Michael Niedermayer856dbbf2005-04-20 09:42:4736
37typedef struct Ir2Context{
38 AVCodecContext *avctx;
Paul B Mahol451b2ca2013-07-26 14:58:4439 AVFrame *picture;
Michael Niedermayer856dbbf2005-04-20 09:42:4740 GetBitContext gb;
41 int decode_delta;
42} Ir2Context;
43
44#define CODE_VLC_BITS 14
Andreas Rheinhardt05577d22023-09-24 15:28:2145static VLCElem ir2_vlc[1 << CODE_VLC_BITS];
Michael Niedermayer856dbbf2005-04-20 09:42:4746
47/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */
48static inline int ir2_get_code(GetBitContext *gb)
49{
Andreas Rheinhardt05577d22023-09-24 15:28:2150 return get_vlc2(gb, ir2_vlc, CODE_VLC_BITS, 1);
Michael Niedermayer856dbbf2005-04-20 09:42:4751}
Michael Niedermayer856dbbf2005-04-20 09:42:4752
Anton Khirnovc04c64c2012-11-17 07:11:3053static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:2254 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:4755{
56 int i;
57 int j;
58 int out = 0;
Diego Biurrun115329f2005-12-17 18:14:3859
Michael Niedermayer4ef27d42019-03-17 20:39:5760 if ((width & 1) || width * height / (2*(IR2_CODES - 0x7F)) > get_bits_left(&ctx->gb))
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) {
Reimar Döffingerc2c27e92014-10-18 13:28:0365 int 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 */
Michael Niedermayer159fb8f2017-05-08 22:02:2273 if (c <= 0)
74 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4775 dst[out++] = table[c * 2];
76 dst[out++] = table[(c * 2) + 1];
77 }
78 }
Kostya Shishkov422e14f2014-06-25 18:28:2279 dst += pitch;
Diego Biurrun115329f2005-12-17 18:14:3880
Anton Khirnovc04c64c2012-11-17 07:11:3081 for (j = 1; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:4782 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:3083 while (out < width) {
Michael Niedermayer52939a22019-07-31 22:50:2184 int c;
85 if (get_bits_left(&ctx->gb) <= 0)
86 return AVERROR_INVALIDDATA;
87 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:3088 if (c >= 0x80) { /* we have a skip */
Michael Niedermayer8b39f752005-04-20 10:16:1989 c -= 0x7F;
Anton Khirnovc04c64c2012-11-17 07:11:3090 if (out + c*2 > width)
Anton Khirnov6ea2c9a2012-11-17 07:06:1991 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:4792 for (i = 0; i < c * 2; i++) {
Kostya Shishkov422e14f2014-06-25 18:28:2293 dst[out] = dst[out - pitch];
Michael Niedermayer856dbbf2005-04-20 09:42:4794 out++;
95 }
96 } else { /* add two deltas from table */
Michael Niedermayer159fb8f2017-05-08 22:02:2297 int t;
98 if (c <= 0)
99 return AVERROR_INVALIDDATA;
100 t = dst[out - pitch] + (table[c * 2] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:30101 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47102 dst[out] = t;
103 out++;
Kostya Shishkov422e14f2014-06-25 18:28:22104 t = dst[out - pitch] + (table[(c * 2) + 1] - 128);
Anton Khirnovc04c64c2012-11-17 07:11:30105 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47106 dst[out] = t;
107 out++;
108 }
109 }
Kostya Shishkov422e14f2014-06-25 18:28:22110 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47111 }
Michael Niedermayerf707a5e2005-04-20 09:52:04112 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47113}
114
Anton Khirnovc04c64c2012-11-17 07:11:30115static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
Kostya Shishkov422e14f2014-06-25 18:28:22116 int pitch, const uint8_t *table)
Michael Niedermayer856dbbf2005-04-20 09:42:47117{
118 int j;
119 int out = 0;
120 int c;
121 int t;
Michael Niedermayerf707a5e2005-04-20 09:52:04122
Anton Khirnovc04c64c2012-11-17 07:11:30123 if (width & 1)
Anton Khirnov6ea2c9a2012-11-17 07:06:19124 return AVERROR_INVALIDDATA;
Michael Niedermayerf707a5e2005-04-20 09:52:04125
Anton Khirnovc04c64c2012-11-17 07:11:30126 for (j = 0; j < height; j++) {
Michael Niedermayer856dbbf2005-04-20 09:42:47127 out = 0;
Anton Khirnovc04c64c2012-11-17 07:11:30128 while (out < width) {
Michael Niedermayer52939a22019-07-31 22:50:21129 if (get_bits_left(&ctx->gb) <= 0)
130 return AVERROR_INVALIDDATA;
Michael Niedermayer856dbbf2005-04-20 09:42:47131 c = ir2_get_code(&ctx->gb);
Anton Khirnovc04c64c2012-11-17 07:11:30132 if (c >= 0x80) { /* we have a skip */
133 c -= 0x7F;
Michael Niedermayer856dbbf2005-04-20 09:42:47134 out += c * 2;
135 } else { /* add two deltas from table */
Michael Niedermayer159fb8f2017-05-08 22:02:22136 if (c <= 0)
137 return AVERROR_INVALIDDATA;
Anton Khirnovc04c64c2012-11-17 07:11:30138 t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
139 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47140 dst[out] = t;
141 out++;
Anton Khirnovc04c64c2012-11-17 07:11:30142 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
143 t = av_clip_uint8(t);
Michael Niedermayer856dbbf2005-04-20 09:42:47144 dst[out] = t;
145 out++;
146 }
147 }
Kostya Shishkov422e14f2014-06-25 18:28:22148 dst += pitch;
Michael Niedermayer856dbbf2005-04-20 09:42:47149 }
Michael Niedermayerf707a5e2005-04-20 09:52:04150 return 0;
Michael Niedermayer856dbbf2005-04-20 09:42:47151}
152
Andreas Rheinhardtce7dbd02022-03-30 19:33:24153static int ir2_decode_frame(AVCodecContext *avctx, AVFrame *picture,
154 int *got_frame, AVPacket *avpkt)
Michael Niedermayer856dbbf2005-04-20 09:42:47155{
156 Ir2Context * const s = avctx->priv_data;
Anton Khirnovc04c64c2012-11-17 07:11:30157 const uint8_t *buf = avpkt->data;
158 int buf_size = avpkt->size;
Paul B Mahol451b2ca2013-07-26 14:58:44159 AVFrame * const p = s->picture;
Anton Khirnov6ea2c9a2012-11-17 07:06:19160 int start, ret;
Luca Barbato73f3c8f2016-02-23 00:58:19161 int ltab, ctab;
Michael Niedermayer856dbbf2005-04-20 09:42:47162
James Almer9ea6d212019-08-30 14:37:25163 if ((ret = ff_reget_buffer(avctx, p, 0)) < 0)
Anton Khirnov6ea2c9a2012-11-17 07:06:19164 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47165
Alex Converseb7ce4f12011-09-09 20:26:49166 start = 48; /* hardcoded for now */
167
168 if (start >= buf_size) {
169 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
170 return AVERROR_INVALIDDATA;
171 }
172
Michael Niedermayer856dbbf2005-04-20 09:42:47173 s->decode_delta = buf[18];
Diego Biurrun115329f2005-12-17 18:14:38174
Michael Niedermayer856dbbf2005-04-20 09:42:47175 /* decide whether frame uses deltas or not */
Michael Niedermayer856dbbf2005-04-20 09:42:47176
Paul B Mahol484cc662015-12-20 20:31:55177 if ((ret = init_get_bits8(&s->gb, buf + start, buf_size - start)) < 0)
178 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47179
Luca Barbato73f3c8f2016-02-23 00:58:19180 ltab = buf[0x22] & 3;
181 ctab = buf[0x22] >> 2;
Michael Niedermayer9ffe44c2016-08-19 11:07:14182
183 if (ctab > 3) {
184 av_log(avctx, AV_LOG_ERROR, "ctab %d is invalid\n", ctab);
185 return AVERROR_INVALIDDATA;
186 }
187
Michael Niedermayer856dbbf2005-04-20 09:42:47188 if (s->decode_delta) { /* intraframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40189 if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46190 p->data[0], p->linesize[0],
Luca Barbato73f3c8f2016-02-23 00:58:19191 ir2_delta_table[ltab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40192 return ret;
193
Michael Niedermayer856dbbf2005-04-20 09:42:47194 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40195 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46196 p->data[2], p->linesize[2],
Luca Barbato73f3c8f2016-02-23 00:58:19197 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40198 return ret;
199 if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46200 p->data[1], p->linesize[1],
Luca Barbato73f3c8f2016-02-23 00:58:19201 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40202 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47203 } else { /* interframe */
Anton Khirnov7b1fbd42012-11-17 07:08:40204 if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
Anton Khirnov79d501a2013-11-09 09:14:46205 p->data[0], p->linesize[0],
Luca Barbato73f3c8f2016-02-23 00:58:19206 ir2_delta_table[ltab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40207 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47208 /* swapped U and V */
Anton Khirnov7b1fbd42012-11-17 07:08:40209 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46210 p->data[2], p->linesize[2],
Luca Barbato73f3c8f2016-02-23 00:58:19211 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40212 return ret;
213 if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
Anton Khirnov79d501a2013-11-09 09:14:46214 p->data[1], p->linesize[1],
Luca Barbato73f3c8f2016-02-23 00:58:19215 ir2_delta_table[ctab])) < 0)
Anton Khirnov7b1fbd42012-11-17 07:08:40216 return ret;
Michael Niedermayer856dbbf2005-04-20 09:42:47217 }
218
Anton Khirnov79d501a2013-11-09 09:14:46219 if ((ret = av_frame_ref(picture, p)) < 0)
Anton Khirnov759001c2012-11-21 20:34:46220 return ret;
221
Anton Khirnovdf9b9562012-11-13 18:35:22222 *got_frame = 1;
Michael Niedermayer856dbbf2005-04-20 09:42:47223
224 return buf_size;
225}
226
Andreas Rheinhardt0d71ac32020-11-15 21:48:35227static av_cold void ir2_init_static(void)
228{
Andreas Rheinhardt05577d22023-09-24 15:28:21229 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(ir2_vlc, CODE_VLC_BITS, IR2_CODES,
230 &ir2_tab[0][1], 2, &ir2_tab[0][0], 2, 1,
231 0, VLC_INIT_OUTPUT_LE);
Andreas Rheinhardt0d71ac32020-11-15 21:48:35232}
233
Anton Khirnovc04c64c2012-11-17 07:11:30234static av_cold int ir2_decode_init(AVCodecContext *avctx)
235{
Andreas Rheinhardt0d71ac32020-11-15 21:48:35236 static AVOnce init_static_once = AV_ONCE_INIT;
Michael Niedermayer856dbbf2005-04-20 09:42:47237 Ir2Context * const ic = avctx->priv_data;
Michael Niedermayer856dbbf2005-04-20 09:42:47238
239 ic->avctx = avctx;
240
Anton Khirnov716d4132012-10-06 10:10:34241 avctx->pix_fmt= AV_PIX_FMT_YUV410P;
Diego Biurrun115329f2005-12-17 18:14:38242
Paul B Mahol451b2ca2013-07-26 14:58:44243 ic->picture = av_frame_alloc();
244 if (!ic->picture)
245 return AVERROR(ENOMEM);
Anton Khirnov3b199d22013-02-13 07:50:04246
Andreas Rheinhardt0d71ac32020-11-15 21:48:35247 ff_thread_once(&init_static_once, ir2_init_static);
Diego Biurrun115329f2005-12-17 18:14:38248
Michael Niedermayer856dbbf2005-04-20 09:42:47249 return 0;
250}
251
Anton Khirnovc04c64c2012-11-17 07:11:30252static av_cold int ir2_decode_end(AVCodecContext *avctx)
253{
Kostya Shishkov6d924b52009-10-14 05:28:24254 Ir2Context * const ic = avctx->priv_data;
Kostya Shishkov6d924b52009-10-14 05:28:24255
Paul B Mahol451b2ca2013-07-26 14:58:44256 av_frame_free(&ic->picture);
Kostya Shishkov6d924b52009-10-14 05:28:24257
258 return 0;
259}
260
Andreas Rheinhardt20f97272022-03-16 20:09:54261const FFCodec ff_indeo2_decoder = {
262 .p.name = "indeo2",
Andreas Rheinhardt48286d42022-08-29 11:38:02263 CODEC_LONG_NAME("Intel Indeo 2"),
Andreas Rheinhardt20f97272022-03-16 20:09:54264 .p.type = AVMEDIA_TYPE_VIDEO,
265 .p.id = AV_CODEC_ID_INDEO2,
Anton Khirnovec6402b2011-07-17 10:54:31266 .priv_data_size = sizeof(Ir2Context),
267 .init = ir2_decode_init,
268 .close = ir2_decode_end,
Andreas Rheinhardt4243da42022-03-30 21:28:24269 FF_CODEC_DECODE_CB(ir2_decode_frame),
Andreas Rheinhardt20f97272022-03-16 20:09:54270 .p.capabilities = AV_CODEC_CAP_DR1,
Michael Niedermayer856dbbf2005-04-20 09:42:47271};