Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/interplayvideo.c
Line
Count
Source
1
/*
2
 * Interplay MVE Video Decoder
3
 * Copyright (C) 2003 The FFmpeg project
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * 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
 * 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
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
 * @file
24
 * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
25
 * For more information about the Interplay MVE format, visit:
26
 *   http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
27
 * This code is written in such a way that the identifiers match up
28
 * with the encoding descriptions in the document.
29
 *
30
 * This decoder presently only supports a PAL8 output colorspace.
31
 *
32
 * An Interplay video frame consists of 2 parts: The decoding map and
33
 * the video data. A demuxer must load these 2 parts together in a single
34
 * buffer before sending it through the stream to this decoder.
35
 */
36
37
#include <stdio.h>
38
#include <string.h>
39
40
#include "libavutil/intreadwrite.h"
41
42
#define BITSTREAM_READER_LE
43
#include "avcodec.h"
44
#include "bytestream.h"
45
#include "codec_internal.h"
46
#include "decode.h"
47
#include "get_bits.h"
48
#include "hpeldsp.h"
49
50
#define PALETTE_COUNT 256
51
52
typedef struct IpvideoContext {
53
54
    AVCodecContext *avctx;
55
    HpelDSPContext hdsp;
56
    AVFrame *second_last_frame;
57
    AVFrame *last_frame;
58
59
    /* For format 0x10 */
60
    AVFrame *cur_decode_frame;
61
    AVFrame *prev_decode_frame;
62
63
    const unsigned char *decoding_map;
64
    int decoding_map_size;
65
    const unsigned char *skip_map;
66
    int skip_map_size;
67
68
    int is_16bpp;
69
    GetByteContext stream_ptr, mv_ptr;
70
    unsigned char *pixel_ptr;
71
    int line_inc;
72
    int stride;
73
    int upper_motion_limit_offset;
74
75
    uint32_t pal[256];
76
} IpvideoContext;
77
78
static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
79
493k
{
80
493k
    int width = dst->width;
81
493k
    int current_offset = s->pixel_ptr - dst->data[0];
82
493k
    int x = (current_offset % dst->linesize[0]) / (1 + s->is_16bpp);
83
493k
    int y = current_offset / dst->linesize[0];
84
493k
    int dx = delta_x + x - ((delta_x + x >= width) - (delta_x + x < 0)) * width;
85
493k
    int dy = delta_y + y + (delta_x + x >= width) - (delta_x + x < 0);
86
493k
    int motion_offset = dy * src->linesize[0] + dx * (1 + s->is_16bpp);
87
88
493k
    if (motion_offset < 0) {
89
19.4k
        av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
90
19.4k
        return AVERROR_INVALIDDATA;
91
473k
    } else if (motion_offset > s->upper_motion_limit_offset) {
92
90.6k
        av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
93
90.6k
            motion_offset, s->upper_motion_limit_offset);
94
90.6k
        return AVERROR_INVALIDDATA;
95
90.6k
    }
96
383k
    if (!src->data[0]) {
97
8.61k
        av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
98
8.61k
        return AVERROR(EINVAL);
99
8.61k
    }
100
374k
    s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
101
374k
                                            dst->linesize[0], 8);
102
374k
    return 0;
103
383k
}
104
105
static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
106
56.0k
{
107
56.0k
    return copy_from(s, s->last_frame, frame, 0, 0);
108
56.0k
}
109
110
static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
111
32.6k
{
112
32.6k
    return copy_from(s, s->second_last_frame, frame, 0, 0);
113
32.6k
}
114
115
static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
116
14.9k
{
117
14.9k
    unsigned char B;
118
14.9k
    int x, y;
119
120
    /* copy block from 2 frames ago using a motion vector; need 1 more byte */
121
14.9k
    if (!s->is_16bpp) {
122
10.5k
        B = bytestream2_get_byte(&s->stream_ptr);
123
10.5k
    } else {
124
4.39k
        B = bytestream2_get_byte(&s->mv_ptr);
125
4.39k
    }
126
127
14.9k
    if (B < 56) {
128
11.4k
        x = 8 + (B % 7);
129
11.4k
        y = B / 7;
130
11.4k
    } else {
131
3.50k
        x = -14 + ((B - 56) % 29);
132
3.50k
        y =   8 + ((B - 56) / 29);
133
3.50k
    }
134
135
14.9k
    ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
136
14.9k
    return copy_from(s, s->second_last_frame, frame, x, y);
137
14.9k
}
138
139
static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
140
4.37k
{
141
4.37k
    unsigned char B;
142
4.37k
    int x, y;
143
144
    /* copy 8x8 block from current frame from an up/left block */
145
146
    /* need 1 more byte for motion */
147
4.37k
    if (!s->is_16bpp) {
148
1.49k
        B = bytestream2_get_byte(&s->stream_ptr);
149
2.87k
    } else {
150
2.87k
        B = bytestream2_get_byte(&s->mv_ptr);
151
2.87k
    }
152
153
4.37k
    if (B < 56) {
154
3.30k
        x = -(8 + (B % 7));
155
3.30k
        y = -(B / 7);
156
3.30k
    } else {
157
1.06k
        x = -(-14 + ((B - 56) % 29));
158
1.06k
        y = -(  8 + ((B - 56) / 29));
159
1.06k
    }
160
161
4.37k
    ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
162
4.37k
    return copy_from(s, frame, frame, x, y);
163
4.37k
}
164
165
static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
166
6.18k
{
167
6.18k
    int x, y;
168
6.18k
    unsigned char B, BL, BH;
169
170
    /* copy a block from the previous frame; need 1 more byte */
171
6.18k
    if (!s->is_16bpp) {
172
1.82k
        B = bytestream2_get_byte(&s->stream_ptr);
173
4.35k
    } else {
174
4.35k
        B = bytestream2_get_byte(&s->mv_ptr);
175
4.35k
    }
176
177
6.18k
    BL = B & 0x0F;
178
6.18k
    BH = (B >> 4) & 0x0F;
179
6.18k
    x = -8 + BL;
180
6.18k
    y = -8 + BH;
181
182
6.18k
    ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
183
6.18k
    return copy_from(s, s->last_frame, frame, x, y);
184
6.18k
}
185
186
static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
187
6.49k
{
188
6.49k
    signed char x, y;
189
190
    /* copy a block from the previous frame using an expanded range;
191
     * need 2 more bytes */
192
6.49k
    x = bytestream2_get_byte(&s->stream_ptr);
193
6.49k
    y = bytestream2_get_byte(&s->stream_ptr);
194
195
6.49k
    ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
196
6.49k
    return copy_from(s, s->last_frame, frame, x, y);
197
6.49k
}
198
199
static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
200
1.52k
{
201
    /* mystery opcode? skip multiple blocks? */
202
1.52k
    av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
203
204
    /* report success */
205
1.52k
    return 0;
206
1.52k
}
207
208
static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
209
5.87k
{
210
5.87k
    int x, y;
211
5.87k
    unsigned char P[2];
212
5.87k
    unsigned int flags;
213
214
5.87k
    if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
215
400
        av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x7\n");
216
400
        return AVERROR_INVALIDDATA;
217
400
    }
