Coverage Report

Created: 2026-05-23 07:06

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.58M
#define MOBI_RL_VLC_BITS 12
40
168k
#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.81k
{
305
1.81k
    static AVOnce init_static_once = AV_ONCE_INIT;
306
1.81k
    MobiClipContext *s = avctx->priv_data;
307
308
1.81k
    if (avctx->width & 15 || avctx->height & 15) {
309
20
        av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
310
20
        return AVERROR_INVALIDDATA;
311
20
    }
312
313
1.79k
    ff_bswapdsp_init(&s->bdsp);
314
315
1.79k
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
316
317
1.79k
    s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
318
1.79k
    if (!s->motion)
319
0
        return AVERROR(ENOMEM);
320
1.79k
    s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
321
322
12.5k
    for (int i = 0; i < 6; i++) {
323
10.7k
        s->pic[i] = av_frame_alloc();
324
10.7k
        if (!s->pic[i])
325
0
            return AVERROR(ENOMEM);
326
10.7k
    }
327
328
1.79k
    ff_thread_once(&init_static_once, mobiclip_init_static);
329
330
1.79k
    return 0;
331
1.79k
}
332
333
static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
334
127k
{
335
127k
    MobiClipContext *s = avctx->priv_data;
336
127k
    int qx, qy;
337
338
127k
    if (quantizer < 12 || quantizer > 161)
339
8.02k
        return AVERROR_INVALIDDATA;
340
341
119k
    s->quantizer = quantizer;
342
343
119k
    qx = quantizer % 6;
344
119k
    qy = quantizer / 6;
345
346
2.03M
    for (int i = 0; i < 16; i++)
347
1.91M
        s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
348
349
7.78M
    for (int i = 0; i < 64; i++)
350
7.66M
        s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
351
352
2.51M
    for (int i = 0; i < 20; i++)
353
2.39M
        s->pre[i] = 9;
354
355
119k
    return 0;
356
127k
}
357
358
static void inverse4(unsigned *rs)
359
13.2M
{
360
13.2M
    unsigned a = rs[0] + rs[2];
361
13.2M
    unsigned b = rs[0] - rs[2];
362
13.2M
    unsigned c = rs[1] + ((int)rs[3] >> 1);
363
13.2M
    unsigned d = ((int)rs[1] >> 1) - rs[3];
364
365
13.2M
    rs[0] = a + c;
366
13.2M
    rs[1] = b + d;
367
13.2M
    rs[2] = b - d;
368
13.2M
    rs[3] = a - c;
369
13.2M
}
370
371
static void idct(int *arr, int size)
372
13.2M
{
373
13.2M
    int e, f, g, h;
374
13.2M
    unsigned x3, x2, x1, x0;
375
13.2M
    int tmp[4];
376
377
13.2M
    if (size == 4) {
378
4.39M
        inverse4(arr);
379
4.39M
        return;
380
4.39M
    }
381
382
8.89M
    tmp[0] = arr[0];
383
8.89M
    tmp[1] = arr[2];
384
8.89M
    tmp[2] = arr[4];
385
8.89M
    tmp[3] = arr[6];
386
387
8.89M
    inverse4(tmp);
388
389
8.89M
    e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
390
8.89M
    f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
391
8.89M
    g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
392
8.89M
    h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
393
8.89M
    x3 = (unsigned)g + (h >> 2);
394
8.89M
    x2 = (unsigned)e + (f >> 2);
395
8.89M
    x1 = (e >> 2) - (unsigned)f;
396
8.89M
    x0 = (unsigned)h - (g >> 2);
397
398
8.89M
    arr[0] = tmp[0] + x0;
399
8.89M
    arr[1] = tmp[1] + x1;
400
8.89M
    arr[2] = tmp[2] + x2;
401
8.89M
    arr[3] = tmp[3] + x3;
402
8.89M
    arr[4] = tmp[3] - x3;
403
8.89M
    arr[5] = tmp[2] - x2;
404
8.89M
    arr[6] = tmp[1] - x1;
405
8.89M
    arr[7] = tmp[0] - x0;
406
8.89M
}
407
408
static void read_run_encoding(AVCodecContext *avctx,
409
                              int *last, int *run, int *level)
410
2.58M
{
411
2.58M
    MobiClipContext *s = avctx->priv_data;
412
2.58M
    GetBitContext *gb = &s->gb;
413
2.58M
    int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx], MOBI_RL_VLC_BITS, 1);
414
415
2.58M
    *last = (n >> 11) == 1;
416
2.58M
    *run  = (n >> 5) & 0x3F;
417
2.58M
    *level = n & 0x1F;
418
2.58M
}
419
420
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
421
                            int bx, int by, int size, int plane)
