optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
[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 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|SYM1|SPLITH,
153   FWD0|SYM1       |SPLITV,
154   BWD0|SYM1|SPLITH,
155   BWD0|SYM1       |SPLITV,
156   SYM0|FWD1|SPLITH,
157   SYM0|FWD1       |SPLITV,
158   SYM0|BWD1|SPLITH,
159   SYM0|BWD1       |SPLITV,
160   SYM0|SYM1|SPLITH,
161   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[26];
233   int8_t golomb_order;
234   int inc_limit;
235   int8_t max_run;
236 } residual_vlc_t;
237
238 static const residual_vlc_t intra_2dvlc[7] = {
239   {
240     { //level / run / table_inc
241       {  1, 0, 1},{ -1, 0, 1},{  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},
242       {  1, 3, 1},{ -1, 3, 1},{  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},
243       {  1, 6, 1},{ -1, 6, 1},{  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},
244       {  1, 9, 1},{ -1, 9, 1},{  1,10, 1},{ -1,10, 1},{  2, 0, 2},{ -2, 0, 2},
245       {  1,11, 1},{ -1,11, 1},{  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},
246       {  1,14, 1},{ -1,14, 1},{  2, 1, 2},{ -2, 1, 2},{  1,15, 1},{ -1,15, 1},
247       {  1,16, 1},{ -1,16, 1},{  3, 0, 3},{ -3, 0, 3},{  1,17, 1},{ -1,17, 1},
248       {  1,18, 1},{ -1,18, 1},{  2, 2, 2},{ -2, 2, 2},{  1,19, 1},{ -1,19, 1},
249       {  1,20, 1},{ -1,20, 1},{  2, 3, 2},{ -2, 3, 2},{  1,21, 1},{ -1,21, 1},
250       {  2, 4, 2},{ -2, 4, 2},{  1,22, 1},{ -1,22, 1},{  0, 0,-1}
251     },
252     //level_add
253     { 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
254       2, 2, 2, 2, 2, 2, 2,-1,-1,-1},
255     2, //golomb_order
256     0, //inc_limit
257     22, //max_run
258   },{
259     { //level / run
260       {  1, 0, 0},{ -1, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  2, 0, 1},{ -2, 0, 1},
261       {  1, 2, 0},{ -1, 2, 0},{  0, 0, 0},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},
262       { -1, 4, 0},{  1, 5, 0},{ -1, 5, 0},{  3, 0, 2},{ -3, 0, 2},{  2, 1, 1},
263       { -2, 1, 1},{  1, 6, 0},{ -1, 6, 0},{  1, 7, 0},{ -1, 7, 0},{  1, 8, 0},
264       { -1, 8, 0},{  2, 2, 1},{ -2, 2, 1},{  4, 0, 2},{ -4, 0, 2},{  1, 9, 0},
265       { -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  2, 3, 1},{ -2, 3, 1},{  3, 1, 2},
266       { -3, 1, 2},{  1,11, 0},{ -1,11, 0},{  2, 4, 1},{ -2, 4, 1},{  5, 0, 3},
267       { -5, 0, 3},{  1,12, 0},{ -1,12, 0},{  2, 5, 1},{ -2, 5, 1},{  1,13, 0},
268       { -1,13, 0},{  2, 6, 1},{ -2, 6, 1},{  2, 7, 1},{ -2, 7, 1},{  3, 2, 2},
269       { -3, 2, 2},{  6, 0, 3},{ -6, 0, 3},{  1,14, 0},{ -1,14, 0}
270     },
271     //level_add
272     { 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,
273       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
274     2, //golomb_order
275     1, //inc_limit
276     14, //max_run
277   },{
278     { //level / run
279       {  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  1, 1, 0},{ -1, 1, 0},
280       {  3, 0, 1},{ -3, 0, 1},{  0, 0, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 0},
281       { -2, 1, 0},{  4, 0, 1},{ -4, 0, 1},{  1, 3, 0},{ -1, 3, 0},{  5, 0, 2},
282       { -5, 0, 2},{  1, 4, 0},{ -1, 4, 0},{  3, 1, 1},{ -3, 1, 1},{  2, 2, 0},
283       { -2, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  6, 0, 2},{ -6, 0, 2},{  2, 3, 0},
284       { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  4, 1, 1},{ -4, 1, 1},{  7, 0, 2},
285       { -7, 0, 2},{  3, 2, 1},{ -3, 2, 1},{  2, 4, 0},{ -2, 4, 0},{  1, 7, 0},
286       { -1, 7, 0},{  2, 5, 0},{ -2, 5, 0},{  8, 0, 3},{ -8, 0, 3},{  1, 8, 0},
287       { -1, 8, 0},{  5, 1, 2},{ -5, 1, 2},{  3, 3, 1},{ -3, 3, 1},{  2, 6, 0},
288       { -2, 6, 0},{  9, 0, 3},{ -9, 0, 3},{  1, 9, 0},{ -1, 9, 0}
289     },
290     //level_add
291     {10, 6, 4, 4, 3, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,
292      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
293     2, //golomb_order
294     2, //inc_limit
295     9, //max_run
296   },{
297     { //level / run
298       {  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},{ -3, 0, 0},
299       {  1, 1, 0},{ -1, 1, 0},{  0, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 1},
300       { -5, 0, 1},{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  6, 0, 1},
301       { -6, 0, 1},{  3, 1, 0},{ -3, 1, 0},{  7, 0, 1},{ -7, 0, 1},{  1, 3, 0},
302       { -1, 3, 0},{  8, 0, 2},{ -8, 0, 2},{  2, 2, 0},{ -2, 2, 0},{  4, 1, 0},
303       { -4, 1, 0},{  1, 4, 0},{ -1, 4, 0},{  9, 0, 2},{ -9, 0, 2},{  5, 1, 1},
304       { -5, 1, 1},{  2, 3, 0},{ -2, 3, 0},{ 10, 0, 2},{-10, 0, 2},{  3, 2, 0},
305       { -3, 2, 0},{  1, 5, 0},{ -1, 5, 0},{ 11, 0, 3},{-11, 0, 3},{  6, 1, 1},
306       { -6, 1, 1},{  1, 6, 0},{ -1, 6, 0},{  2, 4, 0},{ -2, 4, 0},{  3, 3, 0},
307       { -3, 3, 0},{ 12, 0, 3},{-12, 0, 3},{  4, 2, 0},{ -4, 2, 0}
308     },
309     //level_add
310     {13, 7, 5, 4, 3, 2, 2,-1,-1,-1 -1,-1,-1,-1,-1,-1,
311      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
312     2, //golomb_order
313     4, //inc_limit
314     6, //max_run
315   },{
316     { //level / run
317       {  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},{ -3, 0, 0},
318       {  0, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  6, 0, 0},
319       { -6, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  7, 0, 0},{ -7, 0, 0},{  8, 0, 1},
320       { -8, 0, 1},{  2, 1, 0},{ -2, 1, 0},{  9, 0, 1},{ -9, 0, 1},{ 10, 0, 1},
321       {-10, 0, 1},{  1, 2, 0},{ -1, 2, 0},{  3, 1, 0},{ -3, 1, 0},{ 11, 0, 2},
322       {-11, 0, 2},{  4, 1, 0},{ -4, 1, 0},{ 12, 0, 2},{-12, 0, 2},{ 13, 0, 2},
323       {-13, 0, 2},{  5, 1, 0},{ -5, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},
324       { -2, 2, 0},{ 14, 0, 2},{-14, 0, 2},{  6, 1, 0},{ -6, 1, 0},{ 15, 0, 2},
325       {-15, 0, 2},{ 16, 0, 2},{-16, 0, 2},{  3, 2, 0},{ -3, 2, 0},{  1, 4, 0},
326       { -1, 4, 0},{  7, 1, 0},{ -7, 1, 0},{ 17, 0, 2},{-17, 0, 2},
327     },
328     //level_add
329     {18, 8, 4, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
330      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
331     2, //golomb_order
332     7, //inc_limit
333     4, //max_run
334   },{
335     { //level / run
336       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
337       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  6, 0, 0},
338       { -6, 0, 0},{  7, 0, 0},{ -7, 0, 0},{  8, 0, 0},{ -8, 0, 0},{  9, 0, 0},
339       { -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{  1, 1, 0},{ -1, 1, 0},{ 11, 0, 1},
340       {-11, 0, 1},{ 12, 0, 1},{-12, 0, 1},{ 13, 0, 1},{-13, 0, 1},{  2, 1, 0},
341       { -2, 1, 0},{ 14, 0, 1},{-14, 0, 1},{ 15, 0, 1},{-15, 0, 1},{  3, 1, 0},
342       { -3, 1, 0},{ 16, 0, 1},{-16, 0, 1},{  1, 2, 0},{ -1, 2, 0},{ 17, 0, 1},
343       {-17, 0, 1},{  4, 1, 0},{ -4, 1, 0},{ 18, 0, 1},{-18, 0, 1},{  5, 1, 0},
344       { -5, 1, 0},{ 19, 0, 1},{-19, 0, 1},{ 20, 0, 1},{-20, 0, 1},{  6, 1, 0},
345       { -6, 1, 0},{ 21, 0, 1},{-21, 0, 1},{  2, 2, 0},{ -2, 2, 0},
346     },
347     //level_add
348     {22, 7, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
349      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
350     2, //golomb_order
351     10, //inc_limit
352     2, //max_run
353   },{
354     { //level / run
355       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
356       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  6, 0, 0},
357       { -6, 0, 0},{  7, 0, 0},{ -7, 0, 0},{  8, 0, 0},{ -8, 0, 0},{  9, 0, 0},
358       { -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},{-11, 0, 0},{ 12, 0, 0},
359       {-12, 0, 0},{ 13, 0, 0},{-13, 0, 0},{ 14, 0, 0},{-14, 0, 0},{ 15, 0, 0},
360       {-15, 0, 0},{ 16, 0, 0},{-16, 0, 0},{  1, 1, 0},{ -1, 1, 0},{ 17, 0, 0},
361       {-17, 0, 0},{ 18, 0, 0},{-18, 0, 0},{ 19, 0, 0},{-19, 0, 0},{ 20, 0, 0},
362       {-20, 0, 0},{ 21, 0, 0},{-21, 0, 0},{  2, 1, 0},{ -2, 1, 0},{ 22, 0, 0},
363       {-22, 0, 0},{ 23, 0, 0},{-23, 0, 0},{ 24, 0, 0},{-24, 0, 0},{ 25, 0, 0},
364       {-25, 0, 0},{  3, 1, 0},{ -3, 1, 0},{ 26, 0, 0},{-26, 0, 0}
365     },
366     //level_add
367     {27, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
368      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
369     2, //golomb_order
370     INT_MAX, //inc_limit
371     1, //max_run
372   }
373 };
374
375 static const residual_vlc_t inter_2dvlc[7] = {
376   {
377     { //level / run
378       {  1, 0, 1},{ -1, 0, 1},{  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},
379       {  1, 3, 1},{ -1, 3, 1},{  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},
380       {  1, 6, 1},{ -1, 6, 1},{  1, 7, 1},{ -1, 7, 1},{  1, 8, 1},{ -1, 8, 1},
381       {  1, 9, 1},{ -1, 9, 1},{  1,10, 1},{ -1,10, 1},{  1,11, 1},{ -1,11, 1},
382       {  1,12, 1},{ -1,12, 1},{  2, 0, 2},{ -2, 0, 2},{  1,13, 1},{ -1,13, 1},
383       {  1,14, 1},{ -1,14, 1},{  1,15, 1},{ -1,15, 1},{  1,16, 1},{ -1,16, 1},
384       {  1,17, 1},{ -1,17, 1},{  1,18, 1},{ -1,18, 1},{  3, 0, 3},{ -3, 0, 3},
385       {  1,19, 1},{ -1,19, 1},{  1,20, 1},{ -1,20, 1},{  2, 1, 2},{ -2, 1, 2},
386       {  1,21, 1},{ -1,21, 1},{  1,22, 1},{ -1,22, 1},{  1,23, 1},{ -1,23, 1},
387       {  1,24, 1},{ -1,24, 1},{  1,25, 1},{ -1,25, 1},{  0, 0,-1}
388     },
389     //level_add
390     { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
391       2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
392     3, //golomb_order
393     0, //inc_limit
394     25 //max_run
395   },{
396     { //level / run
397       {  1, 0, 0},{ -1, 0, 0},{  0, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  1, 2, 0},
398       { -1, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
399       { -1, 5, 0},{  2, 0, 1},{ -2, 0, 1},{  1, 6, 0},{ -1, 6, 0},{  1, 7, 0},
400       { -1, 7, 0},{  1, 8, 0},{ -1, 8, 0},{  1, 9, 0},{ -1, 9, 0},{  2, 1, 1},
401       { -2, 1, 1},{  1,10, 0},{ -1,10, 0},{  1,11, 0},{ -1,11, 0},{  3, 0, 2},
402       { -3, 0, 2},{  1,12, 0},{ -1,12, 0},{  1,13, 0},{ -1,13, 0},{  2, 2, 1},
403       { -2, 2, 1},{  1,14, 0},{ -1,14, 0},{  2, 3, 1},{ -2, 3, 1},{  1,15, 0},
404       { -1,15, 0},{  2, 4, 1},{ -2, 4, 1},{  1,16, 0},{ -1,16, 0},{  4, 0, 3},
405       { -4, 0, 3},{  2, 5, 1},{ -2, 5, 1},{  1,17, 0},{ -1,17, 0},{  1,18, 0},
406       { -1,18, 0},{  2, 6, 1},{ -2, 6, 1},{  3, 1, 2},{ -3, 1, 2},
407     },
408     //level_add
409     { 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
410       2, 2, 2,-1,-1,-1,-1,-1,-1,-1},
411     2, //golomb_order
412     1, //inc_limit
413     18 //max_run
414   },{
415     { //level / run
416       {  1, 0, 0},{ -1, 0, 0},{  0, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  2, 0, 0},
417       { -2, 0, 0},{  1, 2, 0},{ -1, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  3, 0, 1},
418       { -3, 0, 1},{  2, 1, 0},{ -2, 1, 0},{  1, 4, 0},{ -1, 4, 0},{  1, 5, 0},
419       { -1, 5, 0},{  1, 6, 0},{ -1, 6, 0},{  2, 2, 0},{ -2, 2, 0},{  4, 0, 2},
420       { -4, 0, 2},{  1, 7, 0},{ -1, 7, 0},{  3, 1, 1},{ -3, 1, 1},{  2, 3, 0},
421       { -2, 3, 0},{  1, 8, 0},{ -1, 8, 0},{  1, 9, 0},{ -1, 9, 0},{  5, 0, 2},
422       { -5, 0, 2},{  2, 4, 0},{ -2, 4, 0},{  1,10, 0},{ -1,10, 0},{  2, 5, 0},
423       { -2, 5, 0},{  1,11, 0},{ -1,11, 0},{  3, 2, 1},{ -3, 2, 1},{  6, 0, 2},
424       { -6, 0, 2},{  4, 1, 2},{ -4, 1, 2},{  1,12, 0},{ -1,12, 0},{  2, 6, 0},
425       { -2, 6, 0},{  3, 3, 1},{ -3, 3, 1},{  1,13, 0},{ -1,13, 0},
426     },
427     //level_add
428     { 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,-1,
429       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
430     2, //golomb_order
431     2, //inc_limit
432     13 //max_run
433   },{
434     { //level / run
435       {  1, 0, 0},{ -1, 0, 0},{  0, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  1, 1, 0},
436       { -1, 1, 0},{  3, 0, 0},{ -3, 0, 0},{  1, 2, 0},{ -1, 2, 0},{  2, 1, 0},
437       { -2, 1, 0},{  4, 0, 1},{ -4, 0, 1},{  1, 3, 0},{ -1, 3, 0},{  5, 0, 1},
438       { -5, 0, 1},{  1, 4, 0},{ -1, 4, 0},{  3, 1, 0},{ -3, 1, 0},{  2, 2, 0},
439       { -2, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  6, 0, 1},{ -6, 0, 1},{  2, 3, 0},
440       { -2, 3, 0},{  1, 6, 0},{ -1, 6, 0},{  4, 1, 1},{ -4, 1, 1},{  7, 0, 2},
441       { -7, 0, 2},{  3, 2, 0},{ -3, 2, 0},{  1, 7, 0},{ -1, 7, 0},{  2, 4, 0},
442       { -2, 4, 0},{  8, 0, 2},{ -8, 0, 2},{  1, 8, 0},{ -1, 8, 0},{  3, 3, 0},
443       { -3, 3, 0},{  2, 5, 0},{ -2, 5, 0},{  5, 1, 1},{ -5, 1, 1},{  1, 9, 0},
444       { -1, 9, 0},{  9, 0, 2},{ -9, 0, 2},{  4, 2, 1},{ -4, 2, 1},
445     },
446     //level_add
447     {10, 6, 5, 4, 3, 3, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1,
448      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
449     2, //golomb_order
450     3, //inc_limit
451     9 //max_run
452   },{
453     { //level / run
454       {  1, 0, 0},{ -1, 0, 0},{  0, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
455       { -3, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},
456       { -5, 0, 0},{  2, 1, 0},{ -2, 1, 0},{  1, 2, 0},{ -1, 2, 0},{  6, 0, 0},
457       { -6, 0, 0},{  3, 1, 0},{ -3, 1, 0},{  7, 0, 1},{ -7, 0, 1},{  1, 3, 0},
458       { -1, 3, 0},{  8, 0, 1},{ -8, 0, 1},{  2, 2, 0},{ -2, 2, 0},{  4, 1, 0},
459       { -4, 1, 0},{  1, 4, 0},{ -1, 4, 0},{  9, 0, 1},{ -9, 0, 1},{  5, 1, 0},
460       { -5, 1, 0},{  2, 3, 0},{ -2, 3, 0},{  1, 5, 0},{ -1, 5, 0},{ 10, 0, 2},
461       {-10, 0, 2},{  3, 2, 0},{ -3, 2, 0},{ 11, 0, 2},{-11, 0, 2},{  1, 6, 0},
462       { -1, 6, 0},{  6, 1, 0},{ -6, 1, 0},{  3, 3, 0},{ -3, 3, 0},{  2, 4, 0},
463       { -2, 4, 0},{ 12, 0, 2},{-12, 0, 2},{  4, 2, 0},{ -4, 2, 0},
464     },
465     //level_add
466     {13, 7, 5, 4, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,
467      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
468     2, //golomb_order
469     6, //inc_limit
470     6 //max_run
471   },{
472     { //level / run
473       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
474       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  1, 1, 0},
475       { -1, 1, 0},{  6, 0, 0},{ -6, 0, 0},{  7, 0, 0},{ -7, 0, 0},{  8, 0, 0},
476       { -8, 0, 0},{  2, 1, 0},{ -2, 1, 0},{  9, 0, 0},{ -9, 0, 0},{  1, 2, 0},
477       { -1, 2, 0},{ 10, 0, 1},{-10, 0, 1},{  3, 1, 0},{ -3, 1, 0},{ 11, 0, 1},
478       {-11, 0, 1},{  4, 1, 0},{ -4, 1, 0},{ 12, 0, 1},{-12, 0, 1},{  1, 3, 0},
479       { -1, 3, 0},{  2, 2, 0},{ -2, 2, 0},{ 13, 0, 1},{-13, 0, 1},{  5, 1, 0},
480       { -5, 1, 0},{ 14, 0, 1},{-14, 0, 1},{  6, 1, 0},{ -6, 1, 0},{  1, 4, 0},
481       { -1, 4, 0},{ 15, 0, 1},{-15, 0, 1},{  3, 2, 0},{ -3, 2, 0},{ 16, 0, 1},
482       {-16, 0, 1},{  2, 3, 0},{ -2, 3, 0},{  7, 1, 0},{ -7, 1, 0},
483     },
484     //level_add
485     {17, 8, 4, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
486      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
487     2, //golomb_order
488     9, //inc_limit
489     4 //max_run
490   },{
491     { //level / run
492       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
493       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  6, 0, 0},
494       { -6, 0, 0},{  7, 0, 0},{ -7, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  8, 0, 0},
495       { -8, 0, 0},{  9, 0, 0},{ -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},
496       {-11, 0, 0},{ 12, 0, 0},{-12, 0, 0},{  2, 1, 0},{ -2, 1, 0},{ 13, 0, 0},
497       {-13, 0, 0},{  1, 2, 0},{ -1, 2, 0},{ 14, 0, 0},{-14, 0, 0},{ 15, 0, 0},
498       {-15, 0, 0},{  3, 1, 0},{ -3, 1, 0},{ 16, 0, 0},{-16, 0, 0},{ 17, 0, 0},
499       {-17, 0, 0},{ 18, 0, 0},{-18, 0, 0},{  4, 1, 0},{ -4, 1, 0},{ 19, 0, 0},
500       {-19, 0, 0},{ 20, 0, 0},{-20, 0, 0},{  2, 2, 0},{ -2, 2, 0},{  1, 3, 0},
501       { -1, 3, 0},{  5, 1, 0},{ -5, 1, 0},{ 21, 0, 0},{-21, 0, 0},
502     },
503     //level_add
504     {22, 6, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
505      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
506     2, //golomb_order
507     INT_MAX, //inc_limit
508     3 //max_run
509   }
510 };
511
512 static const residual_vlc_t chroma_2dvlc[5] = {
513   {
514     { //level / run
515       {  1, 0, 1},{ -1, 0, 1},{  1, 1, 1},{ -1, 1, 1},{  1, 2, 1},{ -1, 2, 1},
516       {  1, 3, 1},{ -1, 3, 1},{  1, 4, 1},{ -1, 4, 1},{  1, 5, 1},{ -1, 5, 1},
517       {  1, 6, 1},{ -1, 6, 1},{  2, 0, 2},{ -2, 0, 2},{  1, 7, 1},{ -1, 7, 1},
518       {  1, 8, 1},{ -1, 8, 1},{  1, 9, 1},{ -1, 9, 1},{  1,10, 1},{ -1,10, 1},
519       {  1,11, 1},{ -1,11, 1},{  1,12, 1},{ -1,12, 1},{  1,13, 1},{ -1,13, 1},
520       {  1,14, 1},{ -1,14, 1},{  3, 0, 3},{ -3, 0, 3},{  1,15, 1},{ -1,15, 1},
521       {  1,16, 1},{ -1,16, 1},{  1,17, 1},{ -1,17, 1},{  1,18, 1},{ -1,18, 1},
522       {  1,19, 1},{ -1,19, 1},{  1,20, 1},{ -1,20, 1},{  1,21, 1},{ -1,21, 1},
523       {  2, 1, 2},{ -2, 1, 2},{  1,22, 1},{ -1,22, 1},{  1,23, 1},{ -1,23, 1},
524       {  1,24, 1},{ -1,24, 1},{  4, 0, 3},{ -4, 0, 3},{  0, 0,-1}
525     },
526     //level_add
527     { 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
528       2, 2, 2, 2, 2, 2, 2, 2, 2,-1},
529     2, //golomb_order
530     0, //inc_limit
531     24, //max_run
532   },{
533     { //level / run
534       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  2, 0, 1},
535       { -2, 0, 1},{  1, 2, 0},{ -1, 2, 0},{  1, 3, 0},{ -1, 3, 0},{  1, 4, 0},
536       { -1, 4, 0},{  1, 5, 0},{ -1, 5, 0},{  3, 0, 2},{ -3, 0, 2},{  1, 6, 0},
537       { -1, 6, 0},{  1, 7, 0},{ -1, 7, 0},{  2, 1, 1},{ -2, 1, 1},{  1, 8, 0},
538       { -1, 8, 0},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  4, 0, 2},
539       { -4, 0, 2},{  1,11, 0},{ -1,11, 0},{  1,12, 0},{ -1,12, 0},{  1,13, 0},
540       { -1,13, 0},{  2, 2, 1},{ -2, 2, 1},{  1,14, 0},{ -1,14, 0},{  2, 3, 1},
541       { -2, 3, 1},{  5, 0, 3},{ -5, 0, 3},{  3, 1, 2},{ -3, 1, 2},{  1,15, 0},
542       { -1,15, 0},{  1,16, 0},{ -1,16, 0},{  1,17, 0},{ -1,17, 0},{  2, 4, 1},
543       { -2, 4, 1},{  1,18, 0},{ -1,18, 0},{  1,19, 0},{ -1,19, 0},
544     },
545     //level_add
546     { 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
547       2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
548     0, //golomb_order
549     1, //inc_limit
550     19, //max_run
551   },{
552     { //level / run
553       {  1, 0, 0},{ -1, 0, 0},{  0, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  1, 1, 0},
554       { -1, 1, 0},{  3, 0, 1},{ -3, 0, 1},{  1, 2, 0},{ -1, 2, 0},{  4, 0, 1},
555       { -4, 0, 1},{  2, 1, 0},{ -2, 1, 0},{  1, 3, 0},{ -1, 3, 0},{  5, 0, 2},
556       { -5, 0, 2},{  1, 4, 0},{ -1, 4, 0},{  3, 1, 1},{ -3, 1, 1},{  2, 2, 0},
557       { -2, 2, 0},{  1, 5, 0},{ -1, 5, 0},{  6, 0, 2},{ -6, 0, 2},{  1, 6, 0},
558       { -1, 6, 0},{  2, 3, 0},{ -2, 3, 0},{  7, 0, 2},{ -7, 0, 2},{  1, 7, 0},
559       { -1, 7, 0},{  4, 1, 1},{ -4, 1, 1},{  1, 8, 0},{ -1, 8, 0},{  3, 2, 1},
560       { -3, 2, 1},{  2, 4, 0},{ -2, 4, 0},{  2, 5, 0},{ -2, 5, 0},{  8, 0, 2},
561       { -8, 0, 2},{  1, 9, 0},{ -1, 9, 0},{  1,10, 0},{ -1,10, 0},{  9, 0, 2},
562       { -9, 0, 2},{  5, 1, 2},{ -5, 1, 2},{  3, 3, 1},{ -3, 3, 1},
563     },
564     //level_add
565     {10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2,-1,-1,-1,-1,-1,
566      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
567     1, //golomb_order
568     2, //inc_limit
569     10, //max_run
570   },{
571     { //level / run
572       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
573       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  1, 1, 0},{ -1, 1, 0},{  5, 0, 1},
574       { -5, 0, 1},{  2, 1, 0},{ -2, 1, 0},{  6, 0, 1},{ -6, 0, 1},{  1, 2, 0},
575       { -1, 2, 0},{  7, 0, 1},{ -7, 0, 1},{  3, 1, 0},{ -3, 1, 0},{  8, 0, 1},
576       { -8, 0, 1},{  1, 3, 0},{ -1, 3, 0},{  2, 2, 0},{ -2, 2, 0},{  9, 0, 1},
577       { -9, 0, 1},{  4, 1, 0},{ -4, 1, 0},{  1, 4, 0},{ -1, 4, 0},{ 10, 0, 1},
578       {-10, 0, 1},{  3, 2, 0},{ -3, 2, 0},{  5, 1, 1},{ -5, 1, 1},{  2, 3, 0},
579       { -2, 3, 0},{ 11, 0, 1},{-11, 0, 1},{  1, 5, 0},{ -1, 5, 0},{ 12, 0, 1},
580       {-12, 0, 1},{  1, 6, 0},{ -1, 6, 0},{  6, 1, 1},{ -6, 1, 1},{ 13, 0, 1},
581       {-13, 0, 1},{  2, 4, 0},{ -2, 4, 0},{  1, 7, 0},{ -1, 7, 0},
582     },
583     //level_add
584     {14, 7, 4, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,
585      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
586     1, //golomb_order
587     4, //inc_limit
588     7, //max_run
589   },{
590     { //level / run
591       {  0, 0, 0},{  1, 0, 0},{ -1, 0, 0},{  2, 0, 0},{ -2, 0, 0},{  3, 0, 0},
592       { -3, 0, 0},{  4, 0, 0},{ -4, 0, 0},{  5, 0, 0},{ -5, 0, 0},{  6, 0, 0},
593       { -6, 0, 0},{  7, 0, 0},{ -7, 0, 0},{  8, 0, 0},{ -8, 0, 0},{  1, 1, 0},
594       { -1, 1, 0},{  9, 0, 0},{ -9, 0, 0},{ 10, 0, 0},{-10, 0, 0},{ 11, 0, 0},
595       {-11, 0, 0},{  2, 1, 0},{ -2, 1, 0},{ 12, 0, 0},{-12, 0, 0},{ 13, 0, 0},
596       {-13, 0, 0},{  3, 1, 0},{ -3, 1, 0},{ 14, 0, 0},{-14, 0, 0},{  1, 2, 0},
597       { -1, 2, 0},{ 15, 0, 0},{-15, 0, 0},{  4, 1, 0},{ -4, 1, 0},{ 16, 0, 0},
598       {-16, 0, 0},{ 17, 0, 0},{-17, 0, 0},{  5, 1, 0},{ -5, 1, 0},{  1, 3, 0},
599       { -1, 3, 0},{  2, 2, 0},{ -2, 2, 0},{ 18, 0, 0},{-18, 0, 0},{  6, 1, 0},
600       { -6, 1, 0},{ 19, 0, 0},{-19, 0, 0},{  1, 4, 0},{ -1, 4, 0},
601     },
602     //level_add
603     {20, 7, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
604      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
605     0, //golomb_order
606     INT_MAX, //inc_limit
607     4, //max_run
608   }
609 };
610
611 static const uint8_t alpha_tab[64] = {
612    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  3,  3,
613    4,  4,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 16, 18, 20,
614   22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
615   46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
616 };
617
618 static const uint8_t beta_tab[64] = {
619    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
620    2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,  5,  6,  6,
621    6,  7,  7,  7,  8,  8,  8,  9,  9, 10, 10, 11, 11, 12, 13, 14,
622   15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
623 };
624
625 static const uint8_t tc_tab[64] = {
626   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
627   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
628   2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
629   5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
630 };
631
632 static const int_fast8_t left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7};
633 static const int_fast8_t top_modifier_l[8]  = {-1, 1, 5,-1,-1, 5, 7, 7};
634 static const int_fast8_t left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6};
635 static const int_fast8_t top_modifier_c[7]  = { 4, 1,-1,-1, 4, 6, 6};