218
219
    /* 2-color encoding */
220
5.47k
    P[0] = bytestream2_get_byte(&s->stream_ptr);
221
5.47k
    P[1] = bytestream2_get_byte(&s->stream_ptr);
222
223
5.47k
    if (P[0] <= P[1]) {
224
225
        /* need 8 more bytes from the stream */
226
33.6k
        for (y = 0; y < 8; y++) {
227
29.9k
            flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
228
269k
            for (; flags != 1; flags >>= 1)
229
239k
                *s->pixel_ptr++ = P[flags & 1];
230
29.9k
            s->pixel_ptr += s->line_inc;
231
29.9k
        }
232
233
3.73k
    } else {
234
235
        /* need 2 more bytes from the stream */
236
1.73k
        flags = bytestream2_get_le16(&s->stream_ptr);
237
8.69k
        for (y = 0; y < 8; y += 2) {
238
34.7k
            for (x = 0; x < 8; x += 2, flags >>= 1) {
239
27.8k
                s->pixel_ptr[x                ] =
240
27.8k
                s->pixel_ptr[x + 1            ] =
241
27.8k
                s->pixel_ptr[x +     s->stride] =
242
27.8k
                s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
243
27.8k
            }
244
6.95k
            s->pixel_ptr += s->stride * 2;
245
6.95k
        }
246
1.73k
    }
247
248
    /* report success */
249
5.47k
    return 0;
250
5.87k
}
251
252
static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
253
9.07k
{
254
9.07k
    int x, y;
255
9.07k
    unsigned char P[4];
256
9.07k
    unsigned int flags = 0;
257
258
9.07k
    if (bytestream2_get_bytes_left(&s->stream_ptr) < 12) {
259
570
        av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x8\n");
260
570
        return AVERROR_INVALIDDATA;
261
570
    }
262
263
    /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
264
     * either top and bottom or left and right halves */
265
8.50k
    P[0] = bytestream2_get_byte(&s->stream_ptr);
266
8.50k
    P[1] = bytestream2_get_byte(&s->stream_ptr);
267
268
8.50k
    if (P[0] <= P[1]) {
269
98.8k
        for (y = 0; y < 16; y++) {
270
            // new values for each 4x4 block
271
93.0k
            if (!(y & 3)) {
272
23.2k
                if (y) {
273
17.4k
                    P[0]  = bytestream2_get_byte(&s->stream_ptr);
274
17.4k
                    P[1]  = bytestream2_get_byte(&s->stream_ptr);
275
17.4k
                }
276
23.2k
                flags = bytestream2_get_le16(&s->stream_ptr);
277
23.2k
            }
278
279
465k
            for (x = 0; x < 4; x++, flags >>= 1)
280
372k
                *s->pixel_ptr++ = P[flags & 1];
281
93.0k
            s->pixel_ptr += s->stride - 4;
282
            // switch to right half
283
93.0k
            if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
284
93.0k
        }
285
286
5.81k
    } else {
287
2.69k
        flags = bytestream2_get_le32(&s->stream_ptr);
288
2.69k
        P[2] = bytestream2_get_byte(&s->stream_ptr);
289
2.69k
        P[3] = bytestream2_get_byte(&s->stream_ptr);
290
291
2.69k
        if (P[2] <= P[3]) {
292
293
            /* vertical split; left & right halves are 2-color encoded */
294
295
29.3k
            for (y = 0; y < 16; y++) {
296
138k
                for (x = 0; x < 4; x++, flags >>= 1)
297
110k
                    *s->pixel_ptr++ = P[flags & 1];
298
27.6k
                s->pixel_ptr += s->stride - 4;
299
                // switch to right half
300
27.6k
                if (y == 7) {
301
1.72k
                    s->pixel_ptr -= 8 * s->stride - 4;
302
1.72k
                    P[0]  = P[2];
303
1.72k
                    P[1]  = P[3];
304
1.72k
                    flags = bytestream2_get_le32(&s->stream_ptr);
305
1.72k
                }
306
27.6k
            }
307
308
1.72k
        } else {
309
310
            /* horizontal split; top & bottom halves are 2-color encoded */
311
312
8.67k
            for (y = 0; y < 8; y++) {
313
7.71k
                if (y == 4) {
314
964
                    P[0]  = P[2];
315
964
                    P[1]  = P[3];
316
964
                    flags = bytestream2_get_le32(&s->stream_ptr);
317
964
                }
318
319
69.4k
                for (x = 0; x < 8; x++, flags >>= 1)
320
61.6k
                    *s->pixel_ptr++ = P[flags & 1];
321
7.71k
                s->pixel_ptr += s->line_inc;
322
7.71k
            }
323
964
        }
324
2.69k
    }
325
326
    /* report success */
327
8.50k
    return 0;
328
9.07k
}
329
330
static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
331
7.11k
{
332
7.11k
    int x, y;
333
7.11k
    unsigned char P[4];
334
335
7.11k
    if (bytestream2_get_bytes_left(&s->stream_ptr) < 8) {
336
446
        av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x9\n");
337
446
        return AVERROR_INVALIDDATA;
338
446
    }
339
340
    /* 4-color encoding */
341
6.66k
    bytestream2_get_buffer(&s->stream_ptr, P, 4);
342
343
6.66k
    if (P[0] <= P[1]) {
344
4.02k
        if (P[2] <= P[3]) {
345
346
            /* 1 of 4 colors for each pixel, need 16 more bytes */
347
24.9k
            for (y = 0; y < 8; y++) {
348
                /* get the next set of 8 2-bit flags */
349
22.1k
                int flags = bytestream2_get_le16(&s->stream_ptr);
350
199k
                for (x = 0; x < 8; x++, flags >>= 2)
351
177k
                    *s->pixel_ptr++ = P[flags & 0x03];
352
22.1k
                s->pixel_ptr += s->line_inc;
353
22.1k
            }
354
355
2.76k
        } else {
356
1.25k
            uint32_t flags;
357
358
            /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
359
1.25k
            flags = bytestream2_get_le32(&s->stream_ptr);
360
361
6.27k
            for (y = 0; y < 8; y += 2) {
362
25.0k
                for (x = 0; x < 8; x += 2, flags >>= 2) {
363
20.0k
                    s->pixel_ptr[x                ] =
364
20.0k
                    s->pixel_ptr[x + 1            ] =
365
20.0k
                    s->pixel_ptr[x +     s->stride] =
366
20.0k
                    s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
367
20.0k
                }
368
5.01k
                s->pixel_ptr += s->stride * 2;
369
5.01k
            }
370
371
1.25k
        }
372
4.02k
    } else {
373
2.64k
        uint64_t flags;
374
375
        /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
376
2.64k
        flags = bytestream2_get_le64(&s->stream_ptr);
377
2.64k
        if (P[2] <= P[3]) {
378
12.2k
            for (y = 0; y < 8; y++) {
379
54.3k
                for (x = 0; x < 8; x += 2, flags >>= 2) {
380
43.4k
                    s->pixel_ptr[x    ] =
381
43.4k
                    s->pixel_ptr[x + 1] = P[flags & 0x03];
382
43.4k
                }
383
10.8k
                s->pixel_ptr += s->stride;
384
10.8k
            }
385
1.35k
        } else {
386
6.41k
            for (y = 0; y < 8; y += 2) {
387
46.1k
                for (x = 0; x < 8; x++, flags >>= 2) {
388
41.0k
                    s->pixel_ptr[x            ] =
389
41.0k
                    s->pixel_ptr[x + s->stride] = P[flags & 0x03];
390
41.0k
                }
391
5.13k
                s->pixel_ptr += s->stride * 2;
392
5.13k
            }
393
1.28k
        }
394
2.64k
    }
395
396
    /* report success */
397
6.66k
    return 0;
398
7.11k
}
399
400
static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
401
108k
{
402
108k
    int x, y;
403
108k
    unsigned char P[8];
404
108k
    int flags = 0;
405
406
108k
    if (bytestream2_get_bytes_left(&s->stream_ptr) < 16) {
407
100k
        av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xA\n");
408
100k
        return AVERROR_INVALIDDATA;
409
100k
    }
410
411
7.85k
    bytestream2_get_buffer(&s->stream_ptr, P, 4);
412
413
    /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
414
     * either top and bottom or left and right halves */
415
7.85k
    if (P[0] <= P[1]) {
416
417
        /* 4-color encoding for each quadrant; need 32 bytes */
418
77.7k
        for (y = 0; y < 16; y++) {
419
            // new values for each 4x4 block
420
73.1k
            if (!(y & 3)) {
421
18.2k
                if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
422
18.2k
                flags = bytestream2_get_le32(&s->stream_ptr);
423
18.2k
            }
424
425
365k
            for (x = 0; x < 4; x++, flags >>= 2)
426
292k
                *s->pixel_ptr++ = P[flags & 0x03];
427
428
73.1k
            s->pixel_ptr += s->stride - 4;
429
            // switch to right half
430
73.1k
            if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
431
73.1k
        }
432
433
4.57k
    } else {
434
        // vertical split?
435
3.28k
        int vert;
436
3.28k
        uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
437
438
3.28k
        bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
439
3.28k
        vert = P[4] <= P[5];
440
441
        /* 4-color encoding for either left and right or top and bottom
442
         * halves */
443
444
55.8k
        for (y = 0; y < 16; y++) {
445
262k
            for (x = 0; x < 4; x++, flags >>= 2)
446
210k
                *s->pixel_ptr++ = P[flags & 0x03];
447
448
52.5k
            if (vert) {
449
32.8k
                s->pixel_ptr += s->stride - 4;
450
                // switch to right half
451
32.8k
                if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
452
32.8k
            } else if (y & 1) s->pixel_ptr += s->line_inc;
453
454
            // load values for second half
455
52.5k
            if (y == 7) {
456
3.28k
                memcpy(P, P + 4, 4);
457
3.28k
                flags = bytestream2_get_le64(&s->stream_ptr);
458
3.28k
            }
459
52.5k
        }
460
3.28k
    }
461
462
    /* report success */
463
7.85k
    return 0;
464
108k
}
465
466
static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
467
1.27k
{
468
1.27k
    int y;
469
470
    /* 64-color encoding (each pixel in block is a different color) */
471
11.4k
    for (y = 0; y < 8; y++) {
472
10.2k
        bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
473
10.2k
        s->pixel_ptr  += s->stride;
474
10.2k
    }
475
476
    /* report success */
477
1.27k
    return 0;
478
1.27k
}
479
480
static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
481
1.46k
{
482
1.46k
    int x, y;
483
484
    /* 16-color block encoding: each 2x2 block is a different color */
485
7.30k
    for (y = 0; y < 8; y += 2) {
486
29.2k
        for (x = 0; x < 8; x += 2) {
487
23.3k
            s->pixel_ptr[x                ] =
488
23.3k
            s->pixel_ptr[x + 1            ] =
489
23.3k
            s->pixel_ptr[x +     s->stride] =
490
23.3k
            s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
491
23.3k
        }
492
5.84k
        s->pixel_ptr += s->stride * 2;
493
5.84k
    }
494
495
    /* report success */
496
1.46k
    return 0;
497
1.46k
}
498
499
static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
500
2.42k
{
501
2.42k
    int y;
502
2.42k
    unsigned char P[2];
503
504
2.42k
    if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
505
423
        av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xD\n");
506
423
        return AVERROR_INVALIDDATA;
507
423
    }