422
1.11M
{
423
1.11M
    MobiClipContext *s = avctx->priv_data;
424
1.11M
    GetBitContext *gb = &s->gb;
425
1.11M
    int mat[64] = { 0 };
426
1.11M
    const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
427
1.11M
    const int *qtab = s->qtab[size == 8];
428
1.11M
    uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
429
430
2.57M
    for (int pos = 0; get_bits_left(gb) > 0; pos++) {
431
2.56M
        int qval, last, run, level;
432
433
2.56M
        read_run_encoding(avctx, &last, &run, &level);
434
435
2.56M
        if (level) {
436
2.54M
            if (get_bits1(gb))
437
1.33M
                level = -level;
438
2.54M
        } else if (!get_bits1(gb)) {
439
14.4k
            read_run_encoding(avctx, &last, &run, &level);
440
14.4k
            level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
441
14.4k
            if (get_bits1(gb))
442
7.13k
                level = -level;
443
14.4k
        } else if (!get_bits1(gb)) {
444
2.52k
            read_run_encoding(avctx, &last, &run, &level);
445
2.52k
            run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446
2.52k
            if (get_bits1(gb))
447
968
                level = -level;
448
5.93k
        } else {
449
5.93k
            last  = get_bits1(gb);
450
5.93k
            run   = get_bits(gb, 6);
451
5.93k
            level = get_sbits(gb, 12);
452
5.93k
        }
453
454
2.56M
        pos += run;
455
2.56M
        if (pos >= size * size)
456
12.0k
            return AVERROR_INVALIDDATA;
457
2.55M
        qval = qtab[pos];
458
2.55M
        mat[ztab[pos]] = qval *(unsigned)level;
459
460
2.55M
        if (last)
461
1.09M
            break;
462
2.55M
    }
463
464
1.10M
    mat[0] += 32;
465
7.74M
    for (int y = 0; y < size; y++)
466
6.64M
        idct(&mat[y * size], size);
467
468
7.74M
    for (int y = 0; y < size; y++) {
469
25.5M
        for (int x = y + 1; x < size; x++) {
470
18.8M
            int a = mat[x * size + y];
471
18.8M
            int b = mat[y * size + x];
472
473
18.8M
            mat[y * size + x] = a;
474
18.8M
            mat[x * size + y] = b;
475
18.8M
        }
476
477
6.64M
        idct(&mat[y * size], size);
478
51.0M
        for (int x = 0; x < size; x++)
479
44.3M
            dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
480
6.64M
        dst += frame->linesize[plane];
481
6.64M
    }
482
483
1.10M
    return 0;
484
1.11M
}
485
486
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
487
                                   int bx, int by, int size, int plane)
488
26.0k
{
489
26.0k
    MobiClipContext *s = avctx->priv_data;
490
26.0k
    GetBitContext *gb = &s->gb;
491
26.0k
    int ret, idx = get_ue_golomb_31(gb);
492
493
26.0k
    if (idx == 0) {
494
9.81k
        return add_coefficients(avctx, frame, bx, by, size, plane);
495
16.2k
    } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
496
11.4k
        int flags = pframe_block4x4_coefficients_tab[idx];
497
498
24.5k
        for (int y = by; y < by + 8; y += 4) {
499
47.7k
            for (int x = bx; x < bx + 8; x += 4) {
500
34.6k
                if (flags & 1) {
501
12.7k
                    ret = add_coefficients(avctx, frame, x, y, 4, plane);
502
12.7k
                    if (ret < 0)
503
7.10k
                        return ret;
504
12.7k
                }
505
27.5k
                flags >>= 1;
506
27.5k
            }
507
20.1k
        }
508
4.38k
        return 0;
509
11.4k
    } else {
510
4.74k
        return AVERROR_INVALIDDATA;
511
4.74k
    }
