]> git.sesse.net Git - ffmpeg/blob - libavcodec/mobiclip.c
avformat/avio: Add Metacube support
[ffmpeg] / libavcodec / mobiclip.c
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 "get_bits.h"
33 #include "golomb.h"
34 #include "internal.h"
35
36 #define MOBI_RL_VLC_BITS 12
37 #define MOBI_MV_VLC_BITS 6
38
39 static const uint8_t zigzag4x4_tab[] =
40 {
41     0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
42     0x0D, 0x0E, 0x0B, 0x0F
43 };
44
45 static const uint8_t quant4x4_tab[][16] =
46 {
47     { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
48     { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
49     { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
50     { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
51     { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
52     { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
53 };
54
55 static const uint8_t quant8x8_tab[][64] =
56 {
57     { 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,
58       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,},
59     { 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,
60       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,},
61     { 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,
62       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,},
63     { 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,
64       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,},
65     { 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,
66       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,},
67     { 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,
68       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,},
69 };
70
71 static const uint8_t block4x4_coefficients_tab[] =
72 {
73     15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
74 };
75
76 static const uint8_t pframe_block4x4_coefficients_tab[] =
77 {
78     0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
79 };
80
81 static const uint8_t block8x8_coefficients_tab[] =
82 {
83     0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
84     0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
85     0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
86     0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
87     0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
88     0x2A, 0x28, 0x29, 0x26,
89 };
90
91 static const uint8_t pframe_block8x8_coefficients_tab[] =
92 {
93     0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
94     0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
95     0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
96     0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
97 };
98
99 static const uint8_t run_residue[2][256] =
100 {
101     {
102        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,
103         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,
104         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,
105         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,
106         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,
107         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,
108         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,
109         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,
110     },
111     {
112        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,
113         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,
114         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,
115         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,
116         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,
117         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,
118         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,
119         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,
120     },
121 };
122
123 static const uint8_t bits0[] = {
124      9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
125     10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
126     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
127      9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
128      9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
129      8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
130      6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
131 };
132
133 static const uint16_t syms0[] = {
134     0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
135     0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
136     0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
137     0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
138     0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
139     0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
140     0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
141     0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
142     0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
143     0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
144 };
145
146 static const uint16_t syms1[] = {
147     0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
148     0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
149     0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
150     0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
151     0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
152     0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
153     0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
154     0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
155 };
156
157 static const uint8_t mv_len[16] =
158 {
159     10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
160 };
161
162 static const uint8_t mv_bits[2][16][10] =
163 {
164     {
165         { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
166         { 2, 3, 4, 4, 3, 4, 4, 2 },
167         { 3, 4, 4, 2, 4, 4, 3, 2 },
168         { 1, 3, 4, 5, 5, 3, 3 },
169         { 2, 4, 4, 3, 3, 4, 4, 2 },
170         { 2, 3, 4, 4, 4, 4, 3, 2 },
171         { 2, 3, 4, 4, 4, 4, 3, 2 },
172         { 2, 2, 3, 4, 5, 5, 2 },
173         { 2, 3, 4, 4, 3, 4, 4, 2 },
174         { 2, 4, 4, 3, 4, 4, 3, 2 },
175         { 2, 3, 3, 5, 5, 4, 3, 2 },
176         { 2, 3, 4, 4, 3, 3, 2 },
177         { 1, 4, 4, 3, 3, 4, 4 },
178         { 2, 3, 4, 4, 3, 3, 2 },
179         { 2, 3, 4, 4, 3, 3, 2 },
180         { 3, 3, 2, 2, 3, 3 },
181     },
182     {
183         { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
184         { 2, 3, 4, 5, 5, 2, 3, 3 },
185         { 2, 4, 4, 3, 3, 4, 4, 2 },
186         { 1, 4, 4, 3, 4, 4, 3 },
187         { 3, 3, 2, 4, 5, 5, 3, 2 },
188         { 3, 4, 4, 3, 3, 3, 3, 2 },
189         { 1, 3, 3, 4, 4, 4, 5, 5 },
190         { 1, 4, 4, 3, 3, 4, 4 },
191         { 2, 4, 4, 3, 3, 4, 4, 2 },
192         { 1, 3, 3, 4, 4, 4, 5, 5 },
193         { 2, 3, 4, 4, 4, 4, 3, 2 },
194         { 2, 3, 3, 4, 4, 3, 2 },
195         { 1, 4, 4, 3, 3, 4, 4 },
196         { 1, 4, 4, 3, 3, 4, 4 },
197         { 2, 3, 3, 4, 4, 3, 2 },
198         { 2, 3, 3, 3, 3, 2 },
199     }
200 };
201
202 static const uint8_t mv_syms[2][16][10] =
203 {
204     {
205         { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
206         { 0, 9, 5, 4, 2, 3, 8, 1 },
207         { 3, 9, 5, 0, 4, 8, 2, 1 },
208         { 1, 3, 4, 8, 5, 2, 0 },
209         { 0, 5, 4, 8, 2, 3, 9, 1 },
210         { 0, 3, 5, 9, 4, 8, 2, 1 },
211         { 0, 3, 9, 5, 8, 4, 2, 1 },
212         { 0, 2, 3, 4, 8, 5, 1 },
213         { 0, 3, 8, 4, 2, 5, 9, 1 },
214         { 2, 8, 9, 3, 5, 4, 0, 1 },
215         { 0, 4, 3, 8, 9, 5, 2, 1 },
216         { 0, 4, 8, 5, 3, 2, 1 },
217         { 1, 9, 4, 2, 0, 5, 3 },
218         { 2, 4, 9, 5, 3, 0, 1 },
219         { 0, 4, 9, 5, 3, 2, 1 },
220         { 5, 4, 1, 0, 3, 2 },
221     },
222     {
223         { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
224         { 9, 2, 3, 5, 4, 1, 8, 0 },
225         { 0, 5, 4, 2, 9, 3, 8, 1 },
226         { 1, 5, 4, 2, 8, 3, 0 },
227         { 2, 9, 8, 3, 5, 4, 0, 1 },
228         { 3, 5, 4, 2, 9, 8, 0, 1 },
229         { 1, 2, 0, 9, 8, 3, 5, 4 },
230         { 1, 8, 5, 2, 0, 4, 3 },
231         { 0, 5, 4, 2, 8, 3, 9, 1 },
232         { 1, 2, 0, 9, 8, 3, 5, 4 },
233         { 0, 3, 9, 8, 5, 4, 2, 1 },
234         { 0, 4, 3, 8, 5, 2, 1 },
235         { 1, 5, 4, 2, 0, 9, 3 },
236         { 1, 9, 5, 2, 0, 4, 3 },
237         { 0, 5, 3, 9, 4, 2, 1 },
238         { 0, 4, 5, 3, 2, 1 },
239     }
240 };
241
242 typedef struct BlockXY {
243     int w, h;
244     int ax, ay;
245     int x, y;
246     int size;
247     uint8_t *block;
248     int linesize;
249 } BlockXY;
250
251 typedef struct MotionXY {
252     int x, y;
253 } MotionXY;
254
255 typedef struct MobiClipContext {
256     AVFrame *pic[6];
257
258     int current_pic;
259     int moflex;
260     int dct_tab_idx;
261     int quantizer;
262
263     GetBitContext gb;
264
265     uint8_t *bitstream;
266     int bitstream_size;
267
268     int     qtab[2][64];
269     uint8_t pre[32];
270     MotionXY *motion;
271     int     motion_size;
272
273     BswapDSPContext bdsp;
274 } MobiClipContext;
275
276 static VLC rl_vlc[2];
277 static VLC mv_vlc[2][16];
278
279 static av_cold void mobiclip_init_static(void)
280 {
281     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
282                                  bits0, sizeof(*bits0),
283                                  syms0, sizeof(*syms0), sizeof(*syms0),
284                                  0, 0, 1 << MOBI_RL_VLC_BITS);
285     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
286                                  bits0, sizeof(*bits0),
287                                  syms1, sizeof(*syms1), sizeof(*syms1),
288                                  0, 0, 1 << MOBI_RL_VLC_BITS);
289     for (int i = 0; i < 2; i++) {
290         static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
291         for (int j = 0; j < 16; j++) {
292             mv_vlc[i][j].table           = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
293             mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
294             ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j],
295                                      mv_bits[i][j], sizeof(*mv_bits[i][j]),
296                                      mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
297                                      0, INIT_VLC_USE_NEW_STATIC, NULL);
298         }
299     }
300 }
301
302 static av_cold int mobiclip_init(AVCodecContext *avctx)
303 {
304     static AVOnce init_static_once = AV_ONCE_INIT;
305     MobiClipContext *s = avctx->priv_data;
306
307     if (avctx->width & 15 || avctx->height & 15) {
308         av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
309         return AVERROR_INVALIDDATA;
310     }
311
312     ff_bswapdsp_init(&s->bdsp);
313
314     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
315
316     s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
317     if (!s->motion)
318         return AVERROR(ENOMEM);
319     s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
320
321     for (int i = 0; i < 6; i++) {
322         s->pic[i] = av_frame_alloc();
323         if (!s->pic[i])
324             return AVERROR(ENOMEM);
325     }
326
327     ff_thread_once(&init_static_once, mobiclip_init_static);
328
329     return 0;
330 }
331
332 static int setup_qtables(AVCodecContext *avctx, int quantizer)
333 {
334     MobiClipContext *s = avctx->priv_data;
335     int qx, qy;
336
337     if (quantizer < 12 || quantizer > 161)
338         return AVERROR_INVALIDDATA;
339
340     s->quantizer = quantizer;
341
342     qx = quantizer % 6;
343     qy = quantizer / 6;
344
345     for (int i = 0; i < 16; i++)
346         s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
347
348     for (int i = 0; i < 64; i++)
349         s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
350
351     for (int i = 0; i < 20; i++)
352         s->pre[i] = 9;
353
354     return 0;
355 }
356
357 static void inverse4(unsigned *rs)
358 {
359     unsigned a = rs[0] + rs[2];
360     unsigned b = rs[0] - rs[2];
361     unsigned c = rs[1] + ((int)rs[3] >> 1);
362     unsigned d = ((int)rs[1] >> 1) - rs[3];
363
364     rs[0] = a + c;
365     rs[1] = b + d;
366     rs[2] = b - d;
367     rs[3] = a - c;
368 }
369
370 static void idct(int *arr, int size)
371 {
372     int e, f, g, h;
373     unsigned x3, x2, x1, x0;
374     int tmp[4];
375
376     if (size == 4) {
377         inverse4(arr);
378         return;
379     }
380
381     tmp[0] = arr[0];
382     tmp[1] = arr[2];
383     tmp[2] = arr[4];
384     tmp[3] = arr[6];
385
386     inverse4(tmp);
387
388     e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
389     f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
390     g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
391     h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
392     x3 = (unsigned)g + (h >> 2);
393     x2 = (unsigned)e + (f >> 2);
394     x1 = (e >> 2) - (unsigned)f;
395     x0 = (unsigned)h - (g >> 2);
396
397     arr[0] = tmp[0] + x0;
398     arr[1] = tmp[1] + x1;
399     arr[2] = tmp[2] + x2;
400     arr[3] = tmp[3] + x3;
401     arr[4] = tmp[3] - x3;
402     arr[5] = tmp[2] - x2;
403     arr[6] = tmp[1] - x1;
404     arr[7] = tmp[0] - x0;
405 }
406
407 static void read_run_encoding(AVCodecContext *avctx,
408                               int *last, int *run, int *level)
409 {
410     MobiClipContext *s = avctx->priv_data;
411     GetBitContext *gb = &s->gb;
412     int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
413                      MOBI_RL_VLC_BITS, 1);
414
415     *last = (n >> 11) == 1;
416     *run  = (n >> 5) & 0x3F;
417     *level = n & 0x1F;
418 }
419
420 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
421                             int bx, int by, int size, int plane)
422 {
423     MobiClipContext *s = avctx->priv_data;
424     GetBitContext *gb = &s->gb;
425     int mat[64] = { 0 };
426     const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
427     const int *qtab = s->qtab[size == 8];
428     uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
429
430     for (int pos = 0; get_bits_left(gb) > 0; pos++) {
431         int qval, last, run, level;
432
433         read_run_encoding(avctx, &last, &run, &level);
434
435         if (level) {
436             if (get_bits1(gb))
437                 level = -level;
438         } else if (!get_bits1(gb)) {
439             read_run_encoding(avctx, &last, &run, &level);
440             level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
441             if (get_bits1(gb))
442                 level = -level;
443         } else if (!get_bits1(gb)) {
444             read_run_encoding(avctx, &last, &run, &level);
445             run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446             if (get_bits1(gb))
447                 level = -level;
448         } else {
449             last  = get_bits1(gb);
450             run   = get_bits(gb, 6);
451             level = get_sbits(gb, 12);
452         }
453
454         pos += run;
455         if (pos >= size * size)
456             return AVERROR_INVALIDDATA;
457         qval = qtab[pos];
458         mat[ztab[pos]] = qval *(unsigned)level;
459
460         if (last)
461             break;
462     }
463
464     mat[0] += 32;
465     for (int y = 0; y < size; y++)
466         idct(&mat[y * size], size);
467
468     for (int y = 0; y < size; y++) {
469         for (int x = y + 1; x < size; x++) {
470             int a = mat[x * size + y];
471             int b = mat[y * size + x];
472
473             mat[y * size + x] = a;
474             mat[x * size + y] = b;
475         }
476
477         idct(&mat[y * size], size);
478         for (int x = 0; x < size; x++)
479             dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
480         dst += frame->linesize[plane];
481     }
482
483     return 0;
484 }
485
486 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
487                                    int bx, int by, int size, int plane)
488 {
489     MobiClipContext *s = avctx->priv_data;
490     GetBitContext *gb = &s->gb;
491     int ret, idx = get_ue_golomb_31(gb);
492
493     if (idx == 0) {
494         ret = add_coefficients(avctx, frame, bx, by, size, plane);
495     } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
496         int flags = pframe_block4x4_coefficients_tab[idx];
497
498         for (int y = by; y < by + 8; y += 4) {
499             for (int x = bx; x < bx + 8; x += 4) {
500                 if (flags & 1) {
501                     ret = add_coefficients(avctx, frame, x, y, 4, plane);
502                     if (ret < 0)
503                         return ret;
504                 }
505                 flags >>= 1;
506             }
507         }
508     } else {
509         ret = AVERROR_INVALIDDATA;
510     }
511
512     return ret;
513 }
514
515 static int adjust(int x, int size)
516 {
517     return size == 16 ? (x + 1) >> 1 : x;
518 }
519
520 static 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
541 static uint8_t half(int a, int b)
542 {
543     return ((a + b) + 1) / 2;
544 }
545
546 static uint8_t half3(int a, int b, int c)
547 {
548     return ((a + b + b + c) * 2 / 4 + 1) / 2;
549 }
550
551 static uint8_t pick_above(BlockXY bxy)
552 {
553     bxy.y = bxy.y - 1;
554
555     return pget(bxy);
556 }
557
558 static uint8_t pick_left(BlockXY bxy)
559 {
560     bxy.x = bxy.x - 1;
561
562     return pget(bxy);
563 }
564
565 static 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
575 static 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
585 static 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
616 static 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
656 static 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
696 static 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
728 static 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
779 static 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
787 static 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
815 static 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
829 static 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
929 static 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
951 static 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
992 static 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
1072 static int get_index(int x)
1073 {
1074     return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1075 }
1076
1077 static 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
1211 static int mobiclip_decode(AVCodecContext *avctx, void *data,
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 + 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(data, frame);
1312     if (ret < 0)
1313         return ret;
1314     *got_frame = 1;
1315
1316     return 0;
1317 }
1318
1319 static 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
1327 static 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
1343 const AVCodec ff_mobiclip_decoder = {
1344     .name           = "mobiclip",
1345     .long_name      = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1346     .type           = AVMEDIA_TYPE_VIDEO,
1347     .id             = AV_CODEC_ID_MOBICLIP,
1348     .priv_data_size = sizeof(MobiClipContext),
1349     .init           = mobiclip_init,
1350     .decode         = mobiclip_decode,
1351     .flush          = mobiclip_flush,
1352     .close          = mobiclip_close,
1353     .capabilities   = AV_CODEC_CAP_DR1,
1354     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1355 };