508
509
    /* 4-color block encoding: each 4x4 block is a different color */
510
17.9k
    for (y = 0; y < 8; y++) {
511
15.9k
        if (!(y & 3)) {
512
3.99k
            P[0] = bytestream2_get_byte(&s->stream_ptr);
513
3.99k
            P[1] = bytestream2_get_byte(&s->stream_ptr);
514
3.99k
        }
515
15.9k
        memset(s->pixel_ptr,     P[0], 4);
516
15.9k
        memset(s->pixel_ptr + 4, P[1], 4);
517
15.9k
        s->pixel_ptr += s->stride;
518
15.9k
    }
519
520
    /* report success */
521
1.99k
    return 0;
522
2.42k
}
523
524
static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
525
8.39k
{
526
8.39k
    int y;
527
8.39k
    unsigned char pix;
528
529
    /* 1-color encoding: the whole block is 1 solid color */
530
8.39k
    pix = bytestream2_get_byte(&s->stream_ptr);
531
532
75.5k
    for (y = 0; y < 8; y++) {
533
67.1k
        memset(s->pixel_ptr, pix, 8);
534
67.1k
        s->pixel_ptr += s->stride;
535
67.1k
    }
536
537
    /* report success */
538
8.39k
    return 0;
539
8.39k
}
540
541
static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
542
10.9k
{
543
10.9k
    int x, y;
544
10.9k
    unsigned char sample[2];
545
546
    /* dithered encoding */
547
10.9k
    sample[0] = bytestream2_get_byte(&s->stream_ptr);
548
10.9k
    sample[1] = bytestream2_get_byte(&s->stream_ptr);
549
550
98.1k
    for (y = 0; y < 8; y++) {
551
436k
        for (x = 0; x < 8; x += 2) {
552
348k
            *s->pixel_ptr++ = sample[  y & 1 ];
553
348k
            *s->pixel_ptr++ = sample[!(y & 1)];
554
348k
        }
555
87.2k
        s->pixel_ptr += s->line_inc;
556
87.2k
    }
557
558
    /* report success */
559
10.9k
    return 0;
560
10.9k
}
561
562
static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
563
2.55k
{
564
2.55k
    signed char x, y;
565
566
    /* copy a block from the second last frame using an expanded range */
567
2.55k
    x = bytestream2_get_byte(&s->stream_ptr);
568
2.55k
    y = bytestream2_get_byte(&s->stream_ptr);
569
570
2.55k
    ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
571
2.55k
    return copy_from(s, s->second_last_frame, frame, x, y);
572
2.55k
}
573
574
static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
575
7.52k
{
576
7.52k
    int x, y;
577
7.52k
    uint16_t P[2];
578
7.52k
    unsigned int flags;
579
7.52k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
580
581
    /* 2-color encoding */
582
7.52k
    P[0] = bytestream2_get_le16(&s->stream_ptr);
583
7.52k
    P[1] = bytestream2_get_le16(&s->stream_ptr);
584
585
7.52k
    if (!(P[0] & 0x8000)) {
586
587
49.3k
        for (y = 0; y < 8; y++) {
588
43.8k
            flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
589
394k
            for (; flags != 1; flags >>= 1)
590
350k
                *pixel_ptr++ = P[flags & 1];
591
43.8k
            pixel_ptr += s->line_inc;
592
43.8k
        }
593
594
5.47k
    } else {
595
596
2.04k
        flags = bytestream2_get_le16(&s->stream_ptr);
597
10.2k
        for (y = 0; y < 8; y += 2) {
598
40.9k
            for (x = 0; x < 8; x += 2, flags >>= 1) {
599
32.7k
                pixel_ptr[x                ] =
600
32.7k
                pixel_ptr[x + 1            ] =
601
32.7k
                pixel_ptr[x +     s->stride] =
602
32.7k
                pixel_ptr[x + 1 + s->stride] = P[flags & 1];
603
32.7k
            }
604
8.18k
            pixel_ptr += s->stride * 2;
605
8.18k
        }
606
2.04k
    }
607
608
7.52k
    return 0;
609
7.52k
}
610
611
static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
612
12.6k
{
613
12.6k
    int x, y;
614
12.6k
    uint16_t P[4];
615
12.6k
    unsigned int flags = 0;
616
12.6k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
617
618
    /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
619
     * either top and bottom or left and right halves */
620
12.6k
    P[0] = bytestream2_get_le16(&s->stream_ptr);
621
12.6k
    P[1] = bytestream2_get_le16(&s->stream_ptr);
622
623
12.6k
    if (!(P[0] & 0x8000)) {
624
625
140k
        for (y = 0; y < 16; y++) {
626
            // new values for each 4x4 block
627
131k
            if (!(y & 3)) {
628
32.9k
                if (y) {
629
24.7k
                    P[0] = bytestream2_get_le16(&s->stream_ptr);
630
24.7k
                    P[1] = bytestream2_get_le16(&s->stream_ptr);
631
24.7k
                }
632
32.9k
                flags = bytestream2_get_le16(&s->stream_ptr);
633
32.9k
            }
634
635
658k
            for (x = 0; x < 4; x++, flags >>= 1)
636
527k
                *pixel_ptr++ = P[flags & 1];
637
131k
            pixel_ptr += s->stride - 4;
638
            // switch to right half
639
131k
            if (y == 7) pixel_ptr -= 8 * s->stride - 4;
640
131k
        }
641
642
8.23k
    } else {
643
644
4.37k
        flags = bytestream2_get_le32(&s->stream_ptr);
645
4.37k
        P[2]  = bytestream2_get_le16(&s->stream_ptr);
646
4.37k
        P[3]  = bytestream2_get_le16(&s->stream_ptr);
647
648
4.37k
        if (!(P[2] & 0x8000)) {
649
650
            /* vertical split; left & right halves are 2-color encoded */
651
652
30.4k
            for (y = 0; y < 16; y++) {
653
143k
                for (x = 0; x < 4; x++, flags >>= 1)
654
114k
                    *pixel_ptr++ = P[flags & 1];
655
28.6k
                pixel_ptr += s->stride - 4;
656
                // switch to right half
657
28.6k
                if (y == 7) {
658
1.79k
                    pixel_ptr -= 8 * s->stride - 4;
659
1.79k
                    P[0]  = P[2];
660
1.79k
                    P[1]  = P[3];
661
1.79k
                    flags = bytestream2_get_le32(&s->stream_ptr);
662
1.79k
                }
663
28.6k
            }
664
665
2.58k
        } else {
666
667
            /* horizontal split; top & bottom halves are 2-color encoded */
668
669
23.2k
            for (y = 0; y < 8; y++) {
670
20.6k
                if (y == 4) {
671
2.58k
                    P[0]  = P[2];
672
2.58k
                    P[1]  = P[3];
673
2.58k
                    flags = bytestream2_get_le32(&s->stream_ptr);
674
2.58k
                }
675
676
186k
                for (x = 0; x < 8; x++, flags >>= 1)
677
165k
                    *pixel_ptr++ = P[flags & 1];
678
20.6k
                pixel_ptr += s->line_inc;
679
20.6k
            }
680
2.58k
        }
681
4.37k
    }
682
683
    /* report success */
684
12.6k
    return 0;
685
12.6k
}
686
687
static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
688
8.89k
{
689
8.89k
    int x, y;
690
8.89k
    uint16_t P[4];
691
8.89k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
692
693
    /* 4-color encoding */
694
44.4k
    for (x = 0; x < 4; x++)
695
35.5k
        P[x] = bytestream2_get_le16(&s->stream_ptr);
696
697
8.89k
    if (!(P[0] & 0x8000)) {
698
5.96k
        if (!(P[2] & 0x8000)) {
699
700
            /* 1 of 4 colors for each pixel */
701
43.0k
            for (y = 0; y < 8; y++) {
702
                /* get the next set of 8 2-bit flags */
703
38.2k
                int flags = bytestream2_get_le16(&s->stream_ptr);
704
344k
                for (x = 0; x < 8; x++, flags >>= 2)
705
306k
                    *pixel_ptr++ = P[flags & 0x03];
706
38.2k
                pixel_ptr += s->line_inc;
707
38.2k
            }
708
709
4.78k
        } else {
710
1.17k
            uint32_t flags;
711
712
            /* 1 of 4 colors for each 2x2 block */
713
1.17k
            flags = bytestream2_get_le32(&s->stream_ptr);
714
715
5.87k
            for (y = 0; y < 8; y += 2) {
716
23.4k
                for (x = 0; x < 8; x += 2, flags >>= 2) {
717
18.7k
                    pixel_ptr[x                ] =
718
18.7k
                    pixel_ptr[x + 1            ] =
719
18.7k
                    pixel_ptr[x +     s->stride] =
720
18.7k
                    pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
721
18.7k
                }
722
4.69k
                pixel_ptr += s->stride * 2;
723
4.69k
            }
724
725
1.17k
        }
726
5.96k
    } else {
727
2.93k
        uint64_t flags;
728
729
        /* 1 of 4 colors for each 2x1 or 1x2 block */
730
2.93k
        flags = bytestream2_get_le64(&s->stream_ptr);
731
2.93k
        if (!(P[2] & 0x8000)) {
732
10.2k
            for (y = 0; y < 8; y++) {
733
45.7k
                for (x = 0; x < 8; x += 2, flags >>= 2) {
734
36.5k
                    pixel_ptr[x    ] =
735
36.5k
                    pixel_ptr[x + 1] = P[flags & 0x03];
736
36.5k
                }
737
9.14k
                pixel_ptr += s->stride;
738
9.14k
            }
739
1.78k
        } else {
740
8.94k
            for (y = 0; y < 8; y += 2) {
741
64.4k
                for (x = 0; x < 8; x++, flags >>= 2) {
742
57.2k
                    pixel_ptr[x            ] =
743
57.2k
                    pixel_ptr[x + s->stride] = P[flags & 0x03];
744
57.2k
                }
745
7.15k
                pixel_ptr += s->stride * 2;
746
7.15k
            }
747
1.78k
        }
748
2.93k
    }
749
750
    /* report success */
751
8.89k
    return 0;
752
8.89k
}
753
754
static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
755
19.8k
{
756
19.8k
    int x, y;
757
19.8k
    uint16_t P[8];
758
19.8k
    int flags = 0;
759
19.8k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
760
761
99.0k
    for (x = 0; x < 4; x++)
762
79.2k
        P[x] = bytestream2_get_le16(&s->stream_ptr);
763
764
    /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
765
     * either top and bottom or left and right halves */
766
19.8k
    if (!(P[0] & 0x8000)) {
767
768
        /* 4-color encoding for each quadrant */
769
284k
        for (y = 0; y < 16; y++) {
770
            // new values for each 4x4 block
771
268k
            if (!(y & 3)) {
772
67.0k
                if (y)
773
251k
                    for (x = 0; x < 4; x++)
774
201k
                        P[x] = bytestream2_get_le16(&s->stream_ptr);
775
67.0k
                flags = bytestream2_get_le32(&s->stream_ptr);
776
67.0k
            }
777
778
1.34M
            for (x = 0; x < 4; x++, flags >>= 2)
779
1.07M
                *pixel_ptr++ = P[flags & 0x03];
780
781
268k
            pixel_ptr += s->stride - 4;
782
            // switch to right half
783
268k
            if (y == 7) pixel_ptr -= 8 * s->stride - 4;
784
268k
        }
785
786
16.7k
    } else {
787
        // vertical split?
788
3.05k
        int vert;
789
3.05k
        uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
790
791
15.2k
        for (x = 4; x < 8; x++)
792
12.2k
            P[x] = bytestream2_get_le16(&s->stream_ptr);
793
3.05k
        vert = !(P[4] & 0x8000);
794
795
        /* 4-color encoding for either left and right or top and bottom
796
         * halves */
797
798
51.9k
        for (y = 0; y < 16; y++) {
799
244k
            for (x = 0; x < 4; x++, flags >>= 2)
800
195k
                *pixel_ptr++ = P[flags & 0x03];
801
802
48.8k
            if (vert) {
803
23.3k
                pixel_ptr += s->stride - 4;
804
                // switch to right half
805
23.3k
                if (y == 7) pixel_ptr -= 8 * s->stride - 4;
806
25.5k
            } else if (y & 1) pixel_ptr += s->line_inc;
807
808
            // load values for second half
809
48.8k
            if (y == 7) {
810
3.05k
                memcpy(P, P + 4, 8);
811
3.05k
                flags = bytestream2_get_le64(&s->stream_ptr);
812
3.05k
            }
813
48.8k
        }
814
3.05k
    }
815
816
    /* report success */
817
19.8k
    return 0;
818
19.8k
}
819
820
static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
821
3.08k
{
822
3.08k
    int x, y;
823
3.08k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
824
825
    /* 64-color encoding (each pixel in block is a different color) */
826
27.7k
    for (y = 0; y < 8; y++) {
827
222k
        for (x = 0; x < 8; x++)
828
197k
            pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
829
24.6k
        pixel_ptr  += s->stride;
830
24.6k
    }
831
832
    /* report success */
833
3.08k
    return 0;
834
3.08k
}
835
836
static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
837
2.18k
{
838
2.18k
    int x, y;
839
2.18k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
840
841
    /* 16-color block encoding: each 2x2 block is a different color */
842
10.9k
    for (y = 0; y < 8; y += 2) {
843
43.7k
        for (x = 0; x < 8; x += 2) {
844
35.0k
            pixel_ptr[x                ] =
845
35.0k
            pixel_ptr[x + 1            ] =
846
35.0k
            pixel_ptr[x +     s->stride] =
847
35.0k
            pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
848
35.0k
        }
849
8.75k
        pixel_ptr += s->stride * 2;
850
8.75k
    }
851
852
    /* report success */
853
2.18k
    return 0;
854
2.18k
}
855
856
static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
857
4.29k
{
858
4.29k
    int x, y;
859
4.29k
    uint16_t P[2];
860
4.29k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
861
862
    /* 4-color block encoding: each 4x4 block is a different color */
863
38.6k
    for (y = 0; y < 8; y++) {
864
34.3k
        if (!(y & 3)) {
865
8.59k
            P[0] = bytestream2_get_le16(&s->stream_ptr);
866
8.59k
            P[1] = bytestream2_get_le16(&s->stream_ptr);
867
8.59k
        }
868
309k
        for (x = 0; x < 8; x++)
869
274k
            pixel_ptr[x] = P[x >> 2];
870
34.3k
        pixel_ptr += s->stride;
871
34.3k
    }
872
873
    /* report success */
874
4.29k
    return 0;
875
4.29k
}
876
877
static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
878
7.27k
{
879
7.27k
    int x, y;
880
7.27k
    uint16_t pix;
881
7.27k
    uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
882
883
    /* 1-color encoding: the whole block is 1 solid color */
884
7.27k
    pix = bytestream2_get_le16(&s->stream_ptr);
885
886
65.4k
    for (y = 0; y < 8; y++) {
887
523k
        for (x = 0; x < 8; x++)
888
465k
            pixel_ptr[x] = pix;
889
58.1k
        pixel_ptr += s->stride;
890
58.1k
    }
891
892
    /* report success */
893
7.27k
    return 0;
894
7.27k
}
895
896
static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
897
    ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