512
26.0k
}
513
514
static int adjust(int x, int size)
515
4.75M
{
516
4.75M
    return size == 16 ? (x + 1) >> 1 : x;
517
4.75M
}
518
519
static uint8_t pget(BlockXY b)
520
2.41G
{
521
2.41G
    BlockXY ret = b;
522
2.41G
    int x, y;
523
524
2.41G
    if (b.x == -1 && b.y >= b.size) {
525
295M
        ret.x = -1, ret.y = b.size - 1;
526
2.11G
    } else if (b.x >= -1 && b.y >= -1) {
527
2.11G
        ret.x = b.x, ret.y = b.y;
528
2.11G
    } else if (b.x == -1 && b.y == -2) {
529
479k
        ret.x = 0, ret.y = -1;
530
479k
    } else if (b.x == -2 && b.y == -1) {
531
92.6k
        ret.x = -1, ret.y = 0;
532
92.6k
    }
533
534
2.41G
    y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
535
2.41G
    x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
536
537
2.41G
    return ret.block[y * ret.linesize + x];
538
2.41G
}
539
540
static uint8_t half(int a, int b)
541
209M
{
542
209M
    return ((a + b) + 1) / 2;
543
209M
}
544
545
static uint8_t half3(int a, int b, int c)
546
411M
{
547
411M
    return ((a + b + b + c) * 2 / 4 + 1) / 2;
548
411M
}
549
550
static uint8_t pick_above(BlockXY bxy)
551
62.1M
{
552
62.1M
    bxy.y = bxy.y - 1;
553
554
62.1M
    return pget(bxy);
555
62.1M
}
556
557
static uint8_t pick_left(BlockXY bxy)
558
30.6M
{
559
30.6M
    bxy.x = bxy.x - 1;
560
561
30.6M
    return pget(bxy);
562
30.6M
}
563
564
static uint8_t half_horz(BlockXY bxy)
565
3.57M
{
566
3.57M
    BlockXY a = bxy, b = bxy, c = bxy;
567
568
3.57M
    a.x -= 1;
569
3.57M
    c.x += 1;
570
571
3.57M
    return half3(pget(a), pget(b), pget(c));
572
3.57M
}
573
574
static uint8_t half_vert(BlockXY bxy)
575
209M
{
576
209M
    BlockXY a = bxy, b = bxy, c = bxy;
577
578
209M
    a.y -= 1;
579
209M
    c.y += 1;
580
581
209M
    return half3(pget(a), pget(b), pget(c));
582
209M
}
583
584
static uint8_t pick_4(BlockXY bxy)
585
411M
{
586
411M
    int val;
587
588
411M
    if ((bxy.x % 2) == 0) {
589
205M
        BlockXY ba, bb;
590
205M
        int a, b;
591
592
205M
        ba = bxy;
593
205M
        ba.x = -1;
594
205M
        ba.y = bxy.y + bxy.x / 2;
595
205M
        a = pget(ba);
596
597
205M
        bb = bxy;
598
205M
        bb.x = -1;
599
205M
        bb.y = bxy.y + bxy.x / 2 + 1;
600
205M
        b = pget(bb);
601
602
205M
        val = half(a, b);
603
205M
    } else {
604
205M
        BlockXY ba;
605
606
205M
        ba = bxy;
607
205M
        ba.x = -1;
608
205M
        ba.y = bxy.y + bxy.x / 2 + 1;
609
205M
        val = half_vert(ba);
610
205M
    }
611
612
411M
    return val;
613
411M
}
614
615
static uint8_t pick_5(BlockXY bxy)
616
5.67M
{
617
5.67M
    int val;
618
619
5.67M
    if (bxy.x == 0) {
620
720k
        BlockXY a = bxy;
621
720k
        BlockXY b = bxy;
622
623
720k
        a.x = -1;
624
720k
        a.y -= 1;
625
626
720k
        b.x = -1;
627
628
720k
        val = half(pget(a), pget(b));
629
4.95M
    } else if (bxy.y == 0) {
630
627k
        BlockXY a = bxy;
631
632
627k
        a.x -= 2;
633
627k
        a.y -= 1;
634
635
627k
        val = half_horz(a);
636
4.32M
    } else if (bxy.x == 1) {
637
627k
        BlockXY a = bxy;
638
639
627k
        a.x -= 2;
640
627k
        a.y -= 1;
641
642
627k
        val = half_vert(a);
643
3.70M
    } else {
644
3.70M
        BlockXY a = bxy;
645
646
3.70M
        a.x -= 2;
647
3.70M
        a.y -= 1;
648
649
3.70M
        val = pget(a);
650
3.70M
    }
651
652
5.67M
    return val;
653
5.67M
}
654
655
static uint8_t pick_6(BlockXY bxy)
656
24.7M
{
657
24.7M
    int val;
658
659
24.7M
    if (bxy.y == 0) {
660
3.33M
        BlockXY a = bxy;
661
3.33M
        BlockXY b = bxy;
662
663
3.33M
        a.x -= 1;
664
3.33M
        a.y = -1;
665
666
3.33M
        b.y = -1;
667
668
3.33M
        val = half(pget(a), pget(b));
669
21.3M
    } else if (bxy.x == 0) {
670
2.86M
        BlockXY a = bxy;
671
672
2.86M
        a.x -= 1;
673
2.86M
        a.y -= 2;
674
675
2.86M
        val = half_vert(a);
676
18.5M
    } else if (bxy.y == 1) {
677
2.86M
        BlockXY a = bxy;
678
679
2.86M
        a.x -= 1;
680
2.86M
        a.y -= 2;
681
682
2.86M
        val = half_horz(a);
683
15.6M
    } else {
684
15.6M
        BlockXY a = bxy;
685
686
15.6M
        a.x -= 1;
687
15.6M
        a.y -= 2;
688
689
15.6M
        val = pget(a);
690
15.6M
    }
691
692
24.7M
    return val;
693
24.7M
}
694
695
static uint8_t pick_7(BlockXY bxy)
696
842M
{
697
842M
    int clr, acc1, acc2;
698
842M
    BlockXY a = bxy;
699
700
842M
    a.x -= 1;
701
842M
    a.y -= 1;
702
842M
    clr = pget(a);
703
842M
    if (bxy.x && bxy.y)
704
643M
        return clr;
705
706
199M
    if (bxy.x == 0) {
707
106M
        a.x = -1;
708
106M
        a.y = bxy.y;
709
106M
    } else {
710
92.7M
        a.x = bxy.x - 2;
711
92.7M
        a.y = -1;
712
92.7M
    }
713
199M
    acc1 = pget(a);
714
715
199M
    if (bxy.y == 0) {
716
106M
        a.x = bxy.x;
717
106M
        a.y = -1;
718
106M
    } else {
719
92.7M
        a.x = -1;
720
92.7M
        a.y = bxy.y - 2;
721
92.7M
    }
722
199M
    acc2 = pget(a);
723
724
199M
    return half3(acc1, clr, acc2);
725
842M
}
726
727
static uint8_t pick_8(BlockXY bxy)
728
379k
{
729
379k
    BlockXY ba = bxy;
730
379k
    BlockXY bb = bxy;
731
379k
    int val;
732
733
379k
    if (bxy.y == 0) {
734
65.1k
        int a, b;
735
736
65.1k
        ba.y = -1;
737
65.1k
        a = pget(ba);
738
739
65.1k
        bb.x += 1;
740
65.1k
        bb.y = -1;
741
742
65.1k
        b = pget(bb);
743
744
65.1k
        val = half(a, b);
745
314k
    } else if (bxy.y == 1) {
746
65.1k
        ba.x += 1;
747
65.1k
        ba.y -= 2;
748
749
65.1k
        val = half_horz(ba);
750
249k
    } else if (bxy.x < bxy.size - 1) {
751
209k
        ba.x += 1;
752
209k
        ba.y -= 2;
753
754
209k
        val = pget(ba);
755
209k
    } else if (bxy.y % 2 == 0) {
756
20.0k
        int a, b;
757
758
20.0k
        ba.x = bxy.y / 2 + bxy.size - 1;
759
20.0k
        ba.y = -1;
760
20.0k
        a = pget(ba);
761
762
20.0k
        bb.x = bxy.y / 2 + bxy.size;
763
20.0k
        bb.y = -1;
764
765
20.0k
        b = pget(bb);
766
767
20.0k
        val = half(a, b);
768
20.0k
    } else {
769
20.0k
        ba.x = bxy.y / 2 + bxy.size;
770
20.0k
        ba.y = -1;
771
772
20.0k
        val = half_horz(ba);
773
20.0k
    }
774
775
379k
    return val;
776
379k
}
777
778
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
779
2.65M
{
780
23.2M
    for (int y = 0; y < size; y++) {
781
20.5M
        memset(block, fill, size);
782
20.5M
        block += linesize;
783
20.5M
    }
784
2.65M
}
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
22.3M
{
790
22.3M
    BlockXY bxy;
791
792
22.3M
    bxy.size = size;
793
22.3M
    bxy.block = block;
794
22.3M
    bxy.linesize = linesize;
795
22.3M
    bxy.w = w;
796
22.3M
    bxy.h = h;
797
22.3M
    bxy.ay = ay;
798
22.3M
    bxy.ax = ax;
799
800
196M
    for (int y = 0; y < size; y++) {
801
174M
        bxy.y = y;
802
1.55G
        for (int x = 0; x < size; x++) {
803
1.37G
            uint8_t val;
804
805
1.37G
            bxy.x = x;
806
807
1.37G
            val = pick(bxy);
808
809
1.37G
            block[ax + x + (ay + y) * linesize] = val;
810
1.37G
        }
811
174M
    }
812
22.3M
}
813
814
static int block_sum(const uint8_t *block, int w, int h, int linesize)
815
4.34M
{
816
4.34M
    int sum = 0;
817
818
23.2M
    for (int y = 0; y < h; y++) {
819
52.4M
        for (int x = 0; x < w; x++) {
820
33.5M
            sum += block[x];
821
33.5M
        }
822
18.8M
        block += linesize;
823
18.8M
    }
824
825
4.34M
    return sum;
826
4.34M
}
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
25.4M
{
831
25.4M
    MobiClipContext *s = avctx->priv_data;
832
25.4M
    GetBitContext *gb = &s->gb;
833
25.4M
    int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
834
25.4M
    int ret = 0;
835
836
25.4M
    switch (pmode) {
837
1.12M
    case 0:
838
1.12M
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
839
1.12M
        break;
840
610k
    case 1:
841
610k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
842
610k
        break;
843
262k
    case 2:
844
262k
        {
845
262k
            int arr1[16];
846
262k
            int arr2[16];
847
262k
            uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
848
262k
            uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
849
262k
            int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
850
262k
            int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
851
262k
            int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16);
852
262k
            int r6 = adjust(avg - bottommost, size);
853
262k
            int r9 = adjust(avg - rightmost, size);
854
262k
            int shift = adjust(size, size) == 8 ? 3 : 2;
855
262k
            uint8_t *block;
856
857
2.24M
            for (int x = 0; x < size; x++) {
858
1.98M
                int val = top[x];
859
1.98M
                arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
860
1.98M
            }
861
862
2.24M
            for (int y = 0; y < size; y++) {
863
1.98M
                int val = left[y * frame->linesize[plane]];
864
1.98M
                arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
865
1.98M
            }
866
867
262k
            block = frame->data[plane] + ay * frame->linesize[plane] + ax;
868
2.24M
            for (int y = 0; y < size; y++) {
869
18.1M
                for (int x = 0; x < size; x++) {
870
16.1M
                    block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
871
16.1M
                                                       arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
872
16.1M
                }
873
1.98M
                block += frame->linesize[plane];
874
1.98M
                left  += frame->linesize[plane];
875
1.98M
            }
876
262k
        }
877
262k
        break;
878
2.65M
    case 3:
879
2.65M
        {
880
2.65M
            uint8_t fill;
881
882
2.65M
            if (ax == 0 && ay == 0) {
883
8.71k
                fill = 0x80;
884
2.65M
            } else if (ax >= 1 && ay >= 1) {
885
1.69M
                int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
886
1.69M
                                     1, size, frame->linesize[plane]);
887
1.69M
                int top  = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
888
1.69M
                                     size, 1, frame->linesize[plane]);
889
890
1.69M
                fill = ((left + top) * 2 / (2 * size) + 1) / 2;
891
1.69M
            } else if (ax >= 1) {
892
468k
                fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
893
468k
                                  1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
894
488k
            } else if (ay >= 1) {
895
488k
                fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
896
488k
                                  size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
897
488k
            } else {
898
0
                return -1;
899
0
            }
