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