libvmx
VMX Codec
Loading...
Searching...
No Matches
vmxcodec_common.h
Go to the documentation of this file.
1/*
2* MIT License
3*
4* Copyright (c) 2025 Open Media Transport Contributors
5*
6* Permission is hereby granted, free of charge, to any person obtaining a copy
7* of this software and associated documentation files (the "Software"), to deal
8* in the Software without restriction, including without limitation the rights
9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10* copies of the Software, and to permit persons to whom the Software is
11* furnished to do so, subject to the following conditions:
12*
13* The above copyright notice and this permission notice shall be included in all
14* copies or substantial portions of the Software.
15*
16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22* SOFTWARE.
23*
24*/
25#pragma once
26#include "vmxcodec.h"
27#include <math.h>
28
29#define VMX_ALIGNMENT (64)
30#define VMX_BITSSIZE (64)
31#define VMX_ALIGN(val, alignment) \
32{ \
33 while (val % alignment) \
34 { \
35 val++; \
36 } \
37}
38
39const int VMX_MIN_WIDTH = 16;
40const int VMX_MIN_HEIGHT = 16;
41const int VMX_MAX_WIDTH = 7680;
42const int VMX_MAX_HEIGHT = 4320;
43
44//Profile, Resolution, TargetMbps, DCShift, MinQ, Threads
45//Highest resolutions must be at start of list
46
47static const int VMX_BR_PROFILE_INDEX = 0;
48static const int VMX_BR_RESOLUTION_INDEX = 1;
49static const int VMX_BR_TARGET_INDEX = 2;
50static const int VMX_BR_SHIFT_INDEX = 3;
51static const int VMX_BR_MINQ_INDEX = 4;
52static const int VMX_BR_THREADS_INDEX = 5;
53static const int VMX_BR_TABLE_COUNT = 36;
54
55static const int VMX_OMT_MINQ = 52;
56static const int VMX_MAXQ = 98;
57
58static const int VMX_BITRATE_TABLE[][6]
59{
60 {VMX_PROFILE_HQ, 4320, 1320, 0, 80, 8},
61 {VMX_PROFILE_OMT_HQ, 4320, 1200, 0, VMX_OMT_MINQ, 8},
62 {VMX_PROFILE_SQ, 4320, 660, 3, 60, 8},
63 {VMX_PROFILE_OMT_SQ, 4320, 600, 3, VMX_OMT_MINQ, 8},
64 {VMX_PROFILE_LQ, 4320, 440, 3, 60, 8},
65 {VMX_PROFILE_OMT_LQ, 4320, 400, 3, VMX_OMT_MINQ, 8},
66
67 {VMX_PROFILE_HQ, 2160, 800, 0, 80, 4},
68 {VMX_PROFILE_OMT_HQ, 2160, 600, 0, VMX_OMT_MINQ, 4},
69 {VMX_PROFILE_SQ, 2160, 400, 3, 60, 4},
70 {VMX_PROFILE_OMT_SQ, 2160, 300, 3, VMX_OMT_MINQ, 4},
71 {VMX_PROFILE_LQ, 2160, 266, 3, 60, 4},
72 {VMX_PROFILE_OMT_LQ, 2160, 200, 3, VMX_OMT_MINQ, 4},
73
74 {VMX_PROFILE_HQ, 1440, 504, 0, 80, 4},
75 {VMX_PROFILE_OMT_HQ, 1440, 450, 0, VMX_OMT_MINQ, 4},
76 {VMX_PROFILE_SQ, 1440, 252, 3, 60, 4},
77 {VMX_PROFILE_OMT_SQ, 1440, 300, 0, VMX_OMT_MINQ, 4},
78 {VMX_PROFILE_LQ, 1440, 168, 3, 60, 4},
79 {VMX_PROFILE_OMT_LQ, 1440, 120, 3, VMX_OMT_MINQ, 4},
80
81 {VMX_PROFILE_HQ, 1080, 260, 0, 80, 2},
82 {VMX_PROFILE_OMT_HQ, 1080, 260, 0, VMX_OMT_MINQ, 2},
83 {VMX_PROFILE_SQ, 1080, 130, 3, 60, 2},
84 {VMX_PROFILE_OMT_SQ, 1080, 200, 0, VMX_OMT_MINQ, 2},
85 {VMX_PROFILE_LQ, 1080, 86, 3, 60, 2},
86 {VMX_PROFILE_OMT_LQ, 1080, 86, 3, VMX_OMT_MINQ, 2},
87
88 {VMX_PROFILE_HQ, 720, 136, 0, 80, 2},
89 {VMX_PROFILE_OMT_HQ, 720, 136, 0, VMX_OMT_MINQ, 2},
90 {VMX_PROFILE_SQ, 720, 68, 3, 60, 2},
91 {VMX_PROFILE_OMT_SQ, 720, 68, 3, VMX_OMT_MINQ, 2},
92 {VMX_PROFILE_LQ, 720, 45, 3, 60, 2},
93 {VMX_PROFILE_OMT_LQ, 720, 45, 3, VMX_OMT_MINQ, 2},
94
95 {VMX_PROFILE_HQ, 0, 72, 0, 80, 2},
96 {VMX_PROFILE_OMT_HQ, 0, 72, 0, VMX_OMT_MINQ, 2},
97 {VMX_PROFILE_SQ, 0, 36, 3, 60, 2},
98 {VMX_PROFILE_OMT_SQ, 0, 36, 3, VMX_OMT_MINQ, 2},
99 {VMX_PROFILE_LQ, 0, 24, 3, 60, 2},
100 {VMX_PROFILE_OMT_LQ, 0, 24, 3, VMX_OMT_MINQ, 2},
101};
102
103
104static unsigned short VMX_DEFAULT_QUANTIZATION_MATRIX[64] =
105{ 16, 16, 19, 22, 26, 27, 29, 34,
10616, 16, 22, 24, 27, 29, 34, 37,
10719, 22, 26, 27, 29, 34, 34, 38,
10822, 22, 26, 27, 29, 34, 37, 40,
10922, 26, 27, 29, 32, 35, 40, 48,
11026, 27, 29, 32, 35, 40, 48, 58,
11126, 27, 29, 34, 38, 46, 56, 69,
11227, 29, 35, 38, 46, 56, 69, 83 };
113
114static BYTE VMX_ZIGZAGINV[64] =
115{
116 0,1,5,6,14,15,27,28,
117 2,4,7,13,16,26,29,42,
118 3,8,12,17,25,30,41,43,
119 9,11,18,24,31,40,44,53,
120 10,19,23,32,39,45,52,54,
121 20,22,33,38,46,51,55,60,
122 21,34,37,47,50,56,59,61,
123 35,36,48,49,57,58,62,63
124};
125
126const BYTE VMX_ZIGZAG[64] = {
127 0, 1, 8, 16, 9, 2, 3, 10,
128 17, 24, 32, 25, 18, 11, 4, 5,
129 12, 19, 26, 33, 40, 48, 41, 34,
130 27, 20, 13, 6, 7, 14, 21, 28,
131 35, 42, 49, 56, 57, 50, 43, 36,
132 29, 22, 15, 23, 30, 37, 44, 51,
133 58, 59, 52, 45, 38, 31, 39, 46,
134 53, 60, 61, 54, 47, 55, 62, 63
135};
136
137
138
139static int VMX_QUALITY[VMX_QUALITY_COUNT] = { 1,2,3,4,5,6,7,8,10,12,14,16,18,20,22,24,28,32,36,40,44,48,52,56,64 };
140
141//Color Conversion Tables
143{
144 short R;
145 short G;
146 short B;
147};
148
149//BT709 (0.2126) (0.7152) (0.0722)
150// Y=
151// R 0.2126 * 220 = 46.772
152// G 0.7152 * 220 = 157.344
153// B 0.0722 * 220 = 15.884
154// U=
155// R ((0.5 / (1-0.0722))*-0.2126 * 224 = -25.66415
156// G ((0.5 / (1-0.0722))*-0.7152) * 224 = -86.33584
157// B 0.5 * 224 = 112
158// V=
159// R 0.5 * 224 = 112
160// G ((0.5 / (1-0.2126))*-0.7152 * 224 = -101.7302
161// B ((0.5 / (1-0.2126))*-0.0722) * 224 = -10.26974
162static const ShortRGB RGB_YUV_709[]
163{
164 {47,157,16},
165 {-26,-86,112},
166 {112,-102,-10}
167};
168//INVERSE
169// R = Y + V * ((2*(1-0.2126))*(255/224))
170// G = Y - (((2*0.0722*(1-0.0722))/0.7152)*(255/224)) * U - (((2*0.2126*(1-0.2126))/0.7152)*(255/224)) * V
171// B = Y + U * ((2*(1-0.0722))*(255/224))
172// R = Y + (V * 1.792741071)
173// G = Y - 0.213248614 * U - 0.532909329 * V
174// B = Y + U * 2.112401786
175//MULTIPLY BY 16384 FOR INTRINSICS
176// Expanded Y = (255/219) * 16384 = 1.164383562 * 16384 = 19077
177// R = 1.792741071 * 16384 = 29372
178// GU = 0.213248614 * 16384 = 3494
179// GV = 0.532909329 * 16384 = 8731
180// B = 2.112401786 * 16384 = 34609.59086 (further / 2 to fit in 16bit) = 17305
181static const short YUV_RGB_709[]
182{
183 19077, //Y
184 29372, //R
185 3494, //GU
186 8731, //GV
187 17305 //B
188};
189
190//BT601 (0.299) (0.587) (0.114)
191// Y=
192// R 0.299 * 220 = 65.78
193// G 0.587 * 220 = 129.14
194// B 0.114 * 220 = 25.08
195// U=
196// R ((0.5 / (1-0.114))*-0.299 * 224 = -37.796839
197// G ((0.5 / (1-0.114))*-0.587 * 224 = -74.20316
198// B 0.5 * 224 = 112
199// V=
200// R 0.5 * 224 = 112
201// G ((0.5 / (1-0.299))*-0.587 * 224 = -93.786
202// B ((0.5 / (1-0.299))*-0.114) * 224 = -18.21398
203static const ShortRGB RGB_YUV_601[]
204{
205 {66,129,25},
206 {-38,-74,112},
207 {112,-94,-18}
208};
209//INVERSE
210// R = Y + V * ((2*(1-0.299))*(255/224))
211// G = Y - (((2*0.114*(1-0.114))/0.587)*(255/224)) * U - (((2*0.299*(1-0.299))/0.587)*(255/224)) * V
212// B = Y + U * ((2*(1-0.114))*(255/224))
213// R = Y + (V * 1.596026786)
214// G = Y - 0.39176229 * U - 0.812967647 * V
215// B = Y + U * 2.017232143
216//MULTIPLY BY 16384 FOR INTRINSICS
217// Expanded Y = (255/219) * 16384 = 1.164383562 * 16384 = 19077
218// R = 1.596026786 * 16384 = 26149
219// GU = 0.39176229 * 16384 = 6419
220// GV = 0.812967647 * 16384 = 13320
221// B = 2.017232143 * 16384 = 33050.33143 (further / 2 to fit in 16bit) = 16525
222static const short YUV_RGB_601[]
223{
224 19077, //Y
225 26149, //R
226 6419, //GU
227 13320, //GV
228 16525 //B
229};
230
231//IDCT
232#define BITS_INV_ACC 5 //4
233#define SHIFT_INV_ROW 16 - BITS_INV_ACC
234#define SHIFT_INV_COL 1 + BITS_INV_ACC
235const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
236const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
237const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round
238
239//IDCT10
240#define BITS_INV_ACC10 4
241#define SHIFT_INV_ROW10 16 - BITS_INV_ACC10
242#define SHIFT_INV_COL10 1 + BITS_INV_ACC10
243const short IRND_INV_ROW10 = 1024 * (6 - BITS_INV_ACC10); //1 << (SHIFT_INV_ROW-1)
244const short IRND_INV_COL10 = 16 * (BITS_INV_ACC10 - 3); // 1 << (SHIFT_INV_COL-1)
245const short IRND_INV_CORR10 = IRND_INV_COL10 - 1; // correction -1.0 and round
246
247//FDCT
248#define BITS_FRW_ACC 3
249#define SHIFT_FRW_COL BITS_FRW_ACC
250#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17) - 4 //Shift 4 less (16) due to divide by 16 at quant stage
251#define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1))
252
253//FDCT10
254#define BITS_FRW_ACC10 1
255#define SHIFT_FRW_COL10 BITS_FRW_ACC10
256#define SHIFT_FRW_ROW10 (BITS_FRW_ACC10 + 17) - 2 //Shift 2 less (4) due to divide by 16 at quant stage and preserving extra 2 bits for 10-bit
257#define RND_FRW_ROW10 (1 << (SHIFT_FRW_ROW10-1))
258
259const unsigned short FDCT_ROUND1 = 1;
260const unsigned short FDCT_TAN1 = 13036; //tan(pi / 16)
261const unsigned short FDCT_TAN2 = 27146; // tan(2pi / 16) (= sqrt(2) - 1)
262const unsigned short FDCT_TAN3 = 43790; // tan(3pi / 16) - 1
263const unsigned short FDCT_SQRT2 = 23170; // 0.5 / sqrt(2)
264
265static const buffer_t BitsLeftLookup[] = { 0,1ULL,2ULL,4ULL,8ULL,16ULL,32ULL,64ULL,128ULL,256ULL,512ULL,1024ULL,2048ULL,4096ULL,8192ULL,16384ULL,32768ULL,65536ULL,131072ULL,262144ULL,524288ULL,1048576ULL,2097152ULL,4194304ULL,8388608ULL,16777216ULL,33554432ULL,67108864ULL,134217728ULL,268435456ULL,536870912ULL,1073741824ULL,2147483648ULL,4294967296ULL,8589934592ULL,17179869184ULL,34359738368ULL,68719476736ULL,137438953472ULL,274877906944ULL,549755813888ULL,1099511627776ULL,2199023255552ULL,4398046511104ULL,8796093022208ULL,17592186044416ULL,35184372088832ULL,70368744177664ULL,140737488355328ULL,281474976710656ULL,562949953421312ULL,1125899906842624ULL,2251799813685248ULL,4503599627370496ULL,9007199254740992ULL,18014398509481984ULL,36028797018963968ULL,72057594037927936ULL,144115188075855872ULL,288230376151711744ULL,576460752303423488ULL,1152921504606846976ULL,2305843009213693952ULL,4611686018427387904ULL,9223372036854775808ULL };
266
267//LengthLut is the equivalent of:
268// result = 32 - __lzcnt(input);
269// result = result + result - 1;
270//__declspec(align(16)) static const BYTE GolombLengthLut[] = { 1,1,3,3,5,5,5,5,7,7,7,7,7,7,7,7,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
271//17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
272//19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,21,21,21,21,21,21,21,21,21,21,21,21,
273//21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
274//21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
275//21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,23
276//};
277__declspec(align(16)) static const BYTE GolombLengthLut[] = { 1,1,3,3,5,5,5,5,7,7,7,7,7,7,7,7,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
27817,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
27919,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
28019,19,19,19,19,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
28121,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
28221,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
28323,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
28423,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
28523,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
28623,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
28723,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
28823,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 };
289
295//Lookup complete zero Exp-Golomb codes with length for values up to 64.
296//64 is fine here since zeros that span across blocks are computed separately as they can get very large
297__declspec(align(16)) static const GolombZeroCodeLookup GolombZeroCodeLut[] = {
298{0,0},{3,2},{10,4},{11,4},{36,6},{37,6},{38,6},{39,6},{136,8},{137,8},{138,8},{139,8},{140,8},{141,8},{142,8},{143,8},{528,10},{529,10},{530,10},{531,10},{532,10},{533,10},{534,10},{535,10},{536,10},{537,10},{538,10},{539,10},{540,10},{541,10},{542,10},{543,10},{2080,12},{2081,12},{2082,12},{2083,12},{2084,12},{2085,12},{2086,12},{2087,12},{2088,12},{2089,12},{2090,12},{2091,12},{2092,12},{2093,12},{2094,12},{2095,12},{2096,12},{2097,12},{2098,12},{2099,12},{2100,12},{2101,12},{2102,12},{2103,12},{2104,12},{2105,12},{2106,12},{2107,12},{2108,12},{2109,12},{2110,12},{2111,12} };
299
300
302{
303 int8_t zeros;
304 int8_t value;
305 int16_t length; //16bit to ensure 32bit alignment
306};
307
308
309//16KB Decode LUT for 1x zero code or 1x value code that can fit within 12 bits.
310//0 length means manual decoding required
311//Also factors in any additional 1x zero code after the value code as long as both would fit into 12 bits.
312//This has the possibility it may overread the bitstream into the next plane, see notes on REWINDOVERREAD for how this is resolved.
313__declspec(align(16)) static const GolombLookup GolombLookupLut[] = {
314{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
315{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
316{1,-16,11},{1,-16,11},{1,16,11},{1,16,11},{1,-17,11},{1,-17,11},{1,17,11},{1,17,11},{1,-18,11},{1,-18,11},{1,18,11},{1,18,11},{1,-19,11},{1,-19,11},{1,19,11},{1,19,11},{1,-20,11},{1,-20,11},{1,20,11},{1,20,11},{1,-21,11},{1,-21,11},{1,21,11},{1,21,11},{1,-22,11},{1,-22,11},{1,22,11},{1,22,11},{1,-23,11},{1,-23,11},{1,23,11},{1,23,11},
317{1,-24,11},{1,-24,11},{1,24,11},{1,24,11},{1,-25,11},{1,-25,11},{1,25,11},{1,25,11},{1,-26,11},{1,-26,11},{1,26,11},{1,26,11},{1,-27,11},{1,-27,11},{1,27,11},{1,27,11},{1,-28,11},{1,-28,11},{1,28,11},{1,28,11},{1,-29,11},{1,-29,11},{1,29,11},{1,29,11},{1,-30,11},{1,-30,11},{1,30,11},{1,30,11},{1,-31,11},{1,-31,11},{1,31,11},{1,31,11},
318{1,-8,9},{1,-8,9},{1,-8,9},{1,-8,9},{1,-8,9},{1,-8,9},{2,-8,11},{2,-8,11},{1,8,9},{1,8,9},{1,8,9},{1,8,9},{1,8,9},{1,8,9},{2,8,11},{2,8,11},{1,-9,9},{1,-9,9},{1,-9,9},{1,-9,9},{1,-9,9},{1,-9,9},{2,-9,11},{2,-9,11},{1,9,9},{1,9,9},{1,9,9},{1,9,9},{1,9,9},{1,9,9},{2,9,11},{2,9,11},
319{1,-10,9},{1,-10,9},{1,-10,9},{1,-10,9},{1,-10,9},{1,-10,9},{2,-10,11},{2,-10,11},{1,10,9},{1,10,9},{1,10,9},{1,10,9},{1,10,9},{1,10,9},{2,10,11},{2,10,11},{1,-11,9},{1,-11,9},{1,-11,9},{1,-11,9},{1,-11,9},{1,-11,9},{2,-11,11},{2,-11,11},{1,11,9},{1,11,9},{1,11,9},{1,11,9},{1,11,9},{1,11,9},{2,11,11},{2,11,11},
320{1,-12,9},{1,-12,9},{1,-12,9},{1,-12,9},{1,-12,9},{1,-12,9},{2,-12,11},{2,-12,11},{1,12,9},{1,12,9},{1,12,9},{1,12,9},{1,12,9},{1,12,9},{2,12,11},{2,12,11},{1,-13,9},{1,-13,9},{1,-13,9},{1,-13,9},{1,-13,9},{1,-13,9},{2,-13,11},{2,-13,11},{1,13,9},{1,13,9},{1,13,9},{1,13,9},{1,13,9},{1,13,9},{2,13,11},{2,13,11},
321{1,-14,9},{1,-14,9},{1,-14,9},{1,-14,9},{1,-14,9},{1,-14,9},{2,-14,11},{2,-14,11},{1,14,9},{1,14,9},{1,14,9},{1,14,9},{1,14,9},{1,14,9},{2,14,11},{2,14,11},{1,-15,9},{1,-15,9},{1,-15,9},{1,-15,9},{1,-15,9},{1,-15,9},{2,-15,11},{2,-15,11},{1,15,9},{1,15,9},{1,15,9},{1,15,9},{1,15,9},{1,15,9},{2,15,11},{2,15,11},
322{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{1,-4,7},{3,-4,11},{3,-4,11},{4,-4,11},{4,-4,11},{2,-4,9},{2,-4,9},{2,-4,9},{2,-4,9},{2,-4,9},{2,-4,9},{2,-4,9},{2,-4,9},
323{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{1,4,7},{3,4,11},{3,4,11},{4,4,11},{4,4,11},{2,4,9},{2,4,9},{2,4,9},{2,4,9},{2,4,9},{2,4,9},{2,4,9},{2,4,9},
324{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{1,-5,7},{3,-5,11},{3,-5,11},{4,-5,11},{4,-5,11},{2,-5,9},{2,-5,9},{2,-5,9},{2,-5,9},{2,-5,9},{2,-5,9},{2,-5,9},{2,-5,9},
325{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{1,5,7},{3,5,11},{3,5,11},{4,5,11},{4,5,11},{2,5,9},{2,5,9},{2,5,9},{2,5,9},{2,5,9},{2,5,9},{2,5,9},{2,5,9},
326{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{1,-6,7},{3,-6,11},{3,-6,11},{4,-6,11},{4,-6,11},{2,-6,9},{2,-6,9},{2,-6,9},{2,-6,9},{2,-6,9},{2,-6,9},{2,-6,9},{2,-6,9},
327{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{1,6,7},{3,6,11},{3,6,11},{4,6,11},{4,6,11},{2,6,9},{2,6,9},{2,6,9},{2,6,9},{2,6,9},{2,6,9},{2,6,9},{2,6,9},
328{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{1,-7,7},{3,-7,11},{3,-7,11},{4,-7,11},{4,-7,11},{2,-7,9},{2,-7,9},{2,-7,9},{2,-7,9},{2,-7,9},{2,-7,9},{2,-7,9},{2,-7,9},
329{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{1,7,7},{3,7,11},{3,7,11},{4,7,11},{4,7,11},{2,7,9},{2,7,9},{2,7,9},{2,7,9},{2,7,9},{2,7,9},{2,7,9},{2,7,9},
330{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},
331{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},
332{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{1,-2,5},{5,-2,11},{5,-2,11},{6,-2,11},{6,-2,11},{7,-2,11},{7,-2,11},{8,-2,11},{8,-2,11},{3,-2,9},{3,-2,9},{3,-2,9},{3,-2,9},{3,-2,9},{3,-2,9},{3,-2,9},{3,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},{4,-2,9},
333{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},{2,-2,7},
334{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},
335{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},
336{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{5,2,11},{5,2,11},{6,2,11},{6,2,11},{7,2,11},{7,2,11},{8,2,11},{8,2,11},{3,2,9},{3,2,9},{3,2,9},{3,2,9},{3,2,9},{3,2,9},{3,2,9},{3,2,9},{4,2,9},{4,2,9},{4,2,9},{4,2,9},{4,2,9},{4,2,9},{4,2,9},{4,2,9},
337{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},{2,2,7},
338{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},
339{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},
340{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{1,-3,5},{5,-3,11},{5,-3,11},{6,-3,11},{6,-3,11},{7,-3,11},{7,-3,11},{8,-3,11},{8,-3,11},{3,-3,9},{3,-3,9},{3,-3,9},{3,-3,9},{3,-3,9},{3,-3,9},{3,-3,9},{3,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},{4,-3,9},
341{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},{2,-3,7},
342{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},
343{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},
344{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{1,3,5},{5,3,11},{5,3,11},{6,3,11},{6,3,11},{7,3,11},{7,3,11},{8,3,11},{8,3,11},{3,3,9},{3,3,9},{3,3,9},{3,3,9},{3,3,9},{3,3,9},{3,3,9},{3,3,9},{4,3,9},{4,3,9},{4,3,9},{4,3,9},{4,3,9},{4,3,9},{4,3,9},{4,3,9},
345{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},{2,3,7},
346{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
347{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
348{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
349{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
350{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
351{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
352{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
353{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
354{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},{1,-1,3},
355{5,-1,9},{5,-1,9},{5,-1,9},{5,-1,9},{5,-1,9},{5,-1,9},{5,-1,9},{5,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{6,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{7,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},{8,-1,9},
356{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},{3,-1,7},
357{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},{4,-1,7},
358{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},
359{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},
360{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},
361{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},{2,-1,5},
362{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
363{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
364{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
365{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
366{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
367{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
368{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
369{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
370{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
371{5,1,9},{5,1,9},{5,1,9},{5,1,9},{5,1,9},{5,1,9},{5,1,9},{5,1,9},{6,1,9},{6,1,9},{6,1,9},{6,1,9},{6,1,9},{6,1,9},{6,1,9},{6,1,9},{7,1,9},{7,1,9},{7,1,9},{7,1,9},{7,1,9},{7,1,9},{7,1,9},{7,1,9},{8,1,9},{8,1,9},{8,1,9},{8,1,9},{8,1,9},{8,1,9},{8,1,9},{8,1,9},
372{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},{3,1,7},
373{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},{4,1,7},
374{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},
375{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},
376{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},
377{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},
378{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
379{32,0,12},{33,0,12},{34,0,12},{35,0,12},{36,0,12},{37,0,12},{38,0,12},{39,0,12},{40,0,12},{41,0,12},{42,0,12},{43,0,12},{44,0,12},{45,0,12},{46,0,12},{47,0,12},{48,0,12},{49,0,12},{50,0,12},{51,0,12},{52,0,12},{53,0,12},{54,0,12},{55,0,12},{56,0,12},{57,0,12},{58,0,12},{59,0,12},{60,0,12},{61,0,12},{62,0,12},{63,0,12},
380{16,0,10},{16,0,10},{16,0,10},{16,0,10},{17,0,10},{17,0,10},{17,0,10},{17,0,10},{18,0,10},{18,0,10},{18,0,10},{18,0,10},{19,0,10},{19,0,10},{19,0,10},{19,0,10},{20,0,10},{20,0,10},{20,0,10},{20,0,10},{21,0,10},{21,0,10},{21,0,10},{21,0,10},{22,0,10},{22,0,10},{22,0,10},{22,0,10},{23,0,10},{23,0,10},{23,0,10},{23,0,10},
381{24,0,10},{24,0,10},{24,0,10},{24,0,10},{25,0,10},{25,0,10},{25,0,10},{25,0,10},{26,0,10},{26,0,10},{26,0,10},{26,0,10},{27,0,10},{27,0,10},{27,0,10},{27,0,10},{28,0,10},{28,0,10},{28,0,10},{28,0,10},{29,0,10},{29,0,10},{29,0,10},{29,0,10},{30,0,10},{30,0,10},{30,0,10},{30,0,10},{31,0,10},{31,0,10},{31,0,10},{31,0,10},
382{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{8,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},{9,0,8},
383{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{10,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},{11,0,8},
384{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{12,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},{13,0,8},
385{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{14,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},{15,0,8},
386{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},
387{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},{4,0,6},
388{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},
389{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},{5,0,6},
390{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},
391{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},{6,0,6},
392{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},
393{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},{7,0,6},
394{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
395{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
396{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
397{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
398{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
399{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
400{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
401{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
402{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
403{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
404{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
405{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
406{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
407{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
408{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
409{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},{3,0,4},
410{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
411{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
412{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
413{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
414{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
415{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
416{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
417{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
418{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
419{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
420{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
421{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
422{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
423{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
424{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
425{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
426{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
427{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
428{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
429{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
430{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
431{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
432{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
433{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},{1,0,2},
434{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
435{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
436{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
437{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
438{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
439{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},{2,0,4},
440{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},
441{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{3,0,6},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{4,0,8},{5,0,10},{5,0,10},{5,0,10},{6,0,12},
442};
443
444#define GetIntFrom2MagSign(i) (((i + (i & 1)) >> 1) - ((i + (i & 1)) * (i & 1)))
445
446#define FLUSHREADBITS(data) \
447{ \
448 if (data.BitsLeft == 0U) \
449 { \
450 data.BitsLeft = VMX_BITSSIZE; \
451 data.StreamPos += 8; \
452 buffer_t * s = (buffer_t *)data.StreamPos; \
453 data.TempRead = VMX_BUFFERSWAP(*s); \
454 } \
455}
456#define GETBIT(data, val) \
457{ \
458 data.BitsLeft -= 1; \
459 val = ((data.TempRead >> data.BitsLeft) & 1); \
460 FLUSHREADBITS(data); \
461}
462
463#define GETBITB(data, val) \
464{ \
465 data.BitsLeft -= 1; \
466 val = ((data.TempRead >> data.BitsLeft) & 1); \
467}
468
469#define RELOADBITS(data) \
470{ \
471 if (data.BitsLeft < 32) \
472 { \
473 int n = (VMX_BITSSIZE - data.BitsLeft) >> 3; \
474 data.StreamPos += n; \
475 buffer_t * s = (buffer_t *)data.StreamPos; \
476 data.TempRead = VMX_BUFFERSWAP(*s); \
477 data.BitsLeft += (n<<3); \
478 } \
479}
480
481#define GETZEROS(data, nz) { \
482 nz = __lzcnt64(data.TempRead << (VMX_BITSSIZE - data.BitsLeft)); \
483 if (nz >= data.BitsLeft) { \
484 nz = data.BitsLeft; \
485 data.BitsLeft = 0; \
486 FLUSHREADBITS(data); \
487 buffer_t nz2 = __lzcnt64(data.TempRead); \
488 data.BitsLeft -= nz2; \
489 nz += nz2; \
490 } \
491 else { \
492 data.BitsLeft -= nz; \
493 } \
494}
495
496#define GETBITSB(data, numBits, n) { \
497 data.BitsLeft -= numBits; \
498 n = (data.TempRead >> data.BitsLeft) & ((1 << numBits) - 1); \
499 }
500
501#define GETBITS(data, numBits, n) { \
502 n = 0; \
503 while (numBits > 0U) \
504 { \
505 b = numBits; \
506 if (b > data.BitsLeft) \
507 { \
508 b = data.BitsLeft; \
509 } \
510 if (n) \
511 { \
512 n <<= b; \
513 } \
514 data.BitsLeft -= b; \
515 n |= (data.TempRead >> data.BitsLeft) & ((1 << b) - 1); \
516 numBits -= b; \
517 FLUSHREADBITS(data); \
518 } \
519}
520
521#define GETZEROSB(data, nz) { \
522 nz = __lzcnt64(data.TempRead << (VMX_BITSSIZE - data.BitsLeft)); \
523 data.BitsLeft -= nz; \
524}
525
526//LUT optimization may read a zero code from the next plane.
527//Importantly, each plane bitstream start is byte aligned so RELOADBITS wont erase this data, meaning it is safe to wind back here.
528//The exception is the exceedingly rare chance of an 8bit zero code (1000****), so the LUT intentionally excludes that possibility.
529#define REWINDOVERREAD(data) { \
530if (termsToDecode > 0 && termsToDecode < 64) { \
531 GolombZeroCodeLookup l = GolombZeroCodeLut[termsToDecode]; \
532 data.BitsLeft += l.length; \
533} \
534}
535
536#define FLUSHREMAININGREADBITS(data) \
537{ \
538 if (data.BitsLeft < VMX_BITSSIZE) \
539 { \
540 unsigned int n; \
541 buffer_t r = data.BitsLeft & 7U; \
542 GETBITS(data, r, n); \
543 } \
544 FLUSHREADBITS(data); \
545}
546
547#define FlushRemainingBits(data) \
548{ \
549 if (data.BitsLeft < VMX_BITSSIZE) \
550 { \
551 int bitsToWrite = VMX_BITSSIZE - data.BitsLeft; \
552 while (bitsToWrite > 0) \
553 { \
554 data.StreamPos[0] = data.Temp >> (VMX_BITSSIZE - 8); \
555 data.StreamPos += 1; \
556 data.Temp <<= 8; \
557 bitsToWrite -= 8; \
558 } \
559 data.BitsLeft = VMX_BITSSIZE; \
560 data.Temp = 0; \
561 } \
562}
563#define Get2MagSign(input)((input + input) ^ (input >> 15))
564
565#define EncodeDC(data, val) \
566{ \
567 if (val) \
568 { \
569 input = Get2MagSign(val) + 1; \
570 data.BitsLeft -= GolombLengthLut[input]; \
571 buffer_t t = input; \
572 t <<= data.BitsLeft; \
573 data.Temp |= t; \
574 } \
575 else \
576 { data.BitsLeft -= 2; \
577 buffer_t t = 3; \
578 t <<= data.BitsLeft; \
579 data.Temp |= t; \
580 } \
581}
582
583#define EmitBits32(data) \
584{ \
585 if (data.BitsLeft < 33) { \
586 \
587 buffer_t* s = (buffer_t*)data.StreamPos; \
588 * s = VMX_BUFFERSWAP(data.Temp); \
589 data.Temp <<= 32; \
590 data.StreamPos += 4; \
591 data.BitsLeft += 32; \
592 } \
593}
594
595#define EmitBitsMax(data) \
596{ \
597 buffer_t* s = (buffer_t*)data.StreamPos; \
598 * s = VMX_BUFFERSWAP(data.Temp); \
599 int bytes = (64 - data.BitsLeft) >> 3; \
600 data.Temp <<= (bytes * 8); \
601 data.StreamPos += bytes; \
602 data.BitsLeft += (bytes * 8); \
603}
604
605#define EncodeZeros(data) { \
606 if (numZeros) { \
607 bc = 32 - __lzcnt(numZeros); \
608 data.Temp |= BitsLeftLookup[data.BitsLeft]; \
609 data.BitsLeft -= bc + bc; \
610 buffer_t t = numZeros; \
611 t <<= data.BitsLeft; \
612 data.Temp |= t; \
613 numZeros = 0; \
614 pos += nz; \
615 } \
616}
617
618//Running this regardless of if nz is > 0, as removing the branch results in a 20% performance gain, despite the wasted instructions!
619//Using LUTs is great if we can remove a branch, as the cost penalty is not severe (note for EncodeZeros above we can't do the same!)
620#define EncodeZerosSmall(data) { \
621 zeroLut = GolombZeroCodeLut[nz]; \
622 pos += nz; \
623 data.BitsLeft -= zeroLut.length; \
624 data.Temp |= (zeroLut.value << data.BitsLeft); \
625}
626
627#define EncodeValue(data, input) { \
628 data.BitsLeft -= GolombLengthLut[input]; \
629 buffer_t t = input; \
630 t <<= data.BitsLeft; \
631 data.Temp |= t; \
632}
633
634
635inline void VMX_CreateAlignedStrideBuffer(BYTE* src, int srcStride, VMX_SIZE srcSize, BYTE** aligned, int* alignedStride, int alignment, int bytesPerPixel)
636{
637 int w = srcSize.width;
638 int s = srcStride;
639 BYTE* p = src;
640 if (w % alignment)
641 {
642 while (w % alignment) w++;
643 s = w * bytesPerPixel;
644 p = (BYTE*)malloc(s * srcSize.height);
645 }
646 *aligned = p;
647 *alignedStride = s;
648}
649inline void VMX_CopyFromAlignedStrideBufferAndFree(BYTE* aligned, int alignedStride, BYTE* dstBuffer, int dstStride, VMX_SIZE dstSize, int bytesPerPixel)
650{
651 if (alignedStride != dstStride)
652 {
653 BYTE* pSrc = aligned;
654 for (int y = 0; y < dstSize.height; y++)
655 {
656 memcpy(dstBuffer, pSrc, dstSize.width * bytesPerPixel);
657 dstBuffer += dstStride;
658 pSrc += alignedStride;
659 }
660 free(aligned);
661 }
662}
663inline void VMX_FreeAlignedStrideBuffer(BYTE* aligned, int alignedStride, int srcStride)
664{
665 if (alignedStride != srcStride)
666 {
667 free(aligned);
668 }
669}
670inline void VMX_CopyToAlignedStrideBuffer(BYTE* aligned, int alignedStride, BYTE* srcBuffer, int srcStride, VMX_SIZE srcSize, int bytesPerPixel)
671{
672 if (alignedStride != srcStride)
673 {
674 BYTE* pDst = aligned;
675 for (int y = 0; y < srcSize.height; y++)
676 {
677 memcpy(pDst, srcBuffer, srcSize.width * bytesPerPixel);
678 srcBuffer += srcStride;
679 pDst += alignedStride;
680 }
681 }
682}
Definition vmxcodec_common.h:302
int16_t length
Definition vmxcodec_common.h:305
int8_t zeros
Definition vmxcodec_common.h:303
int8_t value
Definition vmxcodec_common.h:304
Definition vmxcodec_common.h:291
buffer_t length
Definition vmxcodec_common.h:293
buffer_t value
Definition vmxcodec_common.h:292
Definition vmxcodec_common.h:143
short B
Definition vmxcodec_common.h:146
short R
Definition vmxcodec_common.h:144
short G
Definition vmxcodec_common.h:145
Definition vmxcodec.h:50
int width
Definition vmxcodec.h:51
int height
Definition vmxcodec.h:52
unsigned char BYTE
Definition vmxcodec.h:48
unsigned long long buffer_t
Definition vmxcodec.h:47
const int VMX_QUALITY_COUNT
Definition vmxcodec.h:44
@ VMX_PROFILE_OMT_SQ
Definition vmxcodec.h:76
@ VMX_PROFILE_SQ
Definition vmxcodec.h:73
@ VMX_PROFILE_OMT_HQ
Definition vmxcodec.h:77
@ VMX_PROFILE_LQ
Definition vmxcodec.h:72
@ VMX_PROFILE_HQ
Definition vmxcodec.h:74
@ VMX_PROFILE_OMT_LQ
Definition vmxcodec.h:75
const unsigned short FDCT_ROUND1
Definition vmxcodec_common.h:259
const int VMX_MAX_HEIGHT
Definition vmxcodec_common.h:42
const short IRND_INV_CORR
Definition vmxcodec_common.h:237
const BYTE VMX_ZIGZAG[64]
Definition vmxcodec_common.h:126
const short IRND_INV_CORR10
Definition vmxcodec_common.h:245
__declspec(align(16)) static const BYTE GolombLengthLut[]
const unsigned short FDCT_TAN3
Definition vmxcodec_common.h:262
#define BITS_INV_ACC
Definition vmxcodec_common.h:232
#define BITS_INV_ACC10
Definition vmxcodec_common.h:240
void VMX_FreeAlignedStrideBuffer(BYTE *aligned, int alignedStride, int srcStride)
Definition vmxcodec_common.h:663
const short IRND_INV_ROW10
Definition vmxcodec_common.h:243
const unsigned short FDCT_SQRT2
Definition vmxcodec_common.h:263
const short IRND_INV_COL
Definition vmxcodec_common.h:236
const unsigned short FDCT_TAN2
Definition vmxcodec_common.h:261
const int VMX_MIN_WIDTH
Definition vmxcodec_common.h:39
const int VMX_MIN_HEIGHT
Definition vmxcodec_common.h:40
void VMX_CreateAlignedStrideBuffer(BYTE *src, int srcStride, VMX_SIZE srcSize, BYTE **aligned, int *alignedStride, int alignment, int bytesPerPixel)
Definition vmxcodec_common.h:635
const unsigned short FDCT_TAN1
Definition vmxcodec_common.h:260
const short IRND_INV_COL10
Definition vmxcodec_common.h:244
const int VMX_MAX_WIDTH
Definition vmxcodec_common.h:41
void VMX_CopyFromAlignedStrideBufferAndFree(BYTE *aligned, int alignedStride, BYTE *dstBuffer, int dstStride, VMX_SIZE dstSize, int bytesPerPixel)
Definition vmxcodec_common.h:649
void VMX_CopyToAlignedStrideBuffer(BYTE *aligned, int alignedStride, BYTE *srcBuffer, int srcStride, VMX_SIZE srcSize, int bytesPerPixel)
Definition vmxcodec_common.h:670
const short IRND_INV_ROW
Definition vmxcodec_common.h:235