move defines and enums out of cavsdata.h
[ffmpeg.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 file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "cavs.h"
23
24 static const uint8_t partition_flags[30] = {
25   0,                                 //I_8X8
26   0,                                 //P_SKIP
27   0,                                 //P_16X16
28                       SPLITH,        //P_16X8
29                              SPLITV, //P_8X16
30                       SPLITH|SPLITV, //P_8X8
31                       SPLITH|SPLITV, //B_SKIP
32                       SPLITH|SPLITV, //B_DIRECT
33   0,                                 //B_FWD_16X16
34   0,                                 //B_BWD_16X16
35   0,                                 //B_SYM_16X16
36   FWD0|FWD1          |SPLITH,
37   FWD0|FWD1                 |SPLITV,
38   BWD0|BWD1          |SPLITH,
39   BWD0|BWD1                 |SPLITV,
40   FWD0|BWD1          |SPLITH,
41   FWD0|BWD1                 |SPLITV,
42   BWD0|FWD1          |SPLITH,
43   BWD0|FWD1                 |SPLITV,
44   FWD0|FWD1     |SYM1|SPLITH,
45   FWD0|FWD1     |SYM1       |SPLITV,
46   BWD0|FWD1     |SYM1|SPLITH,
47   BWD0|FWD1     |SYM1       |SPLITV,
48   FWD0|FWD1|SYM0     |SPLITH,
49   FWD0|FWD1|SYM0            |SPLITV,
50   FWD0|BWD1|SYM0     |SPLITH,
51   FWD0|BWD1|SYM0            |SPLITV,
52   FWD0|FWD1|SYM0|SYM1|SPLITH,
53   FWD0|FWD1|SYM0|SYM1       |SPLITV,
54                       SPLITH|SPLITV, //B_8X8 = 29
55 };
56
57 static const uint8_t scan3x3[4] = {4,5,7,8};
58
59 static const uint8_t mv_scan[4] = {
60     MV_FWD_X0,MV_FWD_X1,
61     MV_FWD_X2,MV_FWD_X3
62 };
63
64 static const uint8_t cbp_tab[64][2] = {
65   {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13},
66   { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3},
67   { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62},
68   {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6},
69   {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20},
70   {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43},
71   {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49},
72   {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38}
73 };
74
75 static const uint8_t chroma_qp[64] = {
76   0,  1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
77   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
78   32,33,34,35,36,37,38,39,40,41,42,42,43,43,44,44,
79   45,45,46,46,47,47,48,48,48,49,49,49,50,50,50,51
80 };
81
82 static const uint8_t dequant_shift[64] = {
83   14,14,14,14,14,14,14,14,
84   13,13,13,13,13,13,13,13,
85   13,12,12,12,12,12,12,12,
86   11,11,11,11,11,11,11,11,
87   11,10,10,10,10,10,10,10,
88   10, 9, 9, 9, 9, 9, 9, 9,
89   9, 8, 8, 8, 8, 8, 8, 8,
90   7, 7, 7, 7, 7, 7, 7, 7
91 };
92
93 static const uint16_t dequant_mul[64] = {
94   32768,36061,38968,42495,46341,50535,55437,60424,
95   32932,35734,38968,42495,46177,50535,55109,59933,
96   65535,35734,38968,42577,46341,50617,55027,60097,
97   32809,35734,38968,42454,46382,50576,55109,60056,
98   65535,35734,38968,42495,46320,50515,55109,60076,
99   65535,35744,38968,42495,46341,50535,55099,60087,
100   65535,35734,38973,42500,46341,50535,55109,60097,
101   32771,35734,38965,42497,46341,50535,55109,60099
102 };
103
104 /** marks block as unavailable, i.e. out of picture
105     or not yet decoded */
106 static const vector_t un_mv    = {0,0,1,NOT_AVAIL};
107
108 /** marks block as "no prediction from this direction"
109     e.g. forward motion vector in BWD partition */
110 static const vector_t dir_mv   = {0,0,1,REF_DIR};
111
112 /** marks block as using intra prediction */
113 static const vector_t intra_mv = {0,0,1,REF_INTRA};
114
115 #define EOB 0,0,0
116
117 static const residual_vlc_t intra_2dvlc[7] = {
118   {
119     { //level / run / table_inc
120       {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
121       {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
122       {  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},{  1, 9, 1},{ -1, 9, 1},
123       {  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},{  2, 1, 2},{ -2, 1, 2},
124       {  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},{  1,14, 1},{ -1,14, 1},
125       {  1,15, 1},{ -1,15, 1},{  2, 2, 2},{ -2, 2, 2},{  1,16, 1},{ -1,16, 1},
126       {  1,17, 1},{ -1,17, 1},{  3, 1, 3},{ -3, 1, 3},{  1,18, 1},{ -1,18, 1},
127       {  1,19, 1},{ -1,19, 1},{  2, 3, 2},{ -2, 3, 2},{  1,20, 1},{ -1,20, 1},
128       {  1,21, 1},{ -1,21, 1},{  2, 4, 2},{ -2, 4, 2},{  1,22, 1},{ -1,22, 1},
129       {  2, 5, 2},{ -2, 5, 2},{  1,23, 1},{ -1,23, 1},{   EOB   }
130     },
131     //level_add
132     { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
133       2, 2, 2, 2, 2, 2, 2,-1,-1,-1},
134     2, //golomb_order
135     0, //inc_limit
136     23, //max_run
137   },{
138     { //level / run
139       {  1, 1, 0},{ -1, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 1},{ -2, 1, 1},
140       {  1, 3, 0},{ -1, 3, 0},{   EOB   },{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
141       { -1, 5, 0},{  1, 6, 0},{ -1, 6, 0},{  3, 1, 2},{ -3, 1, 2},{  2, 2, 1},
142       { -2, 2, 1},{  1, 7, 0},{ -1, 7, 0},{  1, 8, 0},{ -1, 8, 0},{  1, 9, 0},
143       { -1, 9, 0},{  2, 3, 1},{ -2, 3, 1},{  4, 1, 2},{ -4, 1, 2},{  1,10, 0},
144       { -1,10, 0},{  1,11, 0},{ -1,11, 0},{  2, 4, 1},{ -2, 4, 1},{  3, 2, 2},
145       { -3, 2, 2},{  1,12, 0},{ -1,12, 0},{  2, 5, 1},{ -2, 5, 1},{  5, 1, 3},
146       { -5, 1, 3},{  1,13, 0},{ -1,13, 0},{  2, 6, 1},{ -2, 6, 1},{  1,14, 0},
147       { -1,14, 0},{  2, 7, 1},{ -2, 7, 1},{  2, 8, 1},{ -2, 8, 1},{  3, 3, 2},
148       { -3, 3, 2},{  6, 1, 3},{ -6, 1, 3},{  1,15, 0},{ -1,15, 0}
149     },
150     //level_add
151     { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,
152       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
153     2, //golomb_order
154     1, //inc_limit
155     15, //max_run
156   },{
157     { //level / run
158       {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},{ -1, 2, 0},
159       {  3, 1, 1},{ -3, 1, 1},{   EOB   },{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},
160       { -2, 2, 0},{  4, 1, 1},{ -4, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 2},
161       { -5, 1, 2},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 3, 0},
162       { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 2},{ -6, 1, 2},{  2, 4, 0},
163       { -2, 4, 0},{  1, 7, 0},{ -1, 7, 0},{  4, 2, 1},{ -4, 2, 1},{  7, 1, 2},
164       { -7, 1, 2},{  3, 3, 1},{ -3, 3, 1},{  2, 5, 0},{ -2, 5, 0},{  1, 8, 0},
165       { -1, 8, 0},{  2, 6, 0},{ -2, 6, 0},{  8, 1, 3},{ -8, 1, 3},{  1, 9, 0},
166       { -1, 9, 0},{  5, 2, 2},{ -5, 2, 2},{  3, 4, 1},{ -3, 4, 1},{  2, 7, 0},
167       { -2, 7, 0},{  9, 1, 3},{ -9, 1, 3},{  1,10, 0},{ -1,10, 0}
168     },
169     //level_add
170     { 0,10, 6, 4, 4, 3, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,
171      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
172     2, //golomb_order
173     2, //inc_limit
174     10, //max_run
175   },{
176     { //level / run
177       {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},{ -3, 1, 0},
178       {  1, 2, 0},{ -1, 2, 0},{   EOB   },{  4, 1, 0},{ -4, 1, 0},{  5, 1, 1},
179       { -5, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  6, 1, 1},
180       { -6, 1, 1},{  3, 2, 0},{ -3, 2, 0},{  7, 1, 1},{ -7, 1, 1},{  1, 4, 0},
181       { -1, 4, 0},{  8, 1, 2},{ -8, 1, 2},{  2, 3, 0},{ -2, 3, 0},{  4, 2, 0},
182       { -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  9, 1, 2},{ -9, 1, 2},{  5, 2, 1},
183       { -5, 2, 1},{  2, 4, 0},{ -2, 4, 0},{ 10, 1, 2},{-10, 1, 2},{  3, 3, 0},
184       { -3, 3, 0},{  1, 6, 0},{ -1, 6, 0},{ 11, 1, 3},{-11, 1, 3},{  6, 2, 1},
185       { -6, 2, 1},{  1, 7, 0},{ -1, 7, 0},{  2, 5, 0},{ -2, 5, 0},{  3, 4, 0},
186       { -3, 4, 0},{ 12, 1, 3},{-12, 1, 3},{  4, 3, 0},{ -4, 3, 0}
187     },
188     //level_add
189     { 0,13, 7, 5, 4, 3, 2, 2,-1,-1,-1 -1,-1,-1,-1,-1,-1,
190      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
191     2, //golomb_order
192     4, //inc_limit
193     7, //max_run
194   },{
195     { //level / run
196       {  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},{ -3, 1, 0},
197       {   EOB   },{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
198       { -6, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 1},
199       { -8, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  9, 1, 1},{ -9, 1, 1},{ 10, 1, 1},
200       {-10, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  3, 2, 0},{ -3, 2, 0},{ 11, 1, 2},
201       {-11, 1, 2},{  4, 2, 0},{ -4, 2, 0},{ 12, 1, 2},{-12, 1, 2},{ 13, 1, 2},
202       {-13, 1, 2},{  5, 2, 0},{ -5, 2, 0},{  1, 4, 0},{ -1, 4, 0},{  2, 3, 0},
203       { -2, 3, 0},{ 14, 1, 2},{-14, 1, 2},{  6, 2, 0},{ -6, 2, 0},{ 15, 1, 2},
204       {-15, 1, 2},{ 16, 1, 2},{-16, 1, 2},{  3, 3, 0},{ -3, 3, 0},{  1, 5, 0},
205       { -1, 5, 0},{  7, 2, 0},{ -7, 2, 0},{ 17, 1, 2},{-17, 1, 2}
206     },
207     //level_add
208     { 0,18, 8, 4, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
209      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
210     2, //golomb_order
211     7, //inc_limit
212     5, //max_run
213   },{
214     { //level / run
215       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
216       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
217       { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  9, 1, 0},
218       { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{  1, 2, 0},{ -1, 2, 0},{ 11, 1, 1},
219       {-11, 1, 1},{ 12, 1, 1},{-12, 1, 1},{ 13, 1, 1},{-13, 1, 1},{  2, 2, 0},
220       { -2, 2, 0},{ 14, 1, 1},{-14, 1, 1},{ 15, 1, 1},{-15, 1, 1},{  3, 2, 0},
221       { -3, 2, 0},{ 16, 1, 1},{-16, 1, 1},{  1, 3, 0},{ -1, 3, 0},{ 17, 1, 1},
222       {-17, 1, 1},{  4, 2, 0},{ -4, 2, 0},{ 18, 1, 1},{-18, 1, 1},{  5, 2, 0},
223       { -5, 2, 0},{ 19, 1, 1},{-19, 1, 1},{ 20, 1, 1},{-20, 1, 1},{  6, 2, 0},
224       { -6, 2, 0},{ 21, 1, 1},{-21, 1, 1},{  2, 3, 0},{ -2, 3, 0}
225     },
226     //level_add
227     { 0,22, 7, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
228      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
229     2, //golomb_order
230     10, //inc_limit
231     3, //max_run
232   },{
233     { //level / run
234       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
235       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
236       { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  9, 1, 0},
237       { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},{-11, 1, 0},{ 12, 1, 0},
238       {-12, 1, 0},{ 13, 1, 0},{-13, 1, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0},
239       {-15, 1, 0},{ 16, 1, 0},{-16, 1, 0},{  1, 2, 0},{ -1, 2, 0},{ 17, 1, 0},
240       {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{ 19, 1, 0},{-19, 1, 0},{ 20, 1, 0},
241       {-20, 1, 0},{ 21, 1, 0},{-21, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 22, 1, 0},
242       {-22, 1, 0},{ 23, 1, 0},{-23, 1, 0},{ 24, 1, 0},{-24, 1, 0},{ 25, 1, 0},
243       {-25, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 26, 1, 0},{-26, 1, 0}
244     },
245     //level_add
246     { 0,27, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
247      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
248     2, //golomb_order
249     INT_MAX, //inc_limit
250     2, //max_run
251   }
252 };
253
254 static const residual_vlc_t inter_2dvlc[7] = {
255   {
256     { //level / run
257       {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
258       {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
259       {  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},{  1, 9, 1},{ -1, 9, 1},
260       {  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},{  1,12, 1},{ -1,12, 1},
261       {  1,13, 1},{ -1,13, 1},{  2, 1, 2},{ -2, 1, 2},{  1,14, 1},{ -1,14, 1},
262       {  1,15, 1},{ -1,15, 1},{  1,16, 1},{ -1,16, 1},{  1,17, 1},{ -1,17, 1},
263       {  1,18, 1},{ -1,18, 1},{  1,19, 1},{ -1,19, 1},{  3, 1, 3},{ -3, 1, 3},
264       {  1,20, 1},{ -1,20, 1},{  1,21, 1},{ -1,21, 1},{  2, 2, 2},{ -2, 2, 2},
265       {  1,22, 1},{ -1,22, 1},{  1,23, 1},{ -1,23, 1},{  1,24, 1},{ -1,24, 1},
266       {  1,25, 1},{ -1,25, 1},{  1,26, 1},{ -1,26, 1},{   EOB   }
267     },
268     //level_add
269     { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
270       2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
271     3, //golomb_order
272     0, //inc_limit
273     26 //max_run
274   },{
275     { //level / run
276       {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  1, 2, 0},{ -1, 2, 0},{  1, 3, 0},
277       { -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},{ -1, 5, 0},{  1, 6, 0},
278       { -1, 6, 0},{  2, 1, 1},{ -2, 1, 1},{  1, 7, 0},{ -1, 7, 0},{  1, 8, 0},
279       { -1, 8, 0},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  2, 2, 1},
280       { -2, 2, 1},{  1,11, 0},{ -1,11, 0},{  1,12, 0},{ -1,12, 0},{  3, 1, 2},
281       { -3, 1, 2},{  1,13, 0},{ -1,13, 0},{  1,14, 0},{ -1,14, 0},{  2, 3, 1},
282       { -2, 3, 1},{  1,15, 0},{ -1,15, 0},{  2, 4, 1},{ -2, 4, 1},{  1,16, 0},
283       { -1,16, 0},{  2, 5, 1},{ -2, 5, 1},{  1,17, 0},{ -1,17, 0},{  4, 1, 3},
284       { -4, 1, 3},{  2, 6, 1},{ -2, 6, 1},{  1,18, 0},{ -1,18, 0},{  1,19, 0},
285       { -1,19, 0},{  2, 7, 1},{ -2, 7, 1},{  3, 2, 2},{ -3, 2, 2}
286     },
287     //level_add
288     { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
289       2, 2, 2,-1,-1,-1,-1,-1,-1,-1},
290     2, //golomb_order
291     1, //inc_limit
292     19 //max_run
293   },{
294     { //level / run
295       {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  1, 2, 0},{ -1, 2, 0},{  2, 1, 0},
296       { -2, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  3, 1, 1},
297       { -3, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  1, 6, 0},
298       { -1, 6, 0},{  1, 7, 0},{ -1, 7, 0},{  2, 3, 0},{ -2, 3, 0},{  4, 1, 2},
299       { -4, 1, 2},{  1, 8, 0},{ -1, 8, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 4, 0},
300       { -2, 4, 0},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  5, 1, 2},
301       { -5, 1, 2},{  2, 5, 0},{ -2, 5, 0},{  1,11, 0},{ -1,11, 0},{  2, 6, 0},
302       { -2, 6, 0},{  1,12, 0},{ -1,12, 0},{  3, 3, 1},{ -3, 3, 1},{  6, 1, 2},
303       { -6, 1, 2},{  4, 2, 2},{ -4, 2, 2},{  1,13, 0},{ -1,13, 0},{  2, 7, 0},
304       { -2, 7, 0},{  3, 4, 1},{ -3, 4, 1},{  1,14, 0},{ -1,14, 0}
305     },
306     //level_add
307     { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,-1,
308       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
309     2, //golomb_order
310     2, //inc_limit
311     14 //max_run
312   },{
313     { //level / run
314       {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},
315       { -1, 2, 0},{  3, 1, 0},{ -3, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},
316       { -2, 2, 0},{  4, 1, 1},{ -4, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 1},
317       { -5, 1, 1},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 0},{ -3, 2, 0},{  2, 3, 0},
318       { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 1},{ -6, 1, 1},{  2, 4, 0},
319       { -2, 4, 0},{  1, 7, 0},{ -1, 7, 0},{  4, 2, 1},{ -4, 2, 1},{  7, 1, 2},
320       { -7, 1, 2},{  3, 3, 0},{ -3, 3, 0},{  1, 8, 0},{ -1, 8, 0},{  2, 5, 0},
321       { -2, 5, 0},{  8, 1, 2},{ -8, 1, 2},{  1, 9, 0},{ -1, 9, 0},{  3, 4, 0},
322       { -3, 4, 0},{  2, 6, 0},{ -2, 6, 0},{  5, 2, 1},{ -5, 2, 1},{  1,10, 0},
323       { -1,10, 0},{  9, 1, 2},{ -9, 1, 2},{  4, 3, 1},{ -4, 3, 1}
324     },
325     //level_add
326     { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1,
327      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
328     2, //golomb_order
329     3, //inc_limit
330     10 //max_run
331   },{
332     { //level / run
333       {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
334       { -3, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},
335       { -5, 1, 0},{  2, 2, 0},{ -2, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  6, 1, 0},
336       { -6, 1, 0},{  3, 2, 0},{ -3, 2, 0},{  7, 1, 1},{ -7, 1, 1},{  1, 4, 0},
337       { -1, 4, 0},{  8, 1, 1},{ -8, 1, 1},{  2, 3, 0},{ -2, 3, 0},{  4, 2, 0},
338       { -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  9, 1, 1},{ -9, 1, 1},{  5, 2, 0},
339       { -5, 2, 0},{  2, 4, 0},{ -2, 4, 0},{  1, 6, 0},{ -1, 6, 0},{ 10, 1, 2},
340       {-10, 1, 2},{  3, 3, 0},{ -3, 3, 0},{ 11, 1, 2},{-11, 1, 2},{  1, 7, 0},
341       { -1, 7, 0},{  6, 2, 0},{ -6, 2, 0},{  3, 4, 0},{ -3, 4, 0},{  2, 5, 0},
342       { -2, 5, 0},{ 12, 1, 2},{-12, 1, 2},{  4, 3, 0},{ -4, 3, 0}
343     },
344     //level_add
345     { 0,13, 7, 5, 4, 3, 2, 2,-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     6, //inc_limit
349     7  //max_run
350   },{
351     { //level / run
352       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
353       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  1, 2, 0},
354       { -1, 2, 0},{  6, 1, 0},{ -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},
355       { -8, 1, 0},{  2, 2, 0},{ -2, 2, 0},{  9, 1, 0},{ -9, 1, 0},{  1, 3, 0},
356       { -1, 3, 0},{ 10, 1, 1},{-10, 1, 1},{  3, 2, 0},{ -3, 2, 0},{ 11, 1, 1},
357       {-11, 1, 1},{  4, 2, 0},{ -4, 2, 0},{ 12, 1, 1},{-12, 1, 1},{  1, 4, 0},
358       { -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{ 13, 1, 1},{-13, 1, 1},{  5, 2, 0},
359       { -5, 2, 0},{ 14, 1, 1},{-14, 1, 1},{  6, 2, 0},{ -6, 2, 0},{  1, 5, 0},
360       { -1, 5, 0},{ 15, 1, 1},{-15, 1, 1},{  3, 3, 0},{ -3, 3, 0},{ 16, 1, 1},
361       {-16, 1, 1},{  2, 4, 0},{ -2, 4, 0},{  7, 2, 0},{ -7, 2, 0}
362     },
363     //level_add
364     { 0,17, 8, 4, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
365      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
366     2, //golomb_order
367     9, //inc_limit
368     5  //max_run
369   },{
370     { //level / run
371       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
372       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
373       { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  8, 1, 0},
374       { -8, 1, 0},{  9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},
375       {-11, 1, 0},{ 12, 1, 0},{-12, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 13, 1, 0},
376       {-13, 1, 0},{  1, 3, 0},{ -1, 3, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0},
377       {-15, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 16, 1, 0},{-16, 1, 0},{ 17, 1, 0},
378       {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{  4, 2, 0},{ -4, 2, 0},{ 19, 1, 0},
379       {-19, 1, 0},{ 20, 1, 0},{-20, 1, 0},{  2, 3, 0},{ -2, 3, 0},{  1, 4, 0},
380       { -1, 4, 0},{  5, 2, 0},{ -5, 2, 0},{ 21, 1, 0},{-21, 1, 0}
381     },
382     //level_add
383     { 0,22, 6, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
384      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
385     2, //golomb_order
386     INT_MAX, //inc_limit
387     4 //max_run
388   }
389 };
390
391 static const residual_vlc_t chroma_2dvlc[5] = {
392   {
393     { //level / run
394       {  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},{  1, 3, 1},{ -1, 3, 1},
395       {  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},{  1, 6, 1},{ -1, 6, 1},
396       {  1, 7, 1},{ -1, 7, 1},{  2, 1, 2},{ -2, 1, 2},{  1, 8, 1},{ -1, 8, 1},
397       {  1, 9, 1},{ -1, 9, 1},{  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},
398       {  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},{  1,14, 1},{ -1,14, 1},
399       {  1,15, 1},{ -1,15, 1},{  3, 1, 3},{ -3, 1, 3},{  1,16, 1},{ -1,16, 1},
400       {  1,17, 1},{ -1,17, 1},{  1,18, 1},{ -1,18, 1},{  1,19, 1},{ -1,19, 1},
401       {  1,20, 1},{ -1,20, 1},{  1,21, 1},{ -1,21, 1},{  1,22, 1},{ -1,22, 1},
402       {  2, 2, 2},{ -2, 2, 2},{  1,23, 1},{ -1,23, 1},{  1,24, 1},{ -1,24, 1},
403       {  1,25, 1},{ -1,25, 1},{  4, 1, 3},{ -4, 1, 3},{   EOB   }
404     },
405     //level_add
406     { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
407       2, 2, 2, 2, 2, 2, 2, 2, 2,-1},
408     2, //golomb_order
409     0, //inc_limit
410     25 //max_run
411   },{
412     { //level / run
413       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 1},
414       { -2, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
415       { -1, 5, 0},{  1, 6, 0},{ -1, 6, 0},{  3, 1, 2},{ -3, 1, 2},{  1, 7, 0},
416       { -1, 7, 0},{  1, 8, 0},{ -1, 8, 0},{  2, 2, 1},{ -2, 2, 1},{  1, 9, 0},
417       { -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  1,11, 0},{ -1,11, 0},{  4, 1, 2},
418       { -4, 1, 2},{  1,12, 0},{ -1,12, 0},{  1,13, 0},{ -1,13, 0},{  1,14, 0},
419       { -1,14, 0},{  2, 3, 1},{ -2, 3, 1},{  1,15, 0},{ -1,15, 0},{  2, 4, 1},
420       { -2, 4, 1},{  5, 1, 3},{ -5, 1, 3},{  3, 2, 2},{ -3, 2, 2},{  1,16, 0},
421       { -1,16, 0},{  1,17, 0},{ -1,17, 0},{  1,18, 0},{ -1,18, 0},{  2, 5, 1},
422       { -2, 5, 1},{  1,19, 0},{ -1,19, 0},{  1,20, 0},{ -1,20, 0}
423     },
424     //level_add
425     { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426       2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
427     0, //golomb_order
428     1, //inc_limit
429     20 //max_run
430   },{
431     { //level / run
432       {  1, 1, 0},{ -1, 1, 0},{   EOB   },{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},
433       { -1, 2, 0},{  3, 1, 1},{ -3, 1, 1},{  1, 3, 0},{ -1, 3, 0},{  4, 1, 1},
434       { -4, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  1, 4, 0},{ -1, 4, 0},{  5, 1, 2},
435       { -5, 1, 2},{  1, 5, 0},{ -1, 5, 0},{  3, 2, 1},{ -3, 2, 1},{  2, 3, 0},
436       { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 2},{ -6, 1, 2},{  1, 7, 0},
437       { -1, 7, 0},{  2, 4, 0},{ -2, 4, 0},{  7, 1, 2},{ -7, 1, 2},{  1, 8, 0},
438       { -1, 8, 0},{  4, 2, 1},{ -4, 2, 1},{  1, 9, 0},{ -1, 9, 0},{  3, 3, 1},
439       { -3, 3, 1},{  2, 5, 0},{ -2, 5, 0},{  2, 6, 0},{ -2, 6, 0},{  8, 1, 2},
440       { -8, 1, 2},{  1,10, 0},{ -1,10, 0},{  1,11, 0},{ -1,11, 0},{  9, 1, 2},
441       { -9, 1, 2},{  5, 2, 2},{ -5, 2, 2},{  3, 4, 1},{ -3, 4, 1},
442     },
443     //level_add
444     { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2,-1,-1,-1,-1,-1,
445      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
446     1, //golomb_order
447     2, //inc_limit
448     11 //max_run
449   },{
450     { //level / run
451       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
452       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  5, 1, 1},
453       { -5, 1, 1},{  2, 2, 0},{ -2, 2, 0},{  6, 1, 1},{ -6, 1, 1},{  1, 3, 0},
454       { -1, 3, 0},{  7, 1, 1},{ -7, 1, 1},{  3, 2, 0},{ -3, 2, 0},{  8, 1, 1},
455       { -8, 1, 1},{  1, 4, 0},{ -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{  9, 1, 1},
456       { -9, 1, 1},{  4, 2, 0},{ -4, 2, 0},{  1, 5, 0},{ -1, 5, 0},{ 10, 1, 1},
457       {-10, 1, 1},{  3, 3, 0},{ -3, 3, 0},{  5, 2, 1},{ -5, 2, 1},{  2, 4, 0},
458       { -2, 4, 0},{ 11, 1, 1},{-11, 1, 1},{  1, 6, 0},{ -1, 6, 0},{ 12, 1, 1},
459       {-12, 1, 1},{  1, 7, 0},{ -1, 7, 0},{  6, 2, 1},{ -6, 2, 1},{ 13, 1, 1},
460       {-13, 1, 1},{  2, 5, 0},{ -2, 5, 0},{  1, 8, 0},{ -1, 8, 0},
461     },
462     //level_add
463     { 0,14, 7, 4, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,
464      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
465     1, //golomb_order
466     4, //inc_limit
467     8  //max_run
468   },{
469     { //level / run
470       {   EOB   },{  1, 1, 0},{ -1, 1, 0},{  2, 1, 0},{ -2, 1, 0},{  3, 1, 0},
471       { -3, 1, 0},{  4, 1, 0},{ -4, 1, 0},{  5, 1, 0},{ -5, 1, 0},{  6, 1, 0},
472       { -6, 1, 0},{  7, 1, 0},{ -7, 1, 0},{  8, 1, 0},{ -8, 1, 0},{  1, 2, 0},
473       { -1, 2, 0},{  9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},
474       {-11, 1, 0},{  2, 2, 0},{ -2, 2, 0},{ 12, 1, 0},{-12, 1, 0},{ 13, 1, 0},
475       {-13, 1, 0},{  3, 2, 0},{ -3, 2, 0},{ 14, 1, 0},{-14, 1, 0},{  1, 3, 0},
476       { -1, 3, 0},{ 15, 1, 0},{-15, 1, 0},{  4, 2, 0},{ -4, 2, 0},{ 16, 1, 0},
477       {-16, 1, 0},{ 17, 1, 0},{-17, 1, 0},{  5, 2, 0},{ -5, 2, 0},{  1, 4, 0},
478       { -1, 4, 0},{  2, 3, 0},{ -2, 3, 0},{ 18, 1, 0},{-18, 1, 0},{  6, 2, 0},
479       { -6, 2, 0},{ 19, 1, 0},{-19, 1, 0},{  1, 5, 0},{ -1, 5, 0},
480     },
481     //level_add
482     { 0,20, 7, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
483      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
484     0, //golomb_order
485     INT_MAX, //inc_limit
486     5, //max_run
487   }
488 };
489
490 #undef EOB
491
492 static const uint8_t alpha_tab[64] = {
493    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  3,  3,
494    4,  4,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 16, 18, 20,
495   22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
496   46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
497 };
498
499 static const uint8_t beta_tab[64] = {
500    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
501    2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,  5,  6,  6,
502    6,  7,  7,  7,  8,  8,  8,  9,  9, 10, 10, 11, 11, 12, 13, 14,
503   15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
504 };
505
506 static const uint8_t tc_tab[64] = {
507   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
508   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
509   2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
510   5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
511 };
512
513 static const int_fast8_t left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7};
514 static const int_fast8_t top_modifier_l[8]  = {-1, 1, 5,-1,-1, 5, 7, 7};
515 static const int_fast8_t left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6};
516 static const int_fast8_t top_modifier_c[7]  = { 4, 1,-1,-1, 4, 6, 6};