898
    ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
899
    ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
900
    ipvideo_decode_block_opcode_0x6, ipvideo_decode_block_opcode_0x7,
901
    ipvideo_decode_block_opcode_0x8, ipvideo_decode_block_opcode_0x9,
902
    ipvideo_decode_block_opcode_0xA, ipvideo_decode_block_opcode_0xB,
903
    ipvideo_decode_block_opcode_0xC, ipvideo_decode_block_opcode_0xD,
904
    ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
905
};
906
907
static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
908
    ipvideo_decode_block_opcode_0x0,    ipvideo_decode_block_opcode_0x1,
909
    ipvideo_decode_block_opcode_0x2,    ipvideo_decode_block_opcode_0x3,
910
    ipvideo_decode_block_opcode_0x4,    ipvideo_decode_block_opcode_0x5,
911
    ipvideo_decode_block_opcode_0x6_16, ipvideo_decode_block_opcode_0x7_16,
912
    ipvideo_decode_block_opcode_0x8_16, ipvideo_decode_block_opcode_0x9_16,
913
    ipvideo_decode_block_opcode_0xA_16, ipvideo_decode_block_opcode_0xB_16,
914
    ipvideo_decode_block_opcode_0xC_16, ipvideo_decode_block_opcode_0xD_16,
915
    ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
