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