new files for the CAVS decoder by (Stefan Gehrer <stefan gehrer gmx de)
[libav.git] / libavcodec / cavsdata.h
1 /*
2 * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
3 * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #define SLICE_MIN_START_CODE 0x00000101
21 #define SLICE_MAX_START_CODE 0x000001af
22 #define EXT_START_CODE 0x000001b5
23 #define USER_START_CODE 0x000001b2
24 #define SEQ_START_CODE 0x000001b0
25 #define PIC_I_START_CODE 0x000001b3
26 #define PIC_PB_START_CODE 0x000001b6
27
28 #define A_AVAIL 1
29 #define B_AVAIL 2
30 #define C_AVAIL 4
31 #define D_AVAIL 8
32 #define NOT_AVAIL -1
33 #define REF_INTRA -2
34 #define REF_DIR -3
35
36 #define ESCAPE_CODE 59
37
38 #define FWD0 0x01
39 #define FWD1 0x02
40 #define BWD0 0x04
41 #define BWD1 0x08
42 #define SYM0 0x10
43 #define SYM1 0x20
44
45 #define MV_BWD_OFFS 12
46 #define MV_STRIDE 4
47
48 enum mb_t {
49 I_8X8 = 0,
50 P_SKIP,
51 P_16X16,
52 P_16X8,
53 P_8X16,
54 P_8X8,
55 B_SKIP,
56 B_DIRECT,
57 B_FWD_16X16,
58 B_BWD_16X16,
59 B_SYM_16X16,
60 B_8X8 = 29
61 };
62
63 enum sub_mb_t {
64 B_SUB_DIRECT,
65 B_SUB_FWD,
66 B_SUB_BWD,
67 B_SUB_SYM
68 };
69
70 enum intra_luma_t {
71 INTRA_L_VERT,
72 INTRA_L_HORIZ,
73 INTRA_L_LP,
74 INTRA_L_DOWN_LEFT,
75 INTRA_L_DOWN_RIGHT,
76 INTRA_L_LP_LEFT,
77 INTRA_L_LP_TOP,
78 INTRA_L_DC_128
79 };
80
81 enum intra_chroma_t {
82 INTRA_C_LP,
83 INTRA_C_HORIZ,
84 INTRA_C_VERT,
85 INTRA_C_PLANE,
86 INTRA_C_LP_LEFT,
87 INTRA_C_LP_TOP,
88 INTRA_C_DC_128,
89 };
90
91 enum mv_pred_t {
92 MV_PRED_MEDIAN,
93 MV_PRED_LEFT,
94 MV_PRED_TOP,
95 MV_PRED_TOPRIGHT,
96 MV_PRED_PSKIP,
97 MV_PRED_BSKIP
98 };
99
100 enum block_t {
101 BLK_16X16,
102 BLK_16X8,
103 BLK_8X16,
104 BLK_8X8
105 };
106
107 enum mv_loc_t {
108 MV_FWD_D3 = 0,
109 MV_FWD_B2,
110 MV_FWD_B3,
111 MV_FWD_C2,
112 MV_FWD_A1,
113 MV_FWD_X0,
114 MV_FWD_X1,
115 MV_FWD_A3 = 8,
116 MV_FWD_X2,
117 MV_FWD_X3,
118 MV_BWD_D3 = MV_BWD_OFFS,
119 MV_BWD_B2,
120 MV_BWD_B3,
121 MV_BWD_C2,
122 MV_BWD_A1,
123 MV_BWD_X0,
124 MV_BWD_X1,
125 MV_BWD_A3 = MV_BWD_OFFS+8,
126 MV_BWD_X2,
127 MV_BWD_X3
128 };
129
130 static const uint8_t b_partition_flags[14] = {
131 0,0,0,0,0,
132 FWD0|FWD1,
133 BWD0|BWD1,
134 FWD0|BWD1,
135 BWD0|FWD1,
136 FWD0|SYM1,
137 BWD0|SYM1,
138 SYM0|FWD1,
139 SYM0|BWD1,
140 SYM0|SYM1
141 };
142
143 static const uint8_t scan3x3[4] = {4,5,7,8};
144
145 static const uint8_t mv_scan[4] = {
146 MV_FWD_X0,MV_FWD_X1,
147 MV_FWD_X2,MV_FWD_X3
148 };
149
150 static const uint8_t cbp_tab[64][2] = {
151 {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13},
152 { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3},
153 { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62},
154 {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6},
155 {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20},
156 {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43},
157 {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49},
158 {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38}
159 };
160
161 static const uint8_t chroma_qp[64] = {
162 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
163 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
164 32,33,34,35,36,37,38,39,40,41,42,42,43,43,44,44,
165 45,45,46,46,47,47,48,48,48,49,49,49,50,50,50,51
166 };
167
168 static const uint8_t dequant_shift[64] = {
169 14,14,14,14,14,14,14,14,
170 13,13,13,13,13,13,13,13,
171 13,12,12,12,12,12,12,12,
172 11,11,11,11,11,11,11,11,
173 11,10,10,10,10,10,10,10,
174 10, 9, 9, 9, 9, 9, 9, 9,
175 9, 8, 8, 8, 8, 8, 8, 8,
176 7, 7, 7, 7, 7, 7, 7, 7
177 };
178
179 static const uint16_t dequant_mul[64] = {
180 32768,36061,38968,42495,46341,50535,55437,60424,
181 32932,35734,38968,42495,46177,50535,55109,59933,
182 65535,35734,38968,42577,46341,50617,55027,60097,
183 32809,35734,38968,42454,46382,50576,55109,60056,
184 65535,35734,38968,42495,46320,50515,55109,60076,
185 65535,35744,38968,42495,46341,50535,55099,60087,
186 65535,35734,38973,42500,46341,50535,55109,60097,
187 32771,35734,38965,42497,46341,50535,55109,60099
188 };
189
190 typedef struct {
191 int16_t x;
192 int16_t y;
193 int16_t dist;
194 int16_t ref;
195 } vector_t;
196
197 // marks block as unavailable, i.e. out of picture
198 // or not yet decoded
199 static const vector_t un_mv = {0,0,1,NOT_AVAIL};
200
201 //marks block as "no prediction from this direction"
202 // e.g. forward motion vector in BWD partition
203 static const vector_t dir_mv = {0,0,1,REF_DIR};
204
205 //marks block as using intra prediction
206 static const vector_t intra_mv = {0,0,1,REF_INTRA};
207
208 typedef struct residual_vlc_t {
209 int8_t rltab[59][3];
210 int8_t level_add[26];
211 int8_t golomb_order;
212 int inc_limit;
213 int8_t max_run;
214 } residual_vlc_t;
215
216 static const residual_vlc_t intra_2dvlc[7] = {
217 {
218 { //level / run / table_inc
219 { 1, 0, 1},{ -1, 0, 1},{ 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},
220 { 1, 3, 1},{ -1, 3, 1},{ 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},
221 { 1, 6, 1},{ -1, 6, 1},{ 1, 7, 1},{ -1, 7, 1},{ 1, 8, 1},{ -1, 8, 1},
222 { 1, 9, 1},{ -1, 9, 1},{ 1,10, 1},{ -1,10, 1},{ 2, 0, 2},{ -2, 0, 2},
223 { 1,11, 1},{ -1,11, 1},{ 1,12, 1},{ -1,12, 1},{ 1,13, 1},{ -1,13, 1},
224 { 1,14, 1},{ -1,14, 1},{ 2, 1, 2},{ -2, 1, 2},{ 1,15, 1},{ -1,15, 1},
225 { 1,16, 1},{ -1,16, 1},{ 3, 0, 3},{ -3, 0, 3},{ 1,17, 1},{ -1,17, 1},
226 { 1,18, 1},{ -1,18, 1},{ 2, 2, 2},{ -2, 2, 2},{ 1,19, 1},{ -1,19, 1},
227 { 1,20, 1},{ -1,20, 1},{ 2, 3, 2},{ -2, 3, 2},{ 1,21, 1},{ -1,21, 1},
228 { 2, 4, 2},{ -2, 4, 2},{ 1,22, 1},{ -1,22, 1},{ 0, 0,-1}
229 },
230 //level_add
231 { 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
232 2, 2, 2, 2, 2, 2, 2,-1,-1,-1},
233 2, //golomb_order
234 0, //inc_limit
235 22, //max_run
236 },{
237 { //level / run
238 { 1, 0, 0},{ -1, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 2, 0, 1},{ -2, 0, 1},
239 { 1, 2, 0},{ -1, 2, 0},{ 0, 0, 0},{ 1, 3, 0},{ -1, 3, 0},{ 1, 4, 0},
240 { -1, 4, 0},{ 1, 5, 0},{ -1, 5, 0},{ 3, 0, 2},{ -3, 0, 2},{ 2, 1, 1},
241 { -2, 1, 1},{ 1, 6, 0},{ -1, 6, 0},{ 1, 7, 0},{ -1, 7, 0},{ 1, 8, 0},
242 { -1, 8, 0},{ 2, 2, 1},{ -2, 2, 1},{ 4, 0, 2},{ -4, 0, 2},{ 1, 9, 0},
243 { -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 2, 3, 1},{ -2, 3, 1},{ 3, 1, 2},
244 { -3, 1, 2},{ 1,11, 0},{ -1,11, 0},{ 2, 4, 1},{ -2, 4, 1},{ 5, 0, 3},
245 { -5, 0, 3},{ 1,12, 0},{ -1,12, 0},{ 2, 5, 1},{ -2, 5, 1},{ 1,13, 0},
246 { -1,13, 0},{ 2, 6, 1},{ -2, 6, 1},{ 2, 7, 1},{ -2, 7, 1},{ 3, 2, 2},
247 { -3, 2, 2},{ 6, 0, 3},{ -6, 0, 3},{ 1,14, 0},{ -1,14, 0}
248 },
249 //level_add
250 { 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,
251 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
252 2, //golomb_order
253 1, //inc_limit
254 14, //max_run
255 },{
256 { //level / run
257 { 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 1, 1, 0},{ -1, 1, 0},
258 { 3, 0, 1},{ -3, 0, 1},{ 0, 0, 0},{ 1, 2, 0},{ -1, 2, 0},{ 2, 1, 0},
259 { -2, 1, 0},{ 4, 0, 1},{ -4, 0, 1},{ 1, 3, 0},{ -1, 3, 0},{ 5, 0, 2},
260 { -5, 0, 2},{ 1, 4, 0},{ -1, 4, 0},{ 3, 1, 1},{ -3, 1, 1},{ 2, 2, 0},
261 { -2, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 6, 0, 2},{ -6, 0, 2},{ 2, 3, 0},
262 { -2, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 4, 1, 1},{ -4, 1, 1},{ 7, 0, 2},
263 { -7, 0, 2},{ 3, 2, 1},{ -3, 2, 1},{ 2, 4, 0},{ -2, 4, 0},{ 1, 7, 0},
264 { -1, 7, 0},{ 2, 5, 0},{ -2, 5, 0},{ 8, 0, 3},{ -8, 0, 3},{ 1, 8, 0},
265 { -1, 8, 0},{ 5, 1, 2},{ -5, 1, 2},{ 3, 3, 1},{ -3, 3, 1},{ 2, 6, 0},
266 { -2, 6, 0},{ 9, 0, 3},{ -9, 0, 3},{ 1, 9, 0},{ -1, 9, 0}
267 },
268 //level_add
269 {10, 6, 4, 4, 3, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,
270 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
271 2, //golomb_order
272 2, //inc_limit
273 9, //max_run
274 },{
275 { //level / run
276 { 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},{ -3, 0, 0},
277 { 1, 1, 0},{ -1, 1, 0},{ 0, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 1},
278 { -5, 0, 1},{ 2, 1, 0},{ -2, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 6, 0, 1},
279 { -6, 0, 1},{ 3, 1, 0},{ -3, 1, 0},{ 7, 0, 1},{ -7, 0, 1},{ 1, 3, 0},
280 { -1, 3, 0},{ 8, 0, 2},{ -8, 0, 2},{ 2, 2, 0},{ -2, 2, 0},{ 4, 1, 0},
281 { -4, 1, 0},{ 1, 4, 0},{ -1, 4, 0},{ 9, 0, 2},{ -9, 0, 2},{ 5, 1, 1},
282 { -5, 1, 1},{ 2, 3, 0},{ -2, 3, 0},{ 10, 0, 2},{-10, 0, 2},{ 3, 2, 0},
283 { -3, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 11, 0, 3},{-11, 0, 3},{ 6, 1, 1},
284 { -6, 1, 1},{ 1, 6, 0},{ -1, 6, 0},{ 2, 4, 0},{ -2, 4, 0},{ 3, 3, 0},
285 { -3, 3, 0},{ 12, 0, 3},{-12, 0, 3},{ 4, 2, 0},{ -4, 2, 0}
286 },
287 //level_add
288 {13, 7, 5, 4, 3, 2, 2,-1,-1,-1 -1,-1,-1,-1,-1,-1,
289 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
290 2, //golomb_order
291 4, //inc_limit
292 6, //max_run
293 },{
294 { //level / run
295 { 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},{ -3, 0, 0},
296 { 0, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 6, 0, 0},
297 { -6, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 7, 0, 0},{ -7, 0, 0},{ 8, 0, 1},
298 { -8, 0, 1},{ 2, 1, 0},{ -2, 1, 0},{ 9, 0, 1},{ -9, 0, 1},{ 10, 0, 1},
299 {-10, 0, 1},{ 1, 2, 0},{ -1, 2, 0},{ 3, 1, 0},{ -3, 1, 0},{ 11, 0, 2},
300 {-11, 0, 2},{ 4, 1, 0},{ -4, 1, 0},{ 12, 0, 2},{-12, 0, 2},{ 13, 0, 2},
301 {-13, 0, 2},{ 5, 1, 0},{ -5, 1, 0},{ 1, 3, 0},{ -1, 3, 0},{ 2, 2, 0},
302 { -2, 2, 0},{ 14, 0, 2},{-14, 0, 2},{ 6, 1, 0},{ -6, 1, 0},{ 15, 0, 2},
303 {-15, 0, 2},{ 16, 0, 2},{-16, 0, 2},{ 3, 2, 0},{ -3, 2, 0},{ 1, 4, 0},
304 { -1, 4, 0},{ 7, 1, 0},{ -7, 1, 0},{ 17, 0, 2},{-17, 0, 2},
305 },
306 //level_add
307 {18, 8, 4, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
308 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
309 2, //golomb_order
310 7, //inc_limit
311 4, //max_run
312 },{
313 { //level / run
314 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
315 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 6, 0, 0},
316 { -6, 0, 0},{ 7, 0, 0},{ -7, 0, 0},{ 8, 0, 0},{ -8, 0, 0},{ 9, 0, 0},
317 { -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 11, 0, 1},
318 {-11, 0, 1},{ 12, 0, 1},{-12, 0, 1},{ 13, 0, 1},{-13, 0, 1},{ 2, 1, 0},
319 { -2, 1, 0},{ 14, 0, 1},{-14, 0, 1},{ 15, 0, 1},{-15, 0, 1},{ 3, 1, 0},
320 { -3, 1, 0},{ 16, 0, 1},{-16, 0, 1},{ 1, 2, 0},{ -1, 2, 0},{ 17, 0, 1},
321 {-17, 0, 1},{ 4, 1, 0},{ -4, 1, 0},{ 18, 0, 1},{-18, 0, 1},{ 5, 1, 0},
322 { -5, 1, 0},{ 19, 0, 1},{-19, 0, 1},{ 20, 0, 1},{-20, 0, 1},{ 6, 1, 0},
323 { -6, 1, 0},{ 21, 0, 1},{-21, 0, 1},{ 2, 2, 0},{ -2, 2, 0},
324 },
325 //level_add
326 {22, 7, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
327 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
328 2, //golomb_order
329 10, //inc_limit
330 2, //max_run
331 },{
332 { //level / run
333 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
334 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 6, 0, 0},
335 { -6, 0, 0},{ 7, 0, 0},{ -7, 0, 0},{ 8, 0, 0},{ -8, 0, 0},{ 9, 0, 0},
336 { -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},{-11, 0, 0},{ 12, 0, 0},
337 {-12, 0, 0},{ 13, 0, 0},{-13, 0, 0},{ 14, 0, 0},{-14, 0, 0},{ 15, 0, 0},
338 {-15, 0, 0},{ 16, 0, 0},{-16, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 17, 0, 0},
339 {-17, 0, 0},{ 18, 0, 0},{-18, 0, 0},{ 19, 0, 0},{-19, 0, 0},{ 20, 0, 0},
340 {-20, 0, 0},{ 21, 0, 0},{-21, 0, 0},{ 2, 1, 0},{ -2, 1, 0},{ 22, 0, 0},
341 {-22, 0, 0},{ 23, 0, 0},{-23, 0, 0},{ 24, 0, 0},{-24, 0, 0},{ 25, 0, 0},
342 {-25, 0, 0},{ 3, 1, 0},{ -3, 1, 0},{ 26, 0, 0},{-26, 0, 0}
343 },
344 //level_add
345 {27, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
346 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
347 2, //golomb_order
348 INT_MAX, //inc_limit
349 1, //max_run
350 }
351 };
352
353 static const residual_vlc_t inter_2dvlc[7] = {
354 {
355 { //level / run
356 { 1, 0, 1},{ -1, 0, 1},{ 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},
357 { 1, 3, 1},{ -1, 3, 1},{ 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},
358 { 1, 6, 1},{ -1, 6, 1},{ 1, 7, 1},{ -1, 7, 1},{ 1, 8, 1},{ -1, 8, 1},
359 { 1, 9, 1},{ -1, 9, 1},{ 1,10, 1},{ -1,10, 1},{ 1,11, 1},{ -1,11, 1},
360 { 1,12, 1},{ -1,12, 1},{ 2, 0, 2},{ -2, 0, 2},{ 1,13, 1},{ -1,13, 1},
361 { 1,14, 1},{ -1,14, 1},{ 1,15, 1},{ -1,15, 1},{ 1,16, 1},{ -1,16, 1},
362 { 1,17, 1},{ -1,17, 1},{ 1,18, 1},{ -1,18, 1},{ 3, 0, 3},{ -3, 0, 3},
363 { 1,19, 1},{ -1,19, 1},{ 1,20, 1},{ -1,20, 1},{ 2, 1, 2},{ -2, 1, 2},
364 { 1,21, 1},{ -1,21, 1},{ 1,22, 1},{ -1,22, 1},{ 1,23, 1},{ -1,23, 1},
365 { 1,24, 1},{ -1,24, 1},{ 1,25, 1},{ -1,25, 1},{ 0, 0,-1}
366 },
367 //level_add
368 { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
369 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
370 3, //golomb_order
371 0, //inc_limit
372 25 //max_run
373 },{
374 { //level / run
375 { 1, 0, 0},{ -1, 0, 0},{ 0, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 1, 2, 0},
376 { -1, 2, 0},{ 1, 3, 0},{ -1, 3, 0},{ 1, 4, 0},{ -1, 4, 0},{ 1, 5, 0},
377 { -1, 5, 0},{ 2, 0, 1},{ -2, 0, 1},{ 1, 6, 0},{ -1, 6, 0},{ 1, 7, 0},
378 { -1, 7, 0},{ 1, 8, 0},{ -1, 8, 0},{ 1, 9, 0},{ -1, 9, 0},{ 2, 1, 1},
379 { -2, 1, 1},{ 1,10, 0},{ -1,10, 0},{ 1,11, 0},{ -1,11, 0},{ 3, 0, 2},
380 { -3, 0, 2},{ 1,12, 0},{ -1,12, 0},{ 1,13, 0},{ -1,13, 0},{ 2, 2, 1},
381 { -2, 2, 1},{ 1,14, 0},{ -1,14, 0},{ 2, 3, 1},{ -2, 3, 1},{ 1,15, 0},
382 { -1,15, 0},{ 2, 4, 1},{ -2, 4, 1},{ 1,16, 0},{ -1,16, 0},{ 4, 0, 3},
383 { -4, 0, 3},{ 2, 5, 1},{ -2, 5, 1},{ 1,17, 0},{ -1,17, 0},{ 1,18, 0},
384 { -1,18, 0},{ 2, 6, 1},{ -2, 6, 1},{ 3, 1, 2},{ -3, 1, 2},
385 },
386 //level_add
387 { 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
388 2, 2, 2,-1,-1,-1,-1,-1,-1,-1},
389 2, //golomb_order
390 1, //inc_limit
391 18 //max_run
392 },{
393 { //level / run
394 { 1, 0, 0},{ -1, 0, 0},{ 0, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 2, 0, 0},
395 { -2, 0, 0},{ 1, 2, 0},{ -1, 2, 0},{ 1, 3, 0},{ -1, 3, 0},{ 3, 0, 1},
396 { -3, 0, 1},{ 2, 1, 0},{ -2, 1, 0},{ 1, 4, 0},{ -1, 4, 0},{ 1, 5, 0},
397 { -1, 5, 0},{ 1, 6, 0},{ -1, 6, 0},{ 2, 2, 0},{ -2, 2, 0},{ 4, 0, 2},
398 { -4, 0, 2},{ 1, 7, 0},{ -1, 7, 0},{ 3, 1, 1},{ -3, 1, 1},{ 2, 3, 0},
399 { -2, 3, 0},{ 1, 8, 0},{ -1, 8, 0},{ 1, 9, 0},{ -1, 9, 0},{ 5, 0, 2},
400 { -5, 0, 2},{ 2, 4, 0},{ -2, 4, 0},{ 1,10, 0},{ -1,10, 0},{ 2, 5, 0},
401 { -2, 5, 0},{ 1,11, 0},{ -1,11, 0},{ 3, 2, 1},{ -3, 2, 1},{ 6, 0, 2},
402 { -6, 0, 2},{ 4, 1, 2},{ -4, 1, 2},{ 1,12, 0},{ -1,12, 0},{ 2, 6, 0},
403 { -2, 6, 0},{ 3, 3, 1},{ -3, 3, 1},{ 1,13, 0},{ -1,13, 0},
404 },
405 //level_add
406 { 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,-1,
407 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
408 2, //golomb_order
409 2, //inc_limit
410 13 //max_run
411 },{
412 { //level / run
413 { 1, 0, 0},{ -1, 0, 0},{ 0, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 1, 1, 0},
414 { -1, 1, 0},{ 3, 0, 0},{ -3, 0, 0},{ 1, 2, 0},{ -1, 2, 0},{ 2, 1, 0},
415 { -2, 1, 0},{ 4, 0, 1},{ -4, 0, 1},{ 1, 3, 0},{ -1, 3, 0},{ 5, 0, 1},
416 { -5, 0, 1},{ 1, 4, 0},{ -1, 4, 0},{ 3, 1, 0},{ -3, 1, 0},{ 2, 2, 0},
417 { -2, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 6, 0, 1},{ -6, 0, 1},{ 2, 3, 0},
418 { -2, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 4, 1, 1},{ -4, 1, 1},{ 7, 0, 2},
419 { -7, 0, 2},{ 3, 2, 0},{ -3, 2, 0},{ 1, 7, 0},{ -1, 7, 0},{ 2, 4, 0},
420 { -2, 4, 0},{ 8, 0, 2},{ -8, 0, 2},{ 1, 8, 0},{ -1, 8, 0},{ 3, 3, 0},
421 { -3, 3, 0},{ 2, 5, 0},{ -2, 5, 0},{ 5, 1, 1},{ -5, 1, 1},{ 1, 9, 0},
422 { -1, 9, 0},{ 9, 0, 2},{ -9, 0, 2},{ 4, 2, 1},{ -4, 2, 1},
423 },
424 //level_add
425 {10, 6, 5, 4, 3, 3, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1,
426 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
427 2, //golomb_order
428 3, //inc_limit
429 9 //max_run
430 },{
431 { //level / run
432 { 1, 0, 0},{ -1, 0, 0},{ 0, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
433 { -3, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},
434 { -5, 0, 0},{ 2, 1, 0},{ -2, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 6, 0, 0},
435 { -6, 0, 0},{ 3, 1, 0},{ -3, 1, 0},{ 7, 0, 1},{ -7, 0, 1},{ 1, 3, 0},
436 { -1, 3, 0},{ 8, 0, 1},{ -8, 0, 1},{ 2, 2, 0},{ -2, 2, 0},{ 4, 1, 0},
437 { -4, 1, 0},{ 1, 4, 0},{ -1, 4, 0},{ 9, 0, 1},{ -9, 0, 1},{ 5, 1, 0},
438 { -5, 1, 0},{ 2, 3, 0},{ -2, 3, 0},{ 1, 5, 0},{ -1, 5, 0},{ 10, 0, 2},
439 {-10, 0, 2},{ 3, 2, 0},{ -3, 2, 0},{ 11, 0, 2},{-11, 0, 2},{ 1, 6, 0},
440 { -1, 6, 0},{ 6, 1, 0},{ -6, 1, 0},{ 3, 3, 0},{ -3, 3, 0},{ 2, 4, 0},
441 { -2, 4, 0},{ 12, 0, 2},{-12, 0, 2},{ 4, 2, 0},{ -4, 2, 0},
442 },
443 //level_add
444 {13, 7, 5, 4, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
445 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
446 2, //golomb_order
447 6, //inc_limit
448 6 //max_run
449 },{
450 { //level / run
451 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
452 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 1, 1, 0},
453 { -1, 1, 0},{ 6, 0, 0},{ -6, 0, 0},{ 7, 0, 0},{ -7, 0, 0},{ 8, 0, 0},
454 { -8, 0, 0},{ 2, 1, 0},{ -2, 1, 0},{ 9, 0, 0},{ -9, 0, 0},{ 1, 2, 0},
455 { -1, 2, 0},{ 10, 0, 1},{-10, 0, 1},{ 3, 1, 0},{ -3, 1, 0},{ 11, 0, 1},
456 {-11, 0, 1},{ 4, 1, 0},{ -4, 1, 0},{ 12, 0, 1},{-12, 0, 1},{ 1, 3, 0},
457 { -1, 3, 0},{ 2, 2, 0},{ -2, 2, 0},{ 13, 0, 1},{-13, 0, 1},{ 5, 1, 0},
458 { -5, 1, 0},{ 14, 0, 1},{-14, 0, 1},{ 6, 1, 0},{ -6, 1, 0},{ 1, 4, 0},
459 { -1, 4, 0},{ 15, 0, 1},{-15, 0, 1},{ 3, 2, 0},{ -3, 2, 0},{ 16, 0, 1},
460 {-16, 0, 1},{ 2, 3, 0},{ -2, 3, 0},{ 7, 1, 0},{ -7, 1, 0},
461 },
462 //level_add
463 {17, 8, 4, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
464 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
465 2, //golomb_order
466 9, //inc_limit
467 4 //max_run
468 },{
469 { //level / run
470 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
471 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 6, 0, 0},
472 { -6, 0, 0},{ 7, 0, 0},{ -7, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 8, 0, 0},
473 { -8, 0, 0},{ 9, 0, 0},{ -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},
474 {-11, 0, 0},{ 12, 0, 0},{-12, 0, 0},{ 2, 1, 0},{ -2, 1, 0},{ 13, 0, 0},
475 {-13, 0, 0},{ 1, 2, 0},{ -1, 2, 0},{ 14, 0, 0},{-14, 0, 0},{ 15, 0, 0},
476 {-15, 0, 0},{ 3, 1, 0},{ -3, 1, 0},{ 16, 0, 0},{-16, 0, 0},{ 17, 0, 0},
477 {-17, 0, 0},{ 18, 0, 0},{-18, 0, 0},{ 4, 1, 0},{ -4, 1, 0},{ 19, 0, 0},
478 {-19, 0, 0},{ 20, 0, 0},{-20, 0, 0},{ 2, 2, 0},{ -2, 2, 0},{ 1, 3, 0},
479 { -1, 3, 0},{ 5, 1, 0},{ -5, 1, 0},{ 21, 0, 0},{-21, 0, 0},
480 },
481 //level_add
482 {22, 6, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
483 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
484 2, //golomb_order
485 INT_MAX, //inc_limit
486 3 //max_run
487 }
488 };
489
490 static const residual_vlc_t chroma_2dvlc[5] = {
491 {
492 { //level / run
493 { 1, 0, 1},{ -1, 0, 1},{ 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},
494 { 1, 3, 1},{ -1, 3, 1},{ 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},
495 { 1, 6, 1},{ -1, 6, 1},{ 2, 0, 2},{ -2, 0, 2},{ 1, 7, 1},{ -1, 7, 1},
496 { 1, 8, 1},{ -1, 8, 1},{ 1, 9, 1},{ -1, 9, 1},{ 1,10, 1},{ -1,10, 1},
497 { 1,11, 1},{ -1,11, 1},{ 1,12, 1},{ -1,12, 1},{ 1,13, 1},{ -1,13, 1},
498 { 1,14, 1},{ -1,14, 1},{ 3, 0, 3},{ -3, 0, 3},{ 1,15, 1},{ -1,15, 1},
499 { 1,16, 1},{ -1,16, 1},{ 1,17, 1},{ -1,17, 1},{ 1,18, 1},{ -1,18, 1},
500 { 1,19, 1},{ -1,19, 1},{ 1,20, 1},{ -1,20, 1},{ 1,21, 1},{ -1,21, 1},
501 { 2, 1, 2},{ -2, 1, 2},{ 1,22, 1},{ -1,22, 1},{ 1,23, 1},{ -1,23, 1},
502 { 1,24, 1},{ -1,24, 1},{ 4, 0, 3},{ -4, 0, 3},{ 0, 0,-1}
503 },
504 //level_add
505 { 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
506 2, 2, 2, 2, 2, 2, 2, 2, 2,-1},
507 2, //golomb_order
508 0, //inc_limit
509 24, //max_run
510 },{
511 { //level / run
512 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 2, 0, 1},
513 { -2, 0, 1},{ 1, 2, 0},{ -1, 2, 0},{ 1, 3, 0},{ -1, 3, 0},{ 1, 4, 0},
514 { -1, 4, 0},{ 1, 5, 0},{ -1, 5, 0},{ 3, 0, 2},{ -3, 0, 2},{ 1, 6, 0},
515 { -1, 6, 0},{ 1, 7, 0},{ -1, 7, 0},{ 2, 1, 1},{ -2, 1, 1},{ 1, 8, 0},
516 { -1, 8, 0},{ 1, 9, 0},{ -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 4, 0, 2},
517 { -4, 0, 2},{ 1,11, 0},{ -1,11, 0},{ 1,12, 0},{ -1,12, 0},{ 1,13, 0},
518 { -1,13, 0},{ 2, 2, 1},{ -2, 2, 1},{ 1,14, 0},{ -1,14, 0},{ 2, 3, 1},
519 { -2, 3, 1},{ 5, 0, 3},{ -5, 0, 3},{ 3, 1, 2},{ -3, 1, 2},{ 1,15, 0},
520 { -1,15, 0},{ 1,16, 0},{ -1,16, 0},{ 1,17, 0},{ -1,17, 0},{ 2, 4, 1},
521 { -2, 4, 1},{ 1,18, 0},{ -1,18, 0},{ 1,19, 0},{ -1,19, 0},
522 },
523 //level_add
524 { 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
525 2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
526 0, //golomb_order
527 1, //inc_limit
528 19, //max_run
529 },{
530 { //level / run
531 { 1, 0, 0},{ -1, 0, 0},{ 0, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 1, 1, 0},
532 { -1, 1, 0},{ 3, 0, 1},{ -3, 0, 1},{ 1, 2, 0},{ -1, 2, 0},{ 4, 0, 1},
533 { -4, 0, 1},{ 2, 1, 0},{ -2, 1, 0},{ 1, 3, 0},{ -1, 3, 0},{ 5, 0, 2},
534 { -5, 0, 2},{ 1, 4, 0},{ -1, 4, 0},{ 3, 1, 1},{ -3, 1, 1},{ 2, 2, 0},
535 { -2, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 6, 0, 2},{ -6, 0, 2},{ 1, 6, 0},
536 { -1, 6, 0},{ 2, 3, 0},{ -2, 3, 0},{ 7, 0, 2},{ -7, 0, 2},{ 1, 7, 0},
537 { -1, 7, 0},{ 4, 1, 1},{ -4, 1, 1},{ 1, 8, 0},{ -1, 8, 0},{ 3, 2, 1},
538 { -3, 2, 1},{ 2, 4, 0},{ -2, 4, 0},{ 2, 5, 0},{ -2, 5, 0},{ 8, 0, 2},
539 { -8, 0, 2},{ 1, 9, 0},{ -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 9, 0, 2},
540 { -9, 0, 2},{ 5, 1, 2},{ -5, 1, 2},{ 3, 3, 1},{ -3, 3, 1},
541 },
542 //level_add
543 {10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2,-1,-1,-1,-1,-1,
544 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
545 1, //golomb_order
546 2, //inc_limit
547 10, //max_run
548 },{
549 { //level / run
550 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
551 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 1, 1, 0},{ -1, 1, 0},{ 5, 0, 1},
552 { -5, 0, 1},{ 2, 1, 0},{ -2, 1, 0},{ 6, 0, 1},{ -6, 0, 1},{ 1, 2, 0},
553 { -1, 2, 0},{ 7, 0, 1},{ -7, 0, 1},{ 3, 1, 0},{ -3, 1, 0},{ 8, 0, 1},
554 { -8, 0, 1},{ 1, 3, 0},{ -1, 3, 0},{ 2, 2, 0},{ -2, 2, 0},{ 9, 0, 1},
555 { -9, 0, 1},{ 4, 1, 0},{ -4, 1, 0},{ 1, 4, 0},{ -1, 4, 0},{ 10, 0, 1},
556 {-10, 0, 1},{ 3, 2, 0},{ -3, 2, 0},{ 5, 1, 1},{ -5, 1, 1},{ 2, 3, 0},
557 { -2, 3, 0},{ 11, 0, 1},{-11, 0, 1},{ 1, 5, 0},{ -1, 5, 0},{ 12, 0, 1},
558 {-12, 0, 1},{ 1, 6, 0},{ -1, 6, 0},{ 6, 1, 1},{ -6, 1, 1},{ 13, 0, 1},
559 {-13, 0, 1},{ 2, 4, 0},{ -2, 4, 0},{ 1, 7, 0},{ -1, 7, 0},
560 },
561 //level_add
562 {14, 7, 4, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,
563 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
564 1, //golomb_order
565 4, //inc_limit
566 7, //max_run
567 },{
568 { //level / run
569 { 0, 0, 0},{ 1, 0, 0},{ -1, 0, 0},{ 2, 0, 0},{ -2, 0, 0},{ 3, 0, 0},
570 { -3, 0, 0},{ 4, 0, 0},{ -4, 0, 0},{ 5, 0, 0},{ -5, 0, 0},{ 6, 0, 0},
571 { -6, 0, 0},{ 7, 0, 0},{ -7, 0, 0},{ 8, 0, 0},{ -8, 0, 0},{ 1, 1, 0},
572 { -1, 1, 0},{ 9, 0, 0},{ -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},
573 {-11, 0, 0},{ 2, 1, 0},{ -2, 1, 0},{ 12, 0, 0},{-12, 0, 0},{ 13, 0, 0},
574 {-13, 0, 0},{ 3, 1, 0},{ -3, 1, 0},{ 14, 0, 0},{-14, 0, 0},{ 1, 2, 0},
575 { -1, 2, 0},{ 15, 0, 0},{-15, 0, 0},{ 4, 1, 0},{ -4, 1, 0},{ 16, 0, 0},
576 {-16, 0, 0},{ 17, 0, 0},{-17, 0, 0},{ 5, 1, 0},{ -5, 1, 0},{ 1, 3, 0},
577 { -1, 3, 0},{ 2, 2, 0},{ -2, 2, 0},{ 18, 0, 0},{-18, 0, 0},{ 6, 1, 0},
578 { -6, 1, 0},{ 19, 0, 0},{-19, 0, 0},{ 1, 4, 0},{ -1, 4, 0},
579 },
580 //level_add
581 {20, 7, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
582 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
583 0, //golomb_order
584 INT_MAX, //inc_limit
585 4, //max_run
586 }
587 };
588
589 static const uint8_t alpha_tab[64] = {
590 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
591 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
592 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
593 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
594 };
595
596 static const uint8_t beta_tab[64] = {
597 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
598 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
599 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
600 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
601 };
602
603 static const uint8_t tc_tab[64] = {
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
606 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
607 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
608 };
609
610 static const int_fast8_t left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7};
611 static const int_fast8_t top_modifier_l[8] = {-1, 1, 5,-1,-1, 5, 7, 7};
612 static const int_fast8_t left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6};
613 static const int_fast8_t top_modifier_c[7] = { 4, 1,-1,-1, 4, 6, 6};