916
};
917
918
static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
919
111k
{
920
111k
    int line;
921
922
111k
    if (!opcode) {
923
642k
        for (line = 0; line < 8; ++line) {
924
571k
            bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
925
571k
            s->pixel_ptr += s->stride;
926
571k
        }
927
71.4k
    } else {
928
        /* Don't try to copy second_last_frame data on the first frames */
929
39.7k
        if (s->avctx->frame_num > 2)
930
22.9k
            copy_from(s, s->second_last_frame, frame, 0, 0);
931
39.7k
    }
932
111k
}
933
934
static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
935
111k
{
936
111k
    int off_x, off_y;
937
938
111k
    if (opcode < 0) {
939
18.6k
        off_x = ((uint16_t)opcode - 0xC000) % frame->width;
940
18.6k
        off_y = ((uint16_t)opcode - 0xC000) / frame->width;
941
18.6k
        copy_from(s, s->last_frame, frame, off_x, off_y);
942
92.6k
    } else if (opcode > 0) {
943
21.1k
        off_x = ((uint16_t)opcode - 0x4000) % frame->width;
944
21.1k
        off_y = ((uint16_t)opcode - 0x4000) / frame->width;
945
21.1k
        copy_from(s, frame, frame, off_x, off_y);
946
21.1k
    }
947
111k
}
948
949
static void (* const ipvideo_format_06_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
950
    ipvideo_format_06_firstpass, ipvideo_format_06_secondpass,
951
};
952
953
static void ipvideo_decode_format_06_opcodes(IpvideoContext *s, AVFrame *frame)
954
5.58k
{
955
5.58k
    int pass, x, y;
956
5.58k
    int16_t opcode;
957
5.58k
    GetByteContext decoding_map_ptr;
958
959
    /* this is PAL8, so make the palette available */
960
5.58k
    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
961
5.58k
    s->stride = frame->linesize[0];
962
963
5.58k
    s->line_inc = s->stride - 8;
964
5.58k
    s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
965
5.58k
                                  + (s->avctx->width - 8) * (1 + s->is_16bpp);
966
967
5.58k
    bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
968
969
16.7k
    for (pass = 0; pass < 2; ++pass) {
970
11.1k
        bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
971
100k
        for (y = 0; y < s->avctx->height; y += 8) {
972
312k
            for (x = 0; x < s->avctx->width; x += 8) {
973
222k
                opcode = bytestream2_get_le16(&decoding_map_ptr);
974
975
222k
                ff_tlog(s->avctx,
976
222k
                        "  block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
977
222k
                        x, y, opcode, bytestream2_tell(&s->stream_ptr));
978
979
222k
                s->pixel_ptr = frame->data[0] + x + y * frame->linesize[0];
980
222k
                ipvideo_format_06_passes[pass](s, frame, opcode);
981
222k
            }
982
89.7k
        }
983
11.1k
    }
984
985
5.58k
    if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
986
234
        av_log(s->avctx, AV_LOG_DEBUG,
987
234
               "decode finished with %d bytes left over\n",
988
234
               bytestream2_get_bytes_left(&s->stream_ptr));
989
234
    }
