Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/mobiclip.c
Line
Count
Source
1
/*
2
 * MobiClip Video decoder
3
 * Copyright (c) 2015-2016 Florian Nouwt
4
 * Copyright (c) 2017 Adib Surani
5
 * Copyright (c) 2020 Paul B Mahol
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
#include <inttypes.h>
25
26
#include "libavutil/attributes.h"
27
#include "libavutil/avassert.h"
28
#include "libavutil/mem.h"
29
#include "libavutil/thread.h"
30
31
#include "avcodec.h"
32
#include "bswapdsp.h"
33
#include "codec_internal.h"
34
#include "decode.h"
35
#include "get_bits.h"
36
#include "golomb.h"
37
#include "mathops.h"
38
39
2.11M
#define MOBI_RL_VLC_BITS 12
40
155k
#define MOBI_MV_VLC_BITS 6
41
42
static const uint8_t zigzag4x4_tab[] =
43
{
44
    0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
45
    0x0D, 0x0E, 0x0B, 0x0F
46
};
47
48
static const uint8_t quant4x4_tab[][16] =
49
{
50
    { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
51
    { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
52
    { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
53
    { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
54
    { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
55
    { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
56
};
57
58
static const uint8_t quant8x8_tab[][64] =
59
{
60
    { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19,
61
      19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,},
62
    { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21,
63
      21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,},
64
    { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24,
65
      24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,},
66
    { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26,
67
      26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,},
68
    { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30,
69
      30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,},
70
    { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34,
71
      34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,},
72
};
73
74
static const uint8_t block4x4_coefficients_tab[] =
75
{
76
    15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
77
};
78
79
static const uint8_t pframe_block4x4_coefficients_tab[] =
80
{
81
    0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
82
};
83
84
static const uint8_t block8x8_coefficients_tab[] =
85
{
86
    0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
87
    0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
88
    0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
89
    0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
90
    0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
91
    0x2A, 0x28, 0x29, 0x26,
92
};
93
94
static const uint8_t pframe_block8x8_coefficients_tab[] =
95
{
96
    0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
97
    0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
98
    0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
99
    0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
100
};
101
102
static const uint8_t run_residue[2][256] =
103
{
104
    {
105
       12,  6,  4,  3,  3,  3,  3,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,
106
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
107
        3,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
108
        1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
109
        1, 27, 11,  7,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
110
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
111
        1, 41,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
112
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
113
    },
114
    {
115
       27, 10,  5,  4,  3,  3,  3,  3,  2,  2,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
116
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
117
        8,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
118
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
119
        1, 15, 10,  8,  4,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
120
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
121
        1, 21,  7,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
122
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
123
    },
124
};
125
126
static const uint8_t bits0[] = {
127
     9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
128
    10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
129
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
130
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
131
     9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
132
     8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
133
     6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
134
};
135
136
static const uint16_t syms0[] = {
137
    0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
138
    0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
139
    0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
140
    0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
141
    0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
142
    0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
143
    0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
144
    0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
145
    0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
146
    0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
147
};
148
149
static const uint16_t syms1[] = {
150
    0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
151
    0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
152
    0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
153
    0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
154
    0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
155
    0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
156
    0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
157
    0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
158
};
159
160
static const uint8_t mv_len[16] =
161
{
162
    10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
163
};
164
165
static const uint8_t mv_bits[2][16][10] =
166
{
167
    {
168
        { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
169
        { 2, 3, 4, 4, 3, 4, 4, 2 },
170
        { 3, 4, 4, 2, 4, 4, 3, 2 },
171
        { 1, 3, 4, 5, 5, 3, 3 },
172
        { 2, 4, 4, 3, 3, 4, 4, 2 },
173
        { 2, 3, 4, 4, 4, 4, 3, 2 },
174
        { 2, 3, 4, 4, 4, 4, 3, 2 },
175
        { 2, 2, 3, 4, 5, 5, 2 },
176
        { 2, 3, 4, 4, 3, 4, 4, 2 },
177
        { 2, 4, 4, 3, 4, 4, 3, 2 },
178
        { 2, 3, 3, 5, 5, 4, 3, 2 },
179
        { 2, 3, 4, 4, 3, 3, 2 },
180
        { 1, 4, 4, 3, 3, 4, 4 },
181
        { 2, 3, 4, 4, 3, 3, 2 },
182
        { 2, 3, 4, 4, 3, 3, 2 },
183
        { 3, 3, 2, 2, 3, 3 },
184
    },
185
    {
186
        { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
187
        { 2, 3, 4, 5, 5, 2, 3, 3 },
188
        { 2, 4, 4, 3, 3, 4, 4, 2 },
189
        { 1, 4, 4, 3, 4, 4, 3 },
190
        { 3, 3, 2, 4, 5, 5, 3, 2 },
191
        { 3, 4, 4, 3, 3, 3, 3, 2 },
192
        { 1, 3, 3, 4, 4, 4, 5, 5 },
193
        { 1, 4, 4, 3, 3, 4, 4 },
194
        { 2, 4, 4, 3, 3, 4, 4, 2 },
195
        { 1, 3, 3, 4, 4, 4, 5, 5 },
196
        { 2, 3, 4, 4, 4, 4, 3, 2 },
197
        { 2, 3, 3, 4, 4, 3, 2 },
198
        { 1, 4, 4, 3, 3, 4, 4 },
199
        { 1, 4, 4, 3, 3, 4, 4 },
200
        { 2, 3, 3, 4, 4, 3, 2 },
201
        { 2, 3, 3, 3, 3, 2 },
202
    }
203
};
204
205
static const uint8_t mv_syms[2][16][10] =
206
{
207
    {
208
        { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
209
        { 0, 9, 5, 4, 2, 3, 8, 1 },
210
        { 3, 9, 5, 0, 4, 8, 2, 1 },
211
        { 1, 3, 4, 8, 5, 2, 0 },
212
        { 0, 5, 4, 8, 2, 3, 9, 1 },
213
        { 0, 3, 5, 9, 4, 8, 2, 1 },
214
        { 0, 3, 9, 5, 8, 4, 2, 1 },
215
        { 0, 2, 3, 4, 8, 5, 1 },
216
        { 0, 3, 8, 4, 2, 5, 9, 1 },
217
        { 2, 8, 9, 3, 5, 4, 0, 1 },
218
        { 0, 4, 3, 8, 9, 5, 2, 1 },
219
        { 0, 4, 8, 5, 3, 2, 1 },
220
        { 1, 9, 4, 2, 0, 5, 3 },
221
        { 2, 4, 9, 5, 3, 0, 1 },
222
        { 0, 4, 9, 5, 3, 2, 1 },
223
        { 5, 4, 1, 0, 3, 2 },
224
    },
225
    {
226
        { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
227
        { 9, 2, 3, 5, 4, 1, 8, 0 },
228
        { 0, 5, 4, 2, 9, 3, 8, 1 },
229
        { 1, 5, 4, 2, 8, 3, 0 },
230
        { 2, 9, 8, 3, 5, 4, 0, 1 },
231
        { 3, 5, 4, 2, 9, 8, 0, 1 },
232
        { 1, 2, 0, 9, 8, 3, 5, 4 },
233
        { 1, 8, 5, 2, 0, 4, 3 },
234
        { 0, 5, 4, 2, 8, 3, 9, 1 },
235
        { 1, 2, 0, 9, 8, 3, 5, 4 },
236
        { 0, 3, 9, 8, 5, 4, 2, 1 },
237
        { 0, 4, 3, 8, 5, 2, 1 },
238
        { 1, 5, 4, 2, 0, 9, 3 },
239
        { 1, 9, 5, 2, 0, 4, 3 },
240
        { 0, 5, 3, 9, 4, 2, 1 },
241
        { 0, 4, 5, 3, 2, 1 },
242
    }
243
};
244
245
typedef struct BlockXY {
246
    int w, h;
247
    int ax, ay;
248
    int x, y;
249
    int size;
250
    uint8_t *block;
251
    int linesize;
252
} BlockXY;
253
254
typedef struct MotionXY {
255
    int x, y;
256
} MotionXY;
257
258
typedef struct MobiClipContext {
259
    AVFrame *pic[6];
260
261
    int current_pic;
262
    int moflex;
263
    int dct_tab_idx;
264
    int quantizer;
265
266
    GetBitContext gb;
267
268
    uint8_t *bitstream;
269
    int bitstream_size;
270
271
    int     qtab[2][64];
272
    uint8_t pre[32];
273
    MotionXY *motion;
274
    int     motion_size;
275
276
    BswapDSPContext bdsp;
277
} MobiClipContext;
278
279
static const VLCElem *rl_vlc[2];
280
static const VLCElem *mv_vlc[2][16];
281
282
static av_cold void mobiclip_init_static(void)
283
1
{
284
1
    static VLCElem vlc_buf[(2 << MOBI_RL_VLC_BITS) + (2 * 16 << MOBI_MV_VLC_BITS)];
285
1
    VLCInitState state =VLC_INIT_STATE(vlc_buf);
286
287
3
    for (int i = 0; i < 2; i++) {
288
2
        rl_vlc[i] =
289
2
            ff_vlc_init_tables_from_lengths(&state, MOBI_RL_VLC_BITS, 104,
290
2
                                            bits0, sizeof(*bits0),
291
2
                                            i ? syms1 : syms0, sizeof(*syms0), sizeof(*syms0),
292
2
                                            0, 0);
293
34
        for (int j = 0; j < 16; j++) {
294
32
            mv_vlc[i][j] =
295
32
                ff_vlc_init_tables_from_lengths(&state, MOBI_MV_VLC_BITS, mv_len[j],
296
32
                                                mv_bits[i][j], sizeof(*mv_bits[i][j]),
297
32
                                                mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
298
32
                                                0, 0);
299
32
        }
300
2
    }
301
1
}
302
303
static av_cold int mobiclip_init(AVCodecContext *avctx)
304
1.70k
{
305
1.70k
    static AVOnce init_static_once = AV_ONCE_INIT;
306
1.70k
    MobiClipContext *s = avctx->priv_data;
307
308
1.70k
    if (avctx->width & 15 || avctx->height & 15) {
309
22
        av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
310
22
        return AVERROR_INVALIDDATA;
311
22
    }
312
313
1.67k
    ff_bswapdsp_init(&s->bdsp);
314
315
1.67k
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
316
317
1.67k
    s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
318
1.67k
    if (!s->motion)
319
0
        return AVERROR(ENOMEM);
320
1.67k
    s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
321
322
11.7k
    for (int i = 0; i < 6; i++) {
323
10.0k
        s->pic[i] = av_frame_alloc();
324
10.0k
        if (!s->pic[i])
325
0
            return AVERROR(ENOMEM);
326
10.0k
    }
327
328
1.67k
    ff_thread_once(&init_static_once, mobiclip_init_static);
329
330
1.67k
    return 0;
331
1.67k
}
332
333
static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
334
126k
{
335
126k
    MobiClipContext *s = avctx->priv_data;
336
126k
    int qx, qy;
337
338
126k
    if (quantizer < 12 || quantizer > 161)
339
8.01k
        return AVERROR_INVALIDDATA;
340
341
118k
    s->quantizer = quantizer;
342
343
118k
    qx = quantizer % 6;
344
118k
    qy = quantizer / 6;
345
346
2.01M
    for (int i = 0; i < 16; i++)
347
1.90M
        s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
348
349
7.72M
    for (int i = 0; i < 64; i++)
350
7.60M
        s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
351
352
2.49M
    for (int i = 0; i < 20; i++)
353
2.37M
        s->pre[i] = 9;
354
355
118k
    return 0;
356
126k
}
357
358
static void inverse4(unsigned *rs)
359
10.9M
{
360
10.9M
    unsigned a = rs[0] + rs[2];
361
10.9M
    unsigned b = rs[0] - rs[2];
362
10.9M
    unsigned c = rs[1] + ((int)rs[3] >> 1);
363
10.9M
    unsigned d = ((int)rs[1] >> 1) - rs[3];
364
365
10.9M
    rs[0] = a + c;
366
10.9M
    rs[1] = b + d;
367
10.9M
    rs[2] = b - d;
368
10.9M
    rs[3] = a - c;
369
10.9M
}
370
371
static void idct(int *arr, int size)
372
10.9M
{
373
10.9M
    int e, f, g, h;
374
10.9M
    unsigned x3, x2, x1, x0;
375
10.9M
    int tmp[4];
376
377
10.9M
    if (size == 4) {
378
3.62M
        inverse4(arr);
379
3.62M
        return;
380
3.62M
    }
381
382
7.31M
    tmp[0] = arr[0];
383
7.31M
    tmp[1] = arr[2];
384
7.31M
    tmp[2] = arr[4];
385
7.31M
    tmp[3] = arr[6];
386
387
7.31M
    inverse4(tmp);
388
389
7.31M
    e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
390
7.31M
    f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
391
7.31M
    g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
392
7.31M
    h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
393
7.31M
    x3 = (unsigned)g + (h >> 2);
394
7.31M
    x2 = (unsigned)e + (f >> 2);
395
7.31M
    x1 = (e >> 2) - (unsigned)f;
396
7.31M
    x0 = (unsigned)h - (g >> 2);
397
398
7.31M
    arr[0] = tmp[0] + x0;
399
7.31M
    arr[1] = tmp[1] + x1;
400
7.31M
    arr[2] = tmp[2] + x2;
401
7.31M
    arr[3] = tmp[3] + x3;
402
7.31M
    arr[4] = tmp[3] - x3;
403
7.31M
    arr[5] = tmp[2] - x2;
404
7.31M
    arr[6] = tmp[1] - x1;
405
7.31M
    arr[7] = tmp[0] - x0;
406
7.31M
}
407
408
static void read_run_encoding(AVCodecContext *avctx,
409
                              int *last, int *run, int *level)
410
2.11M
{
411
2.11M
    MobiClipContext *s = avctx->priv_data;
412
2.11M
    GetBitContext *gb = &s->gb;
413
2.11M
    int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx], MOBI_RL_VLC_BITS, 1);
414
415
2.11M
    *last = (n >> 11) == 1;
416
2.11M
    *run  = (n >> 5) & 0x3F;
417
2.11M
    *level = n & 0x1F;
418
2.11M
}
419
420
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
421
                            int bx, int by, int size, int plane)
422
920k
{
423
920k
    MobiClipContext *s = avctx->priv_data;
424
920k
    GetBitContext *gb = &s->gb;
425
920k
    int mat[64] = { 0 };
426
920k
    const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
427
920k
    const int *qtab = s->qtab[size == 8];
428
920k
    uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
429
430
2.10M
    for (int pos = 0; get_bits_left(gb) > 0; pos++) {
431
2.09M
        int qval, last, run, level;
432
433
2.09M
        read_run_encoding(avctx, &last, &run, &level);
434
435
2.09M
        if (level) {
436
2.07M
            if (get_bits1(gb))
437
1.08M
                level = -level;
438
2.07M
        } else if (!get_bits1(gb)) {
439
12.2k
            read_run_encoding(avctx, &last, &run, &level);
440
12.2k
            level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
441
12.2k
            if (get_bits1(gb))
442
6.49k
                level = -level;
443
12.2k
        } else if (!get_bits1(gb)) {
444
2.24k
            read_run_encoding(avctx, &last, &run, &level);
445
2.24k
            run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446
2.24k
            if (get_bits1(gb))
447
824
                level = -level;
448
4.88k
        } else {
449
4.88k
            last  = get_bits1(gb);
450
4.88k
            run   = get_bits(gb, 6);
451
4.88k
            level = get_sbits(gb, 12);
452
4.88k
        }
453
454
2.09M
        pos += run;
455
2.09M
        if (pos >= size * size)
456
9.73k
            return AVERROR_INVALIDDATA;
457
2.08M
        qval = qtab[pos];
458
2.08M
        mat[ztab[pos]] = qval *(unsigned)level;
459
460
2.08M
        if (last)
461
902k
            break;
462
2.08M
    }
463
464
910k
    mat[0] += 32;
465
6.38M
    for (int y = 0; y < size; y++)
466
5.47M
        idct(&mat[y * size], size);
467
468
6.38M
    for (int y = 0; y < size; y++) {
469
20.9M
        for (int x = y + 1; x < size; x++) {
470
15.5M
            int a = mat[x * size + y];
471
15.5M
            int b = mat[y * size + x];
472
473
15.5M
            mat[y * size + x] = a;
474
15.5M
            mat[x * size + y] = b;
475
15.5M
        }
476
477
5.47M
        idct(&mat[y * size], size);
478
41.9M
        for (int x = 0; x < size; x++)
479
36.5M
            dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
480
5.47M
        dst += frame->linesize[plane];
481
5.47M
    }
482
483
910k
    return 0;
484
920k
}
485
486
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
487
                                   int bx, int by, int size, int plane)
488
21.2k
{
489
21.2k
    MobiClipContext *s = avctx->priv_data;
490
21.2k
    GetBitContext *gb = &s->gb;
491
21.2k
    int ret, idx = get_ue_golomb_31(gb);
492
493
21.2k
    if (idx == 0) {
494
7.39k
        return add_coefficients(avctx, frame, bx, by, size, plane);
495
13.8k
    } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
496
9.30k
        int flags = pframe_block4x4_coefficients_tab[idx];
497
498
19.7k
        for (int y = by; y < by + 8; y += 4) {
499
38.4k
            for (int x = bx; x < bx + 8; x += 4) {
500
27.9k
                if (flags & 1) {
501
10.3k
                    ret = add_coefficients(avctx, frame, x, y, 4, plane);
502
10.3k
                    if (ret < 0)
503
5.80k
                        return ret;
504
10.3k
                }
505
22.1k
                flags >>= 1;
506
22.1k
            }
507
16.2k
        }
508
3.50k
        return 0;
509
9.30k
    } else {
510
4.57k
        return AVERROR_INVALIDDATA;
511
4.57k
    }
512
21.2k
}
513
514
static int adjust(int x, int size)
515
3.92M
{
516
3.92M
    return size == 16 ? (x + 1) >> 1 : x;
517
3.92M
}
518
519
static uint8_t pget(BlockXY b)
520
2.29G
{
521
2.29G
    BlockXY ret = b;
522
2.29G
    int x, y;
523
524
2.29G
    if (b.x == -1 && b.y >= b.size) {
525
284M
        ret.x = -1, ret.y = b.size - 1;
526
2.00G
    } else if (b.x >= -1 && b.y >= -1) {
527
2.00G
        ret.x = b.x, ret.y = b.y;
528
2.00G
    } else if (b.x == -1 && b.y == -2) {
529
403k
        ret.x = 0, ret.y = -1;
530
403k
    } else if (b.x == -2 && b.y == -1) {
531
75.5k
        ret.x = -1, ret.y = 0;
532
75.5k
    }
533
534
2.29G
    y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
535
2.29G
    x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
536
537
2.29G
    return ret.block[y * ret.linesize + x];
538
2.29G
}
539
540
static uint8_t half(int a, int b)
541
201M
{
542
201M
    return ((a + b) + 1) / 2;
543
201M
}
544
545
static uint8_t half3(int a, int b, int c)
546
393M
{
547
393M
    return ((a + b + b + c) * 2 / 4 + 1) / 2;
548
393M
}
549
550
static uint8_t pick_above(BlockXY bxy)
551
52.1M
{
552
52.1M
    bxy.y = bxy.y - 1;
553
554
52.1M
    return pget(bxy);
555
52.1M
}
556
557
static uint8_t pick_left(BlockXY bxy)
558
25.3M
{
559
25.3M
    bxy.x = bxy.x - 1;
560
561
25.3M
    return pget(bxy);
562
25.3M
}
563
564
static uint8_t half_horz(BlockXY bxy)
565
2.99M
{
566
2.99M
    BlockXY a = bxy, b = bxy, c = bxy;
567
568
2.99M
    a.x -= 1;
569
2.99M
    c.x += 1;
570
571
2.99M
    return half3(pget(a), pget(b), pget(c));
572
2.99M
}
573
574
static uint8_t half_vert(BlockXY bxy)
575
200M
{
576
200M
    BlockXY a = bxy, b = bxy, c = bxy;
577
578
200M
    a.y -= 1;
579
200M
    c.y += 1;
580
581
200M
    return half3(pget(a), pget(b), pget(c));
582
200M
}
583
584
static uint8_t pick_4(BlockXY bxy)
585
395M
{
586
395M
    int val;
587
588
395M
    if ((bxy.x % 2) == 0) {
589
197M
        BlockXY ba, bb;
590
197M
        int a, b;
591
592
197M
        ba = bxy;
593
197M
        ba.x = -1;
594
197M
        ba.y = bxy.y + bxy.x / 2;
595
197M
        a = pget(ba);
596
597
197M
        bb = bxy;
598
197M
        bb.x = -1;
599
197M
        bb.y = bxy.y + bxy.x / 2 + 1;
600
197M
        b = pget(bb);
601
602
197M
        val = half(a, b);
603
197M
    } else {
604
197M
        BlockXY ba;
605
606
197M
        ba = bxy;
607
197M
        ba.x = -1;
608
197M
        ba.y = bxy.y + bxy.x / 2 + 1;
609
197M
        val = half_vert(ba);
610
197M
    }
611
612
395M
    return val;
613
395M
}
614
615
static uint8_t pick_5(BlockXY bxy)
616
4.62M
{
617
4.62M
    int val;
618
619
4.62M
    if (bxy.x == 0) {
620
586k
        BlockXY a = bxy;
621
586k
        BlockXY b = bxy;
622
623
586k
        a.x = -1;
624
586k
        a.y -= 1;
625
626
586k
        b.x = -1;
627
628
586k
        val = half(pget(a), pget(b));
629
4.03M
    } else if (bxy.y == 0) {
630
510k
        BlockXY a = bxy;
631
632
510k
        a.x -= 2;
633
510k
        a.y -= 1;
634
635
510k
        val = half_horz(a);
636
3.52M
    } else if (bxy.x == 1) {
637
510k
        BlockXY a = bxy;
638
639
510k
        a.x -= 2;
640
510k
        a.y -= 1;
641
642
510k
        val = half_vert(a);
643
3.01M
    } else {
644
3.01M
        BlockXY a = bxy;
645
646
3.01M
        a.x -= 2;
647
3.01M
        a.y -= 1;
648
649
3.01M
        val = pget(a);
650
3.01M
    }
651
652
4.62M
    return val;
653
4.62M
}
654
655
static uint8_t pick_6(BlockXY bxy)
656
20.8M
{
657
20.8M
    int val;
658
659
20.8M
    if (bxy.y == 0) {
660
2.81M
        BlockXY a = bxy;
661
2.81M
        BlockXY b = bxy;
662
663
2.81M
        a.x -= 1;
664
2.81M
        a.y = -1;
665
666
2.81M
        b.y = -1;
667
668
2.81M
        val = half(pget(a), pget(b));
669
18.0M
    } else if (bxy.x == 0) {
670
2.40M
        BlockXY a = bxy;
671
672
2.40M
        a.x -= 1;
673
2.40M
        a.y -= 2;
674
675
2.40M
        val = half_vert(a);
676
15.6M
    } else if (bxy.y == 1) {
677
2.40M
        BlockXY a = bxy;
678
679
2.40M
        a.x -= 1;
680
2.40M
        a.y -= 2;
681
682
2.40M
        val = half_horz(a);
683
13.2M
    } else {
684
13.2M
        BlockXY a = bxy;
685
686
13.2M
        a.x -= 1;
687
13.2M
        a.y -= 2;
688
689
13.2M
        val = pget(a);
690
13.2M
    }
691
692
20.8M
    return val;
693
20.8M
}
694
695
static uint8_t pick_7(BlockXY bxy)
696
805M
{
697
805M
    int clr, acc1, acc2;
698
805M
    BlockXY a = bxy;
699
700
805M
    a.x -= 1;
701
805M
    a.y -= 1;
702
805M
    clr = pget(a);
703
805M
    if (bxy.x && bxy.y)
704
615M
        return clr;
705
706
190M
    if (bxy.x == 0) {
707
101M
        a.x = -1;
708
101M
        a.y = bxy.y;
709
101M
    } else {
710
88.6M
        a.x = bxy.x - 2;
711
88.6M
        a.y = -1;
712
88.6M
    }
713
190M
    acc1 = pget(a);
714
715
190M
    if (bxy.y == 0) {
716
101M
        a.x = bxy.x;
717
101M
        a.y = -1;
718
101M
    } else {
719
88.6M
        a.x = -1;
720
88.6M
        a.y = bxy.y - 2;
721
88.6M
    }
722
190M
    acc2 = pget(a);
723
724
190M
    return half3(acc1, clr, acc2);
725
805M
}
726
727
static uint8_t pick_8(BlockXY bxy)
728
335k
{
729
335k
    BlockXY ba = bxy;
730
335k
    BlockXY bb = bxy;
731
335k
    int val;
732
733
335k
    if (bxy.y == 0) {
734
56.5k
        int a, b;
735
736
56.5k
        ba.y = -1;
737
56.5k
        a = pget(ba);
738
739
56.5k
        bb.x += 1;
740
56.5k
        bb.y = -1;
741
742
56.5k
        b = pget(bb);
743
744
56.5k
        val = half(a, b);
745
278k
    } else if (bxy.y == 1) {
746
56.5k
        ba.x += 1;
747
56.5k
        ba.y -= 2;
748
749
56.5k
        val = half_horz(ba);
750
222k
    } else if (bxy.x < bxy.size - 1) {
751
187k
        ba.x += 1;
752
187k
        ba.y -= 2;
753
754
187k
        val = pget(ba);
755
187k
    } else if (bxy.y % 2 == 0) {
756
17.5k
        int a, b;
757
758
17.5k
        ba.x = bxy.y / 2 + bxy.size - 1;
759
17.5k
        ba.y = -1;
760
17.5k
        a = pget(ba);
761
762
17.5k
        bb.x = bxy.y / 2 + bxy.size;
763
17.5k
        bb.y = -1;
764
765
17.5k
        b = pget(bb);
766
767
17.5k
        val = half(a, b);
768
17.5k
    } else {
769
17.5k
        ba.x = bxy.y / 2 + bxy.size;
770
17.5k
        ba.y = -1;
771
772
17.5k
        val = half_horz(ba);
773
17.5k
    }
774
775
335k
    return val;
776
335k
}
777
778
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
779
2.22M
{
780
19.4M
    for (int y = 0; y < size; y++) {
781
17.2M
        memset(block, fill, size);
782
17.2M
        block += linesize;
783
17.2M
    }
784
2.22M
}
785
786
static void block_fill(uint8_t *block, int size, int linesize,
787
                       int w, int h, int ax, int ay,
788
                       uint8_t (*pick)(BlockXY bxy))
789
21.0M
{
790
21.0M
    BlockXY bxy;
791
792
21.0M
    bxy.size = size;
793
21.0M
    bxy.block = block;
794
21.0M
    bxy.linesize = linesize;
795
21.0M
    bxy.w = w;
796
21.0M
    bxy.h = h;
797
21.0M
    bxy.ay = ay;
798
21.0M
    bxy.ax = ax;
799
800
185M
    for (int y = 0; y < size; y++) {
801
164M
        bxy.y = y;
802
1.46G
        for (int x = 0; x < size; x++) {
803
1.30G
            uint8_t val;
804
805
1.30G
            bxy.x = x;
806
807
1.30G
            val = pick(bxy);
808
809
1.30G
            block[ax + x + (ay + y) * linesize] = val;
810
1.30G
        }
811
164M
    }
812
21.0M
}
813
814
static int block_sum(const uint8_t *block, int w, int h, int linesize)
815
3.60M
{
816
3.60M
    int sum = 0;
817
818
19.2M
    for (int y = 0; y < h; y++) {
819
43.4M
        for (int x = 0; x < w; x++) {
820
27.8M
            sum += block[x];
821
27.8M
        }
822
15.6M
        block += linesize;
823
15.6M
    }
824
825
3.60M
    return sum;
826
3.60M
}
827
828
static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
829
                          int pmode, int add_coeffs, int size, int plane)
830
23.6M
{
831
23.6M
    MobiClipContext *s = avctx->priv_data;
832
23.6M
    GetBitContext *gb = &s->gb;
833
23.6M
    int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
834
23.6M
    int ret = 0;
835
836
23.6M
    switch (pmode) {
837
942k
    case 0:
838
942k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
839
942k
        break;
840
503k
    case 1:
841
503k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
842
503k
        break;
843
216k
    case 2:
844
216k
        {
845
216k
            int arr1[16];
846
216k
            int arr2[16];
847
216k
            uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
848
216k
            uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
849
216k
            int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
850
216k
            int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
851
216k
            int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16);
852
216k
            int r6 = adjust(avg - bottommost, size);
853
216k
            int r9 = adjust(avg - rightmost, size);
854
216k
            int shift = adjust(size, size) == 8 ? 3 : 2;
855
216k
            uint8_t *block;
856
857
1.85M
            for (int x = 0; x < size; x++) {
858
1.63M
                int val = top[x];
859
1.63M
                arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
860
1.63M
            }
861
862
1.85M
            for (int y = 0; y < size; y++) {
863
1.63M
                int val = left[y * frame->linesize[plane]];
864
1.63M
                arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
865
1.63M
            }
866
867
216k
            block = frame->data[plane] + ay * frame->linesize[plane] + ax;
868
1.85M
            for (int y = 0; y < size; y++) {
869
14.9M
                for (int x = 0; x < size; x++) {
870
13.3M
                    block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
871
13.3M
                                                       arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
872
13.3M
                }
873
1.63M
                block += frame->linesize[plane];
874
1.63M
                left  += frame->linesize[plane];
875
1.63M
            }
876
216k
        }
877
216k
        break;
878
2.22M
    case 3:
879
2.22M
        {
880
2.22M
            uint8_t fill;
881
882
2.22M
            if (ax == 0 && ay == 0) {
883
7.91k
                fill = 0x80;
884
2.21M
            } else if (ax >= 1 && ay >= 1) {
885
1.39M
                int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
886
1.39M
                                     1, size, frame->linesize[plane]);
887
1.39M
                int top  = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
888
1.39M
                                     size, 1, frame->linesize[plane]);
889
890
1.39M
                fill = ((left + top) * 2 / (2 * size) + 1) / 2;
891
1.39M
            } else if (ax >= 1) {
892
401k
                fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
893
401k
                                  1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
894
421k
            } else if (ay >= 1) {
895
421k
                fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
896
421k
                                  size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
897
421k
            } else {
898
0
                return -1;
899
0
            }
900
901
2.22M
            block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
902
2.22M
                              size, frame->linesize[plane], fill);
903
2.22M
        }
904
0
        break;
905
6.24M
    case 4:
906
6.24M
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
907
6.24M
        break;
908
75.5k
    case 5:
909
75.5k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
910
75.5k
        break;
911
403k
    case 6:
912
403k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
913
403k
        break;
914
12.8M
    case 7:
915
12.8M
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
916
12.8M
        break;
917
10.7k
    case 8:
918
10.7k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
919
10.7k
        break;
920
23.6M
    }
921
922
23.6M
    if (add_coeffs)
923
902k
        ret = add_coefficients(avctx, frame, ax, ay, size, plane);
924
925
23.6M
    return ret;
926
23.6M
}
927
928
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
929
1.70M
{
930
1.70M
    MobiClipContext *s = avctx->priv_data;
931
1.70M
    GetBitContext *gb = &s->gb;
932
1.70M
    int index = (y & 0xC) | (x / 4 % 4);
933
934
1.70M
    uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
935
1.70M
    if (val == 9)
936
366k
        val = 3;
937
938
1.70M
    if (!get_bits1(gb)) {
939
409k
        int x = get_bits(gb, 3);
940
409k
        val = x + (x >= val ? 1 : 0);
941
409k
    }
942
943
1.70M
    s->pre[index + 4] = val;
944
1.70M
    if (size == 8)
945
1.37M
        s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
946
947
1.70M
    return val;
948
1.70M
}
949
950
static int process_block(AVCodecContext *avctx, AVFrame *frame,
951
                         int x, int y, int pmode, int has_coeffs, int plane)
952
22.6M
{
953
22.6M
    MobiClipContext *s = avctx->priv_data;
954
22.6M
    GetBitContext *gb = &s->gb;
955
22.6M
    int tmp, ret;
956
957
22.6M
    if (!has_coeffs) {
958
21.9M
        if (pmode < 0)
959
1.12M
            pmode = get_prediction(avctx, x, y, 8);
960
21.9M
        return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
961
21.9M
    }
962
963
739k
    tmp = get_ue_golomb_31(gb);
964
739k
    if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
965
6.34k
        return AVERROR_INVALIDDATA;
966
967
733k
    if (tmp == 0) {
968
450k
        if (pmode < 0)
969
248k
            pmode = get_prediction(avctx, x, y, 8);
970
450k
        ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
971
450k
    } else {
972
283k
        int flags = block4x4_coefficients_tab[tmp - 1];
973
974
843k
        for (int by = y; by < y + 8; by += 4) {
975
1.68M
            for (int bx = x; bx < x + 8; bx += 4) {
976
1.12M
                int new_pmode = pmode;
977
978
1.12M
                if (new_pmode < 0)
979
327k
                    new_pmode = get_prediction(avctx, bx, by, 4);
980
1.12M
                ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
981
1.12M
                if (ret < 0)
982
3.48k
                    return ret;
983
1.12M
                flags >>= 1;
984
1.12M
            }
985
563k
        }
986
283k
    }
987
988
730k
    return ret;
989
733k
}
990
991
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
992
                             int x, int y, int predict)
993
3.79M
{
994
3.79M
    MobiClipContext *s = avctx->priv_data;
995
3.79M
    GetBitContext *gb = &s->gb;
996
3.79M
    int flags, pmode_uv, idx = get_ue_golomb(gb);
997
3.79M
    int ret = 0;
998
999
3.79M
    if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1000
2.33k
        return AVERROR_INVALIDDATA;
1001
1002
3.78M
    flags = block8x8_coefficients_tab[idx];
1003
1004
3.78M
    if (predict) {
1005
366k
        ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1006
366k
        if (ret < 0)
1007
840
            return ret;
1008
365k
        flags >>= 1;
1009
365k
        ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1010
365k
        if (ret < 0)
1011
1.19k
            return ret;
1012
364k
        flags >>= 1;
1013
364k
        ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1014
364k
        if (ret < 0)
1015
684
            return ret;
1016
363k
        flags >>= 1;
1017
363k
        ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1018
363k
        if (ret < 0)
1019
1.61k
            return ret;
1020
362k
        flags >>= 1;
1021
3.42M
    } else {
1022
3.42M
        int pmode = get_bits(gb, 3);
1023
1024
3.42M
        if (pmode == 2) {
1025
6.15k
            ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1026
6.15k
            if (ret < 0)
1027
0
                return ret;
1028
6.15k
            pmode = 9;
1029
6.15k
        }
1030
1031
3.42M
        ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1032
3.42M
        if (ret < 0)
1033
2.40k
            return ret;
1034
3.41M
        flags >>= 1;
1035
3.41M
        ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1036
3.41M
        if (ret < 0)
1037
1.42k
            return ret;
1038
3.41M
        flags >>= 1;
1039
3.41M
        ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1040
3.41M
        if (ret < 0)
1041
513
            return ret;
1042
3.41M
        flags >>= 1;
1043
3.41M
        ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1044
3.41M
        if (ret < 0)
1045
471
            return ret;
1046
3.41M
        flags >>= 1;
1047
3.41M
    }
1048
1049
3.77M
    pmode_uv = get_bits(gb, 3);
1050
3.77M
    if (pmode_uv == 2) {
1051
48.6k
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1052
48.6k
        if (ret < 0)
1053
0
            return ret;
1054
48.6k
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1055
48.6k
        if (ret < 0)
1056
0
            return ret;
1057
48.6k
        pmode_uv = 9;
1058
48.6k
    }
1059
1060
3.77M
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1061
3.77M
    if (ret < 0)
1062
393
        return ret;
1063
3.77M
    flags >>= 1;
1064
3.77M
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1065
3.77M
    if (ret < 0)
1066
540
        return ret;
1067
1068
3.77M
    return 0;
1069
3.77M
}
1070
1071
static int get_index(int x)
1072
32.4k
{
1073
32.4k
    return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074
32.4k
}
1075
1076
static int predict_motion(AVCodecContext *avctx,
1077
                          int width, int height, int index,
1078
                          int offsetm, int offsetx, int offsety)
1079
152k
{
1080
152k
    MobiClipContext *s = avctx->priv_data;
1081
152k
    MotionXY *motion = s->motion;
1082
152k
    GetBitContext *gb = &s->gb;
1083
152k
    int fheight = avctx->height;
1084
152k
    int fwidth = avctx->width;
1085
1086
152k
    if (index <= 5) {
1087
135k
        int sidx = -FFMAX(1, index) + s->current_pic;
1088
135k
        MotionXY mv = s->motion[0];
1089
1090
135k
        if (sidx < 0)
1091
22.1k
            sidx += 6;
1092
1093
135k
        if (index > 0) {
1094
26.1k
            mv.x = mv.x + (unsigned)get_se_golomb(gb);
1095
26.1k
            mv.y = mv.y + (unsigned)get_se_golomb(gb);
1096
26.1k
        }
1097
135k
        if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1098
605
            return AVERROR_INVALIDDATA;
1099
1100
135k
        motion[offsetm].x = mv.x;
1101
135k
        motion[offsetm].y = mv.y;
1102
1103
510k
        for (int i = 0; i < 3; i++) {
1104
385k
            int method, src_linesize, dst_linesize;
1105
385k
            uint8_t *src, *dst;
1106
1107
385k
            if (i == 1) {
1108
125k
                offsetx = offsetx >> 1;
1109
125k
                offsety = offsety >> 1;
1110
125k
                mv.x = mv.x >> 1;
1111
125k
                mv.y = mv.y >> 1;
1112
125k
                width = width >> 1;
1113
125k
                height = height >> 1;
1114
125k
                fwidth = fwidth >> 1;
1115
125k
                fheight = fheight >> 1;
1116
125k
            }
1117
1118
385k
            av_assert0(s->pic[sidx]);
1119
385k
            av_assert0(s->pic[s->current_pic]);
1120
385k
            av_assert0(s->pic[s->current_pic]->data[i]);
1121
385k
            if (!s->pic[sidx]->data[i])
1122
7.39k
                return AVERROR_INVALIDDATA;
1123
1124
377k
            method = (mv.x & 1) | ((mv.y & 1) << 1);
1125
377k
            src_linesize = s->pic[sidx]->linesize[i];
1126
377k
            dst_linesize = s->pic[s->current_pic]->linesize[i];
1127
377k
            dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1128
1129
377k
            if (offsetx + (mv.x >> 1) < 0 ||
1130
377k
                offsety + (mv.y >> 1) < 0 ||
1131
376k
                offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1132
375k
                offsety + height + (mv.y + 1 >> 1) > fheight)
1133
2.78k
                return AVERROR_INVALIDDATA;
1134
1135
375k
            switch (method) {
1136
352k
            case 0:
1137
352k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1138
352k
                               (offsety + (mv.y >> 1)) * src_linesize;
1139
3.89M
                for (int y = 0; y < height; y++) {
1140
45.0M
                    for (int x = 0; x < width; x++)
1141
41.4M
                        dst[x] = src[x];
1142
3.54M
                    dst += dst_linesize;
1143
3.54M
                    src += src_linesize;
1144
3.54M
                }
1145
352k
                break;
1146
9.47k
            case 1:
1147
9.47k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1148
9.47k
                               (offsety + (mv.y >> 1)) * src_linesize;
1149
72.4k
                for (int y = 0; y < height; y++) {
1150
642k
                    for (int x = 0; x < width; x++) {
1151
579k
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152
579k
                    }
1153
1154
62.9k
                    dst += dst_linesize;
1155
62.9k
                    src += src_linesize;
1156
62.9k
                }
1157
9.47k
                break;
1158
11.0k
            case 2:
1159
11.0k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1160
11.0k
                               (offsety + (mv.y >> 1)) * src_linesize;
1161
100k
                for (int y = 0; y < height; y++) {
1162
1.28M
                    for (int x = 0; x < width; x++) {
1163
1.19M
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164
1.19M
                    }
1165
1166
89.1k
                    dst += dst_linesize;
1167
89.1k
                    src += src_linesize;
1168
89.1k
                }
1169
11.0k
                break;
1170
2.49k
            case 3:
1171
2.49k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1172
2.49k
                               (offsety + (mv.y >> 1)) * src_linesize;
1173
33.5k
                for (int y = 0; y < height; y++) {
1174
490k
                    for (int x = 0; x < width; x++) {
1175
459k
                        dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1176
459k
                                           (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177
459k
                    }
1178
1179
31.0k
                    dst += dst_linesize;
1180
31.0k
                    src += src_linesize;
1181
31.0k
                }
1182
2.49k
                break;
1183
375k
            }
1184
375k
        }
1185
135k
    } else {
1186
16.2k
        int tidx;
1187
16.2k
        int adjx = index == 8 ? 0 :  width / 2;
1188
16.2k
        int adjy = index == 8 ? height / 2 : 0;
1189
1190
16.2k
        width  = width  - adjx;
1191
16.2k
        height = height - adjy;
1192
16.2k
        tidx = get_index(height) * 4 + get_index(width);
1193
1194
38.1k
        for (int i = 0; i < 2; i++) {
1195
28.2k
            int ret, idx2;
1196
1197
28.2k
            idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx], MOBI_MV_VLC_BITS, 1);
1198
1199
28.2k
            ret = predict_motion(avctx, width, height, idx2,
1200
28.2k
                                 offsetm, offsetx + i * adjx, offsety + i * adjy);
1201
28.2k
            if (ret < 0)
1202
6.37k
                return ret;
1203
28.2k
        }
1204
16.2k
    }
1205
1206
134k
    return 0;
1207
152k
}
1208
1209
static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
1210
                           int *got_frame, AVPacket *pkt)
1211
312k
{
1212
312k
    MobiClipContext *s = avctx->priv_data;
1213
312k
    GetBitContext *gb = &s->gb;
1214
312k
    AVFrame *frame = s->pic[s->current_pic];
1215
312k
    int ret;
1216
1217
312k
    if (avctx->height/16 * (avctx->width/16) * 2 > 8LL*FFALIGN(pkt->size, 2))
1218
179k
        return AVERROR_INVALIDDATA;
1219
1220
132k
    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1221
132k
                          pkt->size);
1222
1223
132k
    if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1224
6.11k
        return ret;
1225
1226
126k
    s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1227
126k
                        (uint16_t *)pkt->data,
1228
126k
                        (pkt->size + 1) >> 1);
1229
1230
126k
    ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1231
126k
    if (ret < 0)
1232
0
        return ret;
1233
1234
126k
    if (get_bits1(gb)) {
1235
20.0k
        frame->pict_type = AV_PICTURE_TYPE_I;
1236
20.0k
        frame->flags |= AV_FRAME_FLAG_KEY;
1237
20.0k
        s->moflex = get_bits1(gb);
1238
20.0k
        s->dct_tab_idx = get_bits1(gb);
1239
1240
20.0k
        ret = setup_qtables(avctx, get_bits(gb, 6));
1241
20.0k
        if (ret < 0)
1242
414
            return ret;
1243
1244
1.12M
        for (int y = 0; y < avctx->height; y += 16) {
1245
4.88M
            for (int x = 0; x < avctx->width; x += 16) {
1246
3.78M
                ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1247
3.78M
                if (ret < 0)
1248
9.53k
                    return ret;
1249
3.78M
            }
1250
1.11M
        }
1251
106k
    } else {
1252
106k
        MotionXY *motion = s->motion;
1253
1254
106k
        memset(motion, 0, s->motion_size);
1255
1256
106k
        frame->pict_type = AV_PICTURE_TYPE_P;
1257
106k
        frame->flags &= ~AV_FRAME_FLAG_KEY;
1258
106k
        s->dct_tab_idx = 0;
1259
1260
106k
        ret = setup_qtables(avctx, s->quantizer + (int64_t)get_se_golomb(gb));
1261
106k
        if (ret < 0)
1262
7.60k
            return ret;
1263
1264
186k
        for (int y = 0; y < avctx->height; y += 16) {
1265
214k
            for (int x = 0; x < avctx->width; x += 16) {
1266
127k
                int idx;
1267
1268
127k
                motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1269
127k
                motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1270
127k
                motion[x / 16 + 2].x = 0;
1271
127k
                motion[x / 16 + 2].y = 0;
1272
1273
127k
                idx = get_vlc2(gb, mv_vlc[s->moflex][0], MOBI_MV_VLC_BITS, 1);
1274
1275
127k
                if (idx == 6 || idx == 7) {
1276
3.54k
                    ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1277
3.54k
                    if (ret < 0)
1278
2.88k
                        return ret;
1279
123k
                } else {
1280
123k
                    int flags, idx2;
1281
123k
                    ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1282
123k
                    if (ret < 0)
1283
10.7k
                        return ret;
1284
113k
                    idx2 = get_ue_golomb(gb);
1285
113k
                    if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1286
1.57k
                        return AVERROR_INVALIDDATA;
1287
111k
                    flags = pframe_block8x8_coefficients_tab[idx2];
1288
1289
334k
                    for (int sy = y; sy < y + 16; sy += 8) {
1290
668k
                        for (int sx = x; sx < x + 16; sx += 8) {
1291
445k
                            if (flags & 1)
1292
19.9k
                                add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1293
445k
                            flags >>= 1;
1294
445k
                        }
1295
222k
                    }
1296
1297
111k
                    if (flags & 1)
1298
892
                        add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1299
111k
                    flags >>= 1;
1300
111k
                    if (flags & 1)
1301
448
                        add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1302
111k
                }
1303
127k
            }
1304
102k
        }
1305
99.1k
    }
1306
1307
94.0k
    if (!s->moflex)
1308
6.96k
        avctx->colorspace = AVCOL_SPC_YCGCO;
1309
1310
94.0k
    s->current_pic = (s->current_pic + 1) % 6;
1311
94.0k
    ret = av_frame_ref(rframe, frame);
1312
94.0k
    if (ret < 0)
1313
0
        return ret;
1314
94.0k
    *got_frame = 1;
1315
1316
94.0k
    return 0;
1317
94.0k
}
1318
1319
static av_cold void mobiclip_flush(AVCodecContext *avctx)
1320
67.6k
{
1321
67.6k
    MobiClipContext *s = avctx->priv_data;
1322
1323
473k
    for (int i = 0; i < 6; i++)
1324
406k
        av_frame_unref(s->pic[i]);
1325
67.6k
}
1326
1327
static av_cold int mobiclip_close(AVCodecContext *avctx)
1328
1.70k
{
1329
1.70k
    MobiClipContext *s = avctx->priv_data;
1330
1331
1.70k
    av_freep(&s->bitstream);
1332
1.70k
    s->bitstream_size = 0;
1333
1.70k
    av_freep(&s->motion);
1334
1.70k
    s->motion_size = 0;
1335
1336
11.9k
    for (int i = 0; i < 6; i++) {
1337
10.2k
        av_frame_free(&s->pic[i]);
1338
10.2k
    }
1339
1340
1.70k
    return 0;
1341
1.70k
}
1342
1343
const FFCodec ff_mobiclip_decoder = {
1344
    .p.name         = "mobiclip",
1345
    CODEC_LONG_NAME("MobiClip Video"),
1346
    .p.type         = AVMEDIA_TYPE_VIDEO,
1347
    .p.id           = AV_CODEC_ID_MOBICLIP,
1348
    .priv_data_size = sizeof(MobiClipContext),
1349
    .init           = mobiclip_init,
1350
    FF_CODEC_DECODE_CB(mobiclip_decode),
1351
    .flush          = mobiclip_flush,
1352
    .close          = mobiclip_close,
1353
    .p.capabilities = AV_CODEC_CAP_DR1,
1354
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1355
};