900
901
2.65M
            block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
902
2.65M
                              size, frame->linesize[plane], fill);
903
2.65M
        }
904
0
        break;
905
6.51M
    case 4:
906
6.51M
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
907
6.51M
        break;
908
92.6k
    case 5:
909
92.6k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
910
92.6k
        break;
911
479k
    case 6:
912
479k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
913
479k
        break;
914
13.5M
    case 7:
915
13.5M
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
916
13.5M
        break;
917
12.5k
    case 8:
918
12.5k
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
919
12.5k
        break;
920
25.4M
    }
921
922
25.4M
    if (add_coeffs)
923
1.09M
        ret = add_coefficients(avctx, frame, ax, ay, size, plane);
924
925
25.4M
    return ret;
926
25.4M
}
927
928
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
929
2.04M
{
930
2.04M
    MobiClipContext *s = avctx->priv_data;
931
2.04M
    GetBitContext *gb = &s->gb;
932
2.04M
    int index = (y & 0xC) | (x / 4 % 4);
933
934
2.04M
    uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
935
2.04M
    if (val == 9)
936
438k
        val = 3;
937
938
2.04M
    if (!get_bits1(gb)) {
939
494k
        int x = get_bits(gb, 3);
940
494k
        val = x + (x >= val ? 1 : 0);
941
494k
    }
942
943
2.04M
    s->pre[index + 4] = val;
944
2.04M
    if (size == 8)
945
1.64M
        s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
946
947
2.04M
    return val;
948
2.04M
}
949
950
static int process_block(AVCodecContext *avctx, AVFrame *frame,
951
                         int x, int y, int pmode, int has_coeffs, int plane)