990
5.58k
}
991
992
static void ipvideo_format_10_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
993
204k
{
994
204k
    int line;
995
996
204k
    if (!opcode) {
997
1.55M
        for (line = 0; line < 8; ++line) {
998
1.38M
            bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
999
1.38M
            s->pixel_ptr += s->stride;
1000
1.38M
        }
1001
173k
    }
1002
204k
}
1003
1004
static void ipvideo_format_10_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
1005
190k
{
1006
190k
    int off_x, off_y;
1007
1008
190k
    if (opcode < 0) {
1009
14.7k
        off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->width;
1010
14.7k
        off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->width;
1011
14.7k
        copy_from(s, s->prev_decode_frame, s->cur_decode_frame, off_x, off_y);
1012
176k
    } else if (opcode > 0) {
1013
14.7k
        off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->width;
1014
14.7k
        off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->width;
1015
14.7k
        copy_from(s, s->cur_decode_frame, s->cur_decode_frame, off_x, off_y);
1016
14.7k
    }
1017
190k
}
1018
1019
static void (* const ipvideo_format_10_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
1020
    ipvideo_format_10_firstpass, ipvideo_format_10_secondpass,
1021
};
1022
1023
static void ipvideo_decode_format_10_opcodes(IpvideoContext *s, AVFrame *frame)
1024
11.5k
{
1025
11.5k
    int pass, x, y, changed_block;
1026
11.5k
    int16_t opcode, skip;
1027
11.5k
    GetByteContext decoding_map_ptr;
1028
11.5k
    GetByteContext skip_map_ptr;
1029
1030
11.5k
    bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1031
1032
    /* this is PAL8, so make the palette available */
1033
11.5k
    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1034
11.5k
    s->stride = frame->linesize[0];
1035
1036
11.5k
    s->line_inc = s->stride - 8;
1037
11.5k
    s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1038
11.5k
                                  + (s->avctx->width - 8) * (1 + s->is_16bpp);
1039
1040
11.5k
    bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
1041
11.5k
    bytestream2_init(&skip_map_ptr, s->skip_map, s->skip_map_size);
1042
1043
33.0k
    for (pass = 0; pass < 2; ++pass) {
1044
22.2k
        bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
1045
22.2k
        bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1046
22.2k
        skip = bytestream2_get_le16(&skip_map_ptr);
1047
1048
204k
        for (y = 0; y < s->avctx->height; y += 8) {
1049
1.00M
            for (x = 0; x < s->avctx->width; x += 8) {
1050
821k
                s->pixel_ptr = s->cur_decode_frame->data[0] + x + y * s->cur_decode_frame->linesize[0];
1051
1052
903k
                while (skip <= 0)  {
1053
477k
                    if (skip != -0x8000 && skip) {
1054
394k
                        opcode = bytestream2_get_le16(&decoding_map_ptr);
1055
394k
                        ipvideo_format_10_passes[pass](s, frame, opcode);
1056
394k
                        break;
1057
394k
                    }
1058
82.5k
                    if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1059
713
                        return;
1060
81.8k
                    skip = bytestream2_get_le16(&skip_map_ptr);
1061
81.8k
                }
1062
820k
                skip *= 2;
1063
820k
            }
1064
182k
        }
1065
22.2k
    }
1066
1067
10.7k
    bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1068
10.7k
    skip = bytestream2_get_le16(&skip_map_ptr);
1069
99.5k
    for (y = 0; y < s->avctx->height; y += 8) {
1070
486k
        for (x = 0; x < s->avctx->width; x += 8) {
1071
397k
            changed_block = 0;
1072
397k
            s->pixel_ptr = frame->data[0] + x + y*frame->linesize[0];
1073
1074
437k
            while (skip <= 0)  {
1075
230k
                if (skip != -0x8000 && skip) {
1076
190k
                    changed_block = 1;
1077
190k
                    break;
1078
190k
                }
1079
40.0k
                if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1080
0
                    return;
1081
40.0k
                skip = bytestream2_get_le16(&skip_map_ptr);
1082
40.0k
            }
1083
1084
397k
            if (changed_block) {
1085
190k
                copy_from(s, s->cur_decode_frame, frame, 0, 0);
1086
206k
            } else {
1087
                /* Don't try to copy last_frame data on the first frame */
1088
206k
                if (s->avctx->frame_num)
1089
87.0k
                    copy_from(s, s->last_frame, frame, 0, 0);
1090
206k
            }
1091
397k
            skip *= 2;
1092
397k
        }
1093
88.7k
    }
1094
1095
10.7k
    FFSWAP(AVFrame*, s->prev_decode_frame, s->cur_decode_frame);
1096
1097
10.7k
    if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1098
351
        av_log(s->avctx, AV_LOG_DEBUG,
1099
351
               "decode finished with %d bytes left over\n",
1100
351
               bytestream2_get_bytes_left(&s->stream_ptr));
1101
351
    }
1102
10.7k
}
1103
1104
static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
1105
134k
{
1106
134k
    int x, y;
1107
134k
    unsigned char opcode;
1108
134k
    int ret;
1109
134k
    GetBitContext gb;
1110
1111
134k
    bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1112
134k
    if (!s->is_16bpp) {
1113
        /* this is PAL8, so make the palette available */
1114
124k
        memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1115
1116
124k
        s->stride = frame->linesize[0];
1117
124k
    } else {
1118
9.81k
        s->stride = frame->linesize[0] >> 1;
1119
9.81k
        s->mv_ptr = s->stream_ptr;
1120
9.81k
        bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
1121
9.81k
    }
1122
134k
    s->line_inc = s->stride - 8;
1123
134k
    s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1124
134k
                                  + (s->avctx->width - 8) * (1 + s->is_16bpp);
1125
1126
134k
    init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
1127
202k
    for (y = 0; y < s->avctx->height; y += 8) {
1128
428k
        for (x = 0; x < s->avctx->width; x += 8) {
1129
359k
            if (get_bits_left(&gb) < 4)
1130
14.2k
                return;
1131
345k
            opcode = get_bits(&gb, 4);
1132
1133
345k
            ff_tlog(s->avctx,
1134
345k
                    "  block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
1135
345k
                    x, y, opcode, bytestream2_tell(&s->stream_ptr));
1136
1137
345k
            if (!s->is_16bpp) {
1138
208k
                s->pixel_ptr = frame->data[0] + x
1139
208k
                              + y*frame->linesize[0];
1140
208k
                ret = ipvideo_decode_block[opcode](s, frame);
1141
208k
            } else {
1142
137k
                s->pixel_ptr = frame->data[0] + x*2
1143
137k
                              + y*frame->linesize[0];
1144
137k
                ret = ipvideo_decode_block16[opcode](s, frame);
1145
137k
            }
1146
345k
            if (ret != 0) {
1147
119k
                av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %"PRId64", @ block (%d, %d)\n",
1148
119k
                       s->avctx->frame_num, x, y);
1149
119k
                return;
1150
119k
            }
1151
345k
        }
1152
202k
    }
1153
468
    if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1154
211
        av_log(s->avctx, AV_LOG_DEBUG,
1155
211
               "decode finished with %d bytes left over\n",
1156
211
               bytestream2_get_bytes_left(&s->stream_ptr));
1157
211
    }
1158
468
}
1159
1160
static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
1161
1.48k
{
1162
1.48k
    IpvideoContext *s = avctx->priv_data;
1163
1164
1.48k
    s->avctx = avctx;
1165
1166
1.48k
    s->is_16bpp = avctx->bits_per_coded_sample == 16;
1167
1.48k
    avctx->pix_fmt = s->is_16bpp ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_PAL8;
1168
1169
1.48k
    ff_hpeldsp_init(&s->hdsp, avctx->flags);
1170
1171
1.48k
    s->last_frame        = av_frame_alloc();
1172
1.48k
    s->second_last_frame = av_frame_alloc();
1173
1.48k
    s->cur_decode_frame  = av_frame_alloc();
1174
1.48k
    s->prev_decode_frame = av_frame_alloc();
1175
1.48k
    if (!s->last_frame || !s->second_last_frame ||
1176
1.48k
        !s->cur_decode_frame || !s->prev_decode_frame) {
1177
0
        return AVERROR(ENOMEM);
1178
0
    }
1179
1180
1.48k
    s->cur_decode_frame->width   = avctx->width;
1181
1.48k
    s->prev_decode_frame->width  = avctx->width;
1182
1.48k
    s->cur_decode_frame->height  = avctx->height;
1183
1.48k
    s->prev_decode_frame->height = avctx->height;
1184
1.48k
    s->cur_decode_frame->format  = avctx->pix_fmt;
1185
1.48k
    s->prev_decode_frame->format = avctx->pix_fmt;
1186
1187
1.48k
    return 0;
1188
1.48k
}
1189
1190
static int ipvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
1191
                                int *got_frame, AVPacket *avpkt)
1192
172k
{
1193
172k
    const uint8_t *buf = avpkt->data;
1194
172k
    int buf_size = avpkt->size;
1195
172k
    IpvideoContext *s = avctx->priv_data;
1196
172k
    int ret;
1197
172k
    int send_buffer;
1198
172k
    int frame_format;
1199
172k
    int video_data_size;
1200
1201
172k
    if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
1202
0
        av_frame_unref(s->last_frame);
1203
0
        av_frame_unref(s->second_last_frame);
1204
0
        av_frame_unref(s->cur_decode_frame);
1205
0
        av_frame_unref(s->prev_decode_frame);
1206
0
    }
1207
1208
172k
    if (!s->cur_decode_frame->data[0]) {
1209
9.80k
        ret = ff_get_buffer(avctx, s->cur_decode_frame, 0);
1210
9.80k
        if (ret < 0)
1211
8.72k
            return ret;
1212
1213
1.08k
        ret = ff_get_buffer(avctx, s->prev_decode_frame, 0);
1214
1.08k
        if (ret < 0) {
1215
0
            av_frame_unref(s->cur_decode_frame);
1216
0
            return ret;
1217
0
        }
1218
1.08k
    }
1219
1220
163k
    if (buf_size < 8)
1221
2.67k
        return AVERROR_INVALIDDATA;
1222
1223
160k
    frame_format         = AV_RL8(buf);
1224
160k
    send_buffer          = AV_RL8(buf + 1);
1225
160k
    video_data_size      = AV_RL16(buf + 2);
1226
160k
    s->decoding_map_size = AV_RL16(buf + 4);
1227
160k
    s->skip_map_size     = AV_RL16(buf + 6);
1228
1229
160k
    switch (frame_format) {
1230
7.40k
    case 0x06:
1231
7.40k
        if (s->decoding_map_size) {
1232
392
            av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n");
1233
392
            return AVERROR_INVALIDDATA;
1234
392
        }
1235
1236
7.00k
        if (s->skip_map_size) {
1237
308
            av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n");
1238
308
            return AVERROR_INVALIDDATA;
1239
308
        }
1240
1241
6.70k
        if (s->is_16bpp) {
1242
247
            av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n");
1243
247
            return AVERROR_INVALIDDATA;
1244
247
        }
1245
1246
        /* Decoding map for 0x06 frame format is at the top of pixeldata */
1247
6.45k
        s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2;
1248
6.45k
        s->decoding_map = buf + 8 + 14; /* 14 bits of op data */
1249
6.45k
        video_data_size -= s->decoding_map_size + 14;
1250
6.45k
        if (video_data_size <= 0 || s->decoding_map_size == 0)
1251
536
            return AVERROR_INVALIDDATA;
1252
1253
5.91k
        if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
1254
330
            return AVERROR_INVALIDDATA;
1255
1256
5.58k
        bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size);
1257
1258
5.58k
        break;
1259
1260
13.0k
    case 0x10:
1261
13.0k
        if (! s->decoding_map_size) {
1262
236
            av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n");
1263
236
            return AVERROR_INVALIDDATA;
1264
236
        }
1265
1266
12.8k
        if (! s->skip_map_size) {
1267
450
            av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n");
1268
450
            return AVERROR_INVALIDDATA;
1269
450
        }
1270
1271
12.4k
        if (s->is_16bpp) {
1272
346
            av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n");
1273
346
            return AVERROR_INVALIDDATA;
1274
346
        }
1275
1276
12.0k
        if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size)
1277
552
            return AVERROR_INVALIDDATA;
1278
1279
11.5k
        bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1280
11.5k
        s->decoding_map = buf + 8 + video_data_size;
1281
11.5k
        s->skip_map = buf + 8 + video_data_size + s->decoding_map_size;
1282
1283
11.5k
        break;
1284
1285
136k
    case 0x11:
1286
136k
        if (! s->decoding_map_size) {
1287
296
            av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n");
1288
296
            return AVERROR_INVALIDDATA;
1289
296
        }
1290
1291
135k
        if (s->skip_map_size) {
1292
1.12k
            av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n");
1293
1.12k
            return AVERROR_INVALIDDATA;
1294
1.12k
        }
1295
1296
134k
        if (buf_size < 8 + video_data_size + s->decoding_map_size)
1297
674
            return AVERROR_INVALIDDATA;
1298
1299
134k
        bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1300
134k
        s->decoding_map = buf + 8 + video_data_size;
1301
1302
134k
        break;
1303
1304
4.14k
    default:
1305
4.14k
        av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format);
1306
160k
    }
1307
1308
    /* ensure we can't overread the packet */
1309
155k
    if (buf_size < 8 + s->decoding_map_size + video_data_size + s->skip_map_size) {
1310
1.08k
        av_log(avctx, AV_LOG_ERROR, "Invalid IP packet size\n");
1311
1.08k
        return AVERROR_INVALIDDATA;
1312
1.08k
    }
1313
1314
154k
    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
1315
11
        return ret;
1316
1317
154k
    if (!s->is_16bpp) {
1318
142k
        ff_copy_palette(s->pal, avpkt, avctx);
1319
142k
    }
1320
1321
154k
    switch (frame_format) {
1322
5.58k
    case 0x06:
1323
5.58k
        ipvideo_decode_format_06_opcodes(s, frame);
1324
5.58k
        break;
1325
11.5k
    case 0x10:
1326
11.5k
        ipvideo_decode_format_10_opcodes(s, frame);
1327
11.5k
        break;
1328
134k
    case 0x11:
1329
134k
        ipvideo_decode_format_11_opcodes(s, frame);
1330
134k
        break;
1331
154k
    }
1332
1333
154k
    *got_frame = send_buffer;
1334
1335
    /* shuffle frames */
1336
154k
    FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);
1337
154k
    if ((ret = av_frame_replace(s->last_frame, frame)) < 0)
1338
0
        return ret;
1339
1340
    /* report that the buffer was completely consumed */
1341
154k
    return buf_size;
1342
154k
}
1343
1344
static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
1345
1.48k
{
1346
1.48k
    IpvideoContext *s = avctx->priv_data;
1347
1348
1.48k
    av_frame_free(&s->last_frame);
1349
1.48k
    av_frame_free(&s->second_last_frame);
1350
1.48k
    av_frame_free(&s->cur_decode_frame);
1351
1.48k
    av_frame_free(&s->prev_decode_frame);
1352
1353
1.48k
    return 0;
1354
1.48k
}
1355
1356
const FFCodec ff_interplay_video_decoder = {
1357
    .p.name         = "interplayvideo",
1358
    CODEC_LONG_NAME("Interplay MVE video"),
1359
    .p.type         = AVMEDIA_TYPE_VIDEO,
1360
    .p.id           = AV_CODEC_ID_INTERPLAY_VIDEO,
1361
    .priv_data_size = sizeof(IpvideoContext),
1362
    .init           = ipvideo_decode_init,
1363
    .close          = ipvideo_decode_end,
1364
    FF_CODEC_DECODE_CB(ipvideo_decode_frame),
1365
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
1366
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1367
};