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