952
24.3M
{
953
24.3M
    MobiClipContext *s = avctx->priv_data;
954
24.3M
    GetBitContext *gb = &s->gb;
955
24.3M
    int tmp, ret;
956
957
24.3M
    if (!has_coeffs) {
958
23.4M
        if (pmode < 0)
959
1.34M
            pmode = get_prediction(avctx, x, y, 8);
960
23.4M
        return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
961
23.4M
    }
962
963
897k
    tmp = get_ue_golomb_31(gb);
964
897k
    if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
965
7.58k
        return AVERROR_INVALIDDATA;
966
967
889k
    if (tmp == 0) {
968
546k
        if (pmode < 0)
969
300k
            pmode = get_prediction(avctx, x, y, 8);
970
546k
        ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
971
546k
    } else {
972
343k
        int flags = block4x4_coefficients_tab[tmp - 1];
973
974
1.02M
        for (int by = y; by < y + 8; by += 4) {
975
2.04M
            for (int bx = x; bx < x + 8; bx += 4) {
976
1.36M
                int new_pmode = pmode;
977
978
1.36M
                if (new_pmode < 0)
979
396k
                    new_pmode = get_prediction(avctx, bx, by, 4);
980
1.36M
                ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
981
1.36M
                if (ret < 0)
982
4.39k
                    return ret;
983
1.35M
                flags >>= 1;
984
1.35M
            }
985
682k
        }
986
343k
    }
987
988
885k
    return ret;
989
889k
}
990
991
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
992
                             int x, int y, int predict)
993
4.06M
{
994
4.06M
    MobiClipContext *s = avctx->priv_data;
995
4.06M
    GetBitContext *gb = &s->gb;
996
4.06M
    int flags, pmode_uv, idx = get_ue_golomb(gb);
997
4.06M
    int ret = 0;
998
999
4.06M
    if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1000
2.57k
        return AVERROR_INVALIDDATA;
1001
1002
4.05M
    flags = block8x8_coefficients_tab[idx];
1003
1004
4.05M
    if (predict) {
1005
439k
        ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1006
439k
        if (ret < 0)
1007
1.02k
            return ret;
1008
438k
        flags >>= 1;
1009
438k
        ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1010
438k
        if (ret < 0)
1011
1.18k
            return ret;
1012
437k
        flags >>= 1;
1013
437k
        ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1014
437k
        if (ret < 0)
1015
1.33k
            return ret;
1016
435k
        flags >>= 1;
1017
435k
        ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1018
435k
        if (ret < 0)
1019
1.86k
            return ret;
1020
434k
        flags >>= 1;
1021
3.61M
    } else {
1022
3.61M
        int pmode = get_bits(gb, 3);
1023
1024
3.61M
        if (pmode == 2) {
1025
7.50k
            ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1026
7.50k
            if (ret < 0)
1027
0
                return ret;
1028
7.50k
            pmode = 9;
1029
7.50k
        }
1030
1031
3.61M
        ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1032
3.61M
        if (ret < 0)
1033
2.65k
            return ret;
1034
3.61M
        flags >>= 1;
1035
3.61M
        ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1036
3.61M
        if (ret < 0)
1037
1.73k
            return ret;
1038
3.61M
        flags >>= 1;
1039
3.61M
        ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1040
3.61M
        if (ret < 0)
1041
636
            return ret;
1042
3.61M
        flags >>= 1;
1043
3.61M
        ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1044
3.61M
        if (ret < 0)
1045
597
            return ret;
1046
3.61M
        flags >>= 1;
1047
3.61M
    }
1048
1049
4.04M
    pmode_uv = get_bits(gb, 3);
1050
4.04M
    if (pmode_uv == 2) {
1051
59.0k
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1052
59.0k
        if (ret < 0)
1053
0
            return ret;
1054
59.0k
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1055
59.0k
        if (ret < 0)
1056
0
            return ret;
1057
59.0k
        pmode_uv = 9;
1058
59.0k
    }
1059
1060
4.04M
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1061
4.04M
    if (ret < 0)
1062
648
        return ret;
1063
4.04M
    flags >>= 1;
1064
4.04M
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1065
4.04M
    if (ret < 0)
1066
629
        return ret;
1067
1068
4.04M
    return 0;
1069
4.04M
}
1070
1071
static int get_index(int x)
1072
40.5k
{
1073
40.5k
    return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074
40.5k
}
1075
1076
static int predict_motion(AVCodecContext *avctx,
1077
                          int width, int height, int index,
1078
                          int offsetm, int offsetx, int offsety)
1079
164k
{
1080
164k
    MobiClipContext *s = avctx->priv_data;
1081
164k
    MotionXY *motion = s->motion;
1082
164k
    GetBitContext *gb = &s->gb;
1083
164k
    int fheight = avctx->height;
1084
164k
    int fwidth = avctx->width;
1085
1086
164k
    if (index <= 5) {
1087
144k
        int sidx = -FFMAX(1, index) + s->current_pic;
1088
144k
        MotionXY mv = s->motion[0];
1089
1090
144k
        if (sidx < 0)
1091
25.5k
            sidx += 6;
1092
1093
144k
        if (index > 0) {
1094
34.1k
            mv.x = mv.x + (unsigned)get_se_golomb(gb);
1095
34.1k
            mv.y = mv.y + (unsigned)get_se_golomb(gb);
1096
34.1k
        }
1097
144k
        if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1098
562
            return AVERROR_INVALIDDATA;
1099
1100
143k
        motion[offsetm].x = mv.x;
1101
143k
        motion[offsetm].y = mv.y;
1102
1103
535k
        for (int i = 0; i < 3; i++) {
1104
404k
            int method, src_linesize, dst_linesize;
1105
404k
            uint8_t *src, *dst;
1106
1107
404k
            if (i == 1) {
1108
130k
                offsetx = offsetx >> 1;
1109
130k
                offsety = offsety >> 1;
1110
130k
                mv.x = mv.x >> 1;
1111
130k
                mv.y = mv.y >> 1;
1112
130k
                width = width >> 1;
1113
130k
                height = height >> 1;
1114
130k
                fwidth = fwidth >> 1;
1115
130k
                fheight = fheight >> 1;
1116
130k
            }
1117
1118
404k
            av_assert0(s->pic[sidx]);
1119
404k
            av_assert0(s->pic[s->current_pic]);
1120
404k
            av_assert0(s->pic[s->current_pic]->data[i]);
1121
404k
            if (!s->pic[sidx]->data[i])
1122
9.42k
                return AVERROR_INVALIDDATA;
1123
1124
395k
            method = (mv.x & 1) | ((mv.y & 1) << 1);
1125
395k
            src_linesize = s->pic[sidx]->linesize[i];
1126
395k
            dst_linesize = s->pic[s->current_pic]->linesize[i];
1127
395k
            dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1128
1129
395k
            if (offsetx + (mv.x >> 1) < 0 ||
1130
394k
                offsety + (mv.y >> 1) < 0 ||
1131
393k
                offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1132
392k
                offsety + height + (mv.y + 1 >> 1) > fheight)
1133
3.40k
                return AVERROR_INVALIDDATA;
1134
1135
391k
            switch (method) {
1136
364k
            case 0:
1137
364k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1138
364k
                               (offsety + (mv.y >> 1)) * src_linesize;
1139
3.97M
                for (int y = 0; y < height; y++) {
1140
45.8M
                    for (int x = 0; x < width; x++)
1141
42.2M
                        dst[x] = src[x];
1142
3.61M
                    dst += dst_linesize;
1143
3.61M
                    src += src_linesize;
1144
3.61M
                }
1145
364k
                break;
1146
11.3k
            case 1:
1147
11.3k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1148
11.3k
                               (offsety + (mv.y >> 1)) * src_linesize;
1149
87.8k
                for (int y = 0; y < height; y++) {
1150
806k
                    for (int x = 0; x < width; x++) {
1151
730k
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152
730k
                    }
1153
1154
76.5k
                    dst += dst_linesize;
1155
76.5k
                    src += src_linesize;
1156
76.5k
                }
1157
11.3k
                break;
1158
13.3k
            case 2:
1159
13.3k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1160
13.3k
                               (offsety + (mv.y >> 1)) * src_linesize;
1161
122k
                for (int y = 0; y < height; y++) {
1162
1.54M
                    for (int x = 0; x < width; x++) {
1163
1.43M
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164
1.43M
                    }
1165
1166
109k
                    dst += dst_linesize;
1167
109k
                    src += src_linesize;
1168
109k
                }
1169
13.3k
                break;
1170
2.79k
            case 3:
1171
2.79k
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1172
2.79k
                               (offsety + (mv.y >> 1)) * src_linesize;
1173
37.4k
                for (int y = 0; y < height; y++) {
1174
547k
                    for (int x = 0; x < width; x++) {
1175
512k
                        dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1176
512k
                                           (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177
512k
                    }
1178
1179
34.6k
                    dst += dst_linesize;
1180
34.6k
                    src += src_linesize;
1181
34.6k
                }
1182
2.79k
                break;
1183
391k
            }
1184
391k
        }
1185
143k
    } else {
1186
20.2k
        int tidx;
1187
20.2k
        int adjx = index == 8 ? 0 :  width / 2;
1188
20.2k
        int adjy = index == 8 ? height / 2 : 0;
1189
1190
20.2k
        width  = width  - adjx;
1191
20.2k
        height = height - adjy;
1192
20.2k
        tidx = get_index(height) * 4 + get_index(width);
1193
1194
47.2k
        for (int i = 0; i < 2; i++) {
1195
34.7k
            int ret, idx2;
1196
1197
34.7k
            idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx], MOBI_MV_VLC_BITS, 1);
1198
1199
34.7k
            ret = predict_motion(avctx, width, height, idx2,
1200
34.7k
                                 offsetm, offsetx + i * adjx, offsety + i * adjy);
1201
34.7k
            if (ret < 0)
1202
7.82k
                return ret;
1203
34.7k
        }
1204
20.2k
    }
1205
1206
143k
    return 0;
1207
164k
}
1208
1209
static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
1210
                           int *got_frame, AVPacket *pkt)
1211
420k
{
1212
420k
    MobiClipContext *s = avctx->priv_data;
1213
420k
    GetBitContext *gb = &s->gb;
1214
420k
    AVFrame *frame = s->pic[s->current_pic];
1215
420k
    int ret;
1216
1217
420k
    if (avctx->height/16 * (avctx->width/16) * 2 > 8LL*FFALIGN(pkt->size, 2))
1218
219k
        return AVERROR_INVALIDDATA;
1219
1220
201k
    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1221
201k
                          pkt->size);
1222
1223
201k
    if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1224
73.4k
        return ret;
1225
1226
127k
    s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1227
127k
                        (uint16_t *)pkt->data,
1228
127k
                        (pkt->size + 1) >> 1);
1229
1230
127k
    ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1231
127k
    if (ret < 0)
1232
0
        return ret;
1233
1234
127k
    if (get_bits1(gb)) {
1235
21.8k
        frame->pict_type = AV_PICTURE_TYPE_I;
1236
21.8k
        frame->flags |= AV_FRAME_FLAG_KEY;
1237
21.8k
        s->moflex = get_bits1(gb);
1238
21.8k
        s->dct_tab_idx = get_bits1(gb);
1239
1240
21.8k
        ret = setup_qtables(avctx, get_bits(gb, 6));
1241
21.8k
        if (ret < 0)
1242
417
            return ret;
1243
1244
1.32M
        for (int y = 0; y < avctx->height; y += 16) {
1245
5.35M
            for (int x = 0; x < avctx->width; x += 16) {
1246
4.05M
                ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1247
4.05M
                if (ret < 0)
1248
11.6k
                    return ret;
1249
4.05M
            }
1250
1.31M
        }
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
181k
        for (int y = 0; y < avctx->height; y += 16) {
1265
216k
            for (int x = 0; x < avctx->width; x += 16) {
1266
133k
                int idx;
1267
1268
133k
                motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1269
133k
                motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1270
133k
                motion[x / 16 + 2].x = 0;
1271
133k
                motion[x / 16 + 2].y = 0;
1272
1273
133k
                idx = get_vlc2(gb, mv_vlc[s->moflex][0], MOBI_MV_VLC_BITS, 1);
1274
1275
133k
                if (idx == 6 || idx == 7) {
1276
4.12k
                    ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1277
4.12k
                    if (ret < 0)
1278
3.26k
                        return ret;
1279
129k
                } else {
1280
129k
                    int flags, idx2;
1281
129k
                    ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1282
129k
                    if (ret < 0)
1283
13.3k
                        return ret;
1284
116k
                    idx2 = get_ue_golomb(gb);
1285
116k
                    if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1286
2.20k
                        return AVERROR_INVALIDDATA;
1287
113k
                    flags = pframe_block8x8_coefficients_tab[idx2];
1288
1289
341k
                    for (int sy = y; sy < y + 16; sy += 8) {
1290
683k
                        for (int sx = x; sx < x + 16; sx += 8) {
1291
455k
                            if (flags & 1)
1292
24.4k
                                add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1293
455k
                            flags >>= 1;
1294
455k
                        }
1295
227k
                    }
1296
1297
113k
                    if (flags & 1)
1298
1.11k
                        add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1299
113k
                    flags >>= 1;
1300
113k
                    if (flags & 1)
1301
465
                        add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1302
113k
                }
1303
133k
            }
1304
101k
        }
1305
98.4k
    }
1306
1307
89.3k
    if (!s->moflex)
1308
4.39k
        avctx->colorspace = AVCOL_SPC_YCGCO;
1309
1310
89.3k
    s->current_pic = (s->current_pic + 1) % 6;
1311
89.3k
    ret = av_frame_ref(rframe, frame);
1312
89.3k
    if (ret < 0)
1313
0
        return ret;
1314
89.3k
    *got_frame = 1;
1315
1316
89.3k
    return 0;
1317
89.3k
}
1318
1319
static av_cold void mobiclip_flush(AVCodecContext *avctx)
1320
81.3k
{
1321
81.3k
    MobiClipContext *s = avctx->priv_data;
1322
1323
569k
    for (int i = 0; i < 6; i++)
1324
488k
        av_frame_unref(s->pic[i]);
1325
81.3k
}
1326
1327
static av_cold int mobiclip_close(AVCodecContext *avctx)
1328
1.81k
{
1329
1.81k
    MobiClipContext *s = avctx->priv_data;
1330
1331
1.81k
    av_freep(&s->bitstream);
1332
1.81k
    s->bitstream_size = 0;
1333
1.81k
    av_freep(&s->motion);
1334
1.81k
    s->motion_size = 0;
1335
1336
12.7k
    for (int i = 0; i < 6; i++) {
1337
10.8k
        av_frame_free(&s->pic[i]);
1338
10.8k
    }
1339
1340
1.81k
    return 0;
1341
1.81k
}
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
};