1// rgbcx.h v1.12 
2// High-performance scalar BC1-5 encoders. Public Domain or MIT license (you choose - see below), written by Richard Geldreich 2020 <richgel99@gmail.com>. 
3// 
4// Influential references: 
5// http://sjbrown.co.uk/2006/01/19/dxt-compression-techniques/ 
6// https://github.com/nothings/stb/blob/master/stb_dxt.h 
7// https://gist.github.com/castano/c92c7626f288f9e99e158520b14a61cf 
8// https://github.com/castano/icbc/blob/master/icbc.h 
9// http://www.humus.name/index.php?page=3D&ID=79 
10// 
11// This is a single header file library. Be sure to "#define RGBCX_IMPLEMENTATION" in one .cpp file somewhere. 
12// 
13// Instructions: 
14// 
15// The library MUST be initialized by calling this function at least once before using any encoder or decoder functions: 
16// 
17// void rgbcx::init(bc1_approx_mode mode = cBC1Ideal); 
18// 
19// This function manipulates global state, so it is not thread safe.  
20// You can call it multiple times to change the global BC1 approximation mode. 
21// Important: BC1/3 textures encoded using non-ideal BC1 approximation modes should only be sampled on parts from that vendor. 
22// If you encode for AMD, average error on AMD parts will go down, but average error on NVidia parts will go up and vice versa. 
23// If in doubt, encode in ideal BC1 mode. 
24// 
25// Call these functions to encode BC1-5: 
26// void rgbcx::encode_bc1(uint32_t level, void* pDst, const uint8_t* pPixels, bool allow_3color, bool use_transparent_texels_for_black); 
27// void rgbcx::encode_bc3(uint32_t level, void* pDst, const uint8_t* pPixels); 
28// void rgbcx::encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride = 4); 
29// void rgbcx::encode_bc5(void* pDst, const uint8_t* pPixels, uint32_t chan0 = 0, uint32_t chan1 = 1, uint32_t stride = 4); 
30// 
31// - level ranges from MIN_LEVEL to MAX_LEVEL. The higher the level, the slower the encoder goes, but the higher the average quality. 
32// levels [0,4] are fast and compete against stb_dxt (default and HIGHQUAL). The remaining levels compete against squish/NVTT/icbc and icbc HQ. 
33// If in doubt just use level 10, set allow_3color to true and use_transparent_texels_for_black to false, and adjust as needed. 
34// 
35// - pDst is a pointer to the 8-byte (BC1/4) or 16-byte (BC3/5) destination block.  
36// 
37// - pPixels is a pointer to the 32-bpp pixels, in either RGBX or RGBA format (R is first in memory).  
38// Alpha is always ignored by encode_bc1(). 
39// 
40// - allow_3color: If true the encoder will use 3-color blocks. This flag is ignored unless level is >= 5 (because lower levels compete against stb_dxt and it doesn't support 3-color blocks). 
41// Do not enable on BC3-5 textures. 3-color block usage slows down encoding. 
42// 
43// - use_transparent_texels_for_black: If true the encoder will use 3-color block transparent black pixels to code very dark or black texels. Your engine/shader MUST ignore the sampled  
44// alpha value for textures encoded in this mode. This is how NVidia's classic "nvdxt" encoder (used by many original Xbox titles) used to work by default on DXT1C textures. It increases  
45// average quality substantially (because dark texels/black are very common) and is highly recommended. 
46// Do not enable on BC3-5 textures.  
47// 
48// - stride is the source pixel stride, in bytes. It's typically 4. 
49// 
50// - chan0 and chan1 are the source channels. Typically they will be 0 and 1. 
51// 
52// All encoding and decoding functions are threade-safe. 
53// 
54// To reduce the compiled size of the encoder, set #define RGBCX_USE_SMALLER_TABLES to 1 before including this header. 
55// 
56#ifndef RGBCX_INCLUDE_H 
57#define RGBCX_INCLUDE_H 
58 
59#include <stdlib.h> 
60#include <stdint.h> 
61#include <algorithm> 
62#include <assert.h> 
63#include <limits.h> 
64 
65// By default, the table used to accelerate cluster fit on 4 color blocks uses a 969x128 entry table.  
66// To reduce the executable size, set RGBCX_USE_SMALLER_TABLES to 1, which selects the smaller 969x32 entry table.  
67#ifndef RGBCX_USE_SMALLER_TABLES 
68#define RGBCX_USE_SMALLER_TABLES 0 
69#endif 
70 
71namespace rgbcx 
72{ 
73 enum class bc1_approx_mode 
74 { 
75 // The default mode. No rounding for 4-color colors 2,3. My older tools/compressors use this mode.  
76 // This matches the D3D10 docs on BC1. 
77 cBC1Ideal = 0, 
78 
79 // NVidia GPU mode. 
80 cBC1NVidia = 1, 
81 
82 // AMD GPU mode. 
83 cBC1AMD = 2, 
84  
85 // This mode matches AMD Compressonator's output. It rounds 4-color colors 2,3 (not 3-color color 2). 
86 // This matches the D3D9 docs on DXT1. 
87 cBC1IdealRound4 = 3 
88 }; 
89 
90 // init() MUST be called once before using the BC1 encoder. 
91 // This function may be called multiple times to change the BC1 approximation mode.  
92 // This function initializes global state, so don't call it while other threads inside the encoder. 
93 // Important: If you encode textures for a specific vendor's GPU's, beware that using that texture data on other GPU's may result in ugly artifacts.  
94 // Encode to cBC1Ideal unless you know the texture data will only be deployed or used on a specific vendor's GPU. 
95 void init(bc1_approx_mode mode = bc1_approx_mode::cBC1Ideal); 
96 
97 // Optimally encodes a solid color block to BC1 format. 
98 void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb, bool allow_3color); 
99 
100 // BC1 low-level API encoder flags. You can ignore this if you use the simple level API. 
101 enum 
102 { 
103 // Try to improve quality using the most likely total orderings.  
104 // The total_orderings_to_try parameter will then control the number of total orderings to try for 4 color blocks, and the  
105 // total_orderings_to_try3 parameter will control the number of total orderings to try for 3 color blocks (if they are enabled). 
106 cEncodeBC1UseLikelyTotalOrderings = 2, 
107  
108 // Use 2 least squares pass, instead of one (same as stb_dxt's HIGHQUAL option). 
109 // Recommended if you're enabling cEncodeBC1UseLikelyTotalOrderings. 
110 cEncodeBC1TwoLeastSquaresPasses = 4, 
111  
112 // cEncodeBC1Use3ColorBlocksForBlackPixels allows the BC1 encoder to use 3-color blocks for blocks containing black or very dark pixels.  
113 // You shader/engine MUST ignore the alpha channel on textures encoded with this flag. 
114 // Average quality goes up substantially for my 100 texture corpus (~.5 dB), so it's worth using if you can. 
115 // Note the BC1 encoder does not actually support transparency in 3-color mode. 
116 // Don't set when encoding to BC3. 
117 cEncodeBC1Use3ColorBlocksForBlackPixels = 8, 
118 
119 // If cEncodeBC1Use3ColorBlocks is set, the encoder can use 3-color mode for a small but noticeable gain in average quality, but lower perf. 
120 // If you also specify the cEncodeBC1UseLikelyTotalOrderings flag, set the total_orderings_to_try3 paramter to the number of total orderings to try. 
121 // Don't set when encoding to BC3. 
122 cEncodeBC1Use3ColorBlocks = 16, 
123 
124 // cEncodeBC1Iterative will greatly increase encode time, but is very slightly higher quality. 
125 // Same as squish's iterative cluster fit option. Not really worth the tiny boost in quality, unless you just don't care about perf. at all. 
126 cEncodeBC1Iterative = 32, 
127 
128 // cEncodeBC1BoundingBox enables a fast all-integer PCA approximation on 4-color blocks.  
129 // At level 0 options (no other flags), this is ~15% faster, and higher *average* quality. 
130 cEncodeBC1BoundingBox = 64, 
131  
132 // Use a slightly lower quality, but ~30% faster MSE evaluation function for 4-color blocks. 
133 cEncodeBC1UseFasterMSEEval = 128, 
134  
135 // Examine all colors to compute selectors/MSE (slower than default) 
136 cEncodeBC1UseFullMSEEval = 256, 
137 
138 // Use 2D least squares+inset+optimal rounding (the method used in Humus's GPU texture encoding demo), instead of PCA.  
139 // Around 18% faster, very slightly lower average quality to better (depends on the content). 
140 cEncodeBC1Use2DLS = 512, 
141 
142 // Use 6 power iterations vs. 4 for PCA. 
143 cEncodeBC1Use6PowerIters = 2048, 
144  
145 // Check all total orderings - *very* slow. The encoder is not designed to be used in this way. 
146 cEncodeBC1Exhaustive = 8192, 
147 
148 // Try 2 different ways of choosing the initial endpoints. 
149 cEncodeBC1TryAllInitialEndponts = 16384, 
150  
151 // Same as cEncodeBC1BoundingBox, but implemented using integer math (faster, slightly less quality) 
152 cEncodeBC1BoundingBoxInt = 32768, 
153  
154 // Try refining the final endpoints by examining nearby colors. 
155 cEncodeBC1EndpointSearchRoundsShift = 22, 
156 cEncodeBC1EndpointSearchRoundsMask = 1023U << cEncodeBC1EndpointSearchRoundsShift, 
157 }; 
158  
159 const uint32_t MIN_TOTAL_ORDERINGS = 1; 
160 const uint32_t MAX_TOTAL_ORDERINGS3 = 32; 
161 
162#if RGBCX_USE_SMALLER_TABLES 
163 const uint32_t MAX_TOTAL_ORDERINGS4 = 32; 
164#else 
165 const uint32_t MAX_TOTAL_ORDERINGS4 = 128; 
166#endif 
167  
168 // DEFAULT_TOTAL_ORDERINGS_TO_TRY is around 3x faster than libsquish at slightly higher average quality. 10-16 is a good range to start to compete against libsquish. 
169 const uint32_t DEFAULT_TOTAL_ORDERINGS_TO_TRY = 10; 
170 
171 const uint32_t DEFAULT_TOTAL_ORDERINGS_TO_TRY3 = 1; 
172  
173 // Encodes a 4x4 block of RGBX (X=ignored) pixels to BC1 format.  
174 // This is the simplified interface for BC1 encoding, which accepts a level parameter and converts that to the best overall flags. 
175 // The pixels are in RGBA format, where R is first in memory. The BC1 encoder completely ignores the alpha channel (i.e. there is no punchthrough alpha support). 
176 // This is the recommended function to use for BC1 encoding, becuase it configures the encoder for you in the best possible way (on average). 
177 // Note that the 3 color modes won't be used at all until level 5 or higher. 
178 // No transparency supported, however if you set use_transparent_texels_for_black to true the encocer will use transparent selectors on very dark/black texels to reduce MSE.  
179 const uint32_t MIN_LEVEL = 0, MAX_LEVEL = 18; 
180 void encode_bc1(uint32_t level, void* pDst, const uint8_t* pPixels, bool allow_3color, bool use_transparent_texels_for_black); 
181 
182 // Low-level interface for BC1 encoding. 
183 // Always returns a 4 color block, unless cEncodeBC1Use3ColorBlocksForBlackPixels or cEncodeBC1Use3ColorBlock flags are specified.  
184 // total_orderings_to_try controls the perf. vs. quality tradeoff on 4-color blocks when the cEncodeBC1UseLikelyTotalOrderings flag is used. It must range between [MIN_TOTAL_ORDERINGS, MAX_TOTAL_ORDERINGS4]. 
185 // total_orderings_to_try3 controls the perf. vs. quality tradeoff on 3-color bocks when the cEncodeBC1UseLikelyTotalOrderings and the cEncodeBC1Use3ColorBlocks flags are used. Valid range is [0,MAX_TOTAL_ORDERINGS3] (0=disabled). 
186 void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags = 0, uint32_t total_orderings_to_try = DEFAULT_TOTAL_ORDERINGS_TO_TRY, uint32_t total_orderings_to_try3 = DEFAULT_TOTAL_ORDERINGS_TO_TRY3); 
187  
188 // Encodes a 4x4 block of RGBA pixels to BC3 format. 
189 // There are two encode_bc3() functions.  
190 // The first is the recommended function, which accepts a level parameter. 
191 // The second is a low-level version that allows fine control over BC1 encoding.  
192 void encode_bc3(uint32_t level, void* pDst, const uint8_t* pPixels); 
193 void encode_bc3(void* pDst, const uint8_t* pPixels, uint32_t flags = 0, uint32_t total_orderings_to_try = DEFAULT_TOTAL_ORDERINGS_TO_TRY); 
194 
195 // Encodes a single channel to BC4. 
196 // stride is the source pixel stride in bytes. 
197 void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride = 4); 
198 
199 // Encodes two channels to BC5.  
200 // chan0/chan1 control which channels, stride is the source pixel stride in bytes. 
201 void encode_bc5(void* pDst, const uint8_t* pPixels, uint32_t chan0 = 0, uint32_t chan1 = 1, uint32_t stride = 4); 
202 
203 // Decompression functions.  
204  
205 // Returns true if the block uses 3 color punchthrough alpha mode. 
206 bool unpack_bc1(const void* pBlock_bits, void* pPixels, bool set_alpha = true, bc1_approx_mode mode = bc1_approx_mode::cBC1Ideal); 
207  
208 void unpack_bc4(const void* pBlock_bits, uint8_t* pPixels, uint32_t stride = 4); 
209  
210 // Returns true if the block uses 3 color punchthrough alpha mode. 
211 bool unpack_bc3(const void* pBlock_bits, void* pPixels, bc1_approx_mode mode = bc1_approx_mode::cBC1Ideal); 
212 
213 void unpack_bc5(const void* pBlock_bits, void* pPixels, uint32_t chan0 = 0, uint32_t chan1 = 1, uint32_t stride = 4); 
214} 
215#endif // #ifndef RGBCX_INCLUDE_H 
216 
217#ifdef RGBCX_IMPLEMENTATION 
218namespace rgbcx 
219{ 
220 const uint32_t NUM_UNIQUE_TOTAL_ORDERINGS4 = 969; 
221 
222 // All total orderings for 16 pixels 2-bit selectors. 
223 // BC1 selector order 0, 2, 3, 1 (i.e. the selectors are reordered into linear order). 
224 static uint8_t g_unique_total_orders4[NUM_UNIQUE_TOTAL_ORDERINGS4][4] =  
225 { 
226 {0,8,2,6},{4,3,9,0},{4,8,1,3},{12,0,3,1},{11,3,2,0},{6,4,6,0},{7,5,0,4},{6,0,8,2},{1,0,0,15},{3,0,8,5},{1,1,13,1},{13,1,2,0},{0,14,1,1},{0,15,1,0},{0,13,0,3},{16,0,0,0},{4,3,4,5},{8,6,0,2},{0,10,0,6},{10,0,4,2},{7,2,1,6},{4,7,5,0},{1,4,7,4},{0,14,2,0},{2,7,2,5},{9,0,5,2},{9,2,2,3},{10,0,5,1},{2,3,7,4},{4,9,0,3},{1,5,0,10},{1,1,6,8}, 
227 {6,6,4,0},{11,5,0,0},{11,2,0,3},{4,0,10,2},{2,3,10,1},{1,13,1,1},{0,14,0,2},{2,3,3,8},{12,3,1,0},{14,0,0,2},{9,1,3,3},{6,4,0,6},{1,1,5,9},{5,9,0,2},{2,10,1,3},{12,0,0,4},{4,6,6,0},{0,6,4,6},{3,7,4,2},{0,13,3,0},{3,10,0,3},{10,2,1,3},{1,12,1,2},{2,0,13,1},{11,0,5,0},{12,1,3,0},{6,4,5,1},{10,4,2,0},{3,6,1,6},{7,3,6,0},{10,4,0,2},{10,0,2,4}, 
228 {0,5,9,2},{0,9,3,4},{6,4,2,4},{3,4,7,2},{3,3,5,5},{4,2,9,1},{6,2,8,0},{3,5,3,5},{4,10,1,1},{10,1,3,2},{5,7,0,4},{5,3,7,1},{6,8,1,1},{8,8,0,0},{11,1,0,4},{14,1,0,1},{9,3,2,2},{8,2,1,5},{0,0,2,14},{3,3,9,1},{10,1,5,0},{8,3,1,4},{1,5,8,2},{6,1,9,0},{3,2,1,10},{3,11,1,1},{7,6,3,0},{9,0,3,4},{5,2,5,4},{0,2,3,11},{15,0,0,1},{0,6,6,4}, 
229 {3,4,9,0},{4,7,0,5},{0,4,4,8},{0,13,2,1},{2,4,1,9},{3,2,5,6},{10,6,0,0},{3,5,6,2},{8,0,4,4},{1,3,6,6},{7,7,0,2},{6,1,4,5},{0,11,1,4},{2,2,8,4},{0,1,2,13},{15,0,1,0},{7,2,6,1},{8,1,7,0},{1,8,4,3},{2,13,1,0},{1,0,7,8},{14,2,0,0},{1,8,1,6},{9,3,3,1},{0,0,7,9},{4,4,1,7},{9,0,6,1},{10,2,4,0},{1,7,3,5},{0,3,8,5},{5,2,4,5},{1,2,5,8}, 
230 {0,8,7,1},{10,3,2,1},{12,0,4,0},{2,1,4,9},{5,2,2,7},{1,9,3,3},{15,1,0,0},{6,3,4,3},{9,5,0,2},{1,6,9,0},{6,6,0,4},{13,2,1,0},{5,1,8,2},{0,5,11,0},{7,1,0,8},{1,2,12,1},{0,3,3,10},{7,4,2,3},{5,1,4,6},{7,0,3,6},{3,12,0,1},{3,4,5,4},{1,10,0,5},{7,4,3,2},{10,5,0,1},{13,3,0,0},{2,5,4,5},{3,10,1,2},{5,1,2,8},{14,0,1,1},{1,5,4,6},{1,4,5,6}, 
231 {2,3,11,0},{11,0,4,1},{11,2,2,1},{5,3,8,0},{1,3,10,2},{0,1,13,2},{3,1,4,8},{4,2,4,6},{1,5,6,4},{2,1,11,2},{1,2,9,4},{4,7,3,2},{6,2,5,3},{7,2,2,5},{8,1,4,3},{3,2,8,3},{12,1,0,3},{7,8,1,0},{7,0,2,7},{5,10,0,1},{0,2,14,0},{2,9,3,2},{7,0,0,9},{11,1,4,0},{10,4,1,1},{2,2,9,3},{5,7,2,2},{1,3,1,11},{13,2,0,1},{4,2,8,2},{2,3,1,10},{4,2,5,5}, 
232 {7,0,7,2},{10,0,0,6},{0,8,5,3},{4,4,0,8},{12,4,0,0},{0,1,14,1},{8,0,1,7},{5,1,5,5},{11,0,3,2},{0,4,1,11},{0,8,8,0},{0,2,5,9},{7,3,2,4},{7,8,0,1},{1,0,3,12},{7,4,5,0},{1,6,7,2},{7,6,1,2},{9,6,1,0},{12,2,0,2},{4,1,6,5},{4,0,1,11},{8,4,4,0},{13,0,1,2},{8,6,2,0},{4,12,0,0},{2,7,5,2},{2,0,5,9},{5,4,5,2},{3,8,5,0},{7,3,3,3},{4,4,8,0}, 
233 {2,1,3,10},{5,0,1,10},{6,4,3,3},{4,9,1,2},{1,4,0,11},{11,3,1,1},{4,0,12,0},{13,0,0,3},{6,1,6,3},{9,0,4,3},{8,0,0,8},{8,4,0,4},{0,12,1,3},{0,4,10,2},{3,4,8,1},{1,3,8,4},{9,2,5,0},{5,7,4,0},{1,0,11,4},{4,10,0,2},{1,3,12,0},{6,9,0,1},{5,0,9,2},{5,9,2,0},{13,1,0,2},{9,3,4,0},{9,4,0,3},{3,1,12,0},{2,4,3,7},{1,2,13,0},{2,2,4,8},{6,8,0,2}, 
234 {9,2,1,4},{9,5,1,1},{2,0,4,10},{5,4,0,7},{0,0,6,10},{1,2,0,13},{4,7,2,3},{6,5,5,0},{3,3,1,9},{1,6,1,8},{12,2,1,1},{4,4,5,3},{1,0,6,9},{0,6,10,0},{4,8,3,1},{4,3,2,7},{2,1,7,6},{1,9,1,5},{3,1,3,9},{8,7,1,0},{1,2,3,10},{14,1,1,0},{5,4,4,3},{3,7,0,6},{7,4,1,4},{3,7,5,1},{1,1,0,14},{0,10,3,3},{0,4,3,9},{1,7,7,1},{2,0,10,4},{5,8,0,3}, 
235 {6,7,3,0},{0,8,4,4},{5,7,3,1},{7,9,0,0},{7,6,2,1},{0,4,5,7},{6,3,5,2},{1,2,1,12},{5,2,0,9},{8,5,0,3},{4,6,1,5},{1,1,7,7},{10,5,1,0},{1,2,8,5},{1,8,2,5},{5,1,0,10},{6,9,1,0},{13,0,2,1},{8,3,5,0},{6,3,6,1},{2,11,3,0},{3,7,3,3},{1,5,2,8},{7,5,2,2},{0,6,7,3},{13,1,1,1},{5,3,4,4},{7,2,7,0},{5,8,3,0},{3,13,0,0},{0,7,9,0},{8,0,3,5}, 
236 {1,3,7,5},{4,0,2,10},{12,0,1,3},{1,7,6,2},{3,9,0,4},{7,2,0,7},{0,1,7,8},{2,1,8,5},{0,13,1,2},{0,8,1,7},{5,0,11,0},{5,6,2,3},{0,3,0,13},{2,3,4,7},{5,6,3,2},{4,2,10,0},{3,3,7,3},{7,2,5,2},{1,1,11,3},{12,3,0,1},{5,1,1,9},{1,15,0,0},{9,7,0,0},{9,1,2,4},{0,7,3,6},{3,0,13,0},{3,0,11,2},{0,6,5,5},{8,2,2,4},{6,10,0,0},{4,8,4,0},{0,0,3,13}, 
237 {0,4,12,0},{7,1,6,2},{3,5,0,8},{8,0,6,2},{6,2,3,5},{2,10,0,4},{4,11,0,1},{6,1,5,4},{5,1,3,7},{0,11,3,2},{4,6,0,6},{2,6,0,8},{3,1,7,5},{2,14,0,0},{2,9,2,3},{0,3,4,9},{11,0,1,4},{13,0,3,0},{8,3,0,5},{0,5,3,8},{5,11,0,0},{0,1,4,11},{2,1,9,4},{3,4,4,5},{7,1,2,6},{12,2,2,0},{9,4,1,2},{6,0,2,8},{4,6,2,4},{11,2,3,0},{3,2,2,9},{10,3,1,2}, 
238 {1,1,2,12},{0,5,2,9},{0,1,11,4},{6,2,4,4},{2,8,2,4},{0,9,4,3},{11,0,2,3},{0,2,11,3},{6,0,7,3},{0,3,6,7},{4,5,5,2},{1,2,6,7},{7,5,1,3},{9,0,2,5},{2,6,4,4},{4,1,9,2},{4,8,2,2},{1,12,3,0},{0,9,6,1},{0,10,6,0},{3,1,5,7},{2,13,0,1},{2,2,1,11},{3,6,0,7},{5,6,5,0},{5,5,4,2},{4,0,3,9},{3,4,1,8},{0,11,2,3},{2,12,1,1},{7,1,3,5},{7,0,9,0}, 
239 {8,0,8,0},{1,0,2,13},{3,3,10,0},{2,4,4,6},{2,3,8,3},{1,10,5,0},{7,3,0,6},{2,9,0,5},{1,4,6,5},{6,6,3,1},{5,6,0,5},{6,3,0,7},{3,10,2,1},{2,5,5,4},{3,8,4,1},{1,14,0,1},{10,3,3,0},{3,5,7,1},{1,1,3,11},{2,4,0,10},{9,3,1,3},{5,10,1,0},{3,0,6,7},{3,1,9,3},{11,2,1,2},{5,3,3,5},{0,5,1,10},{4,1,11,0},{10,2,0,4},{7,6,0,3},{2,7,0,7},{4,2,2,8}, 
240 {6,1,7,2},{4,9,2,1},{0,0,8,8},{3,7,2,4},{9,6,0,1},{0,12,4,0},{6,7,1,2},{0,7,2,7},{1,0,10,5},{0,0,14,2},{2,7,3,4},{5,0,0,11},{7,7,1,1},{6,2,7,1},{4,5,3,4},{3,5,1,7},{5,9,1,1},{6,2,1,7},{3,2,0,11},{0,11,0,5},{3,11,2,0},{10,1,4,1},{7,0,4,5},{11,4,0,1},{10,3,0,3},{0,2,4,10},{0,15,0,1},{0,11,5,0},{6,7,2,1},{1,12,2,1},{4,1,3,8},{1,0,13,2}, 
241 {1,8,5,2},{7,0,1,8},{3,12,1,0},{9,2,4,1},{1,7,4,4},{11,4,1,0},{4,3,8,1},{2,8,4,2},{1,11,3,1},{1,1,4,10},{4,10,2,0},{8,2,5,1},{1,0,9,6},{5,3,2,6},{0,9,7,0},{10,2,2,2},{5,8,1,2},{8,7,0,1},{0,3,12,1},{1,0,1,14},{4,8,0,4},{3,8,0,5},{4,6,5,1},{0,9,5,2},{10,2,3,1},{2,3,9,2},{1,0,12,3},{11,3,0,2},{4,5,2,5},{0,2,12,2},{9,1,0,6},{9,2,0,5}, 
242 {1,2,7,6},{4,7,4,1},{0,12,2,2},{0,0,0,16},{2,8,3,3},{3,6,2,5},{0,6,3,7},{7,5,4,0},{3,3,3,7},{3,3,0,10},{5,0,6,5},{0,0,10,6},{8,5,3,0},{8,1,5,2},{6,0,9,1},{11,1,2,2},{2,11,2,1},{9,5,2,0},{3,0,4,9},{2,2,12,0},{2,6,6,2},{2,1,13,0},{6,0,5,5},{2,0,14,0},{2,11,1,2},{4,4,7,1},{2,0,11,3},{3,1,1,11},{2,9,4,1},{3,7,6,0},{14,0,2,0},{1,10,4,1}, 
243 {8,0,7,1},{3,6,5,2},{0,3,11,2},{2,5,6,3},{11,1,3,1},{6,5,3,2},{3,8,1,4},{0,2,7,7},{2,10,2,2},{1,6,2,7},{11,0,0,5},{12,1,1,2},{12,1,2,1},{0,7,1,8},{0,3,9,4},{0,2,1,13},{7,1,4,4},{10,1,0,5},{4,0,8,4},{5,2,7,2},{0,2,0,14},{4,3,7,2},{2,7,1,6},{1,2,2,11},{6,3,3,4},{1,14,1,0},{2,4,6,4},{5,3,6,2},{5,3,5,3},{8,4,1,3},{1,3,0,12},{3,5,2,6}, 
244 {1,8,7,0},{0,7,4,5},{2,1,6,7},{4,11,1,0},{7,2,4,3},{6,1,3,6},{4,5,4,3},{2,11,0,3},{1,5,7,3},{12,0,2,2},{5,0,4,7},{1,13,0,2},{7,7,2,0},{4,1,7,4},{4,5,0,7},{5,0,5,6},{6,5,4,1},{2,4,2,8},{1,10,1,4},{6,3,1,6},{3,3,8,2},{0,7,7,2},{4,4,2,6},{1,1,8,6},{1,12,0,3},{2,1,12,1},{1,9,2,4},{1,11,0,4},{2,5,2,7},{10,0,3,3},{4,6,3,3},{3,7,1,5}, 
245 {1,9,0,6},{7,1,7,1},{1,6,5,4},{9,2,3,2},{6,2,2,6},{2,2,2,10},{8,3,3,2},{0,1,8,7},{2,0,8,6},{0,3,1,12},{9,4,2,1},{9,4,3,0},{6,2,6,2},{1,8,0,7},{5,1,10,0},{0,5,5,6},{8,2,4,2},{2,3,2,9},{6,0,3,7},{2,2,6,6},{2,6,2,6},{1,13,2,0},{9,3,0,4},{7,3,5,1},{6,5,2,3},{5,2,6,3},{2,0,12,2},{5,7,1,3},{8,1,3,4},{3,1,10,2},{1,0,15,0},{0,8,0,8}, 
246 {5,0,7,4},{4,4,6,2},{0,1,0,15},{10,0,1,5},{7,3,4,2},{4,9,3,0},{2,5,7,2},{3,4,2,7},{8,3,2,3},{5,1,6,4},{0,10,2,4},{6,6,1,3},{6,0,0,10},{4,4,3,5},{1,3,9,3},{7,5,3,1},{3,0,7,6},{1,8,6,1},{4,3,0,9},{3,11,0,2},{6,0,6,4},{0,1,3,12},{0,4,2,10},{5,5,6,0},{4,1,4,7},{8,1,6,1},{5,6,4,1},{8,4,2,2},{4,3,1,8},{3,0,2,11},{1,11,4,0},{0,8,3,5}, 
247 {5,1,7,3},{7,0,8,1},{4,3,5,4},{4,6,4,2},{3,2,4,7},{1,6,3,6},{0,7,8,1},{3,0,1,12},{9,1,4,2},{7,4,0,5},{1,7,0,8},{5,4,1,6},{9,1,5,1},{1,1,9,5},{4,1,1,10},{5,3,0,8},{2,2,5,7},{4,0,0,12},{9,0,7,0},{3,4,0,9},{0,2,6,8},{8,2,0,6},{3,2,6,5},{4,2,6,4},{3,6,4,3},{2,8,6,0},{5,0,3,8},{0,4,0,12},{0,16,0,0},{0,9,2,5},{4,0,11,1},{1,6,4,5}, 
248 {0,1,6,9},{3,4,6,3},{3,0,10,3},{7,0,6,3},{1,4,9,2},{1,5,3,7},{8,5,2,1},{0,12,0,4},{7,2,3,4},{0,5,6,5},{11,1,1,3},{6,5,0,5},{2,1,5,8},{1,4,11,0},{9,1,1,5},{0,0,13,3},{5,8,2,1},{2,12,0,2},{3,3,6,4},{4,1,10,1},{4,0,5,7},{8,1,0,7},{5,1,9,1},{4,3,3,6},{0,2,2,12},{6,3,2,5},{0,0,12,4},{1,5,1,9},{2,6,5,3},{3,6,3,4},{2,12,2,0},{1,6,8,1}, 
249 {10,1,1,4},{1,3,4,8},{7,4,4,1},{1,11,1,3},{1,2,10,3},{3,9,3,1},{8,5,1,2},{2,10,4,0},{4,2,0,10},{2,7,6,1},{8,2,3,3},{1,5,5,5},{3,1,0,12},{3,10,3,0},{8,0,5,3},{0,6,8,2},{0,3,13,0},{0,0,16,0},{1,9,4,2},{4,1,8,3},{1,6,6,3},{0,10,5,1},{0,1,12,3},{4,0,6,6},{3,8,3,2},{0,5,4,7},{1,0,14,1},{0,4,6,6},{3,9,1,3},{3,5,8,0},{3,6,6,1},{5,4,7,0}, 
250 {3,0,12,1},{8,6,1,1},{2,9,5,0},{6,1,1,8},{4,1,2,9},{3,9,4,0},{5,2,9,0},{0,12,3,1},{1,4,10,1},{4,0,7,5},{3,1,2,10},{5,4,2,5},{5,5,5,1},{4,2,3,7},{1,7,5,3},{2,8,0,6},{8,1,2,5},{3,8,2,3},{6,1,2,7},{3,9,2,2},{9,0,0,7},{0,8,6,2},{8,4,3,1},{0,2,8,6},{6,5,1,4},{2,3,5,6},{2,10,3,1},{0,7,0,9},{4,2,7,3},{2,4,8,2},{7,1,1,7},{2,4,7,3}, 
251 {2,4,10,0},{0,1,10,5},{4,7,1,4},{0,10,4,2},{9,0,1,6},{1,9,6,0},{3,3,4,6},{4,5,7,0},{5,5,2,4},{2,8,1,5},{2,3,6,5},{0,1,1,14},{3,2,3,8},{10,1,2,3},{9,1,6,0},{3,4,3,6},{2,2,0,12},{0,0,9,7},{4,0,9,3},{7,0,5,4},{4,5,6,1},{2,5,1,8},{2,5,9,0},{3,5,4,4},{1,3,11,1},{7,1,5,3},{3,2,7,4},{1,4,2,9},{1,11,2,2},{2,2,3,9},{5,0,10,1},{3,2,11,0}, 
252 {1,10,3,2},{8,3,4,1},{3,6,7,0},{0,7,5,4},{1,3,3,9},{2,2,10,2},{1,9,5,1},{0,5,0,11},{3,0,3,10},{0,4,8,4},{2,7,7,0},{2,0,2,12},{1,2,11,2},{6,3,7,0},{0,6,2,8},{0,10,1,5},{0,9,0,7},{6,4,4,2},{6,0,1,9},{1,5,10,0},{5,4,6,1},{5,5,3,3},{0,0,4,12},{0,3,2,11},{1,4,1,10},{3,0,9,4},{5,5,0,6},{1,7,8,0},{2,0,3,11},{6,4,1,5},{10,0,6,0},{0,6,0,10}, 
253 {0,4,11,1},{3,1,6,6},{2,5,8,1},{0,2,10,4},{3,1,11,1},{6,6,2,2},{1,1,10,4},{2,1,2,11},{6,1,8,1},{0,2,13,1},{0,7,6,3},{6,8,2,0},{3,0,0,13},{4,4,4,4},{6,2,0,8},{7,3,1,5},{0,11,4,1},{6,7,0,3},{2,6,3,5},{5,2,1,8},{7,1,8,0},{5,5,1,5},{1,8,3,4},{8,2,6,0},{6,0,10,0},{5,6,1,4},{1,4,4,7},{2,7,4,3},{1,4,8,3},{5,4,3,4},{1,10,2,3},{2,9,1,4}, 
254 {2,2,11,1},{2,5,0,9},{0,0,1,15},{0,0,11,5},{0,4,7,5},{0,1,15,0},{2,1,0,13},{0,3,10,3},{8,0,2,6},{3,3,2,8},{3,5,5,3},{1,7,1,7},{1,3,2,10},{4,0,4,8},{2,0,9,5},{1,1,1,13},{2,2,7,5},{2,1,10,3},{4,2,1,9},{4,3,6,3},{1,3,5,7},{2,5,3,6},{1,0,8,7},{5,0,2,9},{2,8,5,1},{1,6,0,9},{0,0,5,11},{0,4,9,3},{2,0,7,7},{1,7,2,6},{2,1,1,12},{2,4,9,1}, 
255 {0,5,7,4},{6,0,4,6},{3,2,10,1},{0,6,1,9},{2,6,1,7},{0,5,8,3},{4,1,0,11},{1,2,4,9},{4,1,5,6},{6,1,0,9},{1,4,3,8},{4,5,1,6},{1,0,5,10},{5,3,1,7},{0,9,1,6},{2,0,1,13},{2,0,6,8},{8,1,1,6},{1,5,9,1},{0,6,9,1},{0,3,5,8},{0,2,9,5},{5,2,8,1},{1,1,14,0},{3,2,9,2},{5,0,8,3},{0,5,10,1},{5,2,3,6},{2,6,7,1},{2,3,0,11},{0,1,9,6},{1,0,4,11}, 
256 {3,0,5,8},{0,0,15,1},{2,4,5,5},{0,3,7,6},{2,0,0,14},{1,1,12,2},{2,6,8,0},{3,1,8,4},{0,1,5,10} 
257 }; 
258 
259 // All total orderings for 16 pixels [0,2] 2-bit selectors. 
260 // BC1 selector order: 0, 1, 2 
261 // Note this is different from g_unique_total_orders4[], which reorders the selectors into linear order. 
262 const uint32_t NUM_UNIQUE_TOTAL_ORDERINGS3 = 153; 
263 static uint8_t g_unique_total_orders3[NUM_UNIQUE_TOTAL_ORDERINGS3][3] =  
264 { 
265 {6,0,10},{3,6,7},{3,0,13},{13,3,0},{12,4,0},{9,1,6},{2,13,1},{4,7,5},{7,5,4},{9,6,1},{7,4,5},{8,6,2},{16,0,0},{10,6,0},{2,7,7}, 
266 {0,0,16},{0,3,13},{1,15,0},{0,2,14},{1,4,11},{15,1,0},{1,12,3},{9,2,5},{14,1,1},{8,2,6},{3,3,10},{4,2,10},{14,0,2},{0,14,2},{1,7,8},{6,6,4}, 
267 {11,5,0},{6,4,6},{11,3,2},{4,3,9},{7,1,8},{10,4,2},{12,1,3},{11,0,5},{9,3,4},{1,0,15},{9,0,7},{2,6,8},{12,2,2},{6,2,8},{6,8,2},{15,0,1}, 
268 {4,8,4},{0,4,12},{8,5,3},{5,9,2},{11,2,3},{12,3,1},{6,3,7},{1,1,14},{2,9,5},{1,8,7},{4,10,2},{7,7,2},{13,1,2},{0,15,1},{3,2,11},{7,0,9}, 
269 {4,4,8},{3,8,5},{0,5,11},{13,2,1},{1,10,5},{4,11,1},{3,10,3},{5,10,1},{10,2,4},{0,6,10},{14,2,0},{11,4,1},{3,12,1},{1,13,2},{1,5,10},{5,11,0}, 
270 {12,0,4},{8,1,7},{6,10,0},{3,13,0},{7,2,7},{0,7,9},{5,8,3},{0,12,4},{11,1,4},{13,0,3},{0,16,0},{5,7,4},{10,3,3},{10,0,6},{0,13,3},{4,6,6}, 
271 {2,8,6},{2,5,9},{7,8,1},{2,1,13},{2,0,14},{7,3,6},{5,1,10},{3,11,2},{5,4,7},{8,3,5},{10,5,1},{6,9,1},{1,3,12},{4,5,7},{2,2,12},{4,1,11}, 
272 {0,8,8},{4,12,0},{6,5,5},{8,7,1},{5,5,6},{3,7,6},{7,9,0},{4,9,3},{0,10,6},{8,0,8},{5,3,8},{10,1,5},{6,1,9},{7,6,3},{9,5,2},{0,1,15}, 
273 {9,7,0},{2,14,0},{3,4,9},{8,4,4},{9,4,3},{0,9,7},{1,9,6},{3,9,4},{5,2,9},{2,3,11},{5,6,5},{1,14,1},{6,7,3},{2,4,10},{2,12,2},{8,8,0}, 
274 {2,10,4},{4,0,12},{0,11,5},{2,11,3},{1,11,4},{3,5,8},{5,0,11},{3,1,12},{1,2,13},{1,6,9} 
275 }; 
276  
277 // For each total ordering, this table indicates which other total orderings are likely to improve quality using a least squares pass. Each array is sorted by usefulness. 
278 static uint16_t g_best_total_orderings4[NUM_UNIQUE_TOTAL_ORDERINGS4][MAX_TOTAL_ORDERINGS4] =  
279 { 
280#if RGBCX_USE_SMALLER_TABLES 
281 { 202,120,13,318,15,23,403,450,5,51,260,128,77,21,33,494,515,523,4,141,269,1,2,700,137,49,48,102,7,64,753,82 }, 
282 { 13,141,23,217,115,51,77,2,64,21,0,4,5,317,137,269,202,33,318,7,291,352,9,10,3,180,32,6,365,102,341,349 }, 
283 { 29,58,262,1,52,74,6,171,5,287,151,334,27,500,75,26,331,223,53,635,220,19,50,45,46,17,14,396,163,409,324,70 }, 
284 { 40,51,33,453,14,23,62,56,12,196,730,475,153,99,403,775,117,130,585,34,4,17,162,11,139,57,102,38,108,47,123,440 }, 
285 { 33,23,51,13,102,64,202,128,12,40,15,196,153,10,1,2,77,99,141,0,515,5,117,3,120,403,700,165,22,14,269,453 }, 
286 { 13,23,51,4,77,141,202,33,115,64,32,128,0,11,177,40,15,102,2,217,7,137,269,21,90,59,515,1,180,403,22,6 }, 
287 { 26,235,19,47,648,624,78,145,27,112,122,64,444,6,630,453,25,42,65,130,711,85,390,113,416,108,665,29,730,138,644,95 }, 
288 { 64,141,352,751,217,247,237,437,177,269,86,954,947,875,32,318,95,77,304,92,597,180,232,291,128,864,349,588,372,202,312,1 }, 
289 { 642,898,180,638,901,341,82,197,10,951,15,515,165,762,700,253,811,753,752,365,143,479,244,569,8,110,351,873,55,31,499,116 }, 
290 { 221,23,51,125,438,254,13,21,39,49,308,656,0,115,530,159,158,401,30,166,912,386,165,688,518,9,105,627,424,22,421,33 }, 
291 { 143,31,1,44,197,8,180,125,116,55,13,498,23,341,638,242,93,15,2,141,0,901,752,115,36,206,165,479,338,365,515,762 }, 
292 { 12,23,51,13,14,15,37,99,515,38,700,117,2,196,134,153,753,64,54,33,128,120,21,0,328,5,139,82,453,719,457,1 }, 
293 { 13,15,23,515,961,700,457,753,51,115,4,165,197,2,38,569,1,474,0,37,99,719,5,12,629,14,11,3,33,77,64,10 }, 
294 { 15,515,700,753,1,0,2,4,3,23,134,12,961,5,10,197,11,33,82,120,457,51,165,7,6,341,217,21,77,9,40,180 }, 
295 { 13,51,23,457,719,961,730,401,165,453,0,117,386,15,134,1,758,153,12,54,515,99,11,2,700,5,753,4,308,33,6,899 }, 
296 { 134,898,82,117,13,33,77,102,23,260,341,351,120,901,197,153,961,111,196,110,180,457,854,10,450,8,165,40,4,115,0,365 }, 
297 { 60,18,126,167,35,16,191,71,24,92,121,271,68,107,212,146,118,150,199,7,21,1,9,575,727,5,566,48,0,132,108,273 }, 
298 { 62,136,129,123,128,41,162,17,249,211,214,789,618,710,38,678,248,507,57,64,152,269,119,3,177,183,597,106,4,179,216,90 }, 
299 { 403,523,51,475,494,453,817,899,202,23,450,13,421,120,102,730,33,128,4,1,805,5,7,153,757,260,318,196,77,457,326,65 }, 
300 { 4,59,3,62,12,33,56,193,27,21,102,17,40,77,76,84,32,0,6,123,119,177,128,11,18,611,605,25,13,51,73,210 }, 
301 { 43,20,319,422,414,945,0,7,819,61,5,376,325,173,804,904,470,693,97,707,14,49,22,104,147,107,95,32,426,1,330,577 }, 
302 { 13,23,51,2,0,115,4,141,217,33,10,77,1,15,64,180,3,515,7,6,22,102,11,5,40,9,165,700,202,197,317,341 }, 
303 { 28,49,0,105,1,24,65,159,35,55,95,239,16,2,109,7,9,14,170,320,347,168,424,158,10,301,124,5,67,21,64,36 }, 
304 { 15,515,700,753,0,1,13,2,117,4,12,10,5,165,457,3,9,134,11,7,6,51,77,64,961,82,33,197,14,341,120,141 }, 
305 { 7,71,14,149,97,18,60,16,150,92,398,189,140,124,24,273,35,2,69,302,154,68,0,336,517,43,66,28,118,251,230,1 }, 
306 { 4,102,33,77,40,59,11,624,210,12,128,342,5,503,91,139,64,32,25,494,202,678,416,0,403,275,21,450,196,318,523,177 }, 
307 { 25,19,42,6,122,813,256,235,85,26,436,53,297,573,680,390,445,63,27,416,80,233,65,73,389,283,45,605,194,17,250,343 }, 
308 { 402,102,202,128,33,300,403,23,12,77,40,21,342,117,483,99,25,494,6,4,63,32,84,569,139,757,475,318,19,26,196,134 }, 
309 { 158,9,0,109,39,49,65,22,35,168,55,24,68,124,159,16,185,344,333,154,254,272,175,289,1,577,95,28,105,810,30,169 }, 
310 { 197,180,115,237,498,165,2,5,287,546,400,3,61,34,509,13,297,80,341,52,45,186,58,881,23,873,468,176,64,17,311,250 }, 
311 { 120,968,373,260,704,110,450,202,137,318,77,95,269,326,217,717,661,652,851,349,93,1,518,98,827,291,21,177,82,33,848,719 }, 
312 { 44,116,144,268,434,489,367,384,98,127,918,93,948,31,206,940,855,0,203,137,9,22,617,141,332,105,393,492,959,282,299,131 }, 
313 { 13,77,23,33,51,0,64,141,102,4,2,115,1,6,202,15,10,128,269,7,177,180,3,40,22,11,515,217,117,318,700,137 }, 
314 { 15,515,700,753,4,11,141,40,165,23,64,180,13,202,32,3,51,125,5,197,21,128,0,93,77,1,120,82,269,117,110,59 }, 
315 { 176,231,585,62,34,14,412,161,56,236,527,57,17,3,51,202,4,23,369,283,128,13,472,440,84,361,136,457,381,130,719,53 }, 
316 { 9,0,180,217,237,101,141,352,88,100,230,64,175,317,115,498,68,39,30,1,702,83,213,36,365,208,752,13,252,321,952,546 }, 
317 { 28,9,22,1,49,0,109,39,83,95,86,30,13,105,128,55,141,168,158,67,31,159,208,12,96,5,185,2,160,64,137,23 }, 
318 { 72,4,38,12,51,89,477,11,57,76,401,308,23,474,99,148,413,179,59,13,431,152,54,569,17,3,205,629,197,421,405,15 }, 
319 { 457,13,23,961,15,51,515,700,165,12,753,629,11,1,719,117,0,3,2,37,569,197,40,328,33,5,153,134,99,64,38,196 }, 
320 { 254,100,310,9,30,1,39,625,166,265,190,0,272,557,131,731,31,98,578,688,404,93,101,88,49,21,127,264,44,36,252,478 }, 
321 { 51,23,12,13,15,128,99,120,10,202,515,153,64,82,700,33,165,2,5,117,403,1,141,0,3,196,37,453,753,197,260,93 }, 
322 { 38,99,542,139,453,117,196,23,457,13,328,111,37,134,961,11,12,51,40,775,587,401,474,54,153,477,41,629,33,475,14,277 }, 
323 { 6,85,25,233,343,91,26,63,138,29,19,65,283,4,81,235,42,122,605,64,648,256,174,370,74,389,718,59,45,194,445,416 }, 
324 { 49,5,97,20,197,21,18,193,0,64,408,729,173,350,43,422,165,7,14,104,61,32,509,713,523,102,120,95,125,397,35,232 }, 
325 { 144,116,268,434,384,489,367,206,93,855,940,44,98,332,617,127,959,911,137,282,203,31,22,219,141,9,131,276,417,0,1,120 }, 
326 { 17,106,64,62,32,255,136,292,476,162,129,241,123,141,41,237,720,214,209,352,519,211,186,148,752,247,507,90,21,77,197,119 }, 
327 { 2,29,52,50,5,58,14,6,27,1,366,357,45,53,17,19,171,151,26,181,133,38,218,764,287,583,61,113,3,487,600,281 }, 
328 { 130,59,196,412,381,730,711,236,77,210,202,402,453,99,401,108,361,803,291,283,153,4,57,51,128,183,14,719,503,117,23,11 }, 
329 { 13,23,51,141,77,4,33,64,115,0,217,10,180,202,2,102,11,9,15,165,40,21,128,352,22,7,197,3,317,515,269,1 }, 
330 { 23,13,202,51,120,15,21,5,141,1,128,269,137,515,64,102,125,48,98,33,260,523,318,93,700,165,450,77,2,12,403,82 }, 
331 { 1,2,14,46,29,67,38,52,5,171,58,24,103,69,96,70,83,181,54,75,163,223,16,45,112,309,155,0,186,35,18,108 }, 
332 { 15,515,700,753,13,0,1,2,153,5,23,10,117,3,9,7,134,165,12,6,341,33,4,14,77,457,115,21,719,180,217,82 }, 
333 { 197,165,509,13,391,180,308,115,23,546,5,498,2,29,3,401,901,61,34,80,14,457,250,569,237,873,38,297,45,15,468,386 }, 
334 { 19,73,27,250,200,714,444,472,26,53,34,17,813,322,283,390,128,297,78,123,432,14,436,136,106,690,57,122,389,80,503,3 }, 
335 { 3,17,21,45,62,32,38,12,155,14,2,328,5,99,401,536,828,13,227,488,106,51,719,119,540,76,165,221,115,629,209,41 }, 
336 { 115,341,873,197,365,13,901,180,569,752,317,1,10,498,143,634,261,0,509,15,943,237,44,31,116,601,165,127,282,23,141,64 }, 
337 { 453,51,23,403,33,421,475,102,15,153,196,515,13,700,117,523,12,40,753,21,4,134,0,494,670,899,22,801,730,10,11,401 }, 
338 { 23,13,51,33,12,117,153,134,453,196,15,99,515,40,14,700,128,102,11,753,77,64,403,202,0,401,475,37,65,2,3,38 }, 
339 { 2,7,5,14,70,1,29,61,52,45,6,112,66,16,21,32,592,46,38,135,87,58,186,315,290,128,113,0,64,48,227,23 }, 
340 { 33,23,102,51,128,13,64,202,141,1,77,10,153,40,196,117,2,3,0,5,15,269,403,12,137,134,318,165,120,6,453,99 }, 
341 { 16,92,7,20,43,35,126,71,60,14,107,18,68,97,0,121,279,149,24,246,191,48,118,575,55,140,362,783,230,150,375,566 }, 
342 { 13,23,4,33,77,64,51,102,141,128,32,10,0,202,40,115,59,22,90,11,177,21,291,6,7,318,180,117,137,2,95,165 }, 
343 { 507,162,129,41,4,211,62,38,123,59,57,248,183,130,99,11,3,361,202,17,402,556,266,305,803,210,128,184,152,136,313,117 }, 
344 { 643,123,193,650,802,18,25,389,718,256,65,289,84,91,619,511,415,90,235,63,57,510,324,216,862,102,6,183,108,397,217,736 }, 
345 { 13,23,15,1,515,51,0,2,700,5,753,165,141,115,12,3,4,180,21,197,457,7,6,10,120,9,33,202,77,32,8,11 }, 
346 { 23,51,13,453,64,403,12,21,5,202,128,475,165,141,523,95,125,115,3,1,4,730,120,32,2,494,180,719,457,197,450,401 }, 
347 { 204,74,135,66,6,174,192,7,138,172,85,353,348,580,280,97,95,500,29,64,426,32,87,889,65,81,25,2,52,43,568,673 }, 
348 { 35,0,68,69,24,9,1,16,65,103,149,133,18,114,28,50,83,2,189,7,46,14,101,336,175,124,251,55,71,218,38,238 }, 
349 { 16,101,0,118,9,18,24,68,35,154,71,124,60,212,191,520,55,806,694,167,28,39,364,375,1,346,252,65,604,302,22,21 }, 
350 { 0,9,16,35,1,24,68,18,65,21,103,67,13,149,28,189,71,23,101,238,114,7,335,133,486,141,22,212,48,50,30,118 }, 
351 { 13,202,23,77,33,51,128,5,21,141,115,32,102,64,4,0,318,269,10,15,291,2,494,177,11,217,3,515,22,137,6,700 }, 
352 { 16,92,60,35,7,18,24,68,150,149,14,71,0,375,97,126,118,107,230,191,246,273,140,55,175,653,9,575,2,28,566,517 }, 
353 { 76,90,21,179,316,148,205,32,464,288,184,257,245,1,89,2,460,57,152,45,38,358,645,5,12,449,350,48,37,17,4,14 }, 
354 { 19,27,26,813,80,297,17,495,436,53,73,200,4,378,250,59,106,25,45,128,361,42,113,469,122,390,77,40,736,6,11,136 }, 
355 { 6,26,235,138,19,145,112,70,331,262,25,42,52,624,27,453,122,47,500,78,648,85,29,2,630,632,409,113,50,226,108,75 }, 
356 { 7,16,14,24,92,35,18,2,46,9,60,140,0,87,50,5,54,13,12,38,171,23,126,21,58,64,1,70,128,71,220,163 }, 
357 { 90,205,257,184,32,179,460,5,245,45,2,288,769,524,57,21,152,229,17,1,497,4,292,59,619,452,432,76,476,11,266,14 }, 
358 { 15,515,700,753,4,5,11,141,13,1,33,3,0,128,202,23,180,21,2,64,269,32,117,134,120,40,102,318,153,17,137,352 }, 
359 { 47,130,711,108,453,412,730,196,390,283,78,27,51,183,381,236,128,200,719,14,153,472,503,34,59,250,3,4,57,803,123,432 }, 
360 { 12,277,51,474,111,153,23,99,13,37,961,94,629,542,569,431,79,139,38,134,117,453,33,188,196,40,115,15,11,157,401,515 }, 
361 { 17,495,469,106,26,378,80,27,161,483,19,742,527,436,383,862,73,136,53,814,297,6,119,84,62,56,25,3,209,611,4,128 }, 
362 { 81,681,636,91,0,750,370,104,718,138,18,693,173,784,29,397,348,74,192,673,174,65,6,207,64,280,306,52,671,32,355,319 }, 
363 { 15,515,700,753,33,77,4,102,115,117,40,13,1,153,134,11,5,217,23,196,2,21,3,317,32,365,0,341,291,59,12,51 }, 
364 { 0,9,28,35,68,1,65,67,101,39,69,175,16,238,13,22,96,124,18,24,251,30,55,12,23,2,50,141,114,5,154,103 }, 
365 { 23,33,77,13,117,40,11,102,64,4,51,403,153,453,10,0,196,134,128,65,12,291,86,99,95,59,15,141,202,180,137,719 }, 
366 { 214,90,289,6,874,64,25,65,235,42,751,249,256,312,194,85,746,875,174,32,525,288,519,835,247,348,233,544,217,524,437,352 }, 
367 { 1,22,2,0,36,67,28,5,49,95,12,50,168,83,105,55,7,9,14,194,103,23,114,21,584,46,10,13,38,69,208,159 }, 
368 { 269,141,13,202,33,180,318,77,291,137,102,352,128,23,349,51,31,217,372,317,125,197,44,21,11,5,901,1,18,0,4,494 }, 
369 { 435,144,274,88,203,418,30,1,190,410,96,778,100,530,521,326,466,795,686,166,960,321,382,264,367,822,131,31,692,9,213,93 }, 
370 { 76,72,90,21,37,179,12,205,32,428,148,38,308,405,4,413,57,184,749,245,316,221,54,645,288,1,152,155,464,257,2,14 }, 
371 { 77,33,64,102,13,141,23,2,40,1,51,10,0,115,6,180,202,128,4,3,177,269,15,7,22,165,291,14,217,318,137,11 }, 
372 { 397,81,4,32,65,788,693,804,681,11,249,21,91,64,690,494,3,0,422,56,348,725,194,123,23,59,523,319,61,510,95,90 }, 
373 { 60,126,16,7,92,121,314,246,35,107,150,132,14,146,24,18,199,298,232,71,359,140,672,97,392,649,5,423,95,21,22,388 }, 
374 { 15,515,141,217,115,700,13,23,120,317,753,180,33,260,110,137,341,51,1,365,4,77,64,202,0,40,36,352,197,269,10,21 }, 
375 { 111,134,117,474,23,13,961,12,569,431,37,15,51,115,515,700,277,99,753,38,197,405,457,4,72,94,629,45,11,89,54,148 }, 
376 { 23,13,51,5,1,15,2,21,12,202,141,0,515,165,120,32,4,64,700,3,115,197,269,125,753,7,9,128,6,180,453,403 }, 
377 { 13,141,4,23,5,2,115,217,202,51,180,137,269,352,77,1,317,3,21,318,0,15,9,64,10,197,11,341,33,515,752,7 }, 
378 { 165,125,197,13,391,21,23,558,48,380,97,120,298,33,14,426,66,115,32,386,900,180,6,98,357,237,326,509,51,278,221,457 }, 
379 { 120,82,15,260,515,1,351,77,450,700,13,21,141,23,753,202,217,93,110,33,51,854,5,128,326,102,137,180,817,48,269,352 }, 
380 { 23,13,15,51,515,700,961,753,0,457,1,2,4,115,10,453,569,5,33,165,11,719,14,40,64,197,3,21,474,629,38,401 }, 
381 { 264,166,39,30,9,100,435,254,93,921,190,363,1,625,411,382,897,656,203,478,404,812,438,110,473,88,18,691,156,141,274,272 }, 
382 { 9,0,252,100,166,39,101,265,364,68,88,329,520,18,419,676,118,167,404,604,16,1,21,30,212,158,553,49,382,274,48,13 }, 
383 { 15,515,700,753,4,11,141,5,3,13,202,1,180,21,2,165,269,23,40,64,0,318,12,32,128,51,77,117,523,197,120,457 }, 
384 { 24,1,2,69,35,16,67,18,14,50,0,46,68,9,38,7,133,71,83,149,28,108,189,218,65,114,238,29,75,54,5,96 }, 
385 { 90,289,214,64,874,13,77,712,66,751,4,23,51,192,32,0,202,194,312,177,33,65,234,104,875,288,59,5,835,416,102,95 }, 
386 { 0,9,49,127,98,31,301,28,371,159,1,395,512,737,158,761,916,623,16,44,242,39,170,18,293,105,24,272,101,22,23,385 }, 
387 { 17,62,136,214,123,129,32,292,119,209,710,106,141,162,128,64,45,4,77,249,11,618,211,3,207,130,519,183,38,177,21,269 }, 
388 { 5,107,581,356,279,32,441,362,493,660,13,298,0,534,49,147,21,22,132,121,97,423,7,590,259,683,14,786,126,508,60,246 }, 
389 { 51,13,15,730,453,23,515,719,386,457,12,700,403,475,899,1,6,523,753,421,99,401,165,33,2,19,361,5,0,670,120,27 }, 
390 { 49,28,9,159,272,22,254,131,158,327,95,105,0,39,35,168,347,286,374,55,65,627,424,912,68,578,1,24,239,175,688,169 }, 
391 { 15,515,700,33,753,4,77,141,341,317,1,10,13,180,102,22,40,117,115,365,5,901,23,197,134,11,217,351,64,82,21,137 }, 
392 { 134,15,13,515,23,700,12,753,51,474,37,961,197,10,457,569,4,0,99,2,115,38,165,153,94,3,139,11,1,82,33,5 }, 
393 { 7,2,20,58,5,14,128,66,6,29,32,43,21,52,16,38,631,61,74,97,46,135,113,25,202,192,13,0,884,45,112,87 }, 
394 { 77,13,33,202,23,128,102,4,141,342,117,0,269,318,134,22,11,21,32,153,403,291,49,64,137,51,40,15,494,5,196,98 }, 
395 { 2,1,14,6,46,38,29,65,5,36,67,0,103,7,22,86,133,50,108,208,52,83,24,323,283,69,28,18,10,25,23,75 }, 
396 { 15,515,700,753,1,5,4,2,3,13,0,11,180,341,12,33,10,197,134,365,77,23,21,901,6,117,165,7,37,32,17,102 }, 
397 { 203,268,206,93,417,940,31,8,120,137,44,499,959,473,202,692,728,559,0,260,10,326,141,564,817,127,341,1,450,22,110,23 }, 
398 { 15,82,515,120,700,0,10,753,33,8,64,165,110,31,260,93,13,197,23,22,40,4,351,44,77,9,11,153,102,51,1,196 }, 
399 { 60,0,16,7,14,43,20,71,28,10,2,22,154,18,13,24,92,1,51,576,35,615,805,925,68,126,124,149,97,64,23,55 }, 
400 { 19,6,26,80,5,84,27,17,25,2,504,129,45,240,56,123,4,119,618,1,76,106,64,51,14,3,128,65,32,710,0,42 }, 
401 { 15,515,700,753,13,4,77,23,33,51,0,5,8,10,11,31,44,1,82,22,202,64,110,102,93,21,291,40,141,180,9,49 }, 
402 { 195,98,271,223,132,167,146,407,1,360,121,834,393,591,212,199,293,259,522,107,354,147,156,191,807,590,48,18,125,16,765,541 }, 
403 { 128,202,77,210,402,318,33,102,6,40,403,29,342,269,196,757,99,139,2,111,42,4,494,117,275,300,13,12,678,0,177,122 }, 
404 { 13,33,23,40,51,102,4,117,77,64,134,0,128,153,202,196,453,11,15,12,1,22,403,141,59,14,10,475,515,65,700,95 }, 
405 { 7,16,14,24,18,2,28,0,92,71,1,22,6,35,60,20,168,10,154,118,5,302,124,69,97,109,703,158,420,12,149,66 }, 
406 { 15,1,515,23,0,13,700,2,51,753,180,5,120,165,197,21,115,4,33,9,141,7,12,6,3,457,386,202,260,523,8,31 }, 
407 { 60,107,121,132,146,126,199,279,150,92,16,649,441,35,955,7,21,0,423,5,18,195,598,298,493,356,32,653,22,362,953,10 }, 
408 { 31,44,98,276,284,299,116,935,9,201,0,131,39,127,144,662,1,137,371,492,567,489,93,254,49,268,22,28,30,293,434,737 }, 
409 { 13,15,23,515,700,0,1,51,753,4,2,10,77,202,5,115,3,165,197,457,9,12,11,961,33,120,22,141,180,7,6,40 }, 
410 { 123,162,184,257,17,183,229,130,129,3,84,136,99,152,556,383,57,497,12,205,4,62,56,452,80,266,128,14,40,119,27,106 }, 
411 { 196,33,117,40,153,23,134,13,51,102,453,0,15,475,12,14,515,2,22,700,4,21,753,64,401,670,730,1,9,11,10,99 }, 
412 { 224,219,187,131,258,385,442,871,836,31,98,908,44,574,127,944,137,839,116,36,613,1,254,39,926,160,829,96,93,371,860,827 }, 
413 { 121,195,156,132,146,360,590,407,786,522,883,591,259,929,626,941,150,687,5,55,296,379,467,178,586,465,279,21,1,13,60,354 }, 
414 { 2,1,14,29,6,5,46,52,38,19,114,75,26,65,108,96,25,50,36,70,103,309,17,236,218,74,12,86,0,3,10,112 }, 
415 { 15,515,82,700,120,753,10,0,8,197,260,165,351,64,13,110,117,93,31,1,9,33,22,23,457,44,450,77,102,898,40,49 }, 
416 { 7,66,97,2,172,74,226,52,29,135,192,232,43,324,92,5,38,20,222,14,6,568,87,107,353,620,580,16,138,174,448,32 }, 
417 { 62,129,123,162,136,249,618,183,507,57,4,152,17,59,11,184,117,77,3,128,211,41,130,205,12,40,33,106,64,229,38,313 }, 
418 { 1,13,15,2,4,515,23,0,3,115,700,5,51,77,341,141,753,180,33,217,197,202,901,6,21,165,11,365,318,317,10,102 }, 
419 { 6,26,235,19,145,47,112,78,64,27,453,95,29,444,25,624,85,108,648,70,32,130,74,42,711,630,632,138,65,122,113,730 }, 
420 { 23,51,12,15,13,99,515,153,117,10,700,37,120,82,165,2,753,64,128,0,403,3,5,1,134,197,453,31,202,457,110,21 }, 
421 { 16,24,18,71,64,35,92,7,246,146,9,108,60,118,199,5,140,2,267,0,230,830,32,133,1,68,50,330,247,563,36,12 }, 
422 { 15,515,700,753,0,1,13,2,23,3,4,217,51,5,115,8,9,180,341,10,7,6,317,77,33,372,901,197,365,11,120,165 }, 
423 { 234,639,178,202,77,142,5,455,450,49,416,0,147,427,198,21,315,329,13,318,325,557,120,344,113,259,22,128,61,105,23,494 }, 
424 { 1,31,36,44,141,180,55,2,64,22,98,116,13,352,0,115,10,127,5,164,253,498,237,165,341,197,4,86,15,170,125,23 }, 
425 { 15,120,13,141,23,260,217,515,1,77,51,110,180,700,317,82,269,137,115,202,21,753,64,5,351,291,0,450,352,93,36,326 }, 
426 { 26,6,112,396,19,145,25,122,648,287,42,74,624,222,416,45,138,66,644,151,113,651,29,573,64,280,445,27,525,85,70,58 }, 
427 { 156,360,5,146,121,21,271,522,354,132,49,13,18,195,16,340,60,591,446,586,727,0,107,407,167,48,1,463,199,566,32,23 }, 
428 { 5,61,49,147,178,612,660,120,21,182,23,427,259,683,33,4,77,70,13,3,376,98,64,0,481,344,48,595,291,263,141,51 }, 
429 { 89,79,468,179,358,205,94,405,115,498,72,180,365,431,37,111,341,734,188,317,482,217,11,4,245,152,413,216,12,474,490,752 }, 
430 { 24,16,35,68,18,71,7,92,0,108,9,14,118,101,336,175,375,302,28,124,154,55,149,60,398,1,65,2,140,273,345,230 }, 
431 { 51,730,421,801,453,386,23,523,13,475,719,401,670,365,899,403,115,457,758,165,33,494,450,6,423,805,629,56,569,514,958,388 }, 
432 { 113,45,6,311,29,2,151,614,145,491,112,80,5,27,61,74,315,66,209,631,19,25,58,17,73,26,1,243,70,64,611,287 }, 
433 { 4,339,188,471,11,59,79,12,377,94,99,33,77,102,51,111,37,152,13,961,474,542,40,342,3,23,128,403,202,177,184,57 }, 
434 { 15,4,515,11,700,33,82,40,0,120,753,10,8,110,13,93,23,165,77,260,64,31,22,51,44,102,351,1,125,9,197,21 }, 
435 { 16,24,18,0,35,68,28,71,124,118,60,7,9,55,14,92,109,101,419,175,22,252,154,375,149,302,158,346,2,49,1,126 }, 
436 { 17,45,227,21,106,3,2,243,209,5,48,32,221,62,207,50,29,186,290,270,263,52,14,496,400,119,46,255,54,430,38,721 }, 
437 { 340,354,586,658,156,195,698,668,1,296,9,18,883,363,447,379,303,98,411,13,31,163,51,5,371,48,919,846,121,21,360,70 }, 
438 { 277,153,111,12,23,51,474,99,38,37,139,117,41,457,79,453,542,13,11,33,134,157,629,188,961,14,196,401,102,569,15,94 }, 
439 { 0,18,16,159,49,24,9,105,35,68,7,28,22,1,60,344,55,101,109,2,14,158,13,23,71,118,455,286,272,424,5,327 }, 
440 { 0,105,9,49,16,18,158,28,518,24,101,320,1,68,170,301,272,127,7,286,35,890,109,39,159,98,21,344,31,55,371,23 }, 
441 { 141,1,180,15,13,2,365,217,515,352,317,115,341,0,4,5,269,700,23,21,3,752,197,77,753,51,31,901,10,202,8,64 }, 
442 { 4,23,51,33,19,17,102,153,485,880,40,403,196,26,300,453,27,117,78,0,12,200,47,5,11,14,342,99,53,77,475,2 }, 
443 { 62,184,56,440,130,229,183,3,556,152,99,162,12,266,17,548,136,57,305,161,123,14,452,4,383,403,257,34,40,84,33,139 }, 
444 { 13,23,77,141,64,202,33,51,269,115,0,102,21,4,217,128,5,32,318,137,291,9,15,2,180,10,3,317,177,515,7,6 }, 
445 { 1,22,36,105,170,0,86,2,31,28,239,64,55,5,10,98,9,44,127,95,654,67,301,143,13,12,49,23,320,141,83,21 }, 
446 { 15,515,700,753,0,1,13,2,23,901,5,8,51,82,9,180,457,4,7,12,3,6,10,120,341,141,22,898,197,351,115,260 }, 
447 { 1,39,274,98,100,265,190,30,438,310,166,223,88,96,909,31,264,625,530,9,382,812,21,252,593,0,254,539,44,131,23,778 }, 
448 { 18,212,167,118,363,1,447,411,146,60,271,16,781,121,647,9,621,562,21,478,664,68,815,5,354,98,48,101,24,446,777,463 }, 
449 { 24,28,22,0,7,1,2,16,14,65,35,49,158,95,109,159,55,105,10,18,124,9,67,5,239,149,12,289,108,68,21,424 }, 
450 { 105,22,131,272,286,98,55,239,1,31,320,9,127,327,36,185,28,374,86,219,0,64,187,44,578,164,224,913,535,115,601,13 }, 
451 { 22,31,28,301,127,98,44,0,105,1,512,395,9,293,109,299,95,338,239,125,242,116,36,320,55,841,900,685,599,23,13,763 }, 
452 { 2,1,58,29,5,14,52,46,186,334,45,155,151,50,400,75,38,69,502,61,48,227,223,7,163,17,262,67,549,21,70,113 }, 
453 { 7,107,135,232,97,14,2,92,66,16,172,192,278,387,298,356,38,35,448,52,46,43,60,29,20,126,324,526,357,359,64,5 }, 
454 { 20,43,104,426,173,7,560,414,707,784,319,81,0,861,422,819,38,74,715,52,376,97,879,32,330,22,49,64,66,95,192,526 }, 
455 { 104,74,636,66,204,0,355,81,222,25,29,319,145,784,20,65,90,4,174,194,7,64,6,746,138,173,750,715,91,43,192,32 }, 
456 { 0,9,101,35,68,39,65,28,252,124,67,154,364,336,100,166,30,1,289,55,149,346,16,114,158,88,439,24,429,22,570,194 }, 
457 { 57,14,4,231,236,585,176,59,369,23,361,13,719,51,300,342,12,457,56,3,62,38,202,401,34,46,2,322,11,215,210,507 }, 
458 { 1,2,15,3,141,0,515,5,33,700,13,64,77,180,6,128,753,10,4,269,102,202,11,7,134,197,352,120,117,318,12,291 }, 
459 { 5,1,21,202,13,32,48,23,0,61,259,22,494,120,70,49,51,18,137,128,465,12,178,115,2,453,403,141,58,3,90,450 }, 
460 { 141,205,4,72,59,79,245,11,352,94,152,76,247,216,21,188,452,217,497,12,89,37,111,339,588,77,64,875,864,115,358,464 }, 
461 { 15,515,700,753,0,1,2,13,5,4,23,3,8,341,365,51,115,10,120,457,6,141,77,197,31,7,165,9,202,450,961,260 }, 
462 { 5,2,50,14,58,38,171,46,29,1,45,186,17,52,155,218,48,281,61,487,54,36,67,21,328,334,151,227,760,114,400,133 }, 
463 { 457,120,70,125,318,64,23,48,795,291,202,761,751,415,77,846,269,758,21,237,96,260,391,165,87,1,128,5,221,13,137,763 }, 
464 { 13,23,51,33,4,40,117,102,453,64,153,196,0,77,15,11,12,475,1,65,134,10,515,22,21,14,700,59,403,141,2,753 }, 
465 { 229,152,57,266,452,381,432,12,313,184,99,471,17,4,62,339,157,3,129,59,128,11,369,37,77,38,40,123,5,497,188,257 }, 
466 { 49,28,109,22,159,9,272,95,105,131,55,35,254,168,39,327,169,0,1,286,175,374,347,158,420,67,36,194,312,424,627,346 }, 
467 { 5,2,61,29,45,58,80,311,1,17,209,227,52,243,106,869,454,151,592,496,48,334,14,155,6,186,46,171,75,21,255,667 }, 
468 { 244,44,110,141,260,30,269,352,839,131,574,228,373,276,1,406,219,717,217,137,253,224,120,93,36,31,567,116,661,187,341,88 }, 
469 { 12,99,79,139,11,453,196,51,277,474,111,23,542,37,94,188,33,13,401,775,40,961,313,102,4,339,153,485,629,134,300,431 }, 
470 { 16,35,9,0,68,24,149,69,67,18,1,114,65,230,71,7,103,133,50,167,212,118,101,191,140,64,399,28,124,283,55,565 }, 
471 { 88,30,274,435,131,613,190,100,93,829,166,1,187,795,530,127,382,957,960,160,31,137,466,264,39,800,406,254,28,473,521,219 }, 
472 { 167,16,18,118,212,24,60,71,101,68,191,9,375,411,363,35,0,1,589,199,302,21,447,55,146,126,92,271,647,121,562,48 }, 
473 { 64,141,86,177,77,128,147,597,304,95,269,102,275,4,352,49,120,5,372,194,465,13,588,237,947,216,202,180,612,751,107,534 }, 
474 { 18,65,90,403,523,289,240,214,194,102,701,475,202,217,283,862,389,51,33,0,494,421,453,817,84,64,847,899,352,13,23,437 }, 
475 { 13,51,23,202,5,12,21,128,15,115,0,1,141,120,64,32,4,2,515,403,165,457,3,10,700,99,453,318,719,450,308,401 }, 
476 { 98,223,393,31,1,271,834,791,167,44,202,64,93,697,5,116,77,125,450,446,212,18,541,293,51,120,195,132,284,13,807,765 }, 
477 { 15,515,700,753,4,11,23,13,40,51,82,165,0,110,93,33,141,64,120,5,10,77,3,102,180,32,202,125,8,197,31,21 }, 
478 { 15,515,700,753,0,1,13,2,901,23,5,341,3,51,82,8,4,180,961,9,115,10,12,6,898,7,351,141,134,22,31,120 }, 
479 { 234,416,77,5,315,639,325,202,147,198,113,49,450,61,455,142,0,21,22,342,329,494,178,58,102,427,318,230,13,120,43,470 }, 
480 { 60,146,16,18,156,126,121,271,199,360,132,24,167,0,640,10,71,522,21,92,5,340,107,354,118,150,22,195,446,35,28,212 }, 
481 { 4,361,11,14,56,368,377,161,27,12,300,77,59,200,17,554,202,33,40,494,495,21,210,80,757,25,128,23,19,38,444,53 }, 
482 { 141,82,217,351,15,352,120,1,180,260,515,64,854,36,700,317,752,372,13,269,77,753,922,21,349,23,202,110,93,137,51,373 }, 
483 { 15,515,700,753,77,13,0,1,23,33,102,2,51,4,3,5,291,217,10,9,450,120,341,7,317,6,11,117,115,8,260,180 }, 
484 { 15,515,120,13,700,23,77,141,1,260,0,753,180,51,137,202,115,365,110,291,217,5,128,9,21,341,197,269,2,450,317,165 }, 
485 { 174,6,348,85,138,74,280,204,66,233,192,355,289,65,81,580,636,353,25,91,104,343,673,214,64,95,42,712,792,32,194,90 }, 
486 { 152,497,452,59,4,216,11,79,94,77,128,188,269,339,588,33,76,529,318,32,141,471,12,202,111,21,5,51,37,90,72,177 }, 
487 { 417,499,10,141,253,244,110,559,8,564,180,260,728,120,352,638,642,341,951,206,143,752,901,93,137,661,922,373,44,31,811,197 }, 
488 { 13,77,23,33,4,51,0,102,128,59,141,40,64,115,177,10,137,22,202,2,7,11,90,1,117,180,269,14,49,6,134,3 }, 
489 { 1,2,22,0,36,5,67,50,14,28,12,86,38,46,83,168,194,65,103,114,49,7,10,95,21,69,23,24,128,51,55,13 }, 
490 { 17,106,119,207,255,306,742,378,84,62,136,45,3,5,240,80,61,56,209,383,311,790,655,32,2,440,76,151,58,29,179,263 }, 
491 { 3,128,1,141,2,202,33,5,64,15,0,515,102,13,269,10,700,180,134,51,120,6,77,318,23,137,17,117,753,197,82,153 }, 
492 { 514,38,377,328,11,57,41,248,880,266,556,4,152,361,471,757,485,403,305,102,3,211,313,99,457,130,12,14,157,40,23,54 }, 
493 { 68,0,167,101,9,118,264,520,16,18,21,478,562,1,124,212,100,936,664,777,191,88,806,154,48,24,759,604,35,252,265,65 }, 
494 { 230,689,699,213,466,352,217,831,30,443,418,144,854,201,840,855,1,251,203,317,530,957,96,93,822,539,36,752,351,137,83,800 }, 
495 { 33,77,102,117,15,82,13,134,23,64,0,515,120,153,51,4,40,128,700,260,202,141,196,22,753,11,351,10,1,326,95,269 }, 
496 { 11,40,33,51,117,13,542,328,14,134,38,153,23,12,485,231,102,54,775,37,3,377,111,139,211,4,457,403,369,475,99,719 }, 
497 { 33,64,77,128,141,2,1,202,102,13,23,117,0,15,3,153,51,134,10,40,6,5,515,269,137,180,318,165,700,7,196,753 }, 
498 { 15,515,700,753,4,1,5,11,13,21,33,180,93,141,64,2,23,77,82,3,0,102,32,40,352,341,10,197,98,110,117,901 }, 
499 { 1,2,14,67,50,46,38,24,103,83,0,5,36,28,29,133,114,96,65,52,18,75,54,108,22,7,238,58,160,9,361,69 }, 
500 { 258,201,276,137,160,860,116,261,295,843,567,144,131,44,187,268,943,219,284,31,202,935,141,98,662,203,127,96,36,93,224,1 }, 
501 { 7,2,14,16,46,87,75,52,92,278,29,38,140,70,1,5,35,294,24,262,135,69,171,172,58,409,112,60,50,66,97,12 }, 
502 { 13,23,0,2,51,1,33,4,115,10,15,141,77,3,5,180,217,515,9,7,64,11,700,6,102,40,197,22,317,753,165,202 }, 
503 { 74,145,6,66,25,204,42,29,222,337,138,26,7,525,192,174,746,287,544,135,415,2,609,632,112,64,87,0,85,45,712,396 }, 
504 { 77,33,102,15,217,13,23,141,202,515,51,700,291,4,269,753,317,180,21,64,318,115,128,0,275,2,352,196,3,5,137,11 }, 
505 { 187,219,258,871,44,442,160,574,137,224,908,116,839,131,36,926,276,201,93,228,202,860,31,613,144,531,406,1,902,30,190,318 }, 
506 { 1,372,141,5,21,77,225,744,96,30,23,349,13,291,269,284,69,442,459,144,303,839,217,622,160,330,260,48,120,410,189,352 }, 
507 { 66,222,2,74,29,87,135,6,7,145,52,25,294,337,226,172,138,331,42,70,97,112,26,1,632,192,43,5,415,609,461,353 }, 
508 { 45,17,106,209,5,2,21,29,48,207,3,186,243,155,255,263,454,119,400,496,270,14,290,62,425,1,171,32,659,52,38,56 }, 
509 { 93,88,141,120,30,213,260,373,100,717,459,82,110,1,166,450,180,321,217,372,36,269,131,225,22,352,326,466,473,187,244,410 }, 
510 { 266,57,152,381,313,471,12,229,99,369,339,62,157,3,4,37,77,38,188,17,11,162,40,184,129,59,475,775,128,452,403,453 }, 
511 { 217,352,317,141,752,15,180,515,372,365,700,341,753,349,77,21,291,1,115,244,64,120,13,98,269,82,5,498,864,351,23,144 }, 
512 { 14,514,369,102,403,377,51,719,880,153,23,13,457,11,485,4,401,12,328,453,33,40,117,57,629,38,730,236,134,670,361,961 }, 
513 { 107,7,172,14,92,135,2,359,60,314,46,16,126,278,232,150,279,32,38,392,298,5,35,97,24,192,259,288,330,52,356,312 }, 
514 { 0,4,25,13,59,90,65,23,26,19,18,12,5,216,91,51,389,33,77,11,22,85,27,81,21,177,746,45,42,194,37,123 }, 
515 { 5,49,315,202,416,77,455,639,450,21,197,137,350,13,408,0,329,318,494,344,61,402,64,509,347,120,113,48,95,713,308,401 }, 
516 { 130,47,381,390,59,90,200,214,289,6,65,472,29,64,874,648,50,751,624,26,52,32,4,194,875,714,85,249,247,33,881,19 }, 
517 { 51,23,453,13,719,12,457,165,37,730,99,4,386,197,401,17,11,2,3,15,5,961,475,6,515,64,54,700,32,115,0,403 }, 
518 { 15,515,1,13,700,2,23,0,753,5,3,180,51,4,165,12,141,21,197,457,7,115,6,9,352,10,120,202,8,341,11,77 }, 
519 { 0,9,1,67,35,28,68,16,24,65,18,69,50,114,103,12,22,13,5,101,2,96,23,83,149,21,39,55,7,175,433,124 }, 
520 { 28,105,22,0,1,320,170,9,49,301,109,95,127,31,98,55,65,35,2,24,168,159,36,713,16,740,13,338,21,44,512,23 }, 
521 { 13,77,4,51,23,33,102,202,128,59,40,0,64,141,117,403,115,11,15,318,153,269,22,515,475,134,10,494,177,1,90,210 }, 
522 { 13,23,0,51,77,33,2,141,4,10,1,64,115,102,3,6,22,15,217,11,180,7,40,515,165,202,177,9,269,128,700,5 }, 
523 { 456,116,492,8,949,268,867,391,203,51,499,13,719,386,31,791,457,918,125,10,23,93,479,685,417,0,22,338,506,551,870,730 }, 
524 { 17,237,45,180,106,62,32,64,115,41,136,498,255,21,197,129,241,13,3,227,23,352,165,752,350,365,449,155,4,546,476,38 }, 
525 { 1,15,180,515,0,2,341,700,901,352,4,141,13,3,752,5,753,217,317,115,365,23,197,21,51,165,31,6,269,202,77,7 }, 
526 { 205,141,216,269,497,4,588,76,59,152,128,452,79,77,875,11,72,94,188,217,352,12,247,37,90,64,32,1,474,23,947,372 }, 
527 { 64,247,217,237,317,180,752,115,349,141,498,13,437,304,23,372,352,164,579,291,33,864,177,197,0,490,72,10,482,77,269,51 }, 
528 { 2,1,0,13,15,141,3,77,5,515,64,33,23,180,6,700,4,117,217,7,10,11,102,165,753,197,115,134,40,352,12,269 }, 
529 { 11,40,38,328,33,542,12,313,41,339,23,157,377,117,369,51,471,99,775,485,13,305,457,57,14,475,37,248,4,54,188,719 }, 
530 { 33,77,102,40,13,23,0,51,4,128,64,202,117,141,22,196,153,10,134,15,59,269,1,137,65,11,403,318,453,86,515,177 }, 
531 { 472,80,34,250,495,161,17,14,469,176,128,4,389,106,283,436,216,527,3,297,483,177,53,56,231,194,119,84,719,57,255,59 }, 
532 { 317,352,180,141,217,752,115,341,365,244,1,269,202,901,253,15,21,498,372,4,137,515,13,2,700,318,5,197,23,143,753,349 }, 
533 { 9,39,101,18,265,100,333,520,252,16,0,329,593,1,553,364,68,167,310,30,121,254,118,158,363,166,60,604,272,24,286,404 }, 
534 { 15,515,1,180,700,901,0,2,753,341,752,4,3,13,115,365,317,5,23,197,141,217,165,352,6,22,36,9,137,51,7,10 }, 
535 { 131,39,9,829,166,613,578,827,1,30,716,254,100,98,31,224,0,406,228,310,616,219,44,846,127,190,938,96,265,371,856,438 }, 
536 { 17,64,62,106,141,751,136,292,32,129,352,41,38,476,86,128,214,237,5,177,123,209,217,45,269,954,162,710,180,3,90,4 }, 
537 { 25,42,235,65,650,736,605,6,630,85,123,343,233,256,26,122,63,389,141,249,416,444,368,194,19,108,138,174,90,0,544,511 }, 
538 { 184,229,152,57,266,432,497,452,17,381,619,257,313,12,4,205,59,3,99,471,157,128,5,129,339,369,77,11,32,45,202,2 }, 
539 { 137,202,160,860,141,30,93,567,36,276,295,261,131,39,9,964,201,843,1,98,800,318,116,22,943,187,10,219,206,44,269,535 }, 
540 { 0,493,125,64,49,9,279,10,35,18,93,55,293,31,14,13,194,165,325,48,22,132,21,107,98,389,44,581,342,259,174,137 }, 
541 { 15,515,700,753,4,33,13,77,23,5,51,32,102,40,93,11,349,141,21,8,82,202,64,31,110,10,117,0,1,44,3,318 }, 
542 { 110,253,854,811,352,141,244,951,180,642,661,384,498,143,752,317,911,10,269,206,559,351,261,120,902,533,922,959,365,160,332,217 }, 
543 { 2,29,70,1,75,52,6,220,26,112,145,331,74,163,19,69,38,324,46,58,14,5,25,21,278,223,50,307,66,7,67,409 }, 
544 { 13,23,77,33,51,4,64,141,115,102,0,2,128,177,40,11,202,10,6,180,7,15,269,1,32,217,59,22,291,3,137,515 }, 
545 { 340,897,691,478,658,264,914,382,100,812,363,1,724,156,166,698,88,521,39,404,682,447,296,96,303,411,30,909,9,274,656,772 }, 
546 { 9,18,310,101,265,159,326,120,105,158,33,363,77,195,51,55,13,39,354,132,23,7,28,639,16,137,98,1,252,272,709,49 }, 
547 { 57,313,471,12,99,369,157,339,266,152,38,37,475,453,328,775,11,40,59,188,77,514,401,403,342,4,139,33,377,51,229,14 }, 
548 { 16,7,24,14,35,140,60,92,18,69,71,2,189,1,46,230,108,388,150,38,21,172,278,67,246,267,50,309,236,135,451,0 }, 
549 { 206,417,93,940,959,473,499,203,8,137,559,728,31,202,44,120,450,141,10,260,116,564,22,326,269,318,268,244,0,1,253,638 }, 
550 { 15,515,700,753,1,0,13,2,23,4,3,51,5,217,7,77,341,115,8,9,10,33,6,180,317,349,291,120,11,165,457,901 }, 
551 { 1,2,5,14,48,21,290,32,50,45,38,46,263,207,155,72,76,29,17,408,425,171,89,52,7,0,292,449,3,227,513,428 }, 
552 { 121,132,354,167,271,223,146,98,18,463,1,668,446,195,407,60,212,447,781,48,360,363,411,522,156,393,807,9,21,16,293,13 }, 
553 { 131,578,105,371,219,224,716,616,187,49,9,254,737,159,385,98,258,127,272,761,0,916,623,910,28,286,39,31,22,518,924,242 }, 
554 { 302,467,97,6,273,1,24,484,124,51,36,18,2,398,453,421,523,69,7,23,13,403,386,150,66,0,298,65,426,165,22,158 }, 
555 { 30,190,530,88,1,100,778,539,625,274,382,410,96,731,960,39,795,321,9,131,264,144,840,748,44,166,669,957,36,31,435,228 }, 
556 { 141,1,2,128,64,33,15,202,3,0,180,5,13,77,515,134,269,102,197,700,10,137,318,6,120,165,753,352,4,82,23,117 }, 
557 { 44,201,567,116,131,224,295,662,489,268,219,31,434,144,187,276,110,384,93,261,699,137,36,442,120,1,613,30,228,64,141,244 }, 
558 { 12,15,51,23,515,37,99,13,700,0,10,117,753,38,165,82,134,120,11,453,197,64,115,569,1,629,401,22,457,474,110,153 }, 
559 { 7,135,2,92,172,14,66,140,38,52,97,46,29,74,16,324,278,226,6,87,1,571,262,5,357,232,35,380,69,314,24,330 }, 
560 { 125,386,23,963,949,60,51,391,165,221,13,197,118,21,719,193,541,421,517,150,393,7,401,453,308,5,791,551,326,558,48,173 }, 
561 { 6,85,42,25,138,222,174,235,280,256,525,289,26,214,64,746,90,32,544,65,204,19,66,337,355,95,348,415,74,29,5,312 }, 
562 { 1,14,5,50,2,67,24,0,46,69,48,21,58,103,16,12,18,38,54,96,83,7,502,45,36,181,35,9,430,28,10,155 }, 
563 { 811,351,642,180,951,752,110,638,253,10,82,352,197,341,365,564,499,854,873,55,9,417,282,901,244,22,559,143,206,141,28,898 }, 
564 { 23,13,51,15,12,453,403,165,4,515,115,719,475,457,700,523,2,21,0,99,202,197,14,5,386,753,128,401,37,308,33,117 }, 
565 { 120,13,23,77,141,1,15,93,217,82,260,51,137,202,110,515,21,180,165,5,128,102,64,351,291,700,269,352,326,203,177,0 }, 
566 { 1,5,0,22,12,2,36,21,10,23,86,13,28,51,9,128,48,14,32,50,7,3,96,137,54,4,202,49,37,65,208,323 }, 
567 { 219,98,23,127,301,51,258,308,170,910,13,165,22,105,293,616,125,242,276,401,201,395,964,115,55,284,31,374,327,206,512,900 }, 
568 { 64,180,80,165,5,237,2,250,34,58,297,61,197,17,22,29,186,498,231,445,247,3,752,311,95,32,483,153,27,45,115,469 }, 
569 { 13,77,23,33,0,2,1,64,141,51,102,10,15,3,115,40,180,6,515,128,7,22,269,202,4,217,700,5,177,117,14,165 }, 
570 { 15,120,51,515,13,450,23,700,202,153,196,753,260,64,128,141,730,4,326,386,21,523,33,318,5,457,95,32,403,1,77,269 }, 
571 { 2,1,5,29,32,45,207,263,14,425,58,72,76,21,7,408,48,46,52,186,17,292,38,6,61,89,476,50,155,720,119,3 }, 
572 { 15,515,700,753,4,13,11,5,1,23,33,21,3,141,32,2,40,180,117,64,269,202,102,197,0,165,120,51,341,352,153,12 }, 
573 { 76,5,214,129,2,123,45,710,17,249,618,460,179,32,1,257,205,519,90,207,245,184,162,61,769,209,292,106,6,29,14,128 }, 
574 { 1,15,23,13,120,141,51,515,202,21,700,165,0,180,137,2,5,77,128,93,753,260,269,197,326,33,110,352,82,102,318,48 }, 
575 { 7,2,135,14,29,87,66,52,97,172,70,112,5,58,46,337,92,16,20,43,1,38,232,155,74,294,6,461,409,151,262,32 }, 
576 { 574,187,384,926,860,110,258,434,269,531,141,244,160,261,253,116,699,959,940,717,533,36,219,31,902,661,871,295,201,352,10,260 }, 
577 { 156,354,296,1,182,586,64,379,340,937,850,698,31,48,98,44,120,18,163,23,30,658,195,125,77,284,223,291,774,481,96,39 }, 
578 { 250,80,34,472,17,495,176,469,33,194,64,483,4,297,141,14,161,27,53,667,56,833,73,527,585,231,106,51,84,814,2,59 }, 
579 { 97,7,81,140,66,92,172,192,24,298,43,6,74,69,314,426,462,14,501,16,21,508,60,189,267,232,230,104,48,20,135,330 }, 
580 { 31,44,116,144,268,393,492,434,367,489,127,98,918,0,384,9,22,206,948,105,93,203,1,456,332,940,299,28,137,49,293,125 }, 
581 { 15,128,33,3,13,51,141,1,202,64,23,2,515,120,102,0,5,82,10,700,165,197,269,153,403,110,753,137,196,318,117,12 }, 
582 { 31,98,127,9,0,105,22,28,44,512,293,395,299,1,242,49,685,763,320,599,125,116,109,276,284,95,870,159,23,456,36,900 }, 
583 { 7,24,124,1,6,97,2,69,14,18,23,92,21,67,66,16,5,484,43,20,118,65,36,22,28,0,51,140,13,71,29,150 }, 
584 { 1,64,442,303,284,349,202,141,622,67,154,447,260,44,652,429,9,335,237,919,197,98,167,33,682,269,547,77,863,411,340,201 }, 
585 { 1,15,2,141,515,0,700,13,3,180,10,753,5,64,77,33,4,6,7,197,102,269,165,23,134,11,352,341,291,349,22,120 }, 
586 { 99,139,12,453,196,277,775,40,475,33,23,401,215,51,11,14,77,111,313,130,38,211,37,266,129,15,339,153,719,3,369,515 }, 
587 { 33,77,102,4,23,128,13,141,202,64,51,0,40,59,269,115,117,137,153,1,318,11,10,177,15,134,22,90,196,2,403,32 }, 
588 { 7,2,14,58,70,112,16,5,87,38,46,52,6,128,135,1,32,21,155,29,66,64,0,97,92,186,172,294,13,23,20,37 }, 
589 { 15,13,515,1,700,2,23,0,753,5,3,4,51,10,341,115,365,180,11,33,317,77,6,7,217,12,197,165,117,9,64,102 }, 
590 { 2,1,14,29,75,69,67,6,52,46,38,24,103,220,83,25,70,87,262,74,96,267,50,366,26,16,226,394,357,66,108,19 }, 
591 { 9,105,18,39,1,0,16,557,101,272,252,890,326,49,265,21,137,100,23,938,13,310,159,5,31,24,254,51,30,128,202,132 }, 
592 { 80,209,45,61,667,17,6,106,5,2,151,29,483,255,454,833,27,311,112,19,738,378,1,58,113,26,25,469,119,887,32,64 }, 
593 { 13,23,51,15,5,1,515,0,21,2,12,141,700,165,202,115,753,32,180,4,3,197,10,120,457,9,269,128,64,341,7,33 }, 
594 { 99,12,453,277,139,157,369,474,339,51,38,23,37,196,188,401,775,111,11,313,328,475,153,266,4,471,79,40,33,629,102,14 }, 
595 { 7,92,16,232,97,140,126,14,60,107,66,35,298,387,314,104,246,462,441,150,0,38,24,2,172,357,230,330,5,633,22,289 }, 
596 { 13,77,23,202,318,141,33,4,51,269,102,177,115,403,137,2,40,494,90,11,342,128,31,117,21,32,7,12,64,134,14,10 }, 
597 { 13,2,0,23,141,1,77,3,180,33,6,64,15,10,115,51,4,5,217,197,7,165,515,102,22,11,700,269,40,352,177,14 }, 
598 { 15,515,700,753,4,11,1,93,13,5,180,110,82,21,120,23,2,33,10,141,3,165,197,102,901,0,32,341,117,40,153,12 }, 
599 { 15,515,700,753,1,13,0,2,23,4,77,51,3,5,341,291,7,33,6,115,10,9,8,217,11,177,120,180,102,165,197,365 }, 
600 { 20,43,198,325,173,904,104,234,66,147,77,319,416,422,97,426,5,0,7,450,861,202,712,725,2,32,639,376,38,324,945,315 }, 
601 { 105,0,9,28,49,301,170,1,127,159,22,16,31,98,512,623,24,109,158,395,35,68,371,65,713,55,2,242,293,21,44,18 }, 
602 { 213,88,689,466,230,30,321,435,699,352,217,201,795,831,144,854,1,443,96,539,530,840,418,251,855,190,93,100,669,31,957,662 }, 
603 { 130,453,47,196,4,57,14,59,236,711,51,153,730,77,412,381,23,202,108,128,361,13,283,117,11,719,200,46,34,78,210,2 }, 
604 { 1,2,5,14,0,50,36,22,38,46,65,67,12,86,114,28,103,29,208,7,10,128,21,83,218,23,96,54,194,6,133,51 }, 
605 { 6,26,74,19,165,453,14,730,1,125,197,50,29,51,138,357,13,2,108,391,70,719,46,457,47,500,386,262,112,23,235,52 }, 
606 { 9,10,376,20,43,0,49,18,30,120,2,33,325,104,501,470,77,788,725,102,523,39,858,5,904,414,174,55,137,37,342,13 }, 
607 { 15,515,700,753,0,1,13,23,51,77,120,202,341,82,5,4,9,260,2,137,141,128,115,351,901,8,180,10,197,21,450,33 }, 
608 { 105,131,272,578,9,49,371,219,159,616,286,320,224,187,716,98,28,22,0,623,127,258,910,737,385,31,239,347,254,109,424,95 }, 
609 { 457,51,13,23,961,12,719,99,453,15,4,515,165,401,629,3,700,11,17,14,2,37,753,41,57,569,38,45,0,33,5,32 }, 
610 { 202,120,5,33,318,77,450,102,1,260,403,128,494,21,165,13,269,12,326,23,342,523,402,2,817,64,15,141,125,82,457,475 }, 
611 { 141,269,352,217,180,64,349,137,202,160,317,15,372,515,700,752,318,753,244,13,437,291,165,864,22,237,5,82,954,21,77,418 }, 
612 { 70,29,2,145,74,112,26,6,75,52,19,66,632,1,87,220,5,135,163,287,307,25,226,7,58,396,294,278,113,409,69,151 }, 
613 { 82,351,317,15,752,180,898,352,141,901,515,341,10,700,365,1,753,498,0,217,253,115,55,854,33,5,143,32,21,160,36,197 }, 
614 { 39,9,310,254,0,30,101,49,252,272,100,265,105,455,159,557,190,333,286,688,18,166,1,158,709,16,625,627,31,131,327,329 }, 
615 { 2,58,29,5,1,151,186,52,70,45,7,549,14,75,112,400,113,155,61,46,227,163,311,315,66,6,307,27,17,220,287,74 }, 
616 { 141,217,13,21,352,23,269,77,180,115,317,64,202,15,349,137,5,51,165,291,318,752,372,4,0,102,33,365,197,32,341,125 }, 
617 { 68,35,0,9,65,101,149,124,24,154,175,16,28,7,67,1,18,189,114,398,55,14,345,39,118,133,69,2,230,429,71,283 }, 
618 { 66,7,29,2,112,52,20,43,97,151,74,192,135,5,173,525,337,45,145,58,415,25,14,32,644,70,544,226,222,21,6,580 }, 
619 { 31,125,44,22,116,299,242,55,1,170,64,36,479,870,456,685,10,599,558,0,268,506,28,740,23,903,492,164,393,206,2,86 }, 
620 { 188,11,79,12,99,377,94,33,542,339,40,474,111,37,4,51,102,453,139,775,13,475,23,961,277,471,134,57,431,266,115,117 }, 
621 { 658,698,340,98,296,303,1,31,850,363,156,919,44,774,586,385,120,77,82,10,223,30,354,291,23,914,478,87,260,163,48,13 }, 
622 { 15,515,700,753,82,4,1,13,901,33,197,11,5,10,23,165,2,0,180,3,21,77,51,120,365,115,217,40,117,102,32,401 }, 
623 { 15,515,700,753,4,11,5,13,1,141,3,180,23,202,21,2,269,64,165,33,40,32,0,318,120,128,12,197,117,352,51,17 }, 
624 { 91,6,233,85,370,718,81,65,25,256,63,343,42,74,235,123,138,511,397,249,26,194,650,355,64,87,544,18,90,643,66,214 }, 
625 { 23,13,202,51,21,120,1,5,141,128,450,64,318,403,15,137,260,33,12,48,32,31,125,494,269,102,165,515,77,2,197,14 }, 
626 { 180,317,365,341,752,217,115,352,901,482,372,498,1,141,15,253,515,244,2,700,0,21,13,82,23,4,579,351,753,291,269,77 }, 
627 { 13,115,197,341,9,352,468,237,64,498,23,165,22,509,901,546,482,180,28,569,317,51,365,873,391,95,86,217,49,837,752,706 }, 
628 { 13,23,51,1,141,5,165,202,21,120,64,125,180,15,2,33,197,115,128,32,260,269,12,82,4,515,137,7,318,93,0,700 }, 
629 { 214,289,90,174,874,6,138,280,65,81,64,85,355,751,194,233,312,348,835,91,0,32,343,636,249,29,875,288,519,104,247,74 }, 
630 { 15,515,700,753,4,5,11,13,1,33,23,21,2,3,102,32,141,77,180,117,31,64,0,40,134,196,120,352,12,44,197,6 }, 
631 { 33,15,13,515,117,23,700,217,134,753,0,51,153,77,141,2,4,64,196,1,3,180,10,115,5,102,6,11,22,202,165,7 }, 
632 { 15,515,700,753,33,4,77,102,1,40,13,117,11,115,134,5,21,153,23,217,3,32,2,317,120,196,180,141,51,12,59,260 }, 
633 { 15,515,700,753,13,0,1,23,2,217,51,3,4,5,8,317,115,9,341,10,202,180,6,365,7,82,457,22,120,901,33,291 }, 
634 { 7,2,135,20,97,14,66,52,337,673,192,29,43,355,353,5,16,294,107,376,147,226,331,560,64,470,222,104,415,32,4,324 }, 
635 { 195,132,142,167,146,77,363,271,121,354,202,120,647,178,786,212,687,0,101,878,16,522,60,5,450,411,35,55,98,639,259,318 }, 
636 { 202,77,20,0,318,66,104,128,102,269,177,43,33,7,216,291,494,5,2,342,74,173,97,112,450,22,337,10,234,52,64,678 }, 
637 { 107,362,612,356,359,97,414,43,259,20,392,7,298,147,819,683,465,173,729,660,319,14,5,779,581,595,246,35,501,92,0,230 }, 
638 { 6,165,14,453,13,51,19,23,386,457,74,391,308,2,26,401,47,758,603,108,719,366,1,29,309,730,324,197,133,70,115,867 }, 
639 { 179,72,205,180,247,245,4,490,352,59,317,152,79,498,94,217,148,76,752,864,11,216,141,405,89,452,197,111,497,188,37,21 }, 
640 { 107,7,298,314,14,359,32,392,232,279,172,97,60,581,387,126,121,0,534,493,356,92,441,95,13,21,35,147,22,5,16,362 }, 
641 { 156,271,354,586,360,132,591,195,121,18,340,1,5,13,21,48,668,446,23,463,296,658,60,55,407,698,146,70,626,51,163,24 }, 
642 { 13,23,51,4,0,12,457,15,11,453,2,515,5,1,99,10,115,165,700,475,401,403,3,961,40,14,37,753,719,32,64,569 }, 
643 { 48,125,21,165,13,221,23,763,423,508,197,5,98,92,193,16,441,386,64,314,293,457,391,140,49,60,102,693,683,51,35,867 }, 
644 { 202,77,120,450,5,318,1,494,0,195,18,132,523,403,326,604,354,260,121,576,203,167,234,817,682,49,35,615,21,20,13,102 }, 
645 { 39,9,166,30,0,101,158,68,404,190,333,274,252,310,88,100,49,28,344,35,21,22,419,131,438,1,16,65,530,694,124,10 }, 
646 { 15,515,700,753,110,4,1,11,165,180,93,13,82,5,2,197,33,120,0,3,10,23,21,115,901,217,341,77,317,51,32,117 }, 
647 { 2,29,1,14,6,52,5,46,50,26,70,19,103,58,38,67,96,262,516,309,218,133,108,27,75,17,112,114,24,487,331,83 }, 
648 { 120,77,15,13,1,141,260,23,515,217,110,51,137,700,317,202,165,291,180,21,753,128,0,177,326,93,450,82,64,269,197,5 }, 
649 { 255,59,554,297,183,56,33,444,108,358,123,196,269,122,77,153,57,177,117,730,19,467,605,130,128,50,275,4,291,475,134,133 }, 
650 { 13,23,51,12,153,14,117,120,165,134,99,401,38,453,15,128,197,719,64,515,475,403,37,33,196,700,40,125,5,0,54,2 }, 
651 { 64,33,174,348,95,108,467,554,56,0,25,306,233,6,63,511,343,120,13,85,29,561,543,707,319,180,899,355,77,49,256,18 }, 
652 { 120,260,51,23,77,15,202,1,93,82,141,450,13,326,515,137,21,5,64,33,110,700,128,165,318,203,269,102,351,753,197,125 }, 
653 { 15,515,700,753,4,13,11,1,5,21,23,2,33,64,3,180,32,141,22,102,77,0,10,93,82,352,117,40,341,31,165,6 }, 
654 { 15,515,700,753,341,13,23,141,33,1,0,217,4,77,180,10,82,351,51,137,5,64,9,317,21,11,102,40,260,202,854,115 }, 
655 { 105,272,131,22,327,286,28,239,320,9,109,578,219,49,98,224,95,159,538,371,616,127,187,64,713,55,0,170,168,258,716,623 }, 
656 { 16,18,68,35,24,60,71,118,92,126,0,9,101,191,7,55,154,175,212,14,167,150,302,28,375,1,107,124,346,273,21,108 }, 
657 { 20,147,43,470,376,142,904,178,427,798,0,595,198,325,858,319,61,202,173,97,5,422,14,22,107,259,32,49,887,77,414,392 }, 
658 { 13,23,51,12,33,15,99,64,128,515,453,202,117,153,37,102,700,40,134,196,120,0,2,753,141,14,38,3,82,403,77,21 }, 
659 { 383,17,62,136,84,119,56,440,3,504,240,80,378,129,123,548,106,128,4,11,14,555,162,32,184,361,59,64,205,5,469,57 }, 
660 { 70,1,48,652,5,638,846,888,21,349,269,260,340,562,767,761,163,883,774,141,125,518,591,0,23,9,87,13,371,303,622,31 }, 
661 { 66,135,6,97,74,278,69,7,14,324,267,172,2,140,462,1,357,38,808,550,92,841,189,29,16,25,298,87,75,204,24,335 }, 
662 { 51,23,33,13,102,40,12,128,64,77,10,202,0,196,117,4,14,99,134,453,65,153,11,475,139,403,22,141,86,2,21,15 }, 
663 { 88,100,264,166,274,435,772,1,382,921,96,478,30,438,639,909,897,521,190,466,960,410,9,144,530,418,31,329,265,691,778,93 }, 
664 { 62,440,136,56,84,3,504,548,555,383,4,17,129,128,507,361,123,59,119,162,14,57,152,328,161,11,202,495,184,27,80,215 }, 
665 { 911,617,332,959,206,141,253,244,282,384,110,120,10,260,352,143,951,811,269,373,160,417,93,531,728,203,434,940,137,55,36,717 }, 
666 { 120,15,260,141,77,1,515,82,700,351,33,23,450,13,110,326,64,217,269,753,203,137,102,5,165,21,51,291,93,177,373,128 }, 
667 { 15,515,700,753,0,1,2,23,13,51,5,9,82,901,180,8,3,4,120,6,7,141,93,12,197,341,10,33,115,730,64,125 }, 
668 { 7,104,97,107,356,232,66,560,298,289,14,707,38,568,359,64,20,0,65,324,22,214,92,32,192,5,387,43,712,90,172,95 }, 
669 { 6,1,2,66,67,14,74,24,108,29,69,83,458,7,25,38,135,103,36,150,451,114,52,594,75,65,380,18,267,602,19,278 }, 
670 { 13,23,51,12,115,21,202,5,457,15,4,1,64,719,0,403,2,3,453,165,99,141,401,128,32,515,10,37,523,197,120,700 }, 
671 { 57,59,4,11,412,381,77,53,421,291,250,368,99,14,27,369,803,283,23,108,403,19,339,210,0,401,12,444,236,40,361,736 }, 
672 { 15,515,700,1,0,753,2,13,23,5,51,180,3,115,6,7,457,4,9,8,12,82,197,165,141,901,120,719,33,64,21,22 }, 
673 { 64,95,180,247,929,146,90,126,197,32,237,60,288,165,316,92,5,13,77,7,217,955,522,22,16,314,132,4,317,10,312,86 }, 
674 { 15,1,120,13,23,515,0,51,700,180,141,2,5,202,21,260,753,165,137,33,77,110,197,128,326,7,450,4,102,9,269,12 }, 
675 { 14,2,16,46,1,7,24,69,75,35,38,50,29,220,52,140,267,67,18,54,70,309,5,60,92,189,171,87,71,163,58,0 }, 
676 { 31,98,127,44,9,299,0,276,293,284,116,49,935,599,105,22,456,201,28,1,39,125,242,137,371,144,131,492,159,272,51,395 }, 
677 { 6,27,151,53,573,445,297,113,26,73,436,19,491,250,396,315,45,112,145,58,614,881,25,34,611,200,17,80,70,5,138,631 }, 
678 { 32,693,81,788,90,804,403,56,494,21,84,397,202,65,18,77,64,681,214,725,523,784,526,33,102,825,240,0,115,241,817,91 }, 
679 { 24,7,14,2,18,16,65,0,108,149,28,69,1,71,154,36,124,35,67,140,189,429,92,68,66,22,55,118,302,150,9,6 }, 
680 { 0,68,9,35,65,101,189,212,114,67,124,69,1,154,149,39,230,64,252,16,88,702,103,100,18,336,28,329,520,83,30,755 }, 
681 { 5,2,186,29,61,45,17,1,52,48,58,171,155,227,80,209,311,21,14,46,50,106,243,513,334,502,496,38,3,6,32,592 }, 
682 { 15,515,700,753,13,1,2,0,3,4,5,23,341,11,10,33,6,51,165,117,153,7,180,12,365,901,77,569,197,115,64,9 }, 
683 { 13,15,23,515,0,51,1,700,4,2,753,10,3,5,12,77,33,961,165,457,197,11,115,9,22,102,40,403,202,21,14,59 }, 
684 { 15,515,700,753,13,0,1,23,2,33,102,5,4,10,9,3,51,115,77,7,6,341,12,11,217,40,457,196,180,165,8,523 }, 
685 { 166,39,30,274,190,100,333,438,530,310,88,252,0,9,539,265,1,656,404,101,625,131,778,254,31,455,676,329,724,158,21,23 }, 
686 { 734,148,94,308,431,115,37,89,111,413,79,468,197,629,341,474,569,12,13,873,179,401,11,4,180,23,205,72,59,365,134,51 }, 
687 { 539,228,224,219,816,190,30,258,871,840,669,93,406,530,957,187,160,531,748,137,131,88,863,36,728,839,44,213,352,116,202,466 }, 
688 { 393,791,125,801,730,551,386,23,31,175,93,98,51,13,144,788,126,203,21,345,116,22,949,110,575,165,326,44,0,4,60,221 }, 
689 { 13,23,77,141,0,4,51,2,33,115,64,1,10,3,6,15,11,102,7,217,180,40,515,22,128,177,202,9,700,269,165,5 }, 
690 { 2,29,7,70,52,14,1,58,112,46,75,5,171,163,87,220,307,151,186,334,38,66,155,16,69,135,278,45,262,97,6,21 }, 
691 { 88,321,213,100,230,435,689,466,1,382,30,352,217,699,410,96,795,36,921,752,190,141,144,180,44,831,317,83,443,31,840,251 }, 
692 { 363,411,101,520,354,9,195,668,132,156,447,1,905,364,18,23,765,664,146,5,360,13,121,96,98,31,252,39,100,759,264,551 }, 
693 { 13,23,51,730,12,719,453,457,401,475,5,21,403,2,0,1,15,4,3,899,99,32,165,11,515,308,197,115,6,961,700,523 }, 
694 { 72,76,89,12,37,4,308,179,38,528,90,431,54,205,148,184,401,57,152,474,23,59,51,245,428,11,32,99,405,316,257,21 }, 
695 { 376,20,43,147,470,173,97,595,107,319,414,142,819,5,729,178,858,7,427,32,426,104,14,0,392,362,259,61,230,77,560,246 }, 
696 { 202,141,269,494,318,137,51,128,403,4,217,96,77,5,64,177,291,180,15,352,102,10,33,349,2,317,0,341,120,515,21,453 }, 
697 { 77,202,33,128,102,318,494,269,13,0,117,23,342,291,403,15,134,51,153,141,177,515,82,137,196,700,203,64,22,351,753,4 }, 
698 { 253,110,951,352,499,811,10,854,180,638,244,559,642,752,564,8,141,143,417,341,901,260,206,197,922,661,93,15,498,373,165,911 }, 
699 { 141,13,23,180,4,217,5,1,269,317,21,0,2,202,115,51,352,77,3,197,64,341,318,15,291,9,137,93,32,165,515,33 }, 
700 { 9,0,18,252,16,101,68,39,24,118,35,109,158,329,28,167,60,364,333,265,49,100,22,419,553,55,1,677,71,7,212,159 }, 
701 { 28,109,9,39,0,158,49,22,168,35,55,175,1,65,67,185,194,159,289,95,272,114,30,105,86,584,36,169,254,2,83,24 }, 
702 { 15,515,13,700,1,753,2,23,0,3,4,5,33,341,11,51,6,10,197,115,901,180,77,40,102,12,365,165,141,217,7,317 }, 
703 { 173,693,104,422,5,18,61,32,102,0,20,13,784,560,33,66,397,526,49,207,29,25,510,707,65,6,11,344,21,263,81,77 }, 
704 { 23,13,386,51,308,801,719,221,401,949,21,730,165,421,102,115,125,33,341,670,468,117,770,1,120,6,197,14,403,97,67,958 }, 
705 { 0,49,105,16,28,24,159,9,158,320,1,68,35,239,170,18,109,7,55,65,2,95,301,124,347,14,21,154,22,127,286,31 }, 
706 { 2,5,1,207,45,29,32,58,76,61,6,263,292,655,72,14,17,476,7,119,52,306,70,64,21,90,186,214,106,38,3,790 }, 
707 { 21,6,125,49,13,64,715,66,115,95,197,33,22,32,204,165,56,278,0,408,241,120,4,808,681,350,263,85,81,571,135,509 }, 
708 { 612,427,325,107,202,5,376,49,64,392,403,470,21,147,31,788,494,14,362,465,858,98,20,804,518,43,845,318,125,97,725,534 }, 
709 { 32,21,76,72,2,1,14,5,241,449,89,38,350,221,155,48,50,292,37,46,45,90,270,54,17,179,214,12,148,430,476,413 }, 
710 { 24,0,28,16,7,124,35,154,14,149,65,18,9,68,55,108,175,71,2,1,22,109,92,67,484,336,118,69,302,398,570,420 }, 
711 { 1,5,14,2,48,50,38,67,46,21,0,54,45,270,281,12,24,32,155,96,513,103,290,83,61,58,36,17,37,72,69,181 }, 
712 { 13,961,569,197,37,15,23,474,515,94,148,111,12,165,629,341,700,79,901,401,51,405,753,10,134,4,115,734,873,11,89,117 }, 
713 { 33,23,102,51,13,40,77,128,64,202,141,15,4,12,0,1,2,117,22,11,10,403,153,515,99,318,137,269,139,196,700,134 }, 
714 { 0,1,24,67,9,16,18,35,28,69,103,50,5,2,65,12,83,68,7,96,14,22,21,149,75,114,13,133,23,71,218,54 }, 
715 { 384,617,940,332,855,911,206,959,434,282,141,10,93,253,244,110,144,268,120,36,352,137,417,203,116,31,44,269,160,201,143,951 }, 
716 { 30,93,473,137,31,704,450,652,190,203,800,254,166,274,326,144,269,160,127,303,120,625,88,848,110,435,77,521,349,131,340,744 }, 
717 { 53,27,73,26,19,250,297,200,25,630,17,6,611,122,34,42,714,235,472,65,436,14,80,684,690,106,45,113,680,108,64,4 }, 
718 { 15,515,1,2,700,0,753,3,5,141,180,4,13,77,33,10,217,6,7,134,11,352,197,64,165,341,317,23,12,115,102,40 }, 
719 { 254,530,39,613,688,221,30,31,438,190,228,960,1,44,141,21,180,406,23,166,9,202,13,96,137,48,131,829,317,269,393,51 }, 
720 { 9,39,28,35,30,166,158,36,0,175,101,346,364,67,49,68,168,420,88,1,194,131,100,352,55,83,190,64,137,570,86,65 }, 
721 { 62,56,3,548,555,507,440,161,34,4,215,136,162,514,361,527,17,14,211,130,328,11,383,123,84,183,38,57,184,152,205,494 }, 
722 { 92,126,107,7,356,493,97,279,359,298,16,246,35,60,14,441,362,121,43,423,5,132,392,20,508,230,199,146,232,173,150,414 }, 
723 { 15,82,141,515,291,922,349,700,217,260,372,120,351,93,77,753,318,352,373,854,1,326,269,21,13,102,144,202,64,23,203,137 }, 
724 { 141,217,352,115,180,13,269,317,752,77,23,21,341,197,5,372,244,291,9,64,51,102,4,1,365,2,165,33,3,48,237,351 }, 
725 { 78,47,390,19,130,453,108,27,711,813,730,444,412,283,196,690,123,14,128,26,250,389,650,236,200,65,51,4,34,183,297,73 }, 
726 { 34,250,297,80,472,64,495,17,311,3,148,45,667,61,176,53,243,27,90,161,469,141,483,151,62,128,29,4,58,56,5,231 }, 
727 { 51,23,33,13,551,77,102,326,421,21,523,120,5,899,453,692,202,153,308,615,115,958,450,401,791,68,221,93,475,18,403,4 }, 
728 { 98,223,393,363,411,1,478,834,664,156,284,691,447,791,914,293,354,724,697,9,807,541,759,51,18,421,48,264,948,586,195,848 }, 
729 { 7,14,107,232,16,92,2,60,46,5,359,121,24,526,220,620,135,1,172,21,126,314,132,77,18,75,32,278,12,23,52,38 }, 
730 { 32,76,2,1,21,72,241,14,5,48,292,89,476,45,720,270,179,90,17,214,148,38,50,29,129,155,350,46,290,227,123,464 }, 
731 { 15,515,700,753,13,23,33,77,51,4,102,0,32,202,1,11,128,82,117,141,40,5,110,8,3,90,137,21,10,318,403,165 }, 
732 { 66,6,69,2,1,74,14,135,278,267,380,24,29,97,67,38,103,75,7,388,324,25,52,150,87,83,189,357,335,108,204,172 }, 
733 { 152,4,339,59,79,471,188,11,77,94,128,33,529,377,12,111,102,202,452,402,216,99,13,542,51,40,474,37,64,291,23,961 }, 
734 { 15,515,700,753,1,0,196,13,33,2,77,5,23,102,3,10,9,7,217,4,6,153,117,177,14,457,115,12,40,730,11,134 }, 
735 { 17,209,45,106,207,5,255,119,62,2,61,3,263,742,306,655,425,378,32,56,29,136,84,80,311,58,186,240,243,383,14,21 }, 
736 { 120,260,450,15,1,23,817,13,515,523,326,5,700,51,82,31,202,64,21,753,318,93,32,269,98,33,351,77,102,125,457,165 }, 
737 { 116,492,268,93,23,206,203,0,551,918,13,51,8,22,417,940,120,10,499,31,949,791,125,523,165,473,341,730,421,959,401,391 }, 
738 { 15,515,700,753,165,13,0,1,197,23,4,82,120,2,180,12,260,719,8,3,386,117,5,523,901,11,341,51,10,9,141,351 }, 
739 { 14,24,69,7,2,66,108,1,67,6,36,398,18,267,150,97,29,38,83,149,65,74,28,0,189,71,388,16,273,124,46,22 }, 
740 { 330,96,523,335,367,662,141,839,1,922,372,615,244,717,269,443,418,352,403,692,217,854,752,180,36,64,498,576,349,201,98,284 }, 
741 { 184,90,257,205,245,229,57,152,769,17,524,5,32,497,45,432,619,2,452,266,4,106,1,21,179,59,76,3,460,292,381,128 }, 
742 { 7,14,16,2,46,5,70,107,87,13,58,307,92,32,38,23,202,0,172,24,18,21,60,128,77,35,20,10,9,4,171,112 }, 
743 { 7,66,140,16,14,92,97,69,267,172,189,24,380,2,35,60,298,451,230,135,314,74,150,71,38,357,6,330,67,423,21,443 }, 
744 { 121,167,354,132,18,446,147,101,212,146,407,16,55,35,647,191,20,271,199,68,60,259,463,107,9,126,363,7,195,43,14,411 }, 
745 { 76,90,179,32,205,21,184,460,257,288,45,245,316,5,57,152,241,2,358,1,229,72,524,148,48,769,17,4,12,38,14,720 }, 
746 { 147,259,178,878,427,465,581,198,786,798,142,534,325,929,20,362,35,132,107,376,43,5,279,77,49,146,70,202,590,771,33,14 }, 
747 { 473,93,450,778,141,30,855,466,144,203,330,530,88,523,459,372,201,617,839,704,254,321,934,326,39,36,82,717,332,213,559,403 }, 
748 { 523,475,51,899,730,453,23,719,403,33,457,13,421,386,4,120,117,196,102,153,15,801,450,817,515,260,202,11,700,99,165,125 }, 
749 { 15,1,13,515,0,2,700,5,23,753,4,3,341,317,10,115,180,11,33,64,217,77,117,165,197,7,6,365,9,141,102,134 }, 
750 { 19,4,119,40,33,202,27,84,102,56,77,73,504,485,26,494,757,63,862,59,23,300,25,12,128,11,5,13,342,880,469,6 }, 
751 { 32,20,2,13,5,21,23,6,12,38,43,29,64,7,95,51,61,207,48,147,90,178,17,182,49,0,115,202,52,362,37,22 }, 
752 { 339,188,11,79,4,94,377,12,99,111,542,102,37,33,474,51,471,40,453,152,77,13,59,403,342,23,117,57,475,134,128,38 }, 
753 { 34,128,283,176,495,231,318,432,503,275,529,527,161,53,3,202,56,291,585,469,73,17,14,412,57,27,80,245,250,381,402,51 }, 
754 { 15,515,13,700,1,217,141,120,23,180,753,115,365,51,317,341,77,260,0,291,110,137,202,5,21,269,64,36,349,2,4,10 }, 
755 { 13,15,961,515,700,753,4,12,2,457,3,11,197,51,37,569,115,23,5,0,99,10,1,134,6,111,165,33,72,40,38,79 }, 
756 { 15,515,700,753,13,1,0,2,23,33,5,3,10,4,9,115,7,102,6,51,12,217,77,11,40,457,569,341,117,317,14,719 }, 
757 { 5,76,2,32,292,214,45,1,129,519,123,179,90,710,17,29,460,72,14,207,21,249,58,205,464,263,618,48,6,245,3,257 }, 
758 { 72,76,32,4,21,12,38,23,99,54,89,3,14,17,51,57,11,90,13,488,179,2,59,148,45,37,5,115,401,1,10,421 }, 
759 { 98,223,393,1,834,264,284,791,724,293,478,772,697,909,363,682,905,447,541,821,411,51,421,9,807,48,765,31,730,96,386,410 }, 
760 { 341,13,509,8,23,638,165,901,762,10,569,242,391,197,873,642,506,499,629,961,15,180,116,456,206,546,417,1,338,457,515,867 }, 
761 { 1,2,5,50,14,38,46,114,0,36,29,22,218,65,86,96,137,21,133,285,12,10,323,181,17,58,51,23,67,7,28,6 }, 
762 { 481,878,202,13,5,23,182,32,269,21,1,318,77,142,557,494,141,33,640,137,70,291,2,51,260,415,929,403,120,58,4,259 }, 
763 { 15,515,700,753,1,4,13,0,2,5,341,3,11,180,134,12,10,317,197,365,33,21,23,165,117,6,77,7,217,37,32,498 }, 
764 { 25,119,19,6,26,42,27,17,4,790,45,814,2,469,483,84,122,1,0,33,32,128,76,80,611,113,73,56,5,240,202,77 }, 
765 { 14,2,7,1,24,0,65,6,16,69,67,22,124,28,108,5,18,36,86,10,38,46,66,398,289,168,12,83,21,23,610,13 }, 
766 { 51,23,128,13,15,202,12,120,33,64,141,82,10,515,0,403,700,3,1,99,117,269,153,165,753,5,318,197,102,260,2,137 }, 
767 { 16,35,24,0,9,18,7,1,68,69,50,71,103,65,67,189,133,23,28,13,60,537,149,335,75,21,64,5,114,2,12,14 }, 
768 { 754,803,133,576,880,543,2,1,657,50,14,38,46,5,29,67,218,36,58,171,52,96,24,103,775,0,114,83,181,54,65,45 }, 
769 { 21,32,5,3,2,17,14,72,76,1,12,23,38,51,4,54,10,0,89,13,99,137,45,36,421,115,543,11,22,128,221,48 }, 
770 { 434,384,268,144,855,940,617,206,332,116,93,911,959,282,203,137,141,489,44,120,10,110,244,36,98,31,269,253,367,417,160,9 }, 
771 { 15,2,1,0,13,515,5,700,3,23,180,217,141,10,753,4,117,6,77,33,64,7,11,197,352,317,341,134,165,115,12,9 }, 
772 { 2,113,6,25,1,0,29,4,7,833,5,45,32,61,128,19,77,151,74,145,64,42,14,210,655,106,59,177,27,17,21,738 }, 
773 { 116,268,918,203,551,31,8,692,206,791,403,499,417,93,940,421,0,23,22,120,13,523,44,51,299,473,959,1,10,475,202,125 }, 
774 { 107,126,132,612,362,279,20,146,259,493,199,121,590,43,660,147,35,376,939,60,941,534,683,5,0,953,16,7,49,649,595,470 }, 
775 { 15,515,700,753,13,1,0,23,2,33,77,4,3,51,5,102,115,10,9,341,6,7,11,342,217,12,120,180,40,317,141,8 }, 
776 { 53,27,17,161,469,378,73,527,19,136,383,250,495,56,862,26,62,84,80,106,200,4,34,14,440,297,3,128,585,5,129,123 }, 
777 { 17,45,209,106,5,207,243,454,119,255,2,263,186,290,29,3,21,62,425,61,84,32,58,56,48,408,655,136,306,14,742,227 }, 
778 { 4,152,59,452,128,79,216,11,339,471,529,188,94,77,202,12,291,33,318,377,99,51,23,5,402,349,32,474,102,13,205,111 }, 
779 { 15,515,700,753,1,0,2,13,3,5,23,4,180,51,115,9,6,12,7,8,197,33,10,961,901,77,141,752,110,22,120,341 }, 
780 { 951,752,638,811,351,642,180,253,10,341,197,901,110,873,8,244,15,352,165,898,143,515,564,762,499,55,365,700,82,753,141,854 }, 
781 { 6,262,197,350,74,26,115,509,841,583,165,38,21,13,47,50,235,19,33,324,453,4,308,196,138,99,64,903,675,1,223,130 }, 
782 { 125,165,391,23,386,221,21,13,558,457,51,867,197,115,401,758,77,97,308,791,7,180,48,120,963,451,743,89,603,134,403,450 }, 
783 { 1,14,2,5,16,46,7,38,58,24,50,0,69,48,35,67,54,18,12,75,21,45,513,155,430,37,270,9,61,163,223,32 }, 
784 { 23,13,51,0,12,15,4,1,115,2,515,453,10,457,5,3,202,21,165,700,403,11,37,64,77,401,9,197,753,59,475,99 }, 
785 { 129,84,17,56,27,495,19,548,80,123,162,378,3,504,161,469,618,73,40,53,4,26,205,184,106,183,62,6,257,128,862,12 }, 
786 { 28,9,22,49,109,1,67,0,39,55,168,158,83,36,35,86,420,194,185,159,95,105,69,208,272,103,50,114,2,254,169,30 }, 
787 { 242,391,8,456,116,13,23,492,341,165,867,51,499,457,479,638,338,509,719,10,1,642,417,762,401,93,206,268,901,569,22,197 }, 
788 { 211,162,248,130,57,4,41,556,507,266,183,152,305,361,11,129,62,229,38,471,514,313,157,300,377,3,440,128,123,328,339,59 }, 
789 { 7,92,97,16,298,140,60,126,14,35,279,314,232,246,43,230,508,173,71,107,423,24,150,779,20,189,66,18,607,21,0,653 }, 
790 { 15,515,700,753,1,0,2,13,23,5,3,180,51,901,6,4,7,12,9,115,8,457,165,82,120,197,10,64,141,341,22,117 }, 
791 { 0,18,403,25,523,74,6,24,42,91,22,102,13,51,49,193,475,681,95,85,730,64,899,397,273,750,247,673,32,805,757,288 }, 
792 { 56,0,18,65,33,554,84,343,64,6,90,561,22,19,899,108,27,63,289,475,240,467,370,32,233,214,24,123,95,287,28,194 }, 
793 { 31,98,127,9,0,44,293,105,395,299,49,242,28,22,599,116,1,284,276,125,456,685,763,159,272,623,23,935,393,144,201,137 }, 
794 { 1,5,2,14,38,46,50,48,21,7,58,45,270,61,155,171,0,290,69,32,29,54,67,16,24,666,663,17,37,75,502,52 }, 
795 { 23,51,13,453,457,12,719,4,15,99,401,2,961,3,11,730,475,515,0,1,165,115,629,700,14,17,403,40,5,33,37,64 }, 
796 { 968,967,966,965,964,963,962,961,960,959,958,957,956,955,954,953,952,951,950,949,948,947,946,945,944,943,942,941,940,939,938,937 }, 
797 { 2,1,14,29,67,103,6,46,52,75,24,133,38,218,83,309,36,108,70,114,96,5,238,74,25,26,220,236,65,50,69,87 }, 
798 { 7,71,16,92,24,60,14,97,150,140,35,189,149,298,18,230,43,508,2,423,69,0,38,314,66,279,399,517,251,20,232,273 }, 
799 { 23,1,120,51,13,202,77,141,260,21,15,5,128,82,2,450,269,165,102,318,48,32,137,515,125,64,12,115,351,180,33,7 }, 
800 { 77,13,33,23,64,51,4,102,141,128,40,1,2,202,0,6,177,115,137,15,59,10,11,7,269,22,515,180,318,3,700,95 }, 
801 { 101,9,18,363,264,520,411,604,676,682,905,271,16,821,167,0,621,364,39,100,121,118,166,781,647,252,1,848,447,265,404,60 }, 
802 { 144,203,326,382,166,418,93,88,96,822,1,141,859,77,744,438,110,269,921,367,521,274,100,39,494,120,403,473,217,576,13,291 }, 
803 { 13,21,180,125,5,23,191,32,18,16,146,199,115,24,165,118,0,225,22,1,60,197,64,901,375,241,48,12,408,71,522,818 }, 
804 { 15,515,700,753,13,0,23,8,1,51,82,102,2,33,4,9,180,165,5,77,10,110,12,197,120,260,18,326,351,403,22,457 }, 
805 { 33,77,102,64,13,23,128,51,141,202,1,40,0,2,117,10,15,4,6,318,269,134,22,515,180,115,177,153,137,196,3,700 }, 
806 { 174,544,104,525,74,0,151,25,6,624,29,66,2,636,81,45,204,177,64,416,7,644,5,138,222,319,355,77,22,122,789,216 }, 
807 { 141,304,372,352,291,947,177,269,128,954,77,349,217,202,64,318,498,437,102,864,86,13,115,180,137,5,210,197,32,950,678,7 }, 
808 { 161,200,53,17,714,27,34,73,472,62,585,56,440,383,136,78,527,19,4,3,106,361,14,250,80,514,377,84,322,390,862,548 }, 
809 { 32,76,72,21,38,14,89,54,12,37,2,241,5,428,17,1,181,221,350,45,3,4,449,90,148,179,99,292,794,770,477,46 }, 
810 { 33,23,128,64,141,13,77,51,102,202,2,15,1,3,40,10,5,153,269,515,165,0,117,196,180,318,6,700,137,134,120,22 }, 
811 { 96,137,30,0,9,39,840,202,669,406,141,530,613,1,180,88,22,160,679,576,28,403,31,219,49,228,829,100,36,15,10,856 }, 
812 { 180,141,352,1,15,752,115,0,217,365,2,515,13,901,341,317,23,4,197,700,269,5,3,31,753,244,21,165,253,202,51,44 }, 
813 { 1,2,67,0,28,50,83,65,14,46,103,114,24,38,36,9,69,5,18,7,22,133,55,218,16,124,29,54,96,160,12,480 }, 
814 { 180,115,352,317,365,217,752,901,141,15,341,1,515,253,700,0,753,873,2,197,31,137,165,244,4,120,160,44,98,5,202,3 }, 
815 { 5,32,347,49,13,21,95,713,23,1,77,33,60,64,107,4,126,928,296,850,0,241,197,102,652,195,180,534,165,153,379,10 }, 
816 { 341,180,365,901,317,115,15,752,515,700,217,873,753,82,0,110,197,141,951,165,1,564,13,351,253,12,10,3,2,4,308,244 }, 
817 { 17,45,21,3,106,5,155,38,227,32,2,209,62,54,12,243,14,181,552,587,46,540,207,794,37,48,430,119,255,221,770,29 }, 
818 { 16,24,35,18,7,0,50,1,9,14,75,69,2,5,12,21,60,13,67,71,23,48,10,108,223,181,189,103,46,64,92,51 }, 
819 { 127,13,98,165,308,23,286,293,258,51,219,395,197,115,301,401,31,391,22,105,457,170,239,276,55,338,629,116,180,479,509,569 }, 
820 { 539,213,748,840,957,669,30,466,88,217,144,251,863,190,137,93,230,228,679,352,317,203,617,321,258,530,160,219,96,831,816,689 }, 
821 { 5,48,1,21,2,14,0,36,12,38,32,54,430,181,50,270,72,99,281,45,17,10,46,22,37,218,67,3,290,76,23,51 }, 
822 { 13,23,0,4,33,51,2,115,141,1,77,217,180,10,9,317,3,102,11,5,15,197,7,202,22,165,40,64,515,6,341,31 }, 
823 { 13,15,117,515,23,12,37,134,165,700,38,54,457,753,51,64,153,197,14,10,33,82,961,0,99,89,115,719,141,3,4,1 }, 
824 { 5,21,2,3,1,32,14,12,48,17,0,10,51,23,38,22,4,72,13,54,36,45,137,76,99,114,86,37,11,64,540,430 }, 
825 { 202,128,77,318,291,33,269,102,275,141,494,342,40,678,0,177,20,210,402,7,4,5,137,6,13,450,403,32,49,120,23,22 }, 
826 { 1,2,24,14,67,46,69,50,38,103,16,18,75,35,83,29,52,96,5,108,0,7,54,71,149,394,236,309,70,133,220,58 }, 
827 { 15,515,1,700,0,2,753,13,23,5,180,3,51,4,165,457,12,197,115,6,7,21,9,141,8,901,33,82,120,77,10,110 }, 
828 { 0,28,65,14,67,2,124,24,1,9,7,69,55,154,36,16,46,114,175,35,83,22,429,18,109,149,68,189,108,336,251,133 }, 
829 { 56,162,403,3,129,775,99,161,17,40,527,33,880,4,14,128,475,12,548,23,102,202,361,117,34,184,383,200,183,196,64,53 }, 
830 { 151,2,29,58,112,45,186,113,5,70,52,1,311,6,315,66,61,7,74,27,631,17,80,87,287,243,209,227,14,491,19,869 }, 
831 { 6,1,74,2,75,29,25,66,26,70,52,138,67,324,357,42,19,220,14,85,87,108,38,451,309,103,24,69,380,135,114,65 }, 
832 { 15,515,700,13,23,0,1,120,753,51,180,2,260,202,5,141,77,102,9,450,115,21,197,165,7,137,110,33,12,269,901,4 }, 
833 { 5,45,17,2,14,46,48,38,181,50,155,3,186,54,61,29,21,227,281,80,540,106,12,400,52,1,58,32,328,171,209,487 }, 
834 { 16,18,265,121,158,35,60,9,39,7,329,105,252,68,24,1,132,167,159,22,0,49,286,101,21,146,23,327,120,709,5,14 }, 
835 { 108,467,283,56,389,650,123,412,33,177,899,475,216,453,269,349,619,65,51,730,403,670,23,196,523,128,84,13,401,789,503,543 }, 
836 { 514,3,11,377,328,4,361,507,57,403,14,880,130,485,176,215,236,38,152,102,211,56,62,757,54,585,300,556,34,555,40,229 }, 
837 { 3,555,62,266,130,99,507,139,514,12,152,229,215,305,57,40,440,33,403,471,38,56,475,14,361,313,775,328,196,548,123,23 }, 
838 { 120,202,318,15,77,13,1,450,33,269,515,260,5,128,494,51,23,700,102,141,40,753,326,403,817,137,523,21,177,922,342,7 }, 
839 { 15,1,515,23,0,13,700,2,51,753,180,5,165,21,197,12,3,120,115,4,141,6,9,7,457,33,386,202,82,8,31,341 }, 
840 { 15,180,515,82,351,700,10,317,753,115,217,365,141,898,33,901,13,23,110,854,752,77,1,197,4,341,143,36,64,352,102,9 }, 
841 { 104,289,66,707,214,90,712,64,97,173,20,0,414,194,874,43,32,7,568,560,65,38,426,312,715,192,376,74,835,5,324,147 }, 
842 { 84,56,0,554,63,65,453,249,123,643,18,26,847,475,511,403,416,561,524,289,370,73,9,19,45,42,719,194,27,467,33,730 }, 
843 { 21,346,13,350,308,826,197,101,352,68,570,0,165,23,9,841,115,100,509,694,221,230,35,217,569,88,124,749,1,777,212,154 }, 
844 { 16,92,7,24,60,18,35,140,126,14,50,71,46,330,2,75,246,5,121,267,571,1,230,309,220,0,9,64,146,236,54,108 }, 
845 { 82,15,515,898,365,700,180,33,341,753,77,901,10,115,55,351,21,5,1,4,13,102,36,217,2,165,752,120,197,117,11,317 }, 
846 { 16,24,35,18,69,71,140,1,103,7,189,68,0,50,9,108,2,133,60,267,230,46,149,67,167,118,92,14,75,21,191,38 }, 
847 { 60,71,16,18,7,20,43,118,35,68,375,28,608,0,175,566,154,92,14,149,628,33,22,13,2,10,279,23,107,356,55,117 }, 
848 { 187,258,871,295,201,434,219,224,489,384,268,110,261,839,44,699,93,116,36,131,141,228,144,160,940,567,244,406,137,574,98,253 }, 
849 { 66,7,97,172,192,712,232,324,204,74,43,448,387,426,568,20,526,107,104,135,356,729,173,0,22,5,32,95,2,64,500,560 }, 
850 { 15,515,700,753,1,4,0,341,13,3,134,2,5,33,11,77,12,10,23,197,365,901,7,40,217,32,21,6,51,180,961,37 }, 
851 { 0,28,24,9,35,65,16,124,68,55,109,154,7,39,22,149,158,14,175,1,49,252,18,71,2,168,289,419,108,420,67,101 }, 
852 { 7,16,14,92,2,46,140,24,220,35,38,60,75,1,50,18,87,54,5,126,29,52,278,262,314,107,71,21,172,135,330,394 }, 
853 { 7,92,16,14,172,126,2,60,140,35,135,314,278,46,24,38,232,107,330,66,5,18,150,246,230,97,52,1,121,563,279,21 }, 
854 { 6,26,235,53,297,436,27,19,25,73,113,445,90,214,65,42,64,289,250,611,624,32,45,648,614,17,85,491,34,122,200,416 }, 
855 { 352,141,1,217,854,752,351,180,244,36,110,661,82,258,816,160,295,219,567,224,230,269,922,144,260,268,93,201,137,116,489,202 }, 
856 { 16,60,35,18,126,107,68,191,92,121,7,14,598,20,493,279,167,446,118,0,28,43,463,55,24,212,375,566,9,150,575,21 }, 
857 { 15,1,515,2,4,13,0,700,3,5,23,753,341,77,51,115,33,11,180,10,197,141,6,165,7,901,102,40,9,202,217,12 }, 
858 { 23,51,13,202,21,5,1,120,15,137,128,125,32,2,12,141,33,165,64,515,403,318,700,48,180,7,6,450,115,523,475,260 }, 
859 { 131,716,224,371,219,187,737,616,385,254,9,98,105,924,31,258,836,39,127,578,49,916,44,761,272,137,944,159,0,242,442,22 }, 
860 { 15,515,700,1,753,2,5,0,4,13,3,180,11,141,197,10,341,217,33,134,165,6,77,7,317,12,352,64,365,32,102,40 }, 
861 { 66,74,7,173,174,29,192,2,222,20,226,43,353,52,712,6,0,138,500,204,97,145,64,104,426,673,355,90,25,5,65,87 }, 
862 { 5,259,786,534,590,493,279,49,13,581,465,21,929,35,941,132,147,32,23,612,362,626,107,121,178,0,146,61,48,939,10,18 }, 
863 { 2,14,16,7,278,69,135,140,46,24,267,35,92,38,1,189,29,52,309,60,66,75,71,172,74,357,18,87,67,6,230,5 }, 
864 { 165,13,308,197,391,23,401,15,51,457,180,509,115,569,3,629,961,719,34,758,317,734,14,29,46,2,17,901,38,453,5,217 }, 
865 { 1,22,2,14,0,28,7,168,67,49,65,24,36,95,5,105,55,35,12,46,69,16,114,159,194,50,10,9,158,83,164,109 }, 
866 { 34,453,3,196,130,14,322,11,47,51,377,236,361,4,730,153,514,711,57,440,62,17,161,108,176,59,485,56,162,412,202,117 }, 
867 { 18,16,21,23,48,13,24,35,121,5,156,60,51,1,7,132,141,221,163,115,0,271,447,340,363,202,125,71,2,781,22,698 }, 
868 { 165,13,457,23,197,961,629,569,341,41,12,38,401,901,54,51,115,17,15,509,421,37,62,45,719,57,32,328,117,758,157,99 }, 
869 { 2,1,77,141,33,64,3,102,0,23,13,5,128,10,6,15,180,202,269,40,51,515,7,165,137,117,318,4,700,153,197,352 }, 
870 { 68,212,0,124,101,9,154,16,562,191,21,149,65,24,35,1,118,167,818,350,520,100,722,841,264,71,13,302,478,23,375,346 }, 
871 { 98,23,48,598,13,293,541,21,125,121,51,807,0,31,35,259,126,7,386,1,223,783,10,107,199,20,221,144,342,963,49,64 }, 
872 { 21,13,5,586,1,23,167,48,33,781,647,49,165,18,51,271,77,32,761,118,0,82,391,22,146,141,459,31,197,156,115,4 }, 
873 { 2,1,5,61,29,7,58,45,14,6,425,32,70,52,290,738,207,21,72,112,66,76,655,17,186,46,64,263,38,0,128,87 }, 
874 { 39,265,9,100,1,333,363,101,18,411,447,254,166,310,31,98,264,30,639,404,156,286,16,93,593,203,272,682,0,905,44,821 }, 
875 { 6,2,1,19,29,51,26,108,25,74,5,23,14,114,13,386,133,103,42,66,453,70,309,138,719,324,65,38,64,96,52,75 }, 
876 { 20,43,356,107,49,858,595,7,414,359,0,5,392,319,97,612,422,819,14,376,173,246,22,470,147,427,230,92,197,33,683,95 }, 
877 { 0,9,68,35,65,67,114,101,28,1,124,175,336,69,154,103,83,24,189,133,39,16,50,7,2,149,55,251,18,345,230,36 }, 
878 { 23,13,51,15,0,1,515,115,165,2,5,12,700,202,4,21,141,457,753,197,10,3,180,120,32,9,318,11,453,64,6,269 }, 
879 { 121,195,60,16,126,107,98,271,146,407,132,35,1,167,199,223,493,191,279,20,18,5,43,7,21,92,48,393,0,362,212,467 }, 
880 { 31,44,299,116,393,144,492,456,268,22,105,0,367,918,384,434,127,489,98,9,963,125,242,948,1,28,206,49,36,51,93,293 }, 
881 { 23,13,457,51,165,401,719,758,197,453,961,629,308,14,15,12,730,3,386,569,391,29,739,515,34,828,832,901,115,514,670,341 }, 
882 { 105,36,131,22,180,115,341,127,169,1,9,31,64,98,44,365,317,141,272,143,160,55,219,86,197,776,239,187,0,535,13,752 }, 
883 { 1,6,2,14,66,25,29,5,108,67,65,114,19,38,26,52,74,7,24,18,69,86,36,388,64,51,17,83,23,46,42,75 }, 
884 { 51,386,23,453,719,13,730,6,457,670,758,19,401,165,2,475,47,26,899,14,108,17,1,5,197,29,894,754,236,74,27,285 }, 
885 { 252,18,9,101,121,16,132,0,419,167,364,60,604,35,265,363,146,271,39,158,68,109,28,329,848,24,647,907,682,159,212,55 }, 
886 { 283,503,128,432,26,193,63,269,789,529,102,122,389,275,678,6,25,318,445,4,342,27,573,605,177,862,643,291,216,57,235,59 }, 
887 { 2,1,29,75,69,52,14,6,46,74,87,7,220,226,278,38,135,66,267,70,16,262,25,24,380,324,357,140,67,394,97,222 }, 
888 { 97,298,69,7,66,140,189,24,16,267,172,423,60,150,14,314,92,71,81,501,43,35,74,6,517,232,149,607,83,330,18,2 }, 
889 { 475,421,403,899,51,805,523,958,453,817,23,615,401,801,120,326,202,670,494,730,450,386,115,629,260,576,77,365,569,0,165,13 }, 
890 { 7,20,14,128,77,97,112,202,2,177,16,415,269,318,275,66,107,43,141,414,135,38,307,10,58,0,6,291,32,5,4,40 }, 
891 { 24,14,7,0,2,1,22,28,16,65,168,124,35,67,108,109,18,49,10,149,69,158,5,95,289,12,55,6,36,71,46,21 }, 
892 { 26,80,27,73,122,25,19,17,6,42,684,209,445,573,667,106,45,690,4,611,255,680,297,495,65,59,128,119,483,113,64,53 }, 
893 { 107,259,362,376,465,20,470,147,595,534,612,683,660,43,5,49,581,0,858,35,427,246,97,786,178,356,14,21,142,878,7,279 }, 
894 { 131,30,228,190,856,406,224,88,219,530,863,613,778,274,944,816,187,39,100,160,258,31,44,93,1,321,539,36,871,137,435,531 }, 
895 { 113,6,311,25,45,491,80,611,27,26,209,667,17,73,122,42,684,396,19,85,106,5,614,4,2,255,151,29,1,64,648,61 }, 
896 { 15,515,700,753,0,1,23,51,120,2,13,82,5,260,9,4,341,77,180,115,141,10,7,12,450,8,202,901,197,351,165,93 }, 
897 { 219,127,98,258,395,421,924,293,242,201,697,105,276,51,308,23,453,272,401,944,512,137,13,31,284,567,386,365,116,131,964,125 }, 
898 { 15,180,352,141,515,752,217,82,1,317,854,700,351,753,115,341,110,13,260,120,21,36,33,898,23,10,5,365,4,160,901,137 }, 
899 { 129,123,17,257,162,184,205,249,183,769,5,80,3,4,229,130,119,45,90,99,618,106,57,497,12,128,2,84,59,152,27,40 }, 
900 { 33,102,23,77,64,128,51,13,0,202,10,141,40,15,1,22,117,137,2,86,4,403,269,153,515,196,65,11,700,115,99,5 }, 
901 { 7,14,2,16,172,107,46,92,5,135,35,202,294,87,38,232,29,97,20,21,24,1,60,220,66,43,12,0,126,52,54,70 }, 
902 { 403,576,615,523,475,326,805,817,494,421,51,202,120,450,137,453,23,859,260,401,402,77,33,670,0,958,15,197,386,515,165,480 }, 
903 { 141,352,217,137,0,180,202,349,9,269,23,51,115,291,77,372,13,317,120,752,365,351,93,22,2,341,64,10,82,854,28,18 }, 
904 { 1,23,13,51,202,141,5,165,21,15,120,180,64,2,197,125,33,102,12,7,137,515,48,128,269,318,93,700,0,403,9,4 }, 
905 { 25,151,6,145,122,29,174,45,113,74,4,665,42,138,2,614,416,287,19,348,746,0,66,26,1,7,64,243,311,396,81,624 }, 
906 { 30,190,254,166,100,382,731,829,88,131,264,795,9,93,625,274,438,1,578,613,716,31,44,39,530,36,616,921,265,203,160,77 }, 
907 { 132,5,21,13,1,23,32,195,379,687,156,121,626,296,48,70,850,146,51,82,883,771,35,49,652,407,60,4,260,0,845,33 }, 
908 { 9,254,0,49,272,131,39,159,688,101,105,578,518,158,286,28,327,333,68,224,252,219,344,16,22,1,716,31,30,228,24,890 }, 
909 { 16,7,35,60,18,20,14,68,9,0,28,118,43,92,126,55,107,2,101,154,24,71,5,202,121,109,22,252,21,97,1,621 }, 
910 { 15,515,700,753,13,1,341,2,0,4,3,5,11,23,10,33,117,12,901,197,6,134,77,8,165,317,21,365,217,7,17,40 }, 
911 { 78,19,444,47,26,390,27,453,130,813,108,730,711,65,412,122,51,680,113,235,690,196,630,283,128,236,14,64,73,53,200,445 }, 
912 { 2,7,29,5,61,6,45,1,66,113,112,14,52,315,738,128,32,151,74,16,20,64,70,21,592,0,25,4,425,43,491,222 }, 
913 { 145,112,74,66,6,29,26,70,19,396,25,87,2,287,135,151,138,222,5,226,42,122,7,307,1,644,45,58,113,651,635,632 }, 
914 { 92,16,7,60,126,24,140,35,14,232,18,121,246,71,46,267,172,150,107,314,132,146,230,2,278,108,330,199,236,5,38,572 }, 
915 { 13,115,197,538,569,341,98,55,165,127,365,762,219,286,844,23,170,206,734,638,535,901,169,253,629,0,873,509,180,10,332,258 }, 
916 { 58,151,74,53,287,27,29,396,6,70,2,73,5,52,112,26,651,1,297,113,17,75,19,45,334,445,145,34,315,549,436,331 }, 
917 { 214,289,90,874,104,751,64,65,312,835,204,249,750,194,74,81,875,32,519,288,348,0,174,247,636,715,138,192,784,6,524,280 }, 
918 { 9,39,28,35,30,0,166,49,1,175,439,158,64,346,36,101,67,364,86,88,274,100,168,55,23,10,420,22,190,141,505,180 }, 
919 { 341,901,15,515,700,753,1,365,10,0,569,180,2,197,115,31,165,3,5,4,44,22,317,13,9,951,23,253,116,143,762,93 }, 
920 { 120,202,77,450,260,15,128,318,102,515,494,13,817,700,269,5,403,51,1,33,23,753,82,326,141,342,291,137,21,523,351,32 }, 
921 { 13,115,241,64,180,32,125,197,165,4,118,22,21,23,16,247,237,28,225,191,95,141,167,5,0,341,288,35,459,18,177,24 }, 
922 { 16,24,35,14,1,2,7,69,18,46,60,50,267,140,71,189,108,38,75,92,0,5,9,230,67,21,309,335,54,236,394,220 }, 
923 { 15,515,700,753,898,180,901,341,197,638,10,165,33,1,115,4,77,365,317,13,102,217,117,0,5,2,253,3,82,569,21,752 }, 
924 { 193,523,18,84,56,730,233,65,4,817,90,33,643,403,91,511,453,240,59,11,214,51,719,196,153,475,32,123,64,847,102,561 }, 
925 { 112,29,151,2,74,6,66,7,222,145,287,45,5,624,52,25,113,416,58,122,19,70,186,204,4,87,644,549,337,884,32,0 }, 
926 { 13,0,23,2,1,15,33,3,77,515,141,5,4,217,10,51,64,180,700,115,6,117,11,7,753,40,102,165,197,22,317,153 }, 
927 { 28,0,1,67,65,9,2,114,83,69,103,50,36,22,55,24,46,14,124,109,35,7,16,38,133,160,389,323,18,12,154,5 }, 
928 { 121,132,18,167,271,146,101,363,621,9,411,647,16,354,520,60,212,932,1,806,55,0,195,446,68,35,31,364,777,252,407,118 }, 
929 { 26,6,85,396,122,624,25,19,42,445,64,648,573,416,174,680,665,214,45,348,90,65,194,145,113,881,138,289,112,436,297,544 }, 
930 { 16,146,18,92,24,199,60,71,121,126,35,108,156,953,271,674,132,7,32,640,360,246,649,118,21,95,5,517,14,9,1,314 }, 
931 { 51,13,23,453,475,730,719,15,457,403,64,115,33,95,4,523,3,12,21,6,899,102,5,128,401,202,11,141,308,515,22,125 }, 
932 { 151,396,6,53,27,113,58,26,73,112,74,287,45,29,297,19,145,70,138,445,315,436,34,2,17,573,5,61,549,491,1,80 }, 
933 { 223,1,888,774,260,98,269,385,349,202,96,141,421,622,730,863,318,697,87,453,393,418,922,834,751,5,163,335,120,291,352,30 }, 
934 { 16,60,92,35,126,121,7,150,246,18,107,1,598,24,167,195,14,97,71,279,98,441,191,199,517,146,356,223,298,271,230,0 }, 
935 { 22,1,105,28,239,170,0,55,95,31,36,301,2,320,98,127,9,49,44,64,35,67,10,86,5,12,109,23,168,13,21,312 }, 
936 { 2,6,5,207,292,76,1,119,45,32,17,29,61,306,790,58,240,106,14,64,214,151,476,710,7,72,84,128,4,179,70,25 }, 
937 { 51,23,221,254,115,13,438,530,125,48,21,39,541,960,386,49,1,613,15,840,228,308,627,131,688,401,5,326,421,158,165,83 }, 
938 { 1,5,2,0,12,22,21,36,10,14,48,86,23,13,32,54,3,4,28,65,51,50,137,37,208,114,9,38,17,7,281,202 }, 
939 { 363,23,447,182,296,340,1,93,698,478,379,156,284,144,18,269,21,98,141,70,668,411,664,658,110,914,67,937,180,691,335,291 }, 
940 { 17,32,45,498,41,115,180,197,106,62,54,38,546,165,13,155,468,509,341,243,241,217,542,15,57,536,428,51,117,721,292,129 }, 
941 { 32,95,64,246,22,92,180,13,5,652,125,241,638,237,7,49,4,126,21,115,197,296,888,316,0,165,774,23,16,392,1,534 }, 
942 { 15,515,700,753,33,341,13,217,4,141,77,23,180,317,1,10,102,351,82,115,40,5,854,21,137,11,352,901,365,117,197,0 }, 
943 { 15,120,1,82,93,217,515,260,77,141,13,110,700,351,352,23,180,753,21,854,202,317,64,349,269,51,165,137,5,128,291,36 }, 
944 { 13,23,51,141,77,0,33,4,115,64,2,10,102,202,217,128,1,177,269,11,7,22,6,21,32,9,180,40,15,3,165,318 }, 
945 { 478,264,1,520,98,724,9,682,223,664,21,759,13,772,604,100,23,363,411,48,821,5,0,905,909,447,31,265,88,101,166,39 }, 
946 { 20,29,7,2,77,416,6,128,33,5,0,113,104,32,43,13,491,66,23,21,102,51,74,210,202,525,64,318,10,81,174,14 }, 
947 { 2,1,5,14,7,58,61,29,45,290,46,38,52,21,32,270,6,592,425,0,75,155,16,48,17,50,72,70,207,24,263,663 }, 
948 { 80,6,17,209,106,26,483,113,19,469,255,25,378,27,495,833,45,64,161,2,61,667,76,742,32,90,445,5,814,65,887,119 }, 
949 { 98,223,393,1,354,834,195,791,447,697,284,293,360,541,781,156,51,807,18,664,421,411,163,668,48,31,591,765,883,386,948,23 }, 
950 { 679,141,816,36,93,406,876,144,228,137,1,180,669,21,332,251,5,269,116,187,96,351,202,752,317,64,203,831,574,466,855,345 }, 
951 { 15,515,700,13,1,753,2,0,23,341,3,5,4,10,51,11,33,165,6,7,115,197,12,64,180,153,217,77,9,569,901,317 }, 
952 { 13,23,202,51,5,21,403,15,120,64,1,450,128,141,12,523,33,165,494,125,2,515,269,7,48,102,318,95,260,180,453,197 }, 
953 { 16,18,24,60,71,92,146,246,199,35,140,7,9,118,121,108,167,230,126,132,0,640,156,14,68,133,267,360,649,271,64,55 }, 
954 { 269,141,678,177,202,77,128,318,33,947,40,120,291,349,102,137,64,352,210,864,461,498,13,342,196,23,275,450,954,0,205,111 }, 
955 { 16,24,92,18,71,60,35,7,108,191,167,246,140,14,126,21,1,68,150,118,149,388,399,9,273,0,121,796,230,48,212,517 }, 
956 { 2,14,1,29,46,75,52,70,69,171,38,7,58,163,16,5,24,220,67,112,223,54,50,409,155,35,267,186,151,334,394,140 }, 
957 { 9,252,100,265,166,39,88,404,329,0,1,520,382,812,101,593,264,274,604,676,30,118,68,553,18,664,363,23,639,865,21,411 }, 
958 { 16,18,35,24,0,60,158,7,22,68,14,49,109,159,55,9,28,71,2,10,5,105,1,118,329,13,344,23,92,20,21,126 }, 
959 { 15,13,515,700,23,0,753,1,51,2,4,10,77,5,3,197,115,165,961,202,9,457,180,12,141,22,33,120,6,11,318,31 }, 
960 { 160,93,251,137,317,1,180,36,120,217,345,752,617,352,332,10,96,531,498,318,365,202,141,269,816,341,901,679,143,35,83,968 }, 
961 { 6,25,42,128,19,59,122,4,85,26,611,27,269,233,45,0,343,91,318,80,11,177,283,73,33,614,2,77,64,138,445,216 }, 
962 { 95,64,74,7,32,81,51,204,0,20,237,65,56,38,91,23,207,180,347,343,29,6,511,52,49,10,25,18,554,370,14,312 }, 
963 { 202,120,326,260,450,817,494,318,137,403,128,77,523,553,859,5,704,1,15,23,13,576,7,16,615,51,682,291,515,0,21,234 }, 
964 { 20,43,107,356,362,126,595,92,359,7,422,319,493,16,858,5,392,246,414,683,60,0,35,945,441,21,259,819,49,97,279,173 }, 
965 { 25,42,6,77,33,102,0,122,4,690,29,483,210,27,21,19,2,300,18,648,680,119,117,59,1,10,342,12,26,153,91,684 }, 
966 { 31,44,299,116,125,242,456,599,22,393,0,144,492,28,268,1,9,963,301,105,367,36,127,170,384,434,206,98,918,10,13,93 }, 
967 { 410,521,686,367,662,88,335,321,201,96,98,772,144,1,934,921,443,435,284,274,264,551,120,897,44,100,33,225,744,418,909,960 }, 
968 { 142,178,878,234,132,786,195,202,77,416,147,929,146,522,167,259,687,639,450,271,626,481,590,5,198,212,771,49,0,465,315,427 }, 
969 { 254,39,131,9,272,0,578,716,310,224,30,49,105,827,518,829,166,333,616,228,613,846,101,219,1,31,890,98,159,938,252,100 }, 
970 { 230,699,854,473,450,351,831,137,855,217,352,704,800,202,251,498,160,144,206,203,317,201,253,752,418,141,1,332,82,180,443,36 }, 
971 { 403,202,475,453,494,23,51,77,318,402,13,33,128,102,137,141,120,342,269,0,450,4,899,576,40,421,275,117,217,177,196,64 }, 
972 { 23,44,98,182,291,144,116,39,110,141,96,82,905,70,367,264,125,93,77,411,120,1,658,202,100,415,107,363,197,30,447,105 }, 
973 { 15,515,1,13,700,23,77,120,0,753,51,180,202,141,260,5,21,115,2,137,128,9,450,197,365,269,12,326,110,102,318,7 }, 
974 { 0,32,18,95,207,577,193,29,61,104,64,784,715,102,693,887,81,91,583,671,403,5,52,474,397,180,138,49,37,344,38,263 }, 
975 { 0,101,9,68,252,16,100,39,166,364,124,24,154,265,212,88,18,35,329,419,28,118,71,30,65,158,191,55,1,694,21,676 }, 
976 { 16,24,191,18,35,71,167,118,149,68,212,9,0,1,21,108,101,92,60,375,302,7,589,755,124,674,350,48,562,246,13,363 }, 
977 { 2,14,69,24,1,67,46,16,38,103,29,267,7,35,189,135,278,71,108,18,83,309,52,6,149,388,75,236,60,0,150,66 }, 
978 { 13,1,23,0,4,2,51,15,180,33,3,115,5,515,141,10,77,700,11,9,197,341,202,165,217,102,22,7,753,317,365,6 }, 
979 { 447,1,698,411,31,363,98,5,919,4,156,125,759,691,13,64,459,354,44,21,48,293,30,914,478,225,82,120,2,922,848,839 }, 
980 { 854,82,351,217,141,180,352,15,515,752,1,700,317,898,753,244,10,21,922,115,77,36,4,260,64,110,372,13,5,365,120,11 }, 
981 { 0,1,4,13,5,2,82,33,3,120,10,23,9,11,77,260,21,102,8,31,40,6,351,51,64,450,22,117,93,110,7,457 }, 
982 { 51,13,403,23,12,475,1,2,21,5,453,523,115,202,817,7,0,99,3,6,450,120,494,64,22,95,49,899,10,37,32,141 }, 
983 { 180,752,352,141,498,864,317,217,9,0,115,237,230,39,30,197,83,1,930,64,35,365,372,13,579,88,702,36,101,901,482,21 }, 
984 { 16,24,0,7,22,18,28,35,14,158,71,2,109,60,1,168,49,154,124,68,10,55,92,118,159,9,5,747,95,105,65,6 }, 
985 { 15,515,700,753,0,23,1,13,341,51,120,77,141,4,137,33,260,82,202,9,180,5,351,2,291,10,11,901,21,115,40,128 }, 
986 { 24,68,35,149,18,16,0,7,9,14,189,108,69,65,67,1,71,2,118,28,140,101,114,336,230,124,175,133,46,55,251,154 }, 
987 { 13,308,197,115,125,9,165,237,391,23,509,569,546,28,49,629,22,338,317,254,749,180,468,159,903,386,217,352,558,39,36,734 }, 
988 { 64,90,32,217,77,4,141,216,172,312,128,13,86,33,597,147,352,95,5,115,875,22,59,11,102,14,182,437,97,177,874,707 }, 
989 { 1,22,36,0,105,28,2,67,95,49,55,5,239,12,86,9,83,170,312,64,31,21,23,10,164,50,114,159,208,13,7,320 }, 
990 { 9,18,16,0,159,105,101,252,49,310,24,68,35,39,265,272,7,1,60,28,455,890,329,557,118,286,55,137,327,167,5,13 }, 
991 { 129,123,214,249,618,17,5,257,205,184,460,76,2,162,769,245,90,106,128,45,119,1,183,4,3,12,179,64,6,229,99,209 }, 
992 { 51,453,719,457,23,13,730,899,475,386,4,15,11,12,670,196,515,523,961,401,153,3,700,99,753,117,403,32,120,165,57,0 }, 
993 { 173,66,192,204,20,74,104,636,7,43,289,426,825,712,560,214,81,750,65,97,707,0,90,414,64,348,32,500,22,861,95,6 }, 
994 { 13,23,1,51,5,21,141,120,202,15,165,2,515,180,12,125,0,64,82,700,197,269,32,48,260,128,115,93,9,137,33,753 }, 
995 { 200,34,322,78,472,390,27,714,19,14,136,161,453,176,236,444,59,3,62,128,108,57,283,862,73,53,47,17,412,813,4,56 }, 
996 { 33,347,66,204,426,498,56,172,97,95,5,681,546,22,10,0,135,180,4,241,19,174,6,353,263,21,7,370,42,197,27,808 }, 
997 { 131,224,219,187,385,371,258,442,254,737,31,98,836,127,924,944,44,871,908,716,39,827,201,574,116,137,36,1,276,242,578,616 }, 
998 { 1,15,2,180,4,141,13,515,0,5,3,115,700,901,341,23,217,352,753,51,197,77,317,33,365,752,165,21,6,7,269,93 }, 
999 { 370,91,718,74,81,510,397,66,636,240,355,84,138,511,18,278,6,681,701,289,90,5,214,582,64,104,0,643,192,65,750,32 }, 
1000 { 15,515,700,753,13,120,1,0,165,2,197,23,260,180,4,82,51,386,8,5,12,10,3,141,351,341,326,9,450,7,64,6 }, 
1001 { 32,2,76,5,1,292,72,45,476,214,21,241,29,14,17,48,129,90,179,460,464,123,290,148,519,205,3,263,249,38,710,89 }, 
1002 { 13,165,115,17,197,569,23,509,457,45,32,41,106,180,62,38,659,734,155,536,341,629,961,873,587,54,431,37,391,99,405,428 }, 
1003 { 68,24,35,16,0,101,9,124,154,71,149,65,18,175,28,118,7,55,302,108,92,14,22,346,1,39,429,252,375,364,10,67 }, 
1004 { 0,9,1,68,230,65,35,69,83,23,101,13,141,67,217,352,21,39,16,88,28,124,212,100,115,154,51,64,30,36,10,317 }, 
1005 { 100,265,88,909,410,382,812,593,1,213,321,30,252,230,352,264,9,166,689,39,676,98,21,466,724,639,478,217,13,48,553,101 }, 
1006 { 113,61,198,904,43,0,5,37,899,325,20,59,33,523,204,725,817,389,470,329,222,40,174,58,22,453,690,848,122,104,788,105 }, 
1007 { 16,24,141,18,7,0,71,140,35,269,75,352,12,9,108,217,5,330,60,64,199,70,22,13,486,246,318,133,65,50,23,498 }, 
1008 { 271,167,121,60,18,191,146,199,16,1,446,132,575,212,463,354,126,35,598,566,727,98,107,21,608,955,640,407,5,24,223,68 }, 
1009 { 15,515,115,217,700,13,317,753,141,180,33,23,110,120,4,341,82,10,1,260,365,36,64,854,351,21,51,352,137,77,40,0 }, 
1010 { 173,7,97,356,43,107,20,387,729,104,426,232,560,595,359,392,414,707,885,81,5,0,66,858,612,49,861,14,22,32,819,230 }, 
1011 { 15,515,700,753,13,23,51,82,0,33,165,120,196,4,1,2,197,453,260,351,180,12,40,8,386,110,5,326,9,141,217,457 }, 
1012 { 9,100,120,30,77,795,137,82,202,39,264,827,578,127,0,166,373,318,18,326,141,260,1,450,731,31,33,395,217,291,341,254 }, 
1013 { 14,2,67,1,24,69,0,28,65,7,46,18,114,108,36,83,38,398,9,16,124,133,103,154,50,55,22,267,29,160,35,547 }, 
1014 { 14,7,69,24,66,16,2,267,189,67,71,150,140,97,18,60,172,35,6,1,38,149,388,92,83,135,108,74,462,380,29,36 }, 
1015 { 15,515,700,753,1,13,2,0,4,341,5,3,23,365,11,117,180,10,12,33,134,115,77,197,217,165,6,7,317,102,21,9 }, 
1016 { 1,22,0,12,5,2,36,28,21,10,86,13,23,49,128,9,95,51,55,96,208,141,48,202,4,137,37,64,105,3,50,7 }, 
1017 { 605,630,63,123,736,650,65,108,444,368,561,389,19,25,42,619,122,194,183,27,53,33,84,26,297,813,114,73,256,235,249,216 }, 
1018 { 127,39,9,0,31,371,98,254,1,385,395,44,30,836,187,131,100,116,284,578,299,166,28,21,737,16,276,272,23,49,137,935 }, 
1019 { 2,61,6,29,45,151,1,655,7,207,32,5,112,425,17,76,833,4,14,64,58,106,119,25,113,128,72,52,70,21,292,790 }, 
1020 { 2,5,17,14,3,29,23,27,13,401,46,6,51,58,1,453,45,53,34,52,133,19,236,26,181,114,99,366,151,108,218,38 }, 
1021 { 31,22,170,1,301,44,127,98,36,28,55,105,239,0,338,116,512,299,293,125,86,10,242,395,2,13,9,64,841,23,95,685 }, 
1022 { 1,21,2,14,5,32,48,50,38,270,46,76,290,72,45,54,17,0,155,221,263,207,37,281,430,3,89,12,181,408,36,67 }, 
1023 { 17,106,119,378,84,240,62,80,383,136,306,3,56,790,742,5,207,504,64,440,32,128,45,2,123,209,14,4,61,57,297,667 }, 
1024 { 13,15,1,515,23,2,0,700,4,115,3,51,5,10,753,180,33,341,217,11,165,317,365,197,6,77,40,64,22,9,7,117 }, 
1025 { 772,335,96,744,1,367,662,686,652,897,303,264,521,31,225,410,141,520,260,116,64,44,321,98,144,88,919,966,340,269,349,284 }, 
1026 { 1,0,5,28,36,2,12,22,83,67,65,50,24,14,9,96,21,218,18,114,48,281,54,10,7,160,181,103,37,23,133,99 }, 
1027 { 25,6,145,42,138,81,174,348,525,544,26,74,85,280,287,648,746,91,66,0,29,396,204,64,636,90,122,194,355,104,65,233 }, 
1028 { 16,24,0,18,28,158,7,35,49,22,68,159,55,1,14,109,105,2,9,71,65,154,124,95,424,344,60,239,118,577,21,10 }, 
1029 { 352,854,699,230,93,689,137,144,217,160,251,36,669,202,351,120,617,855,752,203,332,82,450,180,141,748,831,30,258,201,1,816 }, 
1030 { 15,13,515,700,1,2,0,753,23,5,4,3,51,33,10,115,11,317,217,77,180,341,117,165,6,134,197,153,64,9,102,7 }, 
1031 { 104,20,43,173,66,319,0,77,202,7,198,5,97,580,355,74,2,204,174,52,712,234,426,155,102,192,32,4,500,337,226,904 }, 
1032 { 13,23,15,51,1,515,0,2,5,700,141,4,753,165,115,12,3,21,457,10,180,269,32,6,197,202,9,7,120,11,77,33 }, 
1033 { 15,515,700,753,0,1,13,2,23,115,4,317,8,3,5,51,9,341,10,217,22,365,33,457,6,180,77,901,197,120,18,7 }, 
1034 { 15,515,700,753,1,0,2,3,4,13,5,141,23,16,82,217,457,10,365,180,9,317,51,21,269,898,64,202,11,12,318,341 }, 
1035 { 2,5,1,14,50,38,29,17,114,46,133,3,45,21,58,171,181,36,218,12,6,52,0,48,137,65,361,23,155,4,285,51 }, 
1036 { 0,68,9,65,101,124,35,212,16,149,154,100,24,1,114,336,67,589,252,39,71,189,69,562,18,13,30,398,118,88,265,264 }, 
1037 { 1,2,14,22,0,7,67,65,28,36,24,46,168,5,86,69,38,16,49,12,289,10,194,50,83,114,95,6,18,23,55,158 }, 
1038 { 13,23,15,51,515,0,700,4,1,753,2,10,115,961,457,12,33,11,3,5,197,9,165,77,102,403,453,40,64,22,37,59 }, 
1039 { 15,515,700,753,0,1,2,13,23,5,51,901,8,9,180,3,7,82,4,120,12,10,719,341,6,31,141,457,197,22,115,93 }, 
1040 { 100,252,88,101,0,265,9,724,48,1,21,352,213,676,410,382,321,230,30,329,593,909,39,812,553,217,23,689,520,264,166,419 }, 
1041 { 2,5,1,58,171,14,46,50,29,52,45,38,186,155,67,54,151,281,334,61,48,96,17,181,103,400,502,227,21,223,12,69 }, 
1042 { 23,120,13,1,202,141,51,21,165,128,260,15,5,269,137,64,33,180,82,318,93,197,77,326,515,125,110,700,450,2,32,48 }, 
1043 { 341,197,10,901,13,15,8,638,569,515,479,23,180,873,700,165,143,642,0,961,753,951,1,115,509,499,116,12,498,242,82,206 }, 
1044 { 15,1,23,13,515,21,120,51,2,141,202,700,5,180,165,0,753,197,12,7,33,260,352,137,269,4,82,128,48,9,110,6 }, 
1045 { 2,29,50,58,1,6,5,52,14,262,17,46,27,53,151,34,171,74,324,26,38,309,45,113,19,96,287,396,223,67,73,583 }, 
1046 { 13,23,141,51,4,202,0,115,77,2,33,217,5,317,180,64,10,269,3,9,15,21,1,128,102,137,318,11,352,515,22,31 }, 
1047 { 1,67,0,24,50,5,14,18,16,69,2,9,103,35,83,12,96,28,54,7,58,223,21,46,281,48,65,181,22,38,36,108 }, 
1048 { 13,23,141,51,77,64,202,115,33,102,128,4,0,269,10,21,217,32,180,318,9,137,2,11,22,291,7,177,16,31,165,197 }, 
1049 { 317,115,180,365,873,498,217,341,13,752,482,197,569,352,1,901,36,23,457,468,165,346,546,143,509,134,579,876,868,2,332,21 }, 
1050 { 184,257,205,229,152,17,57,497,266,432,452,524,5,619,381,32,4,90,2,12,313,128,45,59,245,106,3,471,129,769,339,214 }, 
1051 { 13,23,1,0,15,2,4,515,51,3,10,33,5,700,115,180,753,77,11,365,341,217,9,6,197,7,102,165,317,40,22,64 }, 
1052 { 626,70,771,687,379,846,767,761,518,878,82,481,31,786,49,591,178,163,407,44,87,13,845,125,590,371,195,120,98,557,937,351 }, 
1053 { 264,1,410,909,772,897,686,521,335,478,98,96,691,639,100,44,284,382,31,321,744,88,914,724,662,765,223,9,682,363,0,367 }, 
1054 { 13,23,1,2,0,15,51,515,5,10,4,33,115,77,180,700,3,141,217,40,6,753,317,197,64,165,7,11,102,9,341,22 }, 
1055 { 141,77,13,64,269,23,115,21,318,217,5,202,102,33,137,2,15,291,177,51,48,180,32,4,515,352,128,7,0,10,96,11 }, 
1056 { 13,15,23,515,51,0,700,753,1,2,4,10,33,11,961,453,115,40,457,14,12,3,9,5,165,401,197,77,22,21,64,102 }, 
1057 { 1,22,0,36,2,31,5,12,13,105,28,9,49,86,141,21,23,95,128,55,44,115,170,10,164,98,180,4,137,239,83,51 }, 
1058 { 100,101,88,0,252,9,265,30,21,39,759,724,213,329,321,13,419,68,562,382,676,352,694,35,553,410,1,166,909,593,230,23 }, 
1059 { 539,88,30,190,321,530,840,144,669,435,957,748,778,100,96,418,203,213,1,131,410,228,466,274,36,382,219,863,613,83,822,352 }, 
1060 { 7,97,92,173,298,107,43,314,232,140,16,356,20,387,729,362,126,359,246,14,230,501,426,441,0,5,560,66,104,779,35,60 }, 
1061 { 2,14,7,1,58,5,46,16,38,70,75,45,24,155,29,0,21,52,61,163,220,50,69,270,35,48,32,171,18,6,64,54 }, 
1062 { 447,411,363,664,647,98,621,1,354,271,223,478,18,777,781,936,360,759,167,132,121,48,21,156,9,195,118,293,23,691,13,264 }, 
1063 { 2,1,14,65,36,67,0,7,46,22,69,5,38,24,28,6,83,29,86,114,168,50,124,208,12,18,108,10,194,484,103,16 }, 
1064 { 421,386,51,791,730,958,165,801,23,453,697,403,615,13,221,523,24,899,401,326,551,670,576,102,18,33,125,77,566,115,203,197 }, 
1065 { 104,319,422,945,0,81,20,43,715,32,784,693,879,7,397,74,306,207,52,681,671,2,61,173,6,636,904,95,887,5,18,192 }, 
1066 { 2,29,1,46,14,52,70,262,6,26,50,67,75,96,309,38,103,112,58,19,5,163,145,83,74,220,223,357,24,69,331,25 }, 
1067 { 786,929,590,771,687,626,941,178,465,259,70,5,13,21,35,534,107,518,132,49,878,48,146,121,379,279,31,767,147,195,108,125 }, 
1068 { 5,2,186,45,17,29,48,50,14,61,46,155,400,1,227,171,52,58,38,54,430,209,80,281,3,106,536,311,181,243,21,502 }, 
1069 { 0,32,64,95,817,494,342,403,207,202,194,389,453,365,312,180,316,5,690,237,848,577,450,61,102,523,475,289,49,241,65,482 }, 
1070 { 23,13,51,15,202,515,1,0,2,12,115,4,700,5,165,753,77,457,21,141,128,10,3,64,403,32,197,318,9,11,33,117 }, 
1071 { 119,2,6,76,5,17,45,292,306,240,32,1,19,84,64,61,4,209,710,80,26,0,106,27,214,25,128,129,29,179,3,113 }, 
1072 { 15,515,700,1,753,0,13,23,180,120,51,2,5,33,165,197,9,450,7,260,115,523,4,12,202,141,82,77,21,102,8,6 }, 
1073 { 6,138,74,280,222,85,66,226,25,42,87,204,64,337,29,135,95,174,235,26,145,65,19,32,792,294,112,52,256,2,5,22 }, 
1074 { 39,9,0,101,333,158,49,252,310,254,272,68,16,18,159,286,344,455,30,109,627,327,24,105,419,100,364,22,35,1,329,709 }, 
1075 { 21,5,32,14,2,1,38,72,76,54,17,3,48,221,270,0,45,46,12,181,37,89,36,50,540,290,430,10,4,741,99,23 }, 
1076 { 120,137,202,269,141,260,318,450,922,494,77,291,82,15,5,351,128,1,515,326,64,854,700,352,342,21,753,678,349,32,523,90 }, 
1077 { 16,24,68,35,71,18,149,118,191,167,9,0,212,124,65,246,7,67,140,189,399,101,133,60,1,108,267,114,69,92,695,154 }, 
1078 { 28,0,9,67,1,22,109,36,55,65,194,114,39,83,49,69,2,35,103,50,158,208,86,420,168,289,505,24,7,185,5,323 }, 
1079 { 147,325,198,427,142,178,202,798,5,376,20,318,259,43,120,450,77,234,534,904,470,465,878,725,329,14,315,0,260,858,70,61 }, 
1080 { 28,0,65,9,109,1,55,67,35,22,24,39,289,7,175,14,114,2,158,124,420,194,68,16,336,36,49,69,168,570,154,505 }, 
1081 { 141,180,13,115,1,23,4,269,2,202,0,317,217,51,15,5,21,352,77,318,3,752,197,10,165,365,137,341,9,515,33,64 }, 
1082 { 15,515,700,0,753,1,2,13,23,9,51,5,4,901,33,7,8,3,12,93,180,120,197,6,82,341,10,141,22,260,457,115 }, 
1083 { 6,74,66,1,25,75,324,380,278,26,138,85,135,500,87,42,220,841,97,350,29,19,70,226,38,21,52,606,235,889,2,14 }, 
1084 { 13,23,51,12,4,15,453,0,457,1,403,165,115,3,11,2,64,5,401,10,515,37,202,33,40,32,99,475,197,700,308,17 }, 
1085 { 788,180,5,83,693,319,314,4,32,21,17,11,817,3,510,498,33,12,24,104,814,120,64,117,306,804,523,450,288,160,102,43 }, 
1086 { 15,1,515,13,2,700,23,0,4,753,3,341,5,51,33,11,10,6,77,7,115,102,180,165,141,9,197,217,901,40,12,64 }, 
1087 { 101,18,9,167,520,16,0,118,60,212,604,364,694,24,55,252,68,917,264,35,1,121,146,363,39,100,806,5,21,166,191,28 }, 
1088 { 13,23,0,33,51,141,77,4,64,2,115,217,9,102,7,202,21,10,180,3,15,128,5,269,6,32,11,16,165,352,22,317 }, 
1089 { 66,135,97,74,172,6,278,7,204,324,138,174,29,85,2,87,25,140,92,192,52,38,802,69,448,500,808,620,22,1,280,232 }, 
1090 { 2,24,69,6,97,7,1,0,14,298,423,66,67,29,150,25,189,267,124,74,607,18,36,81,172,33,83,38,52,273,71,809 }, 
1091 { 0,9,158,39,68,49,109,16,24,333,35,344,101,22,159,254,272,30,124,65,28,18,793,154,310,252,327,105,627,419,286,55 }, 
1092 { 15,515,700,10,753,33,77,180,4,341,1,197,13,115,365,23,901,317,5,102,11,217,165,117,141,40,2,3,253,21,134,55 }, 
1093 { 100,166,382,478,265,264,88,39,98,1,404,274,9,593,724,921,639,438,363,682,411,31,30,812,96,447,821,905,252,0,223,435 }, 
1094 { 19,283,436,53,297,26,813,432,27,128,42,25,390,503,122,736,73,123,605,63,389,529,630,250,690,65,381,444,6,269,108,216 }, 
1095 { 33,202,13,128,494,0,51,141,269,1,4,2,102,180,15,137,65,95,6,450,77,40,117,59,457,36,196,817,134,86,49,515 }, 
1096 { 18,16,60,68,101,167,191,118,35,121,9,212,55,0,126,1,24,647,199,146,520,107,628,621,363,71,21,28,346,92,806,727 }, 
1097 { 352,230,217,531,160,93,36,669,748,854,689,258,137,871,728,699,752,251,574,202,373,351,228,120,717,260,144,219,268,82,816,1 }, 
1098 { 15,515,700,753,13,23,0,51,8,1,4,82,165,77,110,33,10,180,5,202,11,22,120,12,9,197,115,93,403,141,40,351 }, 
1099 { 0,9,101,217,35,88,352,100,39,175,30,68,562,752,13,317,252,115,180,197,64,1,83,141,65,213,165,230,194,36,28,265 }, 
1100 { 32,64,5,470,288,90,21,147,0,95,356,22,20,519,835,312,819,18,247,182,11,97,13,4,387,49,43,298,316,48,107,7 }, 
1101 { 16,14,24,1,7,2,35,0,5,50,18,69,46,12,58,75,9,67,70,163,21,54,38,48,223,502,281,37,140,60,28,10 }, 
1102 { 18,265,9,252,39,195,354,411,1,16,132,101,121,682,167,203,5,363,146,593,35,333,21,271,60,13,100,0,156,327,7,520 }, 
1103 { 4,13,1,115,141,23,2,180,5,0,51,3,217,202,77,15,33,269,341,318,317,21,165,515,11,10,197,365,9,137,64,352 }, 
1104 { 7,24,16,14,71,35,18,92,140,189,108,149,68,60,69,150,2,230,97,66,0,458,67,1,65,251,38,314,388,267,36,46 }, 
1105 { 1,22,31,36,0,2,44,5,141,105,180,170,12,64,13,98,86,55,23,21,28,164,115,127,10,125,128,4,9,239,352,197 }, 
1106 { 66,7,97,2,192,20,52,43,135,74,560,107,104,0,750,147,414,29,580,173,324,376,226,194,77,174,204,38,356,64,16,470 }, 
1107 { 0,101,9,68,35,124,24,65,39,16,252,100,154,166,28,364,149,694,30,88,55,346,1,419,71,439,265,289,22,21,175,158 }, 
1108 { 39,9,100,30,127,0,737,856,31,836,827,254,98,931,166,88,93,1,44,190,131,228,120,395,625,385,863,264,219,373,110,28 }, 
1109 { 5,17,2,3,21,45,14,155,48,32,38,1,328,181,186,46,23,51,12,61,227,29,106,54,99,133,62,832,13,37,514,543 }, 
1110 { 131,613,30,224,228,716,274,100,827,406,219,856,39,190,31,88,1,166,9,44,829,863,931,93,0,187,625,924,127,98,137,254 }, 
1111 { 352,217,64,141,752,269,180,864,437,372,954,115,498,177,77,349,317,318,579,291,947,197,247,0,23,717,237,304,128,457,776,678 }, 
1112 { 141,217,180,317,352,115,15,341,1,23,13,365,515,752,2,64,0,5,498,700,372,165,51,237,753,77,244,197,137,4,21,253 }, 
1113 { 5,2,17,14,1,45,3,38,21,29,181,58,46,48,50,133,114,171,61,155,32,6,186,281,361,12,36,54,4,13,52,514 }, 
1114 { 6,2,119,25,790,4,45,483,655,113,1,29,76,26,32,19,887,17,128,0,292,833,59,61,106,64,77,814,14,151,84,42 }, 
1115 { 13,23,2,0,51,4,1,115,141,3,5,180,33,217,77,9,202,11,7,15,10,6,317,64,21,197,515,165,102,128,22,269 }, 
1116 { 13,23,51,202,21,5,1,15,141,165,120,2,115,12,32,0,515,128,318,64,125,700,4,403,197,453,180,457,3,7,10,6 }, 
1117 { 9,39,31,30,0,127,1,44,100,131,98,187,385,276,88,442,219,908,254,116,49,166,935,28,201,36,141,827,137,299,284,21 }, 
1118 { 22,49,28,109,9,185,105,95,1,131,159,272,36,67,86,254,39,55,35,0,505,31,83,169,208,327,286,98,168,535,312,708 }, 
1119 { 5,1,2,21,0,12,48,22,10,14,36,3,32,17,23,54,86,38,4,51,13,37,137,50,65,281,114,45,28,99,58,202 }, 
1120 { 141,269,352,82,217,351,180,854,372,922,752,1,15,260,317,318,515,202,64,700,120,349,954,753,77,35,67,717,898,137,365,115 }, 
1121 { 144,203,613,418,326,406,96,669,137,679,1,228,494,822,840,317,36,83,855,160,817,859,856,816,217,831,345,93,876,77,44,251 }, 
1122 { 15,13,515,23,700,753,51,1,33,0,202,21,2,5,180,141,120,165,217,82,12,117,4,352,269,197,115,32,3,9,134,260 }, 
1123 { 13,23,115,1,0,51,4,77,2,33,15,141,10,5,341,180,515,3,217,202,9,365,317,64,700,102,11,165,197,22,753,7 }, 
1124 { 531,943,373,160,728,93,206,260,261,559,964,269,717,535,332,384,365,295,110,533,141,10,180,352,244,137,120,55,959,564,36,253 }, 
1125 { 1,31,36,170,22,55,44,10,86,64,127,0,2,98,301,164,740,338,237,143,5,125,116,13,242,141,299,180,23,169,105,12 }, 
1126 { 13,23,141,77,51,4,64,32,33,202,115,269,102,128,21,0,177,180,318,90,40,10,7,5,137,15,217,352,9,291,59,22 }, 
1127 { 202,120,260,318,77,15,450,269,1,82,33,23,141,13,51,515,351,128,700,5,64,326,137,21,102,110,753,494,93,523,817,165 }, 
1128 { 523,899,102,33,730,15,23,403,719,117,153,13,515,51,475,4,700,5,453,817,196,753,494,40,202,120,1,2,450,457,17,421 }, 
1129 { 202,403,494,450,120,817,523,475,318,453,33,402,128,77,13,51,260,576,342,102,15,23,515,4,700,5,82,753,326,210,137,615 }, 
1130 { 2,29,112,66,7,52,70,151,58,87,135,5,74,226,307,6,14,186,1,45,549,172,644,25,113,287,46,155,334,64,294,97 }, 
1131 { 1,77,349,291,260,120,652,102,5,39,64,269,9,33,340,342,13,98,888,698,23,296,100,318,51,202,87,137,638,128,50,850 }, 
1132 { 1,13,15,2,0,4,23,515,5,141,180,3,700,341,115,51,753,269,77,901,197,352,217,33,21,11,365,6,165,202,7,317 }, 
1133 { 7,14,16,2,46,5,70,58,1,38,24,35,92,163,0,75,21,18,50,54,140,12,87,220,155,69,171,23,60,9,13,307 }, 
1134 { 2,29,66,226,135,7,87,74,52,278,6,75,222,220,294,70,97,1,145,25,172,262,324,38,69,112,331,92,5,14,140,26 }, 
1135 { 15,515,700,753,33,77,117,4,1,102,134,40,153,11,13,196,217,21,5,51,23,115,32,3,2,202,141,137,128,291,48,177 }, 
1136 { 15,217,82,515,351,141,317,1,13,700,260,77,110,120,115,854,23,753,180,51,21,36,137,922,5,64,365,352,291,202,93,341 }, 
1137 { 31,190,30,373,120,110,863,88,44,127,908,856,260,318,82,98,93,187,836,717,935,39,442,131,141,254,228,219,1,968,77,116 }, 
1138 { 23,13,308,9,165,115,51,21,401,125,49,39,197,391,159,254,217,743,28,438,773,629,558,386,341,95,32,317,876,679,109,166 }, 
1139 { 49,5,43,165,7,0,21,104,125,22,173,422,64,13,623,102,20,18,314,95,91,141,23,31,193,51,391,900,779,558,92,232 }, 
1140 { 1,4,13,2,15,0,23,515,77,3,341,33,5,700,115,51,202,753,141,180,11,10,102,217,6,901,40,7,197,318,317,365 }, 
1141 { 93,843,295,120,36,160,206,261,10,137,567,110,384,141,943,268,201,332,258,55,1,180,64,116,44,144,699,203,282,31,260,373 }, 
1142 { 81,7,192,426,43,173,172,104,879,91,5,712,715,526,6,97,568,95,448,66,33,861,560,32,49,20,0,636,232,825,2,22 }, 
1143 { 475,403,51,453,33,102,13,23,494,202,0,196,15,77,153,18,4,117,515,450,318,22,730,128,700,421,65,753,269,402,134,817 }, 
1144 { 141,269,260,318,202,120,352,349,82,351,1,5,854,137,64,291,15,922,180,851,32,77,515,372,21,700,7,217,13,947,33,753 }, 
1145 { 15,515,700,753,1,13,0,2,4,23,3,5,180,115,197,12,51,165,217,10,961,9,6,141,352,21,8,7,33,77,457,120 }, 
1146 { 39,166,9,30,0,101,274,404,252,333,190,100,158,438,310,88,68,265,656,21,1,530,329,344,49,539,625,254,13,131,48,419 }, 
1147 { 0,1,28,9,22,12,65,83,67,36,5,2,50,55,96,109,16,13,24,23,21,238,49,18,285,160,128,39,69,114,7,323 }, 
1148 { 15,515,700,1,0,753,23,2,13,51,5,180,115,6,3,9,197,12,457,120,7,165,901,82,4,21,8,141,31,33,719,341 }, 
1149 { 9,39,30,0,28,166,22,49,180,1,352,35,317,158,88,141,498,131,115,345,752,128,228,217,100,83,219,930,13,251,365,36 }, 
1150 { 5,61,45,2,80,29,311,209,6,17,58,1,151,106,454,667,243,70,52,496,287,592,255,738,64,74,483,14,27,32,112,19 }, 
1151 { 31,125,22,44,299,456,685,242,599,116,170,28,0,1,492,393,506,144,558,10,268,301,239,23,13,36,963,367,55,206,105,95 }, 
1152 { 187,258,926,574,839,93,228,860,406,219,871,160,137,531,224,116,120,902,669,201,36,131,44,144,843,533,318,384,442,1,434,268 }, 
1153 { 7,107,75,16,87,9,64,177,24,18,291,77,349,141,60,232,23,0,51,269,132,14,5,21,70,32,678,112,126,121,71,947 }, 
1154 { 15,515,700,753,1,0,2,13,5,3,23,180,4,115,901,51,6,8,961,9,7,10,12,82,197,22,141,341,33,120,365,457 }, 
1155 { 13,23,51,1,5,202,2,12,15,21,165,141,0,115,3,4,32,515,197,10,180,318,128,120,64,700,6,7,403,269,457,137 }, 
1156 { 1,2,0,77,64,3,141,13,33,15,23,10,6,102,5,515,180,4,117,7,700,165,11,217,269,40,753,115,128,17,197,134 }, 
1157 { 345,531,332,269,260,317,717,752,373,351,180,352,728,82,10,365,160,533,217,143,498,251,244,93,341,901,36,1,141,898,55,864 }, 
1158 { 16,7,33,189,92,77,388,60,140,35,102,24,14,1,230,21,150,117,733,314,18,915,71,13,108,134,5,64,69,2,98,22 }, 
1159 { 142,202,234,178,5,786,77,49,70,0,416,450,639,878,1,48,21,929,147,259,315,455,198,120,12,481,163,113,846,329,318,22 }, 
1160 { 81,715,192,0,173,712,681,104,636,91,74,20,750,370,7,718,95,879,22,43,825,560,422,64,207,49,172,18,397,10,426,319 }, 
1161 { 13,23,15,51,515,0,700,753,4,1,961,2,10,115,457,11,33,453,3,5,9,40,12,197,165,77,401,475,64,102,22,569 }, 
1162 { 64,297,5,445,95,61,250,311,80,34,17,312,45,2,86,472,58,14,180,53,22,151,869,738,247,237,29,1,128,165,21,288 }, 
1163 { 16,24,18,71,7,35,118,92,14,154,60,68,0,149,28,302,124,150,55,175,2,9,97,1,429,20,108,273,22,65,43,126 }, 
1164 { 195,360,156,771,132,163,626,687,591,371,883,146,121,846,70,586,379,13,293,98,407,48,761,296,354,18,31,1,55,49,21,105 }, 
1165 { 202,13,77,23,318,33,51,0,4,141,5,21,217,32,291,102,64,128,15,10,9,494,269,137,515,403,1,31,117,700,120,317 }, 
1166 { 7,192,97,81,172,66,426,173,43,715,712,232,861,879,104,330,568,298,74,893,885,526,387,825,92,140,91,14,636,6,5,448 }, 
1167 { 2,1,14,6,67,7,65,69,24,36,66,124,108,83,38,29,22,86,0,18,484,5,28,46,12,10,25,302,150,16,650,74 }, 
1168 { 33,77,13,202,102,4,0,23,128,51,141,64,318,22,403,269,137,10,15,40,494,117,32,59,11,153,1,21,177,196,515,115 }, 
1169 { 269,141,318,77,349,291,217,202,33,15,372,304,515,22,102,177,351,700,352,120,5,137,10,317,260,753,64,851,854,403,49,21 }, 
1170 { 6,74,66,85,138,25,87,42,135,26,226,222,280,29,75,500,220,278,792,70,19,2,1,294,204,64,32,145,853,112,52,174 }, 
1171 { 9,0,105,39,16,18,1,101,272,31,127,98,24,518,333,252,310,28,68,737,846,371,158,916,938,49,30,7,286,35,301,455 }, 
1172 { 2,1,14,67,24,46,83,108,69,29,38,103,114,36,6,133,18,0,28,7,65,52,236,75,50,398,5,309,135,16,278,160 }, 
1173 { 22,1,28,105,49,95,0,2,67,55,36,239,168,159,65,35,14,170,320,164,9,7,10,5,114,12,83,64,194,109,24,301 }, 
1174 { 7,66,172,97,92,140,232,568,298,14,192,314,16,380,135,324,2,330,74,38,357,448,126,69,35,5,107,6,387,60,204,572 }, 
1175 { 2,29,1,14,5,6,46,133,114,50,52,26,218,108,19,13,366,236,27,45,70,17,58,23,86,51,137,65,112,38,25,12 }, 
1176 { 6,1,74,25,2,26,29,66,42,19,75,14,388,67,108,70,52,85,103,65,38,138,357,133,114,594,324,516,603,96,309,69 }, 
1177 { 22,9,28,1,36,49,109,105,86,95,131,31,169,39,0,141,272,159,44,55,98,180,13,30,185,115,83,128,352,137,64,208 }, 
1178 { 203,822,326,23,77,859,403,494,576,39,473,182,33,1,691,100,18,217,13,817,411,447,363,102,93,966,96,478,291,704,310,120 }, 
1179 { 15,515,700,753,33,77,117,4,102,134,115,153,13,1,40,217,11,196,341,2,5,3,23,317,365,0,21,291,32,51,12,569 }, 
1180 { 15,515,700,753,13,0,23,1,8,82,51,165,197,120,180,2,9,33,4,110,5,12,10,260,351,386,141,7,457,475,93,901 }, 
1181 { 1,23,13,15,51,0,21,2,515,5,141,180,120,165,700,202,197,4,753,12,33,9,7,82,115,93,3,352,260,6,110,48 }, 
1182 { 15,515,700,753,0,1,2,5,3,4,8,13,180,341,10,23,7,6,9,51,77,197,961,115,165,82,120,31,22,202,457,217 }, 
1183 { 559,661,922,564,141,533,10,317,373,110,143,269,244,260,332,261,93,642,752,295,351,876,531,843,180,206,728,384,352,1,434,120 }, 
1184 { 15,515,1,0,700,2,13,23,753,5,51,180,3,165,12,6,197,115,4,9,7,21,719,8,457,82,141,120,33,22,901,10 }, 
1185 { 198,234,0,325,5,77,202,416,20,147,32,43,639,315,49,61,450,455,142,21,113,230,22,318,725,342,207,13,95,904,494,10 }, 
1186 { 447,264,363,9,411,676,682,1,156,664,821,478,166,354,812,39,100,905,382,897,98,18,759,404,31,101,724,5,265,223,88,13 }, 
1187 { 24,14,69,16,35,18,2,7,108,189,71,67,267,149,1,46,68,83,38,140,0,236,251,9,388,60,133,103,65,28,29,50 }, 
1188 { 16,7,35,20,14,18,109,2,43,120,107,60,1,121,326,907,553,77,13,147,23,82,68,260,0,403,5,24,202,126,265,199 }, 
1189 { 30,131,187,276,31,44,613,442,39,9,190,228,1,839,116,935,908,219,127,88,244,224,110,137,93,201,98,141,36,567,0,856 }, 
1190 { 98,223,1,393,812,265,100,421,593,834,697,48,51,410,791,382,21,88,31,284,9,125,96,293,230,23,213,217,656,689,541,5 }, 
1191 { 98,51,127,219,616,258,105,293,395,421,924,512,31,308,23,201,116,44,301,272,763,276,125,13,453,170,401,295,261,944,115,567 }, 
1192 { 253,110,951,352,811,206,332,180,141,244,282,10,854,417,642,638,559,752,143,911,260,55,93,533,499,498,661,120,351,959,564,341 }, 
1193 { 49,9,159,254,272,158,0,131,28,39,627,105,327,286,22,518,688,578,68,347,374,101,224,424,95,35,219,24,16,364,65,344 }, 
1194 { 105,22,131,272,98,286,327,109,374,239,28,95,320,219,9,224,55,127,187,36,578,169,64,185,538,1,159,10,371,634,49,616 }, 
1195 { 691,478,340,1,658,914,724,363,744,698,156,772,411,296,682,447,9,284,335,98,264,303,909,21,354,410,225,13,664,686,88,919 }, 
1196 { 16,24,35,18,71,7,140,108,189,267,92,60,14,230,68,69,9,1,149,46,246,191,388,167,2,0,118,236,133,21,674,5 }, 
1197 { 9,0,127,31,98,371,395,39,737,49,1,44,385,272,512,28,293,242,836,761,254,299,101,16,187,22,116,158,159,131,18,21 }, 
1198 { 16,18,68,0,60,35,9,101,252,28,118,24,419,55,7,109,604,71,39,121,22,364,14,158,191,167,925,126,329,21,92,49 }, 
1199 { 116,268,203,93,206,692,551,31,417,940,499,8,473,44,202,523,959,0,120,137,559,22,450,403,576,10,728,299,13,326,51,1 }, 
1200 { 225,459,744,1,919,914,691,330,622,21,141,223,5,284,934,335,88,538,340,82,385,839,363,120,478,98,48,30,64,32,686,166 }, 
1201 { 5,1,2,0,14,36,21,281,12,48,50,67,22,28,54,83,24,218,38,10,181,9,32,18,65,58,45,114,430,17,99,37 }, 
1202 { 137,450,202,704,120,260,326,318,968,269,851,403,291,77,23,141,182,310,494,373,351,457,82,890,349,110,60,128,817,678,105,96 }, 
1203 { 15,515,700,753,4,33,13,23,77,5,40,11,102,93,1,21,110,51,82,117,141,2,10,8,32,64,120,31,202,3,217,115 }, 
1204 { 15,13,1,23,515,0,51,2,700,5,753,21,180,141,165,3,12,115,197,4,7,6,457,9,352,202,33,8,719,120,77,341 }, 
1205 { 219,127,258,98,276,201,131,395,944,293,116,284,567,31,242,105,137,935,295,44,403,860,51,224,576,456,9,371,578,475,202,512 }, 
1206 { 16,7,18,35,60,0,14,20,118,28,68,22,2,24,1,92,158,107,5,49,154,126,109,12,43,10,55,6,677,71,21,168 }, 
1207 { 93,728,531,160,559,373,574,120,295,860,533,269,717,260,926,902,258,318,36,201,261,434,851,137,617,141,187,352,843,384,332,251 }, 
1208 { 28,0,1,9,22,109,83,39,49,12,36,67,55,5,96,2,128,30,158,69,21,23,160,208,35,13,65,323,50,141,194,238 }, 
1209 { 23,13,51,1,5,15,141,21,0,2,165,515,202,700,12,197,180,120,32,115,4,753,64,9,7,269,6,3,125,386,48,453 }, 
1210 { 5,21,13,49,14,20,7,23,43,32,1,0,652,48,713,22,38,2,16,132,955,107,12,279,24,888,197,640,70,303,18,638 }, 
1211 { 9,0,28,39,1,30,35,101,22,67,83,141,49,175,36,68,55,88,13,251,10,69,23,158,180,115,64,100,217,65,345,166 }, 
1212 { 260,120,82,269,5,450,351,1,202,141,854,13,77,922,32,33,137,4,23,125,291,21,15,515,165,349,177,700,318,326,180,753 }, 
1213 { 121,16,18,35,363,101,60,20,107,14,68,259,621,55,604,43,7,252,9,364,126,0,167,191,5,407,132,28,199,419,146,10 }, 
1214 { 13,23,51,1,15,0,2,141,5,515,12,21,700,115,165,180,4,753,3,197,202,32,9,120,7,8,6,11,37,10,457,269 }, 
1215 { 201,144,206,443,418,203,435,96,335,459,187,1,88,332,330,321,269,934,30,372,822,521,268,326,44,523,382,141,410,264,494,473 }, 
1216 { 31,44,276,201,116,131,284,662,567,144,9,489,98,295,268,434,0,30,137,39,93,1,187,22,219,918,110,299,141,36,224,384 }, 
1217 { 520,478,664,1,264,604,9,167,777,759,411,0,806,724,48,21,101,68,647,936,363,223,118,682,410,18,100,16,252,98,265,13 }, 
1218 { 23,70,21,87,60,75,120,182,163,379,92,18,7,937,71,121,446,132,24,98,931,126,107,77,795,195,115,44,411,146,51,850 }, 
1219 { 39,9,0,737,127,31,846,98,1,827,105,310,371,30,254,100,44,18,395,242,272,101,385,916,836,16,265,131,938,93,166,557 }, 
1220 { 279,20,43,126,107,7,92,16,356,362,60,595,246,359,598,35,0,683,939,653,121,97,125,441,399,392,150,199,48,230,14,649 }, 
1221 { 206,417,93,959,499,728,8,559,120,473,137,141,10,564,31,260,44,450,203,341,253,244,373,116,143,638,268,180,352,110,318,940 }, 
1222 { 259,465,147,132,590,687,534,199,581,146,941,427,107,640,279,178,121,5,195,150,522,955,198,35,786,929,798,142,1,21,325,626 }, 
1223 { 523,15,120,450,202,515,403,51,817,700,13,753,23,457,33,899,128,64,730,102,494,342,115,719,453,196,49,99,318,421,308,5 }, 
1224 { 141,559,10,244,365,564,661,180,253,143,752,110,55,317,533,341,901,93,373,206,535,160,82,922,260,36,531,964,352,332,261,197 }, 
1225 { 219,258,98,127,276,964,943,137,843,535,201,935,131,860,261,295,284,567,206,44,116,31,253,492,203,332,160,615,36,93,55,692 }, 
1226 { 0,319,422,207,945,693,577,887,32,804,95,344,104,904,61,20,5,43,7,725,113,510,306,102,49,263,153,426,33,83,22,9 }, 
1227 { 1,22,0,5,12,2,36,21,28,86,49,105,9,10,23,13,141,95,31,55,128,37,51,4,83,202,3,64,96,7,32,44 }, 
1228 { 15,515,13,700,1,0,753,2,23,3,4,5,51,10,115,197,6,33,12,9,165,7,8,77,11,961,180,269,141,22,120,457 }, 
1229 { 15,1,23,120,77,13,515,51,141,202,700,180,110,137,260,753,326,5,128,102,0,21,2,165,269,33,197,450,318,217,93,115 }, 
1230 { 15,515,1,700,0,753,13,2,23,180,51,5,120,4,9,115,197,12,7,165,21,33,6,82,3,8,523,901,31,141,457,260 }, 
1231 { 16,18,24,7,92,35,60,75,9,13,71,14,0,108,50,21,126,121,1,140,23,5,132,146,2,12,128,10,64,141,70,87 }, 
1232 { 180,341,901,15,515,1,365,700,0,2,197,753,115,4,10,13,752,5,3,8,165,317,141,23,143,873,44,31,569,55,93,6 }, 
1233 { 9,0,175,35,101,28,39,67,68,1,65,83,30,69,364,336,22,114,55,124,194,158,100,289,252,166,64,345,103,36,50,88 }, 
1234 { 64,165,180,197,115,247,217,237,21,13,32,316,22,141,352,72,288,304,95,225,76,391,386,16,468,90,49,35,365,640,372,23 }, 
1235 { 15,515,700,13,753,1,0,2,23,4,5,3,115,51,141,197,12,10,180,961,7,9,21,33,217,6,8,165,457,11,77,341 }, 
1236 { 132,121,199,146,60,279,493,640,407,598,126,195,534,581,955,590,107,5,150,35,522,49,259,16,18,360,156,0,147,362,21,167 }, 
1237 { 0,1,28,9,22,5,36,12,65,24,67,96,2,83,18,50,114,55,21,16,7,10,23,14,13,160,137,51,48,218,103,69 }, 
1238 { 93,120,957,77,30,968,459,110,137,160,613,102,202,352,373,141,31,372,217,330,190,318,269,260,203,44,28,473,228,177,863,704 }, 
1239 { 15,515,700,0,753,1,13,23,2,51,5,9,120,82,4,7,901,197,10,8,260,180,341,12,33,6,3,523,165,102,115,141 }, 
1240 { 206,417,8,141,499,44,244,93,31,10,137,253,559,116,728,144,120,564,269,638,203,352,143,260,341,752,268,717,951,180,160,110 }, 
1241 { 530,254,228,1,96,21,406,39,827,31,669,840,613,829,137,679,166,98,23,51,960,438,131,93,48,224,219,317,310,36,876,190 }, 
1242 { 15,515,700,753,13,457,0,197,719,1,165,82,23,8,120,730,2,10,12,180,134,5,9,141,260,4,351,51,115,3,341,899 }, 
1243 { 0,16,68,9,24,28,18,35,252,109,39,419,124,158,154,55,101,71,22,118,60,7,49,65,333,14,1,10,329,364,677,346 }, 
1244 { 1,15,13,23,515,51,120,0,700,180,2,165,5,753,141,197,21,33,202,102,260,4,9,12,7,326,137,450,115,6,82,110 }, 
1245 { 535,253,352,564,110,365,82,180,341,10,854,533,55,898,244,901,873,141,752,143,642,559,498,317,36,951,115,964,638,282,661,197 }, 
1246 { 31,44,125,338,116,64,242,36,1,10,55,22,456,237,180,13,299,164,506,86,23,165,558,143,0,762,492,479,844,546,93,8 }, 
1247 { 13,23,4,1,202,2,0,51,115,77,141,180,5,15,217,3,33,11,515,317,9,10,102,21,700,341,365,318,269,64,32,128 }, 
1248 { 9,39,0,166,68,101,28,364,30,158,562,35,175,65,333,154,49,404,706,124,21,252,274,168,190,289,100,570,16,1,310,346 }, 
1249 { 15,515,700,753,341,13,0,23,1,33,141,4,260,82,77,51,351,180,9,5,115,137,10,217,11,120,102,40,349,269,202,854 } 
1250#else 
1251 #include "rgbcx_table4.h" 
1252#endif 
1253 }; 
1254 
1255 static uint8_t g_best_total_orderings3[NUM_UNIQUE_TOTAL_ORDERINGS3][32] =  
1256 { 
1257 { 12,1,3,5,27,2,4,38,8,7,16,18,6,10,41,79,40,23,46,9,20,88,22,37,14,19,24,126,99,119,35,11 }, 
1258 { 7,64,116,14,94,30,8,42,1,108,47,55,137,10,134,95,96,115,69,32,63,29,90,113,11,148,16,103,19,9,34,25 }, 
1259 { 12,1,0,5,3,7,4,27,8,6,38,40,41,16,18,46,9,10,20,23,79,62,14,22,88,99,37,126,92,19,120,11 }, 
1260 { 16,88,27,18,46,48,126,107,79,19,59,38,37,65,23,66,0,2,3,43,12,151,28,25,5,87,72,40,1,20,52,92 }, 
1261 { 79,48,88,16,27,65,18,38,46,19,37,4,72,33,126,41,52,0,12,92,5,1,2,107,3,77,23,91,43,51,22,74 }, 
1262 { 1,8,41,122,10,22,2,0,87,24,37,120,38,7,39,4,5,3,9,92,62,59,23,16,104,11,27,79,19,26,25,32 }, 
1263 { 2,76,99,28,40,86,93,21,138,60,6,0,17,128,145,119,98,144,141,82,147,54,67,75,5,12,27,132,146,1,38,14 }, 
1264 { 47,7,64,90,1,118,116,85,57,14,30,94,50,45,137,134,8,42,69,139,55,68,58,108,95,29,10,115,0,32,2,11 }, 
1265 { 49,8,10,30,124,11,32,113,130,58,125,9,100,53,104,115,131,103,24,7,1,39,45,36,139,0,137,22,90,44,114,105 }, 
1266 { 9,38,72,125,49,41,84,11,13,5,27,0,16,92,8,2,65,105,10,18,48,29,127,131,36,14,1,46,111,79,130,12 }, 
1267 { 130,8,10,100,104,131,49,32,53,39,30,36,113,24,11,22,124,44,83,58,7,103,1,4,9,125,5,0,91,33,115,74 }, 
1268 { 114,11,58,8,120,49,9,124,142,111,41,30,10,0,97,130,62,84,38,5,72,125,92,127,100,27,139,113,13,132,32,1 }, 
1269 { 60,46,28,27,40,20,0,17,18,2,126,16,6,38,86,23,79,54,1,93,5,88,41,14,21,111,7,48,3,84,72,62 }, 
1270 { 72,92,38,65,84,48,41,79,27,16,29,111,88,5,18,46,1,0,152,14,37,19,77,42,132,7,22,13,119,56,12,2 }, 
1271 { 7,55,1,95,29,56,64,116,143,8,14,30,47,94,152,90,65,67,10,133,42,72,146,84,16,48,6,0,25,108,77,21 }, 
1272 { 27,23,20,5,0,79,38,2,3,1,59,46,4,41,33,86,37,87,88,92,7,126,43,8,22,152,151,150,149,148,147,146 }, 
1273 { 12,0,1,2,7,6,3,5,28,4,8,14,60,40,17,19,21,86,126,93,10,18,9,29,48,99,65,25,84,119,72,41 }, 
1274 { 60,40,99,2,54,12,0,1,19,28,98,93,6,138,21,5,27,17,151,14,76,46,16,18,38,29,86,144,107,7,25,41 }, 
1275 { 12,0,1,2,3,5,6,7,4,28,8,60,14,40,16,17,21,10,19,9,86,38,126,41,93,27,29,48,62,84,79,99 }, 
1276 { 0,1,2,10,5,8,3,25,4,29,32,34,63,7,77,26,16,48,65,56,14,22,129,103,72,24,18,152,140,53,96,42 }, 
1277 { 46,126,18,54,12,16,1,0,5,2,27,98,20,23,6,3,88,48,28,7,19,8,4,60,151,38,37,21,79,14,65,40 }, 
1278 { 76,6,141,86,119,2,138,67,28,145,0,93,17,1,40,60,146,99,147,14,21,144,132,7,5,29,55,27,16,75,19,12 }, 
1279 { 71,5,51,39,22,80,0,43,10,122,8,62,41,24,104,87,35,37,2,91,33,120,36,38,1,131,9,100,130,66,3,4 }, 
1280 { 126,18,46,27,20,16,88,23,12,79,54,59,48,0,73,1,37,151,5,19,28,38,2,66,60,3,65,98,14,26,6,43 }, 
1281 { 22,10,8,5,0,71,35,80,104,39,24,51,100,1,62,32,2,130,11,41,7,9,53,43,49,83,122,120,30,44,37,38 }, 
1282 { 1,34,14,129,53,63,42,26,121,148,7,44,96,10,0,24,100,32,64,116,140,22,5,19,29,103,135,108,8,61,39,83 }, 
1283 { 1,7,34,63,44,25,135,14,24,108,22,0,83,94,5,129,35,101,47,121,2,19,42,53,6,110,103,8,148,10,16,123 }, 
1284 { 12,28,16,60,18,1,6,21,14,0,86,19,2,48,93,17,38,29,7,5,65,126,46,72,41,79,84,119,40,56,54,88 }, 
1285 { 0,2,12,27,5,46,38,40,41,79,88,99,3,23,1,62,20,4,22,37,92,35,18,8,16,24,10,60,7,120,98,54 }, 
1286 { 1,7,14,56,8,0,84,67,10,2,133,72,42,111,5,30,21,4,9,3,25,94,16,116,47,11,65,18,132,90,55,64 }, 
1287 { 30,8,124,139,45,11,58,90,113,137,7,115,10,32,1,49,94,85,9,47,108,103,0,97,63,14,50,114,53,106,100,25 }, 
1288 { 65,38,48,27,16,79,72,18,88,19,46,77,84,92,37,41,0,29,1,14,12,111,2,5,31,36,87,74,105,40,28,51 }, 
1289 { 10,8,30,113,130,100,53,32,115,103,104,7,1,121,39,49,131,44,24,36,63,137,34,45,22,90,108,83,26,11,94,139 }, 
1290 { 51,52,43,33,5,74,16,37,71,91,38,3,36,87,48,22,4,0,122,41,39,18,66,27,79,24,65,88,59,23,62,92 }, 
1291 { 1,7,63,53,108,121,94,44,103,100,14,10,129,47,32,26,24,25,148,42,135,22,0,61,83,8,39,104,5,64,115,34 }, 
1292 { 1,8,10,7,5,0,80,32,62,2,24,44,53,83,9,41,30,22,100,11,14,25,120,4,26,6,3,16,122,34,19,35 }, 
1293 { 74,4,36,48,33,91,39,79,22,16,65,5,131,38,24,71,27,52,0,105,51,18,88,104,3,31,10,37,72,19,41,130 }, 
1294 { 59,43,38,79,23,27,92,51,0,16,46,5,18,88,41,37,66,3,87,20,48,2,122,4,22,12,1,126,19,65,33,24 }, 
1295 { 12,28,1,27,0,16,2,46,65,60,21,3,5,18,6,19,48,14,4,7,79,88,86,29,22,72,93,40,23,8,17,41 }, 
1296 { 22,91,39,33,24,71,5,131,36,10,51,0,130,8,104,2,35,125,9,43,52,49,83,80,100,41,122,3,37,38,4,16 }, 
1297 { 12,0,1,2,5,3,4,8,7,27,18,38,10,6,16,46,9,20,41,23,126,79,22,14,19,99,88,54,37,48,62,35 }, 
1298 { 12,27,1,2,3,0,46,4,38,16,8,28,7,79,18,5,84,6,88,10,14,21,23,20,40,22,60,19,9,29,72,65 }, 
1299 { 1,14,7,55,95,29,8,94,30,56,10,108,77,116,152,64,32,48,63,42,143,148,16,25,137,65,11,0,115,9,19,72 }, 
1300 { 37,79,66,38,16,52,48,59,43,27,87,33,41,4,23,51,3,5,88,18,92,46,73,122,22,71,20,0,65,19,2,120 }, 
1301 { 24,32,83,22,53,1,8,10,7,30,35,5,103,0,100,101,121,113,34,123,63,2,44,25,71,115,80,14,26,108,51,39 }, 
1302 { 97,45,111,58,85,139,0,90,47,7,120,106,142,30,50,132,41,62,84,1,119,114,14,56,117,8,38,29,2,64,116,5 }, 
1303 { 12,28,16,18,1,60,6,14,2,21,0,86,126,19,48,93,7,27,17,29,5,65,54,38,72,79,84,88,119,145,8,111 }, 
1304 { 118,47,64,116,57,85,7,14,50,1,42,0,45,68,86,69,2,111,134,28,90,55,16,29,56,48,84,144,60,30,112,41 }, 
1305 { 12,1,2,0,7,6,28,5,3,4,8,14,60,21,18,40,17,86,10,9,16,29,19,93,126,79,38,84,72,27,111,119 }, 
1306 { 11,8,49,130,10,125,9,124,100,114,131,30,58,104,32,39,24,113,36,105,0,41,22,120,5,53,111,38,142,44,83,35 }, 
1307 { 50,70,47,118,85,57,106,0,45,7,64,90,81,14,2,134,28,62,86,55,69,1,78,119,68,56,18,67,16,60,29,21 }, 
1308 { 43,37,33,87,51,41,66,5,122,38,22,59,92,0,23,91,27,16,71,79,18,52,120,4,3,24,46,20,73,39,62,36 }, 
1309 { 79,48,4,16,27,88,43,33,18,38,65,37,46,3,19,51,52,22,66,87,74,5,41,91,23,59,0,71,122,72,20,92 }, 
1310 { 32,100,10,8,30,104,24,44,39,113,83,103,1,7,22,53,115,63,135,121,26,35,34,5,0,108,137,90,91,45,2,130 }, 
1311 { 0,1,2,5,16,12,6,7,14,3,19,18,29,20,4,21,40,8,17,35,23,48,126,22,25,56,26,10,98,27,38,65 }, 
1312 { 143,67,56,146,1,7,133,55,64,141,134,69,6,47,14,29,84,21,111,147,57,16,95,72,118,132,50,0,2,18,119,42 }, 
1313 { 1,7,67,14,133,111,8,84,0,21,2,47,64,132,55,10,95,147,119,42,16,5,72,56,4,3,6,29,9,25,18,30 }, 
1314 { 68,57,69,112,144,86,102,2,134,55,0,70,118,64,75,47,14,28,93,143,67,7,50,149,1,21,29,56,119,95,60,78 }, 
1315 { 58,97,114,30,124,45,11,139,8,90,0,142,7,10,41,113,84,62,49,111,85,1,9,5,137,120,32,14,2,117,47,38 }, 
1316 { 23,66,18,79,38,20,43,27,16,88,46,59,126,37,87,12,73,92,3,5,48,0,19,54,2,51,28,1,41,65,122,22 }, 
1317 { 0,12,2,27,5,40,46,38,1,41,3,79,88,23,99,4,20,62,22,54,92,18,8,37,16,35,10,7,19,120,144,24 }, 
1318 { 1,14,25,26,0,7,44,34,129,42,24,5,135,22,19,148,6,96,83,2,29,16,63,35,101,64,140,136,116,110,3,10 }, 
1319 { 12,1,2,27,3,4,38,5,7,8,18,16,46,6,0,40,41,10,79,23,88,9,20,22,14,19,37,92,48,126,28,21 }, 
1320 { 7,1,10,32,108,103,94,47,8,53,25,14,34,115,100,129,121,130,148,42,64,116,63,26,44,0,24,30,113,4,104,22 }, 
1321 { 47,134,7,14,55,69,64,95,1,29,85,118,56,116,45,57,102,143,50,90,42,30,16,94,0,8,67,75,133,2,18,48 }, 
1322 { 12,1,2,0,7,6,28,8,14,5,3,4,40,21,17,18,60,86,16,93,126,10,9,29,99,38,119,25,19,54,27,84 }, 
1323 { 59,16,27,18,23,88,79,37,46,66,38,20,73,126,3,43,48,87,92,51,41,12,19,5,52,107,65,0,151,122,54,2 }, 
1324 { 1,21,147,7,119,14,76,132,55,0,86,145,2,6,69,67,16,143,111,138,17,28,29,60,18,93,8,19,40,56,84,5 }, 
1325 { 144,86,112,2,68,102,69,0,149,93,75,28,57,55,145,60,21,67,99,134,143,40,146,119,82,110,62,6,29,26,78,14 }, 
1326 { 102,57,55,69,143,75,146,67,56,68,134,2,29,141,0,21,6,14,133,118,64,1,7,95,47,84,111,28,147,82,72,119 }, 
1327 { 0,70,57,119,50,145,2,86,28,118,69,78,149,47,60,68,67,55,93,81,134,21,14,62,64,7,5,1,132,85,41,16 }, 
1328 { 51,5,43,71,122,87,41,37,91,39,0,22,33,36,38,24,66,120,62,2,80,16,92,10,59,4,27,23,35,79,8,3 }, 
1329 { 12,1,2,0,7,6,28,5,8,14,3,21,40,4,60,17,86,18,16,93,10,9,126,119,99,29,19,41,38,27,25,92 }, 
1330 { 27,18,46,126,23,16,88,79,20,151,59,73,48,38,0,54,12,2,37,1,19,5,28,60,66,41,3,109,86,65,40,6 }, 
1331 { 48,79,4,33,16,74,65,38,88,27,91,52,18,36,22,19,46,0,37,3,51,5,71,39,72,43,24,41,92,87,2,10 }, 
1332 { 86,2,144,93,28,112,141,6,102,21,99,60,75,0,68,82,69,146,67,149,55,40,145,76,111,147,56,119,110,143,26,132 }, 
1333 { 6,138,2,99,86,17,40,93,28,21,145,141,0,60,119,147,128,76,67,54,1,12,5,27,144,14,38,98,146,41,29,19 }, 
1334 { 1,8,0,10,2,29,7,5,3,56,4,25,14,152,63,32,65,72,96,42,34,108,48,9,26,16,84,103,67,148,22,129 }, 
1335 { 149,145,0,86,2,28,93,144,62,60,119,101,21,41,5,35,78,99,26,40,12,68,57,67,110,120,69,18,55,76,132,70 }, 
1336 { 12,28,16,1,48,19,6,60,2,14,18,21,0,27,46,65,86,29,5,7,72,93,40,3,17,84,56,88,126,4,38,8 }, 
1337 { 1,8,5,10,7,24,2,62,0,41,22,122,120,9,4,3,32,87,11,37,38,83,100,44,25,104,16,26,39,80,14,6 }, 
1338 { 0,119,62,86,145,149,28,132,93,2,120,67,60,41,35,5,144,21,123,38,111,81,84,56,12,44,24,50,92,55,40,22 }, 
1339 { 2,93,99,28,40,144,60,0,86,150,76,21,149,98,6,25,1,61,82,26,12,5,54,141,7,18,145,16,27,138,110,38 }, 
1340 { 24,8,10,22,32,35,100,5,1,53,0,7,71,80,30,123,83,104,51,11,2,39,44,113,9,62,25,103,34,101,43,41 }, 
1341 { 12,1,2,0,7,6,28,5,40,60,8,16,3,18,14,4,86,21,17,93,41,10,9,99,27,119,38,19,126,22,48,145 }, 
1342 { 45,47,50,7,85,90,97,1,64,139,116,118,30,58,14,106,70,111,0,57,94,42,137,142,29,120,8,56,18,134,84,41 }, 
1343 { 12,0,2,5,27,38,1,46,41,40,79,144,3,22,88,23,28,60,99,62,6,24,26,7,4,16,10,35,37,18,14,20 }, 
1344 { 37,38,59,92,0,5,23,51,79,41,27,22,2,3,87,16,46,4,1,43,20,33,18,88,24,71,8,10,48,19,126,122 }, 
1345 { 12,28,16,60,1,18,6,21,19,14,48,0,2,86,93,5,46,29,17,27,65,7,3,72,38,126,119,40,84,37,56,4 }, 
1346 { 0,2,5,1,16,6,27,28,18,38,60,7,14,21,46,40,86,41,19,48,93,8,3,79,22,4,10,37,62,23,24,111 }, 
1347 { 85,7,90,30,47,139,45,50,94,58,137,1,8,64,14,116,118,115,113,11,124,108,0,10,97,57,32,70,42,106,29,114 }, 
1348 { 33,36,22,71,51,5,91,39,0,52,43,24,131,74,16,37,38,122,41,3,87,48,4,104,35,80,10,2,105,62,27,18 }, 
1349 { 12,1,27,2,0,16,3,28,46,18,4,6,5,72,21,79,38,7,14,60,88,8,65,19,48,29,23,40,22,20,86,126 }, 
1350 { 0,12,2,27,5,38,46,41,1,40,79,3,88,23,22,99,20,37,62,4,18,6,16,35,60,28,24,7,92,8,14,10 }, 
1351 { 7,47,1,30,137,8,116,94,90,64,14,115,108,118,57,10,148,113,42,85,32,11,63,50,103,45,124,134,55,9,69,34 }, 
1352 { 55,7,1,29,56,143,64,47,67,133,14,146,95,72,84,8,116,111,6,134,141,21,65,0,69,30,16,45,85,42,50,10 }, 
1353 { 14,1,42,8,10,29,108,63,55,148,95,32,7,19,25,115,103,34,56,129,77,0,16,152,94,30,113,26,2,5,48,4 }, 
1354 { 111,120,142,97,58,0,41,45,62,132,114,84,139,30,5,8,38,2,7,85,119,90,117,1,124,11,56,47,28,27,35,72 }, 
1355 { 1,0,14,2,6,5,16,19,7,29,42,18,3,25,12,35,21,8,26,17,40,4,20,48,109,99,22,96,55,101,10,61 }, 
1356 { 12,0,1,5,3,2,4,7,27,8,38,6,40,18,16,10,20,46,9,41,23,22,79,14,62,19,37,126,88,11,92,48 }, 
1357 { 10,8,104,39,24,32,22,83,44,100,30,130,53,91,113,5,11,1,35,33,7,49,0,2,103,71,36,124,9,80,131,34 }, 
1358 { 1,7,0,14,8,34,5,25,35,26,6,63,10,123,2,16,103,19,44,32,135,121,108,80,62,30,115,94,149,144,53,18 }, 
1359 { 75,68,146,141,102,67,2,21,6,57,69,143,0,55,82,86,28,144,147,29,93,112,56,119,133,14,76,60,84,134,111,145 }, 
1360 { 10,32,115,7,8,53,1,108,30,113,94,137,100,63,90,34,130,103,121,47,44,25,104,39,24,26,85,14,49,36,22,131 }, 
1361 { 39,24,10,22,8,130,91,104,83,49,5,33,100,11,0,35,32,131,71,36,9,44,53,2,80,51,30,1,41,7,43,62 }, 
1362 { 38,36,65,105,27,72,31,79,41,131,5,48,125,39,0,16,92,46,22,13,18,84,24,37,88,2,33,74,91,71,130,49 }, 
1363 { 0,106,62,50,45,119,85,81,132,28,2,86,41,47,38,60,35,117,5,29,7,30,145,90,55,70,14,111,18,67,93,56 }, 
1364 { 0,2,5,1,3,25,19,26,4,34,29,10,22,16,8,7,24,14,48,65,53,18,6,77,44,56,72,61,121,21,136,40 }, 
1365 { 7,1,94,8,47,115,10,32,113,103,30,108,137,63,14,64,116,148,129,42,90,25,34,118,53,57,11,49,85,9,96,50 }, 
1366 { 14,0,1,26,19,5,42,2,25,24,29,22,6,44,61,16,7,96,136,3,140,34,35,55,135,18,48,77,83,4,8,10 }, 
1367 { 1,7,14,0,25,6,34,5,26,16,63,2,19,8,35,101,108,29,94,10,18,42,123,144,129,47,61,21,3,62,149,4 }, 
1368 { 12,0,2,1,28,5,6,120,7,60,40,16,18,86,27,14,21,93,8,62,41,38,3,17,4,119,99,48,19,126,10,9 }, 
1369 { 86,144,93,2,28,149,0,60,99,112,110,145,40,21,102,26,75,62,69,1,12,101,119,25,76,67,7,68,55,5,6,14 }, 
1370 { 8,30,10,32,113,49,115,137,124,103,45,90,7,139,11,1,58,53,130,94,108,100,9,63,85,125,34,47,0,24,44,104 }, 
1371 { 120,142,111,41,58,114,97,0,11,62,84,124,5,30,8,38,132,127,27,139,92,10,72,45,49,9,28,2,29,56,16,1 }, 
1372 { 8,113,30,137,7,32,10,90,94,115,1,103,108,63,47,85,49,53,11,45,34,50,14,25,9,124,100,130,139,121,42,26 }, 
1373 { 64,7,14,47,134,55,1,42,95,69,116,90,94,30,8,29,56,137,45,108,85,10,57,16,102,143,118,19,63,32,11,50 }, 
1374 { 62,132,0,119,120,41,111,86,35,28,5,84,56,38,2,93,145,60,67,12,92,27,29,72,55,117,21,24,133,149,22,45 }, 
1375 { 57,68,69,118,134,64,50,47,55,14,7,2,102,144,0,112,70,86,85,1,95,29,116,143,42,75,16,56,28,45,21,48 }, 
1376 { 0,12,2,1,5,28,6,40,60,27,7,38,16,14,86,18,93,41,62,46,99,35,8,23,3,17,22,21,10,19,79,20 }, 
1377 { 12,1,2,27,16,3,38,111,4,0,18,5,7,46,40,8,79,6,14,28,88,10,48,41,19,84,21,9,22,23,20,72 }, 
1378 { 53,103,32,7,1,100,22,63,71,44,10,115,108,24,92,104,26,30,122,94,8,39,83,34,137,135,90,91,121,5,87,47 }, 
1379 { 87,37,41,0,22,38,2,92,1,24,4,8,3,59,10,5,39,23,71,79,122,27,16,46,33,7,91,20,18,51,9,120 }, 
1380 { 1,7,8,10,0,5,35,32,53,44,14,30,2,80,25,34,6,62,26,103,16,19,63,9,149,24,121,41,22,11,113,83 }, 
1381 { 11,58,8,30,124,49,10,113,9,114,139,45,97,32,7,137,90,1,0,130,115,125,100,24,5,94,53,41,14,13,35,38 }, 
1382 { 125,105,9,36,131,49,8,130,39,11,10,5,22,38,41,104,0,31,13,24,27,16,2,72,65,91,48,32,84,18,100,74 }, 
1383 { 12,1,0,2,6,3,7,5,4,8,14,28,16,60,18,10,21,17,19,9,40,27,86,93,29,38,54,11,25,48,46,41 }, 
1384 { 84,41,38,72,92,29,111,5,65,120,79,0,27,56,48,14,132,16,119,22,86,88,46,28,62,12,1,2,93,18,24,127 }, 
1385 { 99,28,40,60,2,93,138,0,98,17,86,54,76,12,27,1,21,144,128,38,5,14,46,18,25,16,109,6,41,145,7,29 }, 
1386 { 1,63,10,32,148,14,103,34,42,7,8,108,116,53,64,96,25,121,26,94,140,0,29,19,55,24,100,136,5,4,44,115 }, 
1387 { 131,100,130,49,10,8,36,104,39,0,48,41,11,38,4,24,27,22,16,44,79,5,33,2,53,9,125,74,91,120,32,83 }, 
1388 { 36,39,131,74,4,91,22,33,125,104,130,48,10,24,16,5,49,8,100,105,79,0,9,65,71,2,18,83,31,11,19,44 }, 
1389 { 0,12,2,1,6,5,7,28,40,60,16,14,18,62,86,27,93,8,17,38,21,41,35,99,3,19,10,23,22,4,9,48 }, 
1390 { 1,7,67,14,21,147,111,55,132,119,0,8,2,76,64,16,47,84,6,18,86,95,145,10,42,29,133,5,56,134,17,72 }, 
1391 { 69,55,47,134,102,143,7,57,118,95,14,64,29,56,1,50,75,67,146,2,0,133,68,16,21,6,141,85,116,18,72,65 }, 
1392 { 1,44,7,24,83,63,34,103,22,121,53,32,25,35,0,115,108,5,14,8,10,101,94,30,2,123,110,26,137,47,90,19 }, 
1393 { 14,1,25,42,34,0,26,96,19,29,140,5,53,10,2,121,3,24,44,22,55,77,129,7,63,16,8,4,6,61,100,48 }, 
1394 { 30,90,7,8,137,94,85,1,47,113,115,108,45,139,124,11,10,32,50,58,103,14,63,64,9,116,49,42,25,148,0,53 }, 
1395 { 40,99,2,60,28,17,0,54,93,98,86,138,6,12,21,76,1,5,27,144,128,38,19,46,14,41,145,7,16,67,3,109 }, 
1396 { 45,58,30,139,90,7,85,137,97,8,124,47,1,11,106,114,50,94,0,113,10,115,14,32,9,64,108,41,49,29,62,116 }, 
1397 { 14,42,10,1,63,96,32,25,34,8,129,29,0,103,55,19,26,53,77,5,95,2,4,7,3,16,148,56,18,24,121,108 }, 
1398 { 21,2,75,86,6,76,144,28,119,99,93,147,141,67,102,145,60,132,146,128,0,82,40,138,55,111,143,17,133,112,69,14 }, 
1399 { 111,120,41,62,84,132,0,5,38,119,56,92,72,142,27,28,29,35,58,80,2,86,65,79,12,14,1,24,145,16,21,48 }, 
1400 { 146,67,141,69,133,21,6,143,57,55,111,147,56,1,14,132,7,2,134,102,0,119,29,84,76,64,86,72,28,68,47,75 }, 
1401 { 12,1,0,5,27,3,7,4,38,8,6,41,16,40,46,10,18,79,2,9,23,86,20,22,62,14,37,88,92,19,24,11 }, 
1402 { 0,12,2,1,27,5,38,28,60,6,40,7,16,46,18,14,41,99,93,62,3,79,86,23,149,8,22,35,88,17,19,10 }, 
1403 { 141,6,21,67,147,102,146,2,76,119,132,69,55,111,86,75,28,133,143,0,1,145,14,128,56,99,17,60,29,93,84,68 }, 
1404 { 21,76,1,119,86,145,2,0,14,7,6,138,146,55,17,28,132,93,67,40,60,143,29,147,111,16,69,141,5,56,19,133 }, 
1405 { 1,8,108,14,7,116,64,42,10,63,94,32,115,103,113,96,30,34,55,47,95,148,29,140,129,25,134,53,69,26,19,11 }, 
1406 { 12,1,3,5,4,2,0,7,8,38,27,16,18,6,10,20,41,40,79,46,9,23,22,88,92,37,14,24,62,19,48,99 }, 
1407 { 1,14,7,0,6,25,5,16,19,2,42,26,29,35,61,8,18,129,101,21,3,110,34,148,96,10,17,4,22,40,12,20 }, 
1408 { 0,2,5,1,3,19,22,26,16,24,29,7,14,6,4,25,18,44,8,48,12,61,20,21,10,35,65,56,23,40,17,107 }, 
1409 { 1,7,8,29,56,0,10,14,2,42,72,5,4,65,3,30,84,94,67,9,25,133,111,11,32,108,16,63,21,96,26,48 } 
1410 }; 
1411 
1412 static inline uint32_t iabs(int32_t i) { return (i < 0) ? static_cast<uint32_t>(-i) : static_cast<uint32_t>(i); } 
1413 static inline uint64_t iabs(int64_t i) { return (i < 0) ? static_cast<uint64_t>(-i) : static_cast<uint64_t>(i); } 
1414 
1415 static inline uint8_t to_5(uint32_t v) { v = v * 31 + 128; return (uint8_t)((v + (v >> 8)) >> 8); } 
1416 static inline uint8_t to_6(uint32_t v) { v = v * 63 + 128; return (uint8_t)((v + (v >> 8)) >> 8); } 
1417 
1418 template <typename S> inline S maximum(S a, S b) { return (a > b) ? a : b; } 
1419 template <typename S> inline S maximum(S a, S b, S c) { return maximum(maximum(a, b), c); } 
1420 template <typename S> inline S maximum(S a, S b, S c, S d) { return maximum(maximum(maximum(a, b), c), d); } 
1421  
1422 template <typename S> inline S minimum(S a, S b) { return (a < b) ? a : b; } 
1423 template <typename S> inline S minimum(S a, S b, S c) { return minimum(minimum(a, b), c); } 
1424 template <typename S> inline S minimum(S a, S b, S c, S d) { return minimum(minimum(minimum(a, b), c), d); } 
1425 
1426 template<typename T> inline T square(T a) { return a * a; } 
1427 
1428 static inline float clampf(float value, float low, float high) { if (value < low) value = low; else if (value > high) value = high; return value; } 
1429 static inline uint8_t clamp255(int32_t i) { return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i); } 
1430 
1431 template <typename S> inline S clamp(S value, S low, S high) { return (value < low) ? low : ((value > high) ? high : value); } 
1432 static inline int32_t clampi(int32_t value, int32_t low, int32_t high) { if (value < low) value = low; else if (value > high) value = high; return value; } 
1433 
1434 static inline int squarei(int a) { return a * a; } 
1435 static inline int absi(int a) { return (a < 0) ? -a : a; } 
1436 
1437 template<typename F> inline F lerp(F a, F b, F s) { return a + (b - a) * s; } 
1438 
1439 enum class eNoClamp { cNoClamp }; 
1440 
1441 struct color32 
1442 { 
1443 union 
1444 { 
1445 struct 
1446 { 
1447 uint8_t r; 
1448 uint8_t g; 
1449 uint8_t b; 
1450 uint8_t a; 
1451 }; 
1452 
1453 uint8_t c[4]; 
1454  
1455 uint32_t m; 
1456 }; 
1457 
1458 color32() { } 
1459 
1460 color32(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { set(vr, vg, vb, va); } 
1461 color32(eNoClamp unused, uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { (void)unused; set_noclamp_rgba(vr, vg, vb, va); } 
1462 
1463 void set(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { c[0] = static_cast<uint8_t>(vr); c[1] = static_cast<uint8_t>(vg); c[2] = static_cast<uint8_t>(vb); c[3] = static_cast<uint8_t>(va); } 
1464 
1465 void set_noclamp_rgb(uint32_t vr, uint32_t vg, uint32_t vb) { c[0] = static_cast<uint8_t>(vr); c[1] = static_cast<uint8_t>(vg); c[2] = static_cast<uint8_t>(vb); } 
1466 void set_noclamp_rgba(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { set(vr, vg, vb, va); } 
1467 
1468 void set_clamped(int vr, int vg, int vb, int va) { c[0] = clamp255(vr); c[1] = clamp255(vg); c[2] = clamp255(vb); c[3] = clamp255(va); } 
1469 
1470 uint8_t operator[] (uint32_t idx) const { assert(idx < 4); return c[idx]; } 
1471 uint8_t &operator[] (uint32_t idx) { assert(idx < 4); return c[idx]; } 
1472 
1473 bool operator== (const color32&rhs) const { return m == rhs.m; } 
1474 
1475 void set_rgb(const color32& other) { c[0] = static_cast<uint8_t>(other.c[0]); c[1] = static_cast<uint8_t>(other.c[1]); c[2] = static_cast<uint8_t>(other.c[2]); } 
1476 
1477 static color32 comp_min(const color32& a, const color32& b) { return color32(eNoClamp::cNoClamp, std::min(a[0], b[0]), std::min(a[1], b[1]), std::min(a[2], b[2]), std::min(a[3], b[3])); } 
1478 static color32 comp_max(const color32& a, const color32& b) { return color32(eNoClamp::cNoClamp, std::max(a[0], b[0]), std::max(a[1], b[1]), std::max(a[2], b[2]), std::max(a[3], b[3])); } 
1479 }; 
1480  
1481 enum dxt_constants 
1482 { 
1483 cDXT1SelectorBits = 2U, cDXT1SelectorValues = 1U << cDXT1SelectorBits, cDXT1SelectorMask = cDXT1SelectorValues - 1U, 
1484 cDXT5SelectorBits = 3U, cDXT5SelectorValues = 1U << cDXT5SelectorBits, cDXT5SelectorMask = cDXT5SelectorValues - 1U, 
1485 }; 
1486 
1487 struct bc1_block 
1488 { 
1489 enum { cTotalEndpointBytes = 2, cTotalSelectorBytes = 4 }; 
1490 
1491 uint8_t m_low_color[cTotalEndpointBytes]; 
1492 uint8_t m_high_color[cTotalEndpointBytes]; 
1493 uint8_t m_selectors[cTotalSelectorBytes]; 
1494  
1495 inline uint32_t get_low_color() const { return m_low_color[0] | (m_low_color[1] << 8U); } 
1496 inline uint32_t get_high_color() const { return m_high_color[0] | (m_high_color[1] << 8U); } 
1497 inline bool is_3color() const { return get_low_color() <= get_high_color(); } 
1498 inline void set_low_color(uint16_t c) { m_low_color[0] = static_cast<uint8_t>(c & 0xFF); m_low_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); } 
1499 inline void set_high_color(uint16_t c) { m_high_color[0] = static_cast<uint8_t>(c & 0xFF); m_high_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); } 
1500 inline uint32_t get_selector(uint32_t x, uint32_t y) const { assert((x < 4U) && (y < 4U)); return (m_selectors[y] >> (x * cDXT1SelectorBits)) & cDXT1SelectorMask; } 
1501 inline void set_selector(uint32_t x, uint32_t y, uint32_t val) { assert((x < 4U) && (y < 4U) && (val < 4U)); m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits))); m_selectors[y] |= (val << (x * cDXT1SelectorBits)); } 
1502 
1503 static inline uint16_t pack_color(const color32& color, bool scaled, uint32_t bias = 127U) 
1504 { 
1505 uint32_t r = color.r, g = color.g, b = color.b; 
1506 if (scaled) 
1507 { 
1508 r = (r * 31U + bias) / 255U; 
1509 g = (g * 63U + bias) / 255U; 
1510 b = (b * 31U + bias) / 255U; 
1511 } 
1512 return static_cast<uint16_t>(minimum(b, 31U) | (minimum(g, 63U) << 5U) | (minimum(r, 31U) << 11U)); 
1513 } 
1514 
1515 static inline uint16_t pack_unscaled_color(uint32_t r, uint32_t g, uint32_t b) { return static_cast<uint16_t>(b | (g << 5U) | (r << 11U)); } 
1516 
1517 static inline void unpack_color(uint32_t c, uint32_t& r, uint32_t& g, uint32_t& b) 
1518 { 
1519 r = (c >> 11) & 31; 
1520 g = (c >> 5) & 63; 
1521 b = c & 31; 
1522 
1523 r = (r << 3) | (r >> 2); 
1524 g = (g << 2) | (g >> 4); 
1525 b = (b << 3) | (b >> 2); 
1526 } 
1527 
1528 static inline void unpack_color_unscaled(uint32_t c, uint32_t& r, uint32_t& g, uint32_t& b) 
1529 { 
1530 r = (c >> 11) & 31; 
1531 g = (c >> 5) & 63; 
1532 b = c & 31; 
1533 } 
1534 }; 
1535 
1536 static const uint32_t TOTAL_ORDER_4_0_16 = 15; 
1537 static const uint32_t TOTAL_ORDER_4_1_16 = 700; 
1538 static const uint32_t TOTAL_ORDER_4_2_16 = 753; 
1539 static const uint32_t TOTAL_ORDER_4_3_16 = 515; 
1540 static uint16_t g_total_ordering4_hash[4096]; 
1541 static float g_selector_factors4[NUM_UNIQUE_TOTAL_ORDERINGS4][3]; 
1542 
1543 static const uint32_t TOTAL_ORDER_3_0_16 = 12; 
1544 static const uint32_t TOTAL_ORDER_3_1_16 = 15; 
1545 static const uint32_t TOTAL_ORDER_3_2_16 = 89; 
1546 static uint16_t g_total_ordering3_hash[256]; 
1547 static float g_selector_factors3[NUM_UNIQUE_TOTAL_ORDERINGS3][3]; 
1548  
1549 struct hist4 
1550 { 
1551 uint8_t m_hist[4]; 
1552 
1553 hist4()  
1554 {  
1555 memset(m_hist, 0, sizeof(m_hist));  
1556 } 
1557 
1558 hist4(uint32_t i, uint32_t j, uint32_t k, uint32_t l) 
1559 { 
1560 m_hist[0] = (uint8_t)i; 
1561 m_hist[1] = (uint8_t)j; 
1562 m_hist[2] = (uint8_t)k; 
1563 m_hist[3] = (uint8_t)l; 
1564 } 
1565 
1566 inline bool operator== (const hist4 &h) const 
1567 { 
1568 if (m_hist[0] != h.m_hist[0]) return false; 
1569 if (m_hist[1] != h.m_hist[1]) return false; 
1570 if (m_hist[2] != h.m_hist[2]) return false; 
1571 if (m_hist[3] != h.m_hist[3]) return false; 
1572 return true; 
1573 } 
1574 
1575 inline bool any_16() const  
1576 { 
1577 return (m_hist[0] == 16) || (m_hist[1] == 16) || (m_hist[2] == 16) || (m_hist[3] == 16); 
1578 } 
1579  
1580 inline uint32_t lookup_total_ordering_index() const 
1581 { 
1582 if (m_hist[0] == 16) 
1583 return TOTAL_ORDER_4_0_16; 
1584 else if (m_hist[1] == 16) 
1585 return TOTAL_ORDER_4_1_16; 
1586 else if (m_hist[2] == 16) 
1587 return TOTAL_ORDER_4_2_16; 
1588 else if (m_hist[3] == 16) 
1589 return TOTAL_ORDER_4_3_16; 
1590 
1591 // Must sum to 16, so m_hist[3] isn't needed. 
1592 return g_total_ordering4_hash[m_hist[0] | (m_hist[1] << 4) | (m_hist[2] << 8)]; 
1593 } 
1594 }; 
1595 
1596 struct hist3 
1597 { 
1598 uint8_t m_hist[3]; 
1599 
1600 hist3()  
1601 {  
1602 memset(m_hist, 0, sizeof(m_hist));  
1603 } 
1604 
1605 hist3(uint32_t i, uint32_t j, uint32_t k) 
1606 { 
1607 m_hist[0] = (uint8_t)i; 
1608 m_hist[1] = (uint8_t)j; 
1609 m_hist[2] = (uint8_t)k; 
1610 } 
1611 
1612 inline bool operator== (const hist3 &h) const 
1613 { 
1614 if (m_hist[0] != h.m_hist[0]) return false; 
1615 if (m_hist[1] != h.m_hist[1]) return false; 
1616 if (m_hist[2] != h.m_hist[2]) return false; 
1617 return true; 
1618 } 
1619 
1620 inline bool any_16() const  
1621 { 
1622 return (m_hist[0] == 16) || (m_hist[1] == 16) || (m_hist[2] == 16); 
1623 } 
1624  
1625 inline uint32_t lookup_total_ordering_index() const 
1626 { 
1627 if (m_hist[0] == 16) 
1628 return TOTAL_ORDER_3_0_16; 
1629 else if (m_hist[1] == 16) 
1630 return TOTAL_ORDER_3_1_16; 
1631 else if (m_hist[2] == 16) 
1632 return TOTAL_ORDER_3_2_16; 
1633 
1634 // Must sum to 16, so m_hist[2] isn't needed. 
1635 return g_total_ordering3_hash[m_hist[0] | (m_hist[1] << 4)]; 
1636 } 
1637 }; 
1638 
1639 struct bc1_match_entry 
1640 { 
1641 uint8_t m_hi; 
1642 uint8_t m_lo; 
1643 uint8_t m_e; 
1644 }; 
1645 
1646 static bc1_approx_mode g_bc1_approx_mode; 
1647 static bc1_match_entry g_bc1_match5_equals_1[256], g_bc1_match6_equals_1[256]; 
1648 static bc1_match_entry g_bc1_match5_half[256], g_bc1_match6_half[256];  
1649 
1650 static inline int scale_5_to_8(int v) { return (v << 3) | (v >> 2); } 
1651 static inline int scale_6_to_8(int v) { return (v << 2) | (v >> 4); } 
1652 
1653 // v0, v1 = unexpanded DXT1 endpoint values (5/6-bits) 
1654 // c0, c1 = expanded DXT1 endpoint values (8-bits) 
1655 static inline int interp_5_6_ideal(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 * 2 + c1) / 3; } 
1656 static inline int interp_5_6_ideal_round(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 * 2 + c1 + 1) / 3; } 
1657 static inline int interp_half_5_6_ideal(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 + c1) / 2; } 
1658 
1659 static inline int interp_5_nv(int v0, int v1) { assert(v0 < 32 && v1 < 32); return ((2 * v0 + v1) * 22) / 8; } 
1660 static inline int interp_6_nv(int c0, int c1) { assert(c0 < 256 && c1 < 256); const int gdiff = c1 - c0; return (256 * c0 + (gdiff / 4) + 128 + gdiff * 80) / 256; } 
1661 
1662 static inline int interp_half_5_nv(int v0, int v1) { assert(v0 < 32 && v1 < 32); return ((v0 + v1) * 33) / 8; } 
1663 static inline int interp_half_6_nv(int c0, int c1) { assert(c0 < 256 && c1 < 256); const int gdiff = c1 - c0; return (256 * c0 + gdiff/4 + 128 + gdiff * 128) / 256; } 
1664 
1665 static inline int interp_5_6_amd(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 * 43 + c1 * 21 + 32) >> 6; } 
1666 static inline int interp_half_5_6_amd(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 + c1 + 1) >> 1; } 
1667 
1668 static inline int interp_5(int v0, int v1, int c0, int c1, bc1_approx_mode mode)  
1669 {  
1670 assert(scale_5_to_8(v0) == c0 && scale_5_to_8(v1) == c1); 
1671 switch (mode) 
1672 { 
1673 case bc1_approx_mode::cBC1NVidia: return interp_5_nv(v0, v1);  
1674 case bc1_approx_mode::cBC1AMD: return interp_5_6_amd(c0, c1); 
1675 default: 
1676 case bc1_approx_mode::cBC1Ideal: return interp_5_6_ideal(c0, c1);  
1677 case bc1_approx_mode::cBC1IdealRound4: return interp_5_6_ideal_round(c0, c1);  
1678 } 
1679 } 
1680 
1681 static inline int interp_6(int v0, int v1, int c0, int c1, bc1_approx_mode mode)  
1682 {  
1683 (void)v0; (void)v1; 
1684 assert(scale_6_to_8(v0) == c0 && scale_6_to_8(v1) == c1); 
1685 switch (mode) 
1686 { 
1687 case bc1_approx_mode::cBC1NVidia: return interp_6_nv(c0, c1);  
1688 case bc1_approx_mode::cBC1AMD: return interp_5_6_amd(c0, c1); 
1689 default: 
1690 case bc1_approx_mode::cBC1Ideal: return interp_5_6_ideal(c0, c1);  
1691 case bc1_approx_mode::cBC1IdealRound4: return interp_5_6_ideal_round(c0, c1);  
1692 } 
1693 } 
1694 
1695 static inline int interp_half_5(int v0, int v1, int c0, int c1, bc1_approx_mode mode)  
1696 {  
1697 assert(scale_5_to_8(v0) == c0 && scale_5_to_8(v1) == c1); 
1698 switch (mode) 
1699 { 
1700 case bc1_approx_mode::cBC1NVidia: return interp_half_5_nv(v0, v1);  
1701 case bc1_approx_mode::cBC1AMD: return interp_half_5_6_amd(c0, c1); 
1702 case bc1_approx_mode::cBC1Ideal:  
1703 case bc1_approx_mode::cBC1IdealRound4:  
1704 default: 
1705 return interp_half_5_6_ideal(c0, c1);  
1706 } 
1707 } 
1708 
1709 static inline int interp_half_6(int v0, int v1, int c0, int c1, bc1_approx_mode mode)  
1710 {  
1711 (void)v0; (void)v1; 
1712 assert(scale_6_to_8(v0) == c0 && scale_6_to_8(v1) == c1); 
1713 switch (mode) 
1714 { 
1715 case bc1_approx_mode::cBC1NVidia: return interp_half_6_nv(c0, c1);  
1716 case bc1_approx_mode::cBC1AMD: return interp_half_5_6_amd(c0, c1); 
1717 case bc1_approx_mode::cBC1Ideal:  
1718 case bc1_approx_mode::cBC1IdealRound4:  
1719 default: 
1720 return interp_half_5_6_ideal(c0, c1);  
1721 } 
1722 } 
1723 
1724 static void prepare_bc1_single_color_table_half(bc1_match_entry* pTable, const uint8_t* pExpand, int size, bc1_approx_mode mode) 
1725 { 
1726 for (int i = 0; i < 256; i++) 
1727 { 
1728 int lowest_e = 256; 
1729 for (int lo = 0; lo < size; lo++) 
1730 { 
1731 const int lo_e = pExpand[lo]; 
1732 
1733 for (int hi = 0; hi < size; hi++) 
1734 { 
1735 const int hi_e = pExpand[hi]; 
1736  
1737 const int v = (size == 32) ? interp_half_5(hi, lo, hi_e, lo_e, mode) : interp_half_6(hi, lo, hi_e, lo_e, mode); 
1738  
1739 int e = iabs(v - i); 
1740 
1741 // We only need to factor in 3% error in BC1 ideal mode. 
1742 if ((mode == bc1_approx_mode::cBC1Ideal) || (mode == bc1_approx_mode::cBC1IdealRound4)) 
1743 e += (iabs(hi_e - lo_e) * 3) / 100; 
1744 
1745 // Favor equal endpoints, for lower error on actual GPU's which approximate the interpolation. 
1746 if ((e < lowest_e) || ((e == lowest_e) && (lo == hi))) 
1747 { 
1748 pTable[i].m_hi = static_cast<uint8_t>(hi); 
1749 pTable[i].m_lo = static_cast<uint8_t>(lo); 
1750  
1751 assert(e <= UINT8_MAX); 
1752 pTable[i].m_e = static_cast<uint8_t>(e); 
1753 
1754 lowest_e = e; 
1755 } 
1756 
1757 } // hi 
1758 } // lo 
1759 } 
1760 } 
1761 
1762 static void prepare_bc1_single_color_table(bc1_match_entry* pTable, const uint8_t* pExpand, int size, bc1_approx_mode mode) 
1763 { 
1764 for (int i = 0; i < 256; i++) 
1765 { 
1766 int lowest_e = 256; 
1767 for (int lo = 0; lo < size; lo++) 
1768 { 
1769 const int lo_e = pExpand[lo]; 
1770 
1771 for (int hi = 0; hi < size; hi++) 
1772 { 
1773 const int hi_e = pExpand[hi]; 
1774 
1775 const int v = (size == 32) ? interp_5(hi, lo, hi_e, lo_e, mode) : interp_6(hi, lo, hi_e, lo_e, mode); 
1776  
1777 int e = iabs(v - i); 
1778 
1779 if ((mode == bc1_approx_mode::cBC1Ideal) || (mode == bc1_approx_mode::cBC1IdealRound4)) 
1780 e += (iabs(hi_e - lo_e) * 3) / 100; 
1781 
1782 // Favor equal endpoints, for lower error on actual GPU's which approximate the interpolation. 
1783 if ((e < lowest_e) || ((e == lowest_e) && (lo == hi))) 
1784 { 
1785 pTable[i].m_hi = static_cast<uint8_t>(hi); 
1786 pTable[i].m_lo = static_cast<uint8_t>(lo); 
1787  
1788 assert(e <= UINT8_MAX); 
1789 pTable[i].m_e = static_cast<uint8_t>(e); 
1790 
1791 lowest_e = e; 
1792 } 
1793 
1794 } // hi 
1795 } // lo 
1796 } 
1797 } 
1798 
1799 // This table is: 9 * (w * w), 9 * ((1.0f - w) * w), 9 * ((1.0f - w) * (1.0f - w)) 
1800 // where w is [0,1/3,2/3,1]. 9 is the perfect multiplier. 
1801 static const uint32_t g_weight_vals4[4] = { 0x000009, 0x010204, 0x040201, 0x090000 }; 
1802  
1803 // multiplier is 4 for 3-color 
1804 static const uint32_t g_weight_vals3[3] = { 0x000004, 0x040000, 0x010101 }; 
1805 
1806 static inline void compute_selector_factors4(const hist4 &h, float &iz00, float &iz10, float &iz11) 
1807 { 
1808 uint32_t weight_accum = 0; 
1809 for (uint32_t sel = 0; sel < 4; sel++) 
1810 weight_accum += g_weight_vals4[sel] * h.m_hist[sel]; 
1811 
1812 float z00 = (float)((weight_accum >> 16) & 0xFF); 
1813 float z10 = (float)((weight_accum >> 8) & 0xFF); 
1814 float z11 = (float)(weight_accum & 0xFF); 
1815 float z01 = z10; 
1816 
1817 float det = z00 * z11 - z01 * z10; 
1818 if (fabs(det) < 1e-8f) 
1819 det = 0.0f; 
1820 else 
1821 det = (3.0f / 255.0f) / det; 
1822  
1823 iz00 = z11 * det; 
1824 iz10 = -z10 * det; 
1825 iz11 = z00 * det; 
1826 } 
1827 
1828 static inline void compute_selector_factors3(const hist3 &h, float &iz00, float &iz10, float &iz11) 
1829 { 
1830 uint32_t weight_accum = 0; 
1831 for (uint32_t sel = 0; sel < 3; sel++) 
1832 weight_accum += g_weight_vals3[sel] * h.m_hist[sel]; 
1833 
1834 float z00 = (float)((weight_accum >> 16) & 0xFF); 
1835 float z10 = (float)((weight_accum >> 8) & 0xFF); 
1836 float z11 = (float)(weight_accum & 0xFF); 
1837 float z01 = z10; 
1838 
1839 float det = z00 * z11 - z01 * z10; 
1840 if (fabs(det) < 1e-8f) 
1841 det = 0.0f; 
1842 else 
1843 det = (2.0f / 255.0f) / det; 
1844  
1845 iz00 = z11 * det; 
1846 iz10 = -z10 * det; 
1847 iz11 = z00 * det; 
1848 } 
1849 
1850 static bool g_initialized; 
1851  
1852 void init(bc1_approx_mode mode) 
1853 { 
1854 g_bc1_approx_mode = mode; 
1855  
1856 uint8_t bc1_expand5[32]; 
1857 for (int i = 0; i < 32; i++) 
1858 bc1_expand5[i] = static_cast<uint8_t>((i << 3) | (i >> 2)); 
1859 prepare_bc1_single_color_table(g_bc1_match5_equals_1, bc1_expand5, 32, mode); 
1860 prepare_bc1_single_color_table_half(g_bc1_match5_half, bc1_expand5, 32, mode); 
1861 
1862 uint8_t bc1_expand6[64]; 
1863 for (int i = 0; i < 64; i++) 
1864 bc1_expand6[i] = static_cast<uint8_t>((i << 2) | (i >> 4)); 
1865 prepare_bc1_single_color_table(g_bc1_match6_equals_1, bc1_expand6, 64, mode); 
1866 prepare_bc1_single_color_table_half(g_bc1_match6_half, bc1_expand6, 64, mode); 
1867 
1868 for (uint32_t i = 0; i < NUM_UNIQUE_TOTAL_ORDERINGS4; i++) 
1869 { 
1870 hist4 h; 
1871 h.m_hist[0] = (uint8_t)g_unique_total_orders4[i][0]; 
1872 h.m_hist[1] = (uint8_t)g_unique_total_orders4[i][1]; 
1873 h.m_hist[2] = (uint8_t)g_unique_total_orders4[i][2]; 
1874 h.m_hist[3] = (uint8_t)g_unique_total_orders4[i][3]; 
1875  
1876 if (!h.any_16()) 
1877 { 
1878 const uint32_t index = h.m_hist[0] | (h.m_hist[1] << 4) | (h.m_hist[2] << 8); 
1879 assert(index < 4096); 
1880 g_total_ordering4_hash[index] = (uint16_t)i; 
1881 } 
1882 
1883 compute_selector_factors4(h, g_selector_factors4[i][0], g_selector_factors4[i][1], g_selector_factors4[i][2]); 
1884 } 
1885 
1886 for (uint32_t i = 0; i < NUM_UNIQUE_TOTAL_ORDERINGS3; i++) 
1887 { 
1888 hist3 h; 
1889 h.m_hist[0] = (uint8_t)g_unique_total_orders3[i][0]; 
1890 h.m_hist[1] = (uint8_t)g_unique_total_orders3[i][1]; 
1891 h.m_hist[2] = (uint8_t)g_unique_total_orders3[i][2]; 
1892  
1893 if (!h.any_16()) 
1894 { 
1895 const uint32_t index = h.m_hist[0] | (h.m_hist[1] << 4); 
1896 assert(index < 256); 
1897 g_total_ordering3_hash[index] = (uint16_t)i; 
1898 } 
1899 
1900 compute_selector_factors3(h, g_selector_factors3[i][0], g_selector_factors3[i][1], g_selector_factors3[i][2]); 
1901 } 
1902 
1903 g_initialized = true; 
1904 } 
1905  
1906 void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb, bool allow_3color)  
1907 { 
1908 bc1_block* pDst_block = static_cast<bc1_block*>(pDst); 
1909 
1910 uint32_t mask = 0xAA; 
1911 int max16 = -1, min16 = 0; 
1912 
1913 if (allow_3color) 
1914 { 
1915 const uint32_t err4 = g_bc1_match5_equals_1[fr].m_e + g_bc1_match6_equals_1[fg].m_e + g_bc1_match5_equals_1[fb].m_e; 
1916 const uint32_t err3 = g_bc1_match5_half[fr].m_e + g_bc1_match6_half[fg].m_e + g_bc1_match5_half[fb].m_e; 
1917 
1918 if (err3 < err4) 
1919 { 
1920 max16 = (g_bc1_match5_half[fr].m_hi << 11) | (g_bc1_match6_half[fg].m_hi << 5) | g_bc1_match5_half[fb].m_hi; 
1921 min16 = (g_bc1_match5_half[fr].m_lo << 11) | (g_bc1_match6_half[fg].m_lo << 5) | g_bc1_match5_half[fb].m_lo; 
1922 
1923 if (max16 > min16) 
1924 std::swap(max16, min16); 
1925 } 
1926 } 
1927 
1928 if (max16 == -1) 
1929 { 
1930 max16 = (g_bc1_match5_equals_1[fr].m_hi << 11) | (g_bc1_match6_equals_1[fg].m_hi << 5) | g_bc1_match5_equals_1[fb].m_hi; 
1931 min16 = (g_bc1_match5_equals_1[fr].m_lo << 11) | (g_bc1_match6_equals_1[fg].m_lo << 5) | g_bc1_match5_equals_1[fb].m_lo; 
1932 
1933 if (min16 == max16) 
1934 { 
1935 // Always forbid 3 color blocks 
1936 // This is to guarantee that BC3 blocks never use punchthrough alpha (3 color) mode, which isn't supported on some (all?) GPU's. 
1937 mask = 0; 
1938 
1939 // Make l > h 
1940 if (min16 > 0) 
1941 min16--; 
1942 else 
1943 { 
1944 // l = h = 0 
1945 assert(min16 == max16 && max16 == 0); 
1946 
1947 max16 = 1; 
1948 min16 = 0; 
1949 mask = 0x55; 
1950 } 
1951 
1952 assert(max16 > min16); 
1953 } 
1954 
1955 if (max16 < min16) 
1956 { 
1957 std::swap(max16, min16); 
1958 mask ^= 0x55; 
1959 } 
1960 } 
1961 
1962 pDst_block->set_low_color(static_cast<uint16_t>(max16)); 
1963 pDst_block->set_high_color(static_cast<uint16_t>(min16)); 
1964 pDst_block->m_selectors[0] = static_cast<uint8_t>(mask); 
1965 pDst_block->m_selectors[1] = static_cast<uint8_t>(mask); 
1966 pDst_block->m_selectors[2] = static_cast<uint8_t>(mask); 
1967 pDst_block->m_selectors[3] = static_cast<uint8_t>(mask); 
1968 } 
1969 
1970 static const float g_midpoint5[32] = { .015686f, .047059f, .078431f, .111765f, .145098f, .176471f, .207843f, .241176f, .274510f, .305882f, .337255f, .370588f, .403922f, .435294f, .466667f, .5f, .533333f, .564706f, .596078f, .629412f, .662745f, .694118f, .725490f, .758824f, .792157f, .823529f, .854902f, .888235f, .921569f, .952941f, .984314f, 1e+37f }; 
1971 static const float g_midpoint6[64] = { .007843f, .023529f, .039216f, .054902f, .070588f, .086275f, .101961f, .117647f, .133333f, .149020f, .164706f, .180392f, .196078f, .211765f, .227451f, .245098f, .262745f, .278431f, .294118f, .309804f, .325490f, .341176f, .356863f, .372549f, .388235f, .403922f, .419608f, .435294f, .450980f, .466667f, .482353f, .500000f, .517647f, .533333f, .549020f, .564706f, .580392f, .596078f, .611765f, .627451f, .643137f, .658824f, .674510f, .690196f, .705882f, .721569f, .737255f, .754902f, .772549f, .788235f, .803922f, .819608f, .835294f, .850980f, .866667f, .882353f, .898039f, .913725f, .929412f, .945098f, .960784f, .976471f, .992157f, 1e+37f }; 
1972 
1973 struct vec3F { float c[3]; }; 
1974 
1975 static inline void compute_least_squares_endpoints4_rgb( 
1976 vec3F* pXl, vec3F* pXh, 
1977 int total_r, int total_g, int total_b, 
1978 float iz00, float iz10, float iz11, 
1979 uint32_t s, const uint32_t r_sum[17], const uint32_t g_sum[17], const uint32_t b_sum[17]) 
1980 { 
1981 const float iz01 = iz10; 
1982 
1983 const uint32_t f1 = g_unique_total_orders4[s][0]; 
1984 const uint32_t f2 = g_unique_total_orders4[s][0] + g_unique_total_orders4[s][1]; 
1985 const uint32_t f3 = g_unique_total_orders4[s][0] + g_unique_total_orders4[s][1] + g_unique_total_orders4[s][2]; 
1986 uint32_t uq00_r = (r_sum[f2] - r_sum[f1]) + (r_sum[f3] - r_sum[f2]) * 2 + (r_sum[16] - r_sum[f3]) * 3; 
1987 uint32_t uq00_g = (g_sum[f2] - g_sum[f1]) + (g_sum[f3] - g_sum[f2]) * 2 + (g_sum[16] - g_sum[f3]) * 3; 
1988 uint32_t uq00_b = (b_sum[f2] - b_sum[f1]) + (b_sum[f3] - b_sum[f2]) * 2 + (b_sum[16] - b_sum[f3]) * 3; 
1989 
1990 float q10_r = (float)(total_r * 3 - uq00_r); 
1991 float q10_g = (float)(total_g * 3 - uq00_g); 
1992 float q10_b = (float)(total_b * 3 - uq00_b); 
1993 
1994 pXl->c[0] = iz00 * (float)uq00_r + iz01 * q10_r; 
1995 pXh->c[0] = iz10 * (float)uq00_r + iz11 * q10_r; 
1996 
1997 pXl->c[1] = iz00 * (float)uq00_g + iz01 * q10_g; 
1998 pXh->c[1] = iz10 * (float)uq00_g + iz11 * q10_g; 
1999 
2000 pXl->c[2] = iz00 * (float)uq00_b + iz01 * q10_b; 
2001 pXh->c[2] = iz10 * (float)uq00_b + iz11 * q10_b; 
2002 } 
2003  
2004 static inline bool compute_least_squares_endpoints4_rgb(const color32* pColors, const uint8_t* pSelectors, vec3F* pXl, vec3F* pXh, int total_r, int total_g, int total_b) 
2005 { 
2006 uint32_t uq00_r = 0, uq00_g = 0, uq00_b = 0; 
2007 uint32_t weight_accum = 0; 
2008 for (uint32_t i = 0; i < 16; i++) 
2009 { 
2010 const uint8_t r = pColors[i].c[0], g = pColors[i].c[1], b = pColors[i].c[2]; 
2011 const uint8_t sel = pSelectors[i]; 
2012  
2013 weight_accum += g_weight_vals4[sel]; 
2014 uq00_r += sel * r; 
2015 uq00_g += sel * g; 
2016 uq00_b += sel * b; 
2017 } 
2018 
2019 int q10_r = total_r * 3 - uq00_r; 
2020 int q10_g = total_g * 3 - uq00_g; 
2021 int q10_b = total_b * 3 - uq00_b; 
2022 
2023 float z00 = (float)((weight_accum >> 16) & 0xFF); 
2024 float z10 = (float)((weight_accum >> 8) & 0xFF); 
2025 float z11 = (float)(weight_accum & 0xFF); 
2026 float z01 = z10; 
2027 
2028 float det = z00 * z11 - z01 * z10; 
2029 if (fabs(det) < 1e-8f) 
2030 return false; 
2031 
2032 det = (3.0f / 255.0f) / det; 
2033 
2034 float iz00, iz01, iz10, iz11; 
2035 iz00 = z11 * det; 
2036 iz01 = -z01 * det; 
2037 iz10 = -z10 * det; 
2038 iz11 = z00 * det; 
2039 
2040 pXl->c[0] = iz00 * (float)uq00_r + iz01 * q10_r; 
2041 pXh->c[0] = iz10 * (float)uq00_r + iz11 * q10_r; 
2042 
2043 pXl->c[1] = iz00 * (float)uq00_g + iz01 * q10_g; 
2044 pXh->c[1] = iz10 * (float)uq00_g + iz11 * q10_g; 
2045 
2046 pXl->c[2] = iz00 * (float)uq00_b + iz01 * q10_b; 
2047 pXh->c[2] = iz10 * (float)uq00_b + iz11 * q10_b; 
2048 
2049 return true; 
2050 } 
2051 
2052 static inline void compute_least_squares_endpoints3_rgb( 
2053 vec3F* pXl, vec3F* pXh, 
2054 int total_r, int total_g, int total_b, 
2055 float iz00, float iz10, float iz11, 
2056 uint32_t s, const uint32_t r_sum[17], const uint32_t g_sum[17], const uint32_t b_sum[17]) 
2057 { 
2058 const float iz01 = iz10; 
2059 
2060 // Compensates for BC1 3-color ordering, which is selector 0, 2, 1 
2061 const uint32_t f1 = g_unique_total_orders3[s][0]; 
2062 const uint32_t f2 = g_unique_total_orders3[s][0] + g_unique_total_orders3[s][2]; 
2063 uint32_t uq00_r = (r_sum[16] - r_sum[f2]) * 2 + (r_sum[f2] - r_sum[f1]); 
2064 uint32_t uq00_g = (g_sum[16] - g_sum[f2]) * 2 + (g_sum[f2] - g_sum[f1]); 
2065 uint32_t uq00_b = (b_sum[16] - b_sum[f2]) * 2 + (b_sum[f2] - b_sum[f1]); 
2066 
2067 float q10_r = (float)(total_r * 2 - uq00_r); 
2068 float q10_g = (float)(total_g * 2 - uq00_g); 
2069 float q10_b = (float)(total_b * 2 - uq00_b); 
2070 
2071 pXl->c[0] = iz00 * (float)uq00_r + iz01 * q10_r; 
2072 pXh->c[0] = iz10 * (float)uq00_r + iz11 * q10_r; 
2073 
2074 pXl->c[1] = iz00 * (float)uq00_g + iz01 * q10_g; 
2075 pXh->c[1] = iz10 * (float)uq00_g + iz11 * q10_g; 
2076 
2077 pXl->c[2] = iz00 * (float)uq00_b + iz01 * q10_b; 
2078 pXh->c[2] = iz10 * (float)uq00_b + iz11 * q10_b; 
2079 } 
2080 
2081 static inline bool compute_least_squares_endpoints3_rgb(bool use_black, const color32* pColors, const uint8_t* pSelectors, vec3F* pXl, vec3F* pXh) 
2082 { 
2083 int uq00_r = 0, uq00_g = 0, uq00_b = 0; 
2084 uint32_t weight_accum = 0; 
2085 int total_r = 0, total_g = 0, total_b = 0; 
2086 for (uint32_t i = 0; i < 16; i++) 
2087 { 
2088 const uint8_t r = pColors[i].c[0], g = pColors[i].c[1], b = pColors[i].c[2]; 
2089 if (use_black) 
2090 { 
2091 if ((r | g | b) < 4) 
2092 continue; 
2093 } 
2094 
2095 const uint8_t sel = pSelectors[i]; 
2096 assert(sel <= 3); 
2097 if (sel == 3) 
2098 continue; 
2099  
2100 weight_accum += g_weight_vals3[sel]; 
2101 
2102 static const uint8_t s_tran[3] = { 0, 2, 1 }; 
2103 const uint8_t tsel = s_tran[sel]; 
2104 uq00_r += tsel * r; 
2105 uq00_g += tsel * g; 
2106 uq00_b += tsel * b; 
2107 
2108 total_r += r; 
2109 total_g += g; 
2110 total_b += b; 
2111 } 
2112 
2113 int q10_r = total_r * 2 - uq00_r; 
2114 int q10_g = total_g * 2 - uq00_g; 
2115 int q10_b = total_b * 2 - uq00_b; 
2116 
2117 float z00 = (float)((weight_accum >> 16) & 0xFF); 
2118 float z10 = (float)((weight_accum >> 8) & 0xFF); 
2119 float z11 = (float)(weight_accum & 0xFF); 
2120 float z01 = z10; 
2121 
2122 float det = z00 * z11 - z01 * z10; 
2123 if (fabs(det) < 1e-8f) 
2124 return false; 
2125 
2126 det = (2.0f / 255.0f) / det; 
2127 
2128 float iz00, iz01, iz10, iz11; 
2129 iz00 = z11 * det; 
2130 iz01 = -z01 * det; 
2131 iz10 = -z10 * det; 
2132 iz11 = z00 * det; 
2133 
2134 pXl->c[0] = iz00 * (float)uq00_r + iz01 * q10_r; 
2135 pXh->c[0] = iz10 * (float)uq00_r + iz11 * q10_r; 
2136 
2137 pXl->c[1] = iz00 * (float)uq00_g + iz01 * q10_g; 
2138 pXh->c[1] = iz10 * (float)uq00_g + iz11 * q10_g; 
2139 
2140 pXl->c[2] = iz00 * (float)uq00_b + iz01 * q10_b; 
2141 pXh->c[2] = iz10 * (float)uq00_b + iz11 * q10_b; 
2142 
2143 return true; 
2144 } 
2145 
2146 static inline void bc1_get_block_colors4(uint32_t block_r[4], uint32_t block_g[4], uint32_t block_b[4], uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb) 
2147 { 
2148 block_r[0] = (lr << 3) | (lr >> 2); block_g[0] = (lg << 2) | (lg >> 4); block_b[0] = (lb << 3) | (lb >> 2); 
2149 block_r[3] = (hr << 3) | (hr >> 2); block_g[3] = (hg << 2) | (hg >> 4); block_b[3] = (hb << 3) | (hb >> 2); 
2150 
2151 if (g_bc1_approx_mode == bc1_approx_mode::cBC1Ideal) 
2152 { 
2153 block_r[1] = (block_r[0] * 2 + block_r[3]) / 3; block_g[1] = (block_g[0] * 2 + block_g[3]) / 3; block_b[1] = (block_b[0] * 2 + block_b[3]) / 3; 
2154 block_r[2] = (block_r[3] * 2 + block_r[0]) / 3; block_g[2] = (block_g[3] * 2 + block_g[0]) / 3; block_b[2] = (block_b[3] * 2 + block_b[0]) / 3; 
2155 } 
2156 else if (g_bc1_approx_mode == bc1_approx_mode::cBC1IdealRound4) 
2157 { 
2158 block_r[1] = (block_r[0] * 2 + block_r[3] + 1) / 3; block_g[1] = (block_g[0] * 2 + block_g[3] + 1) / 3; block_b[1] = (block_b[0] * 2 + block_b[3] + 1) / 3; 
2159 block_r[2] = (block_r[3] * 2 + block_r[0] + 1) / 3; block_g[2] = (block_g[3] * 2 + block_g[0] + 1) / 3; block_b[2] = (block_b[3] * 2 + block_b[0] + 1) / 3; 
2160 } 
2161 else if (g_bc1_approx_mode == bc1_approx_mode::cBC1AMD) 
2162 { 
2163 block_r[1] = interp_5_6_amd(block_r[0], block_r[3]); block_g[1] = interp_5_6_amd(block_g[0], block_g[3]); block_b[1] = interp_5_6_amd(block_b[0], block_b[3]); 
2164 block_r[2] = interp_5_6_amd(block_r[3], block_r[0]); block_g[2] = interp_5_6_amd(block_g[3], block_g[0]); block_b[2] = interp_5_6_amd(block_b[3], block_b[0]); 
2165 } 
2166 else 
2167 { 
2168 block_r[1] = interp_5_nv(lr, hr); block_g[1] = interp_6_nv(block_g[0], block_g[3]); block_b[1] = interp_5_nv(lb, hb); 
2169 block_r[2] = interp_5_nv(hr, lr); block_g[2] = interp_6_nv(block_g[3], block_g[0]); block_b[2] = interp_5_nv(hb, lb); 
2170 } 
2171 } 
2172 
2173 static inline void bc1_get_block_colors3(uint32_t block_r[3], uint32_t block_g[3], uint32_t block_b[3], uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb) 
2174 { 
2175 block_r[0] = (lr << 3) | (lr >> 2); block_g[0] = (lg << 2) | (lg >> 4); block_b[0] = (lb << 3) | (lb >> 2); 
2176 block_r[1] = (hr << 3) | (hr >> 2); block_g[1] = (hg << 2) | (hg >> 4); block_b[1] = (hb << 3) | (hb >> 2); 
2177 
2178 if ((g_bc1_approx_mode == bc1_approx_mode::cBC1Ideal) || (g_bc1_approx_mode == bc1_approx_mode::cBC1IdealRound4)) 
2179 { 
2180 block_r[2] = (block_r[0] + block_r[1]) / 2; block_g[2] = (block_g[0] + block_g[1]) / 2; block_b[2] = (block_b[0] + block_b[1]) / 2; 
2181 } 
2182 else if (g_bc1_approx_mode == bc1_approx_mode::cBC1AMD) 
2183 { 
2184 block_r[2] = interp_half_5_6_amd(block_r[0], block_r[1]); block_g[2] = interp_half_5_6_amd(block_g[0], block_g[1]); block_b[2] = interp_half_5_6_amd(block_b[0], block_b[1]); 
2185 } 
2186 else 
2187 { 
2188 block_r[2] = interp_half_5_nv(lr, hr); block_g[2] = interp_half_6_nv(block_g[0], block_g[1]); block_b[2] = interp_half_5_nv(lb, hb); 
2189 } 
2190 } 
2191 
2192 static inline void bc1_find_sels4_noerr(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16]) 
2193 { 
2194 uint32_t block_r[4], block_g[4], block_b[4]; 
2195 bc1_get_block_colors4(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb); 
2196 
2197 int ar = block_r[3] - block_r[0], ag = block_g[3] - block_g[0], ab = block_b[3] - block_b[0]; 
2198 
2199 int dots[4]; 
2200 for (uint32_t i = 0; i < 4; i++) 
2201 dots[i] = (int)block_r[i] * ar + (int)block_g[i] * ag + (int)block_b[i] * ab; 
2202 
2203 int t0 = dots[0] + dots[1], t1 = dots[1] + dots[2], t2 = dots[2] + dots[3]; 
2204 
2205 ar *= 2; ag *= 2; ab *= 2; 
2206 
2207 static const uint8_t s_sels[4] = { 3, 2, 1, 0 }; 
2208 
2209 for (uint32_t i = 0; i < 16; i += 4) 
2210 { 
2211 const int d0 = pSrc_pixels[i+0].r * ar + pSrc_pixels[i+0].g * ag + pSrc_pixels[i+0].b * ab; 
2212 const int d1 = pSrc_pixels[i+1].r * ar + pSrc_pixels[i+1].g * ag + pSrc_pixels[i+1].b * ab; 
2213 const int d2 = pSrc_pixels[i+2].r * ar + pSrc_pixels[i+2].g * ag + pSrc_pixels[i+2].b * ab; 
2214 const int d3 = pSrc_pixels[i+3].r * ar + pSrc_pixels[i+3].g * ag + pSrc_pixels[i+3].b * ab; 
2215 
2216 sels[i+0] = s_sels[(d0 <= t0) + (d0 < t1) + (d0 < t2)]; 
2217 sels[i+1] = s_sels[(d1 <= t0) + (d1 < t1) + (d1 < t2)]; 
2218 sels[i+2] = s_sels[(d2 <= t0) + (d2 < t1) + (d2 < t2)]; 
2219 sels[i+3] = s_sels[(d3 <= t0) + (d3 < t1) + (d3 < t2)]; 
2220 } 
2221 } 
2222 
2223 static inline uint32_t bc1_find_sels4_fasterr(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16], uint32_t cur_err) 
2224 { 
2225 uint32_t block_r[4], block_g[4], block_b[4]; 
2226 bc1_get_block_colors4(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb); 
2227  
2228 int ar = block_r[3] - block_r[0], ag = block_g[3] - block_g[0], ab = block_b[3] - block_b[0]; 
2229 
2230 int dots[4]; 
2231 for (uint32_t i = 0; i < 4; i++) 
2232 dots[i] = (int)block_r[i] * ar + (int)block_g[i] * ag + (int)block_b[i] * ab; 
2233 
2234 int t0 = dots[0] + dots[1], t1 = dots[1] + dots[2], t2 = dots[2] + dots[3]; 
2235 
2236 ar *= 2; ag *= 2; ab *= 2; 
2237 
2238 static const uint8_t s_sels[4] = { 3, 2, 1, 0 }; 
2239 
2240 uint32_t total_err = 0; 
2241 
2242 for (uint32_t i = 0; i < 16; i += 4) 
2243 { 
2244 const int d0 = pSrc_pixels[i+0].r * ar + pSrc_pixels[i+0].g * ag + pSrc_pixels[i+0].b * ab; 
2245 const int d1 = pSrc_pixels[i+1].r * ar + pSrc_pixels[i+1].g * ag + pSrc_pixels[i+1].b * ab; 
2246 const int d2 = pSrc_pixels[i+2].r * ar + pSrc_pixels[i+2].g * ag + pSrc_pixels[i+2].b * ab; 
2247 const int d3 = pSrc_pixels[i+3].r * ar + pSrc_pixels[i+3].g * ag + pSrc_pixels[i+3].b * ab; 
2248 
2249 uint8_t sel0 = s_sels[(d0 <= t0) + (d0 < t1) + (d0 < t2)]; 
2250 uint8_t sel1 = s_sels[(d1 <= t0) + (d1 < t1) + (d1 < t2)]; 
2251 uint8_t sel2 = s_sels[(d2 <= t0) + (d2 < t1) + (d2 < t2)]; 
2252 uint8_t sel3 = s_sels[(d3 <= t0) + (d3 < t1) + (d3 < t2)]; 
2253 
2254 sels[i+0] = sel0; 
2255 sels[i+1] = sel1; 
2256 sels[i+2] = sel2; 
2257 sels[i+3] = sel3; 
2258 
2259 total_err += squarei(pSrc_pixels[i+0].r - block_r[sel0]) + squarei(pSrc_pixels[i+0].g - block_g[sel0]) + squarei(pSrc_pixels[i+0].b - block_b[sel0]); 
2260 total_err += squarei(pSrc_pixels[i+1].r - block_r[sel1]) + squarei(pSrc_pixels[i+1].g - block_g[sel1]) + squarei(pSrc_pixels[i+1].b - block_b[sel1]); 
2261 total_err += squarei(pSrc_pixels[i+2].r - block_r[sel2]) + squarei(pSrc_pixels[i+2].g - block_g[sel2]) + squarei(pSrc_pixels[i+2].b - block_b[sel2]); 
2262 total_err += squarei(pSrc_pixels[i+3].r - block_r[sel3]) + squarei(pSrc_pixels[i+3].g - block_g[sel3]) + squarei(pSrc_pixels[i+3].b - block_b[sel3]); 
2263 
2264 if (total_err >= cur_err) 
2265 break; 
2266 } 
2267 
2268 return total_err; 
2269 } 
2270  
2271 static inline uint32_t bc1_find_sels4_check2_err(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16], uint32_t cur_err) 
2272 { 
2273 uint32_t block_r[4], block_g[4], block_b[4]; 
2274 bc1_get_block_colors4(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb); 
2275  
2276 int dr = block_r[3] - block_r[0], dg = block_g[3] - block_g[0], db = block_b[3] - block_b[0]; 
2277 
2278 const float f = 4.0f / (float)(squarei(dr) + squarei(dg) + squarei(db) + .00000125f); 
2279 
2280 uint32_t total_err = 0; 
2281 
2282 for (uint32_t i = 0; i < 16; i++) 
2283 { 
2284 const int r = pSrc_pixels[i].r; 
2285 const int g = pSrc_pixels[i].g; 
2286 const int b = pSrc_pixels[i].b; 
2287 
2288 int sel = (int)((float)((r - (int)block_r[0]) * dr + (g - (int)block_g[0]) * dg + (b - (int)block_b[0]) * db) * f + .5f); 
2289 sel = clampi(sel, 1, 3); 
2290 
2291 uint32_t err0 = squarei((int)block_r[sel - 1] - (int)r) + squarei((int)block_g[sel - 1] - (int)g) + squarei((int)block_b[sel - 1] - (int)b); 
2292 uint32_t err1 = squarei((int)block_r[sel] - (int)r) + squarei((int)block_g[sel] - (int)g) + squarei((int)block_b[sel] - (int)b); 
2293  
2294 int best_sel = sel; 
2295 uint32_t best_err = err1; 
2296 if (err0 == err1) 
2297 { 
2298 // Prefer non-interpolation 
2299 if ((best_sel - 1) == 0) 
2300 best_sel = 0; 
2301 } 
2302 else if (err0 < best_err) 
2303 { 
2304 best_sel = sel - 1; 
2305 best_err = err0; 
2306 } 
2307  
2308 total_err += best_err; 
2309  
2310 if (total_err >= cur_err) 
2311 break; 
2312  
2313 sels[i] = (uint8_t)best_sel; 
2314 } 
2315 return total_err; 
2316 } 
2317 
2318 static inline uint32_t bc1_find_sels4_fullerr(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16], uint32_t cur_err) 
2319 { 
2320 uint32_t block_r[4], block_g[4], block_b[4]; 
2321 bc1_get_block_colors4(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb); 
2322  
2323 uint32_t total_err = 0; 
2324 
2325 for (uint32_t i = 0; i < 16; i++) 
2326 { 
2327 const int r = pSrc_pixels[i].r; 
2328 const int g = pSrc_pixels[i].g; 
2329 const int b = pSrc_pixels[i].b; 
2330 
2331 uint32_t best_err = squarei((int)block_r[0] - (int)r) + squarei((int)block_g[0] - (int)g) + squarei((int)block_b[0] - (int)b); 
2332 uint8_t best_sel = 0; 
2333  
2334 for (uint32_t j = 1; (j < 4) && best_err; j++) 
2335 { 
2336 uint32_t err = squarei((int)block_r[j] - (int)r) + squarei((int)block_g[j] - (int)g) + squarei((int)block_b[j] - (int)b); 
2337 if ( (err < best_err) || ((err == best_err) && (j == 3)) ) 
2338 { 
2339 best_err = err; 
2340 best_sel = (uint8_t)j; 
2341 } 
2342 } 
2343  
2344 total_err += best_err; 
2345  
2346 if (total_err >= cur_err) 
2347 break; 
2348  
2349 sels[i] = (uint8_t)best_sel; 
2350 } 
2351 return total_err; 
2352 } 
2353 
2354 static inline uint32_t bc1_find_sels4(uint32_t flags, const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16], uint32_t cur_err) 
2355 { 
2356 uint32_t err; 
2357 
2358 if (flags & cEncodeBC1UseFasterMSEEval) 
2359 err = bc1_find_sels4_fasterr(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels, cur_err); 
2360 else if (flags & cEncodeBC1UseFullMSEEval) 
2361 err = bc1_find_sels4_fullerr(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels, cur_err); 
2362 else 
2363 err = bc1_find_sels4_check2_err(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels, cur_err); 
2364 
2365 return err; 
2366 } 
2367  
2368 static inline uint32_t bc1_find_sels3_fullerr(bool use_black, const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16], uint32_t cur_err) 
2369 { 
2370 uint32_t block_r[3], block_g[3], block_b[3]; 
2371 bc1_get_block_colors3(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb); 
2372  
2373 uint32_t total_err = 0; 
2374 
2375 for (uint32_t i = 0; i < 16; i++) 
2376 { 
2377 const int r = pSrc_pixels[i].r; 
2378 const int g = pSrc_pixels[i].g; 
2379 const int b = pSrc_pixels[i].b; 
2380 
2381 uint32_t best_err = squarei((int)block_r[0] - (int)r) + squarei((int)block_g[0] - (int)g) + squarei((int)block_b[0] - (int)b); 
2382 uint32_t best_sel = 0; 
2383 
2384 uint32_t err1 = squarei((int)block_r[1] - (int)r) + squarei((int)block_g[1] - (int)g) + squarei((int)block_b[1] - (int)b); 
2385 if (err1 < best_err) 
2386 { 
2387 best_err = err1; 
2388 best_sel = 1; 
2389 } 
2390 
2391 uint32_t err2 = squarei((int)block_r[2] - (int)r) + squarei((int)block_g[2] - (int)g) + squarei((int)block_b[2] - (int)b); 
2392 if (err2 < best_err) 
2393 { 
2394 best_err = err2; 
2395 best_sel = 2; 
2396 } 
2397 
2398 if (use_black) 
2399 { 
2400 uint32_t err3 = squarei(r) + squarei(g) + squarei(b); 
2401 if (err3 < best_err) 
2402 { 
2403 best_err = err3; 
2404 best_sel = 3; 
2405 } 
2406 } 
2407  
2408 total_err += best_err; 
2409 if (total_err >= cur_err) 
2410 return total_err; 
2411  
2412 sels[i] = (uint8_t)best_sel; 
2413 } 
2414 
2415 return total_err; 
2416 } 
2417 
2418 static inline void precise_round_565(const vec3F &xl, const vec3F &xh,  
2419 int &trial_lr, int &trial_lg, int &trial_lb, 
2420 int &trial_hr, int &trial_hg, int &trial_hb) 
2421 { 
2422 trial_lr = (int)(xl.c[0] * 31.0f);  
2423 trial_lg = (int)(xl.c[1] * 63.0f);  
2424 trial_lb = (int)(xl.c[2] * 31.0f);  
2425 
2426 trial_hr = (int)(xh.c[0] * 31.0f);  
2427 trial_hg = (int)(xh.c[1] * 63.0f);  
2428 trial_hb = (int)(xh.c[2] * 31.0f);  
2429 
2430 if ((uint32_t)(trial_lr | trial_lb | trial_hr | trial_hb) > 31U) 
2431 { 
2432 trial_lr = ((uint32_t)trial_lr > 31U) ? (~trial_lr >> 31) & 31 : trial_lr; 
2433 trial_hr = ((uint32_t)trial_hr > 31U) ? (~trial_hr >> 31) & 31 : trial_hr; 
2434 
2435 trial_lb = ((uint32_t)trial_lb > 31U) ? (~trial_lb >> 31) & 31 : trial_lb; 
2436 trial_hb = ((uint32_t)trial_hb > 31U) ? (~trial_hb >> 31) & 31 : trial_hb; 
2437 } 
2438 
2439 if ((uint32_t)(trial_lg | trial_hg) > 63U) 
2440 { 
2441 trial_lg = ((uint32_t)trial_lg > 63U) ? (~trial_lg >> 31) & 63 : trial_lg; 
2442 trial_hg = ((uint32_t)trial_hg > 63U) ? (~trial_hg >> 31) & 63 : trial_hg; 
2443 } 
2444 
2445 trial_lr = (trial_lr + (xl.c[0] > g_midpoint5[trial_lr])) & 31; 
2446 trial_lg = (trial_lg + (xl.c[1] > g_midpoint6[trial_lg])) & 63; 
2447 trial_lb = (trial_lb + (xl.c[2] > g_midpoint5[trial_lb])) & 31; 
2448  
2449 trial_hr = (trial_hr + (xh.c[0] > g_midpoint5[trial_hr])) & 31; 
2450 trial_hg = (trial_hg + (xh.c[1] > g_midpoint6[trial_hg])) & 63; 
2451 trial_hb = (trial_hb + (xh.c[2] > g_midpoint5[trial_hb])) & 31; 
2452 } 
2453 
2454 static inline void precise_round_565_noscale(vec3F xl, vec3F xh,  
2455 int &trial_lr, int &trial_lg, int &trial_lb, 
2456 int &trial_hr, int &trial_hg, int &trial_hb) 
2457 { 
2458 xl.c[0] *= 1.0f/255.0f; 
2459 xl.c[1] *= 1.0f/255.0f; 
2460 xl.c[2] *= 1.0f/255.0f; 
2461 
2462 xh.c[0] *= 1.0f/255.0f; 
2463 xh.c[1] *= 1.0f/255.0f; 
2464 xh.c[2] *= 1.0f/255.0f; 
2465 
2466 precise_round_565(xl, xh, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb); 
2467 } 
2468 
2469 static inline void bc1_encode4(bc1_block *pDst_block, int lr, int lg, int lb, int hr, int hg, int hb, const uint8_t sels[16]) 
2470 { 
2471 uint32_t lc16 = bc1_block::pack_unscaled_color(lr, lg, lb); 
2472 uint32_t hc16 = bc1_block::pack_unscaled_color(hr, hg, hb); 
2473  
2474 // Always forbid 3 color blocks 
2475 if (lc16 == hc16) 
2476 { 
2477 uint8_t mask = 0; 
2478 
2479 // Make l > h 
2480 if (hc16 > 0) 
2481 hc16--; 
2482 else 
2483 { 
2484 // lc16 = hc16 = 0 
2485 assert(lc16 == hc16 && hc16 == 0); 
2486 
2487 hc16 = 0; 
2488 lc16 = 1; 
2489 mask = 0x55; // select hc16 
2490 } 
2491 
2492 assert(lc16 > hc16); 
2493 pDst_block->set_low_color(static_cast<uint16_t>(lc16)); 
2494 pDst_block->set_high_color(static_cast<uint16_t>(hc16)); 
2495 
2496 pDst_block->m_selectors[0] = mask; 
2497 pDst_block->m_selectors[1] = mask; 
2498 pDst_block->m_selectors[2] = mask; 
2499 pDst_block->m_selectors[3] = mask; 
2500 } 
2501 else 
2502 { 
2503 uint8_t invert_mask = 0; 
2504 if (lc16 < hc16) 
2505 { 
2506 std::swap(lc16, hc16); 
2507 invert_mask = 0x55; 
2508 } 
2509 
2510 assert(lc16 > hc16); 
2511 pDst_block->set_low_color((uint16_t)lc16); 
2512 pDst_block->set_high_color((uint16_t)hc16); 
2513 
2514 uint32_t packed_sels = 0; 
2515 static const uint8_t s_sel_trans[4] = { 0, 2, 3, 1 }; 
2516 for (uint32_t i = 0; i < 16; i++) 
2517 packed_sels |= ((uint32_t)s_sel_trans[sels[i]] << (i * 2)); 
2518 
2519 pDst_block->m_selectors[0] = (uint8_t)packed_sels ^ invert_mask; 
2520 pDst_block->m_selectors[1] = (uint8_t)(packed_sels >> 8) ^ invert_mask; 
2521 pDst_block->m_selectors[2] = (uint8_t)(packed_sels >> 16) ^ invert_mask; 
2522 pDst_block->m_selectors[3] = (uint8_t)(packed_sels >> 24) ^ invert_mask; 
2523 } 
2524 } 
2525 
2526 static inline void bc1_encode3(bc1_block *pDst_block, int lr, int lg, int lb, int hr, int hg, int hb, const uint8_t sels[16]) 
2527 { 
2528 uint32_t lc16 = bc1_block::pack_unscaled_color(lr, lg, lb); 
2529 uint32_t hc16 = bc1_block::pack_unscaled_color(hr, hg, hb); 
2530 
2531 bool invert_flag = false; 
2532 if (lc16 > hc16) 
2533 { 
2534 std::swap(lc16, hc16); 
2535 invert_flag = true; 
2536 } 
2537 
2538 assert(lc16 <= hc16); 
2539  
2540 pDst_block->set_low_color((uint16_t)lc16); 
2541 pDst_block->set_high_color((uint16_t)hc16); 
2542 
2543 uint32_t packed_sels = 0; 
2544  
2545 if (invert_flag) 
2546 { 
2547 static const uint8_t s_sel_trans_inv[4] = { 1, 0, 2, 3 }; 
2548  
2549 for (uint32_t i = 0; i < 16; i++) 
2550 packed_sels |= ((uint32_t)s_sel_trans_inv[sels[i]] << (i * 2)); 
2551 } 
2552 else 
2553 { 
2554 for (uint32_t i = 0; i < 16; i++) 
2555 packed_sels |= ((uint32_t)sels[i] << (i * 2)); 
2556 } 
2557 
2558 pDst_block->m_selectors[0] = (uint8_t)packed_sels; 
2559 pDst_block->m_selectors[1] = (uint8_t)(packed_sels >> 8); 
2560 pDst_block->m_selectors[2] = (uint8_t)(packed_sels >> 16); 
2561 pDst_block->m_selectors[3] = (uint8_t)(packed_sels >> 24); 
2562 } 
2563  
2564 struct bc1_encode_results 
2565 { 
2566 int lr, lg, lb; 
2567 int hr, hg, hb; 
2568 uint8_t sels[16]; 
2569 bool m_3color; 
2570 }; 
2571  
2572 static bool try_3color_block_useblack(const color32* pSrc_pixels, uint32_t flags, uint32_t &cur_err, bc1_encode_results &results) 
2573 { 
2574 int total_r = 0, total_g = 0, total_b = 0; 
2575 int max_r = 0, max_g = 0, max_b = 0; 
2576 int min_r = 255, min_g = 255, min_b = 255; 
2577 int total_pixels = 0; 
2578 for (uint32_t i = 0; i < 16; i++) 
2579 { 
2580 const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; 
2581 if ((r | g | b) < 4) 
2582 continue; 
2583  
2584 max_r = std::max(max_r, r); max_g = std::max(max_g, g); max_b = std::max(max_b, b); 
2585 min_r = std::min(min_r, r); min_g = std::min(min_g, g); min_b = std::min(min_b, b); 
2586 total_r += r; total_g += g; total_b += b; 
2587  
2588 total_pixels++; 
2589 } 
2590 
2591 if (!total_pixels) 
2592 return false; 
2593 
2594 int half_total_pixels = total_pixels >> 1; 
2595 int avg_r = (total_r + half_total_pixels) / total_pixels; 
2596 int avg_g = (total_g + half_total_pixels) / total_pixels; 
2597 int avg_b = (total_b + half_total_pixels) / total_pixels; 
2598 
2599 uint32_t low_c = 0, high_c = 0; 
2600 
2601 int icov[6] = { 0, 0, 0, 0, 0, 0 }; 
2602 for (uint32_t i = 0; i < 16; i++) 
2603 { 
2604 int r = (int)pSrc_pixels[i].r; 
2605 int g = (int)pSrc_pixels[i].g; 
2606 int b = (int)pSrc_pixels[i].b; 
2607 
2608 if ((r | g | b) < 4) 
2609 continue; 
2610 
2611 r -= avg_r; 
2612 g -= avg_g; 
2613 b -= avg_b; 
2614 
2615 icov[0] += r * r; 
2616 icov[1] += r * g; 
2617 icov[2] += r * b; 
2618 icov[3] += g * g; 
2619 icov[4] += g * b; 
2620 icov[5] += b * b; 
2621 } 
2622 
2623 float cov[6]; 
2624 for (uint32_t i = 0; i < 6; i++) 
2625 cov[i] = (float)(icov[i]) * (1.0f / 255.0f); 
2626  
2627 float xr = (float)(max_r - min_r); 
2628 float xg = (float)(max_g - min_g); 
2629 float xb = (float)(max_b - min_b); 
2630  
2631 if (icov[2] < 0) 
2632 xr = -xr; 
2633 
2634 if (icov[4] < 0) 
2635 xg = -xg; 
2636 
2637 for (uint32_t power_iter = 0; power_iter < 4; power_iter++) 
2638 { 
2639 float r = xr * cov[0] + xg * cov[1] + xb * cov[2]; 
2640 float g = xr * cov[1] + xg * cov[3] + xb * cov[4]; 
2641 float b = xr * cov[2] + xg * cov[4] + xb * cov[5]; 
2642 xr = r; xg = g; xb = b; 
2643 } 
2644 
2645 float k = maximum(fabsf(xr), fabsf(xg), fabsf(xb)); 
2646 int saxis_r = 306, saxis_g = 601, saxis_b = 117; 
2647 if (k >= 2) 
2648 { 
2649 float m = 1024.0f / k; 
2650 saxis_r = (int)(xr * m); 
2651 saxis_g = (int)(xg * m); 
2652 saxis_b = (int)(xb * m); 
2653 } 
2654  
2655 int low_dot = INT_MAX, high_dot = INT_MIN; 
2656 for (uint32_t i = 0; i < 16; i++) 
2657 { 
2658 int r = (int)pSrc_pixels[i].r, g = (int)pSrc_pixels[i].g, b = (int)pSrc_pixels[i].b; 
2659 
2660 if ((r | g | b) < 4) 
2661 continue; 
2662 
2663 int dot = r * saxis_r + g * saxis_g + b * saxis_b; 
2664 if (dot < low_dot) 
2665 { 
2666 low_dot = dot; 
2667 low_c = i; 
2668 } 
2669 if (dot > high_dot) 
2670 { 
2671 high_dot = dot; 
2672 high_c = i; 
2673 } 
2674 } 
2675 
2676 int lr = to_5(pSrc_pixels[low_c].r); 
2677 int lg = to_6(pSrc_pixels[low_c].g); 
2678 int lb = to_5(pSrc_pixels[low_c].b); 
2679 
2680 int hr = to_5(pSrc_pixels[high_c].r); 
2681 int hg = to_6(pSrc_pixels[high_c].g); 
2682 int hb = to_5(pSrc_pixels[high_c].b); 
2683 
2684 uint8_t trial_sels[16]; 
2685 uint32_t trial_err = bc1_find_sels3_fullerr(true, pSrc_pixels, lr, lg, lb, hr, hg, hb, trial_sels, UINT32_MAX); 
2686 
2687 if (trial_err) 
2688 { 
2689 const uint32_t total_ls_passes = flags & cEncodeBC1TwoLeastSquaresPasses ? 2 : 1; 
2690 for (uint32_t trials = 0; trials < total_ls_passes; trials++) 
2691 { 
2692 vec3F xl, xh; 
2693 int lr2, lg2, lb2, hr2, hg2, hb2; 
2694 if (!compute_least_squares_endpoints3_rgb(true, pSrc_pixels, trial_sels, &xl, &xh)) 
2695 { 
2696 lr2 = g_bc1_match5_half[avg_r].m_hi; 
2697 lg2 = g_bc1_match6_half[avg_g].m_hi; 
2698 lb2 = g_bc1_match5_half[avg_b].m_hi; 
2699 
2700 hr2 = g_bc1_match5_half[avg_r].m_lo; 
2701 hg2 = g_bc1_match6_half[avg_g].m_lo; 
2702 hb2 = g_bc1_match5_half[avg_b].m_lo; 
2703 } 
2704 else 
2705 { 
2706 precise_round_565(xl, xh, hr2, hg2, hb2, lr2, lg2, lb2); 
2707 } 
2708 
2709 if ((lr == lr2) && (lg == lg2) && (lb == lb2) && (hr == hr2) && (hg == hg2) && (hb == hb2)) 
2710 break; 
2711  
2712 uint8_t trial_sels2[16]; 
2713 uint32_t trial_err2 = bc1_find_sels3_fullerr(true, pSrc_pixels, lr2, lg2, lb2, hr2, hg2, hb2, trial_sels2, trial_err); 
2714  
2715 if (trial_err2 < trial_err) 
2716 { 
2717 trial_err = trial_err2; 
2718 lr = lr2; lg = lg2; lb = lb2; 
2719 hr = hr2; hg = hg2; hb = hb2; 
2720 memcpy(trial_sels, trial_sels2, sizeof(trial_sels)); 
2721 } 
2722 else 
2723 break; 
2724 } 
2725 } 
2726 
2727 if (trial_err < cur_err) 
2728 { 
2729 results.m_3color = true; 
2730 results.lr = lr; 
2731 results.lg = lg; 
2732 results.lb = lb; 
2733 results.hr = hr; 
2734 results.hg = hg; 
2735 results.hb = hb; 
2736 memcpy(results.sels, trial_sels, 16); 
2737  
2738 cur_err = trial_err; 
2739  
2740 return true; 
2741 } 
2742 
2743 return false; 
2744 } 
2745 
2746 static bool try_3color_block(const color32* pSrc_pixels, uint32_t flags, uint32_t &cur_err,  
2747 int avg_r, int avg_g, int avg_b, int lr, int lg, int lb, int hr, int hg, int hb, int total_r, int total_g, int total_b, uint32_t total_orderings_to_try, 
2748 bc1_encode_results &results) 
2749 { 
2750 uint8_t trial_sels[16]; 
2751 uint32_t trial_err = bc1_find_sels3_fullerr(false, pSrc_pixels, lr, lg, lb, hr, hg, hb, trial_sels, UINT32_MAX); 
2752 
2753 if (trial_err) 
2754 { 
2755 const uint32_t total_ls_passes = flags & cEncodeBC1TwoLeastSquaresPasses ? 2 : 1; 
2756 for (uint32_t trials = 0; trials < total_ls_passes; trials++) 
2757 { 
2758 vec3F xl, xh; 
2759 int lr2, lg2, lb2, hr2, hg2, hb2; 
2760 if (!compute_least_squares_endpoints3_rgb(false, pSrc_pixels, trial_sels, &xl, &xh)) 
2761 { 
2762 lr2 = g_bc1_match5_half[avg_r].m_hi; 
2763 lg2 = g_bc1_match6_half[avg_g].m_hi; 
2764 lb2 = g_bc1_match5_half[avg_b].m_hi; 
2765 
2766 hr2 = g_bc1_match5_half[avg_r].m_lo; 
2767 hg2 = g_bc1_match6_half[avg_g].m_lo; 
2768 hb2 = g_bc1_match5_half[avg_b].m_lo; 
2769 } 
2770 else 
2771 { 
2772 precise_round_565(xl, xh, hr2, hg2, hb2, lr2, lg2, lb2); 
2773 } 
2774 
2775 if ((lr == lr2) && (lg == lg2) && (lb == lb2) && (hr == hr2) && (hg == hg2) && (hb == hb2)) 
2776 break; 
2777  
2778 uint8_t trial_sels2[16]; 
2779 uint32_t trial_err2 = bc1_find_sels3_fullerr(false, pSrc_pixels, lr2, lg2, lb2, hr2, hg2, hb2, trial_sels2, trial_err); 
2780  
2781 if (trial_err2 < trial_err) 
2782 { 
2783 trial_err = trial_err2; 
2784 lr = lr2; lg = lg2; lb = lb2; 
2785 hr = hr2; hg = hg2; hb = hb2; 
2786 memcpy(trial_sels, trial_sels2, sizeof(trial_sels)); 
2787 } 
2788 else 
2789 break; 
2790 } 
2791 } 
2792 
2793 if ((trial_err) && (flags & cEncodeBC1UseLikelyTotalOrderings) && (total_orderings_to_try)) 
2794 { 
2795 hist3 h; 
2796 for (uint32_t i = 0; i < 16; i++) 
2797 { 
2798 assert(trial_sels[i] < 3); 
2799 h.m_hist[trial_sels[i]]++; 
2800 } 
2801 
2802 const uint32_t orig_total_order_index = h.lookup_total_ordering_index(); 
2803 
2804 int r0, g0, b0, r3, g3, b3; 
2805 r0 = (lr << 3) | (lr >> 2); g0 = (lg << 2) | (lg >> 4); b0 = (lb << 3) | (lb >> 2); 
2806 r3 = (hr << 3) | (hr >> 2); g3 = (hg << 2) | (hg >> 4); b3 = (hb << 3) | (hb >> 2); 
2807 
2808 int ar = r3 - r0, ag = g3 - g0, ab = b3 - b0; 
2809  
2810 int dots[16]; 
2811 for (uint32_t i = 0; i < 16; i++) 
2812 { 
2813 int r = pSrc_pixels[i].r; 
2814 int g = pSrc_pixels[i].g; 
2815 int b = pSrc_pixels[i].b; 
2816 int d = 0x1000000 + (r * ar + g * ag + b * ab); 
2817 assert(d >= 0); 
2818 dots[i] = (d << 4) + i; 
2819 } 
2820 
2821 std::sort(dots, dots + 16); 
2822 
2823 uint32_t r_sum[17], g_sum[17], b_sum[17]; 
2824 uint32_t r = 0, g = 0, b = 0; 
2825 for (uint32_t i = 0; i < 16; i++) 
2826 { 
2827 const uint32_t p = dots[i] & 15; 
2828 
2829 r_sum[i] = r; 
2830 g_sum[i] = g; 
2831 b_sum[i] = b; 
2832 
2833 r += pSrc_pixels[p].r; 
2834 g += pSrc_pixels[p].g; 
2835 b += pSrc_pixels[p].b; 
2836 } 
2837 
2838 r_sum[16] = total_r; 
2839 g_sum[16] = total_g; 
2840 b_sum[16] = total_b; 
2841  
2842 const uint32_t q_total = (flags & cEncodeBC1Exhaustive) ? NUM_UNIQUE_TOTAL_ORDERINGS3 : std::min(total_orderings_to_try, MAX_TOTAL_ORDERINGS3); 
2843 for (uint32_t q = 0; q < q_total; q++) 
2844 { 
2845 const uint32_t s = (flags & cEncodeBC1Exhaustive) ? q : g_best_total_orderings3[orig_total_order_index][q]; 
2846 
2847 int trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb; 
2848 
2849 vec3F xl, xh; 
2850 
2851 if ((s == TOTAL_ORDER_3_0_16) || (s == TOTAL_ORDER_3_1_16) || (s == TOTAL_ORDER_3_2_16)) 
2852 { 
2853 trial_lr = g_bc1_match5_half[avg_r].m_hi; 
2854 trial_lg = g_bc1_match6_half[avg_g].m_hi; 
2855 trial_lb = g_bc1_match5_half[avg_b].m_hi; 
2856 
2857 trial_hr = g_bc1_match5_half[avg_r].m_lo; 
2858 trial_hg = g_bc1_match6_half[avg_g].m_lo; 
2859 trial_hb = g_bc1_match5_half[avg_b].m_lo; 
2860 } 
2861 else 
2862 { 
2863 compute_least_squares_endpoints3_rgb(&xl, &xh, total_r, total_g, total_b,  
2864 g_selector_factors3[s][0], g_selector_factors3[s][1], g_selector_factors3[s][2], s, r_sum, g_sum, b_sum); 
2865  
2866 precise_round_565(xl, xh, trial_hr, trial_hg, trial_hb, trial_lr, trial_lg, trial_lb); 
2867 } 
2868 
2869 uint8_t trial_sels2[16]; 
2870 uint32_t trial_err2 = bc1_find_sels3_fullerr(false, pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, trial_sels2, UINT32_MAX); 
2871  
2872 if (trial_err2 < trial_err) 
2873 { 
2874 trial_err = trial_err2; 
2875 
2876 lr = trial_lr; 
2877 lg = trial_lg; 
2878 lb = trial_lb; 
2879 
2880 hr = trial_hr; 
2881 hg = trial_hg; 
2882 hb = trial_hb; 
2883 
2884 memcpy(trial_sels, trial_sels2, sizeof(trial_sels)); 
2885 } 
2886 
2887 } // s 
2888 } 
2889 
2890 if (trial_err < cur_err) 
2891 { 
2892 results.m_3color = true; 
2893 results.lr = lr; 
2894 results.lg = lg; 
2895 results.lb = lb; 
2896 results.hr = hr; 
2897 results.hg = hg; 
2898 results.hb = hb; 
2899 memcpy(results.sels, trial_sels, 16); 
2900  
2901 cur_err = trial_err; 
2902 
2903 return true; 
2904 } 
2905 
2906 return false; 
2907 } 
2908 
2909 void encode_bc1(uint32_t level, void* pDst, const uint8_t* pPixels, bool allow_3color, bool allow_transparent_texels_for_black) 
2910 { 
2911 uint32_t flags = 0, total_orderings4 = 1, total_orderings3 = 1; 
2912 
2913 static_assert(MAX_TOTAL_ORDERINGS3 >= 32, "MAX_TOTAL_ORDERINGS3 >= 32"); 
2914 static_assert(MAX_TOTAL_ORDERINGS4 >= 32, "MAX_TOTAL_ORDERINGS4 >= 32"); 
2915 
2916 switch (level) 
2917 { 
2918 case 0: 
2919 // Faster/higher quality than stb_dxt default. 
2920 flags = cEncodeBC1BoundingBoxInt; 
2921 break; 
2922 case 1: 
2923 // Faster/higher quality than stb_dxt default. A bit higher average quality vs. mode 0. 
2924 flags = cEncodeBC1Use2DLS; 
2925 break; 
2926 case 2: 
2927 // On average mode 2 is a little weaker than modes 0/1, but it's stronger on outliers (very tough textures). 
2928 // Slightly stronger than stb_dxt. 
2929 flags = 0; 
2930 break; 
2931 case 3: 
2932 // Slightly stronger than stb_dxt HIGHQUAL. 
2933 flags = cEncodeBC1TwoLeastSquaresPasses; 
2934 break; 
2935 case 4: 
2936 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1Use6PowerIters; 
2937 break; 
2938 default: 
2939 case 5: 
2940 // stb_dxt HIGHQUAL + permit 3 color (if it's enabled). 
2941 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFasterMSEEval; 
2942 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2943 break; 
2944 case 6: 
2945 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFasterMSEEval | cEncodeBC1UseLikelyTotalOrderings; 
2946 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2947 break; 
2948 case 7: 
2949 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFasterMSEEval | cEncodeBC1UseLikelyTotalOrderings; 
2950 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2951 total_orderings4 = 4; 
2952 break; 
2953 case 8: 
2954 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFasterMSEEval | cEncodeBC1UseLikelyTotalOrderings; 
2955 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2956 total_orderings4 = 8; 
2957 break; 
2958 case 9: 
2959 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseLikelyTotalOrderings; 
2960 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2961 total_orderings4 = 11; 
2962 total_orderings3 = 3; 
2963 break; 
2964 case 10: 
2965 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseLikelyTotalOrderings; 
2966 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2967 total_orderings4 = 20; 
2968 total_orderings3 = 8; 
2969 break; 
2970 case 11: 
2971 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseLikelyTotalOrderings; 
2972 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2973 total_orderings4 = 28; 
2974 total_orderings3 = 16; 
2975 break; 
2976 case 12: 
2977 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseLikelyTotalOrderings; 
2978 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2979 total_orderings4 = 32; 
2980 total_orderings3 = 32; 
2981 break; 
2982 case 13: 
2983 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | (20 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
2984 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2985 total_orderings4 = 32; 
2986 total_orderings3 = 32; 
2987 break; 
2988 case 14: 
2989 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | (32 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
2990 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2991 total_orderings4 = 32; 
2992 total_orderings3 = 32; 
2993 break; 
2994 case 15: 
2995 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | (32 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
2996 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
2997 total_orderings4 = ((((32 + MAX_TOTAL_ORDERINGS4) / 2) + 32) / 2); 
2998 total_orderings3 = 32; 
2999 break; 
3000 case 16: 
3001 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | (256 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
3002 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
3003 total_orderings4 = (32 + MAX_TOTAL_ORDERINGS4) / 2; 
3004 total_orderings3 = 32; 
3005 break; 
3006 case 17: 
3007 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | (256 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
3008 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
3009 total_orderings4 = MAX_TOTAL_ORDERINGS4; 
3010 total_orderings3 = 32; 
3011 break; 
3012 case 18: 
3013 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | cEncodeBC1Iterative | (256 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
3014 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
3015 total_orderings4 = MAX_TOTAL_ORDERINGS4; 
3016 total_orderings3 = 32; 
3017 break; 
3018 case 19: 
3019 // This hidden mode is *extremely* slow and abuses the encoder. It's just for testing/training. 
3020 flags = cEncodeBC1TwoLeastSquaresPasses | cEncodeBC1UseFullMSEEval | cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use6PowerIters | cEncodeBC1Exhaustive | cEncodeBC1Iterative | (256 << cEncodeBC1EndpointSearchRoundsShift) | cEncodeBC1TryAllInitialEndponts; 
3021 flags |= (allow_3color ? cEncodeBC1Use3ColorBlocks : 0) | (allow_transparent_texels_for_black ? cEncodeBC1Use3ColorBlocksForBlackPixels : 0); 
3022 total_orderings4 = 32; 
3023 total_orderings3 = 32; 
3024 break; 
3025 } 
3026 
3027 encode_bc1(pDst, pPixels, flags, total_orderings4, total_orderings3); 
3028 } 
3029 
3030 static inline void encode_bc1_pick_initial(const color32 *pSrc_pixels, uint32_t flags, bool grayscale_flag, 
3031 int min_r, int min_g, int min_b, int max_r, int max_g, int max_b,  
3032 int avg_r, int avg_g, int avg_b, int total_r, int total_g, int total_b, 
3033 int &lr, int &lg, int &lb, int &hr, int &hg, int &hb) 
3034 { 
3035 if (grayscale_flag)  
3036 { 
3037 const int fr = pSrc_pixels[0].r; 
3038 
3039 // Grayscale blocks are a common enough case to specialize. 
3040 if ((max_r - min_r) < 2) 
3041 { 
3042 lr = lb = hr = hb = to_5(fr); 
3043 lg = hg = to_6(fr); 
3044 } 
3045 else 
3046 { 
3047 lr = lb = to_5(min_r); 
3048 lg = to_6(min_r); 
3049 
3050 hr = hb = to_5(max_r); 
3051 hg = to_6(max_r); 
3052 } 
3053 } 
3054 else if (flags & cEncodeBC1Use2DLS) 
3055 { 
3056 // 2D Least Squares approach from Humus's example, with added inset and optimal rounding. 
3057 int big_chan = 0, min_chan_val = min_r, max_chan_val = max_r; 
3058 if ((max_g - min_g) > (max_chan_val - min_chan_val)) 
3059 big_chan = 1, min_chan_val = min_g, max_chan_val = max_g; 
3060 
3061 if ((max_b - min_b) > (max_chan_val - min_chan_val)) 
3062 big_chan = 2, min_chan_val = min_b, max_chan_val = max_b; 
3063  
3064 int sum_xy_r = 0, sum_xy_g = 0, sum_xy_b = 0; 
3065 vec3F l, h; 
3066 if (big_chan == 0) 
3067 { 
3068 for (uint32_t i = 0; i < 16; i++) 
3069 { 
3070 const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; 
3071 sum_xy_r += r * r, sum_xy_g += r * g, sum_xy_b += r * b; 
3072 } 
3073 
3074 int sum_x = total_r; 
3075 int sum_x2 = sum_xy_r; 
3076 
3077 float div = (float)(16 * sum_x2 - sum_x * sum_x); 
3078 float b_y = 0.0f, b_z = 0.0f; 
3079 if (fabs(div) > 1e-8f) 
3080 { 
3081 div = 1.0f / div; 
3082 b_y = (16 * sum_xy_g - sum_x * total_g) * div; 
3083 b_z = (16 * sum_xy_b - sum_x * total_b) * div; 
3084 } 
3085 
3086 float a_y = (total_g - b_y * sum_x) / 16.0f; 
3087 float a_z = (total_b - b_z * sum_x) / 16.0f; 
3088  
3089 l.c[1] = a_y + b_y * min_chan_val; 
3090 l.c[2] = a_z + b_z * min_chan_val; 
3091 
3092 h.c[1] = a_y + b_y * max_chan_val; 
3093 h.c[2] = a_z + b_z * max_chan_val; 
3094 
3095 float dg = (h.c[1] - l.c[1]); 
3096 float db = (h.c[2] - l.c[2]); 
3097  
3098 h.c[1] = l.c[1] + dg * (15.0f/16.0f); 
3099 h.c[2] = l.c[2] + db * (15.0f/16.0f); 
3100 
3101 l.c[1] = l.c[1] + dg * (1.0f/16.0f); 
3102 l.c[2] = l.c[2] + db * (1.0f/16.0f); 
3103  
3104 float d = (float)(max_chan_val - min_chan_val); 
3105 float fmin_chan_val = min_chan_val + d * (1.0f/16.0f); 
3106 float fmax_chan_val = min_chan_val + d * (15.0f/16.0f); 
3107 
3108 l.c[0] = fmin_chan_val; 
3109 h.c[0] = fmax_chan_val; 
3110 } 
3111 else if (big_chan == 1) 
3112 { 
3113 for (uint32_t i = 0; i < 16; i++) 
3114 { 
3115 const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; 
3116 sum_xy_r += g * r, sum_xy_g += g * g, sum_xy_b += g * b; 
3117 } 
3118 
3119 int sum_x = total_g; 
3120 int sum_x2 = sum_xy_g; 
3121 
3122 float div = (float)(16 * sum_x2 - sum_x * sum_x); 
3123 float b_x = 0.0f, b_z = 0.0f; 
3124 if (fabs(div) > 1e-8f) 
3125 { 
3126 div = 1.0f / div; 
3127 b_x = (16 * sum_xy_r - sum_x * total_r) * div; 
3128 b_z = (16 * sum_xy_b - sum_x * total_b) * div; 
3129 } 
3130 
3131 float a_x = (total_r - b_x * sum_x) / 16.0f; 
3132 float a_z = (total_b - b_z * sum_x) / 16.0f; 
3133 
3134 l.c[0] = a_x + b_x * min_chan_val; 
3135 l.c[2] = a_z + b_z * min_chan_val; 
3136 
3137 h.c[0] = a_x + b_x * max_chan_val; 
3138 h.c[2] = a_z + b_z * max_chan_val; 
3139 
3140 float dr = (h.c[0] - l.c[0]); 
3141 float db = (h.c[2] - l.c[2]); 
3142  
3143 h.c[0] = l.c[0] + dr * (15.0f/16.0f); 
3144 h.c[2] = l.c[2] + db * (15.0f/16.0f); 
3145 
3146 l.c[0] = l.c[0] + dr * (1.0f/16.0f); 
3147 l.c[2] = l.c[2] + db * (1.0f/16.0f); 
3148  
3149 float d = (float)(max_chan_val - min_chan_val); 
3150 float fmin_chan_val = min_chan_val + d * (1.0f/16.0f); 
3151 float fmax_chan_val = min_chan_val + d * (15.0f/16.0f); 
3152 
3153 l.c[1] = fmin_chan_val; 
3154 h.c[1] = fmax_chan_val; 
3155 } 
3156 else 
3157 { 
3158 for (uint32_t i = 0; i < 16; i++) 
3159 { 
3160 const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; 
3161 sum_xy_r += b * r, sum_xy_g += b * g, sum_xy_b += b * b; 
3162 } 
3163 
3164 int sum_x = total_b; 
3165 int sum_x2 = sum_xy_b; 
3166 
3167 float div = (float)(16 * sum_x2 - sum_x * sum_x); 
3168 float b_x = 0.0f, b_y = 0.0f; 
3169 if (fabs(div) > 1e-8f) 
3170 { 
3171 div = 1.0f / div; 
3172 b_x = (16 * sum_xy_r - sum_x * total_r) * div; 
3173 b_y = (16 * sum_xy_g - sum_x * total_g) * div; 
3174 } 
3175 
3176 float a_x = (total_r - b_x * sum_x) / 16.0f; 
3177 float a_y = (total_g - b_y * sum_x) / 16.0f; 
3178 
3179 l.c[0] = a_x + b_x * min_chan_val; 
3180 l.c[1] = a_y + b_y * min_chan_val; 
3181 
3182 h.c[0] = a_x + b_x * max_chan_val; 
3183 h.c[1] = a_y + b_y * max_chan_val; 
3184 
3185 float dr = (h.c[0] - l.c[0]); 
3186 float dg = (h.c[1] - l.c[1]); 
3187  
3188 h.c[0] = l.c[0] + dr * (15.0f/16.0f); 
3189 h.c[1] = l.c[1] + dg * (15.0f/16.0f); 
3190 
3191 l.c[0] = l.c[0] + dr * (1.0f/16.0f); 
3192 l.c[1] = l.c[1] + dg * (1.0f/16.0f); 
3193 
3194 float d = (float)(max_chan_val - min_chan_val); 
3195 float fmin_chan_val = min_chan_val + d * (1.0f/16.0f); 
3196 float fmax_chan_val = min_chan_val + d * (15.0f/16.0f); 
3197 
3198 l.c[2] = fmin_chan_val; 
3199 h.c[2] = fmax_chan_val; 
3200 } 
3201 
3202 precise_round_565_noscale(l, h, lr, lg, lb, hr, hg, hb); 
3203 } 
3204 else if (flags & cEncodeBC1BoundingBox) 
3205 { 
3206 // Algorithm from icbc.h compress_dxt1_fast() 
3207 vec3F l, h; 
3208 l.c[0] = min_r * (1.0f/255.0f); 
3209 l.c[1] = min_g * (1.0f/255.0f); 
3210 l.c[2] = min_b * (1.0f/255.0f); 
3211 
3212 h.c[0] = max_r * (1.0f/255.0f); 
3213 h.c[1] = max_g * (1.0f/255.0f); 
3214 h.c[2] = max_b * (1.0f/255.0f); 
3215 
3216 const float bias = 8.0f / 255.0f; 
3217 float inset_r = (h.c[0] - l.c[0] - bias) * (1.0f/16.0f); 
3218 float inset_g = (h.c[1] - l.c[1] - bias) * (1.0f/16.0f); 
3219 float inset_b = (h.c[2] - l.c[2] - bias) * (1.0f/16.0f); 
3220  
3221 l.c[0] = clampf(l.c[0] + inset_r, 0.0f, 1.0f); 
3222 l.c[1] = clampf(l.c[1] + inset_g, 0.0f, 1.0f); 
3223 l.c[2] = clampf(l.c[2] + inset_b, 0.0f, 1.0f); 
3224 
3225 h.c[0] = clampf(h.c[0] - inset_r, 0.0f, 1.0f); 
3226 h.c[1] = clampf(h.c[1] - inset_g, 0.0f, 1.0f); 
3227 h.c[2] = clampf(h.c[2] - inset_b, 0.0f, 1.0f); 
3228 
3229 int icov_xz = 0, icov_yz = 0; 
3230 for (uint32_t i = 0; i < 16; i++) 
3231 { 
3232 int r = (int)pSrc_pixels[i].r - avg_r; 
3233 int g = (int)pSrc_pixels[i].g - avg_g; 
3234 int b = (int)pSrc_pixels[i].b - avg_b; 
3235 icov_xz += r * b; 
3236 icov_yz += g * b; 
3237 } 
3238  
3239 if (icov_xz < 0) 
3240 std::swap(l.c[0], h.c[0]); 
3241 
3242 if (icov_yz < 0) 
3243 std::swap(l.c[1], h.c[1]); 
3244 
3245 precise_round_565(l, h, lr, lg, lb, hr, hg, hb); 
3246 } 
3247 else if (flags & cEncodeBC1BoundingBoxInt) 
3248 { 
3249 // Algorithm from icbc.h compress_dxt1_fast(), but converted to integer. 
3250 int inset_r = (max_r - min_r - 8) >> 4; 
3251 int inset_g = (max_g - min_g - 8) >> 4; 
3252 int inset_b = (max_b - min_b - 8) >> 4; 
3253 
3254 min_r += inset_r; 
3255 min_g += inset_g; 
3256 min_b += inset_b; 
3257 if ((uint32_t)(min_r | min_g | min_b) > 255U) 
3258 { 
3259 min_r = clampi(min_r, 0, 255); 
3260 min_g = clampi(min_g, 0, 255); 
3261 min_b = clampi(min_b, 0, 255); 
3262 } 
3263 
3264 max_r -= inset_r; 
3265 max_g -= inset_g; 
3266 max_b -= inset_b; 
3267 if ((uint32_t)(max_r | max_g | max_b) > 255U) 
3268 { 
3269 max_r = clampi(max_r, 0, 255); 
3270 max_g = clampi(max_g, 0, 255); 
3271 max_b = clampi(max_b, 0, 255); 
3272 } 
3273 
3274 int icov_xz = 0, icov_yz = 0; 
3275 for (uint32_t i = 0; i < 16; i++) 
3276 { 
3277 int r = (int)pSrc_pixels[i].r - avg_r; 
3278 int g = (int)pSrc_pixels[i].g - avg_g; 
3279 int b = (int)pSrc_pixels[i].b - avg_b; 
3280 icov_xz += r * b; 
3281 icov_yz += g * b; 
3282 } 
3283 
3284 int x0 = min_r; 
3285 int y0 = min_g; 
3286 int x1 = max_r; 
3287 int y1 = max_g; 
3288 
3289 if (icov_xz < 0) 
3290 std::swap(x0, x1); 
3291 
3292 if (icov_yz < 0) 
3293 std::swap(y0, y1); 
3294  
3295 lr = to_5(x0); 
3296 lg = to_6(y0); 
3297 lb = to_5(min_b); 
3298 
3299 hr = to_5(x1); 
3300 hg = to_6(y1); 
3301 hb = to_5(max_b); 
3302 } 
3303 else 
3304 { 
3305 // Select 2 colors along the principle axis. (There must be a faster/simpler way.) 
3306 uint32_t low_c = 0, high_c = 0; 
3307 
3308 int icov[6] = { 0, 0, 0, 0, 0, 0 }; 
3309 for (uint32_t i = 0; i < 16; i++) 
3310 { 
3311 int r = (int)pSrc_pixels[i].r - avg_r; 
3312 int g = (int)pSrc_pixels[i].g - avg_g; 
3313 int b = (int)pSrc_pixels[i].b - avg_b; 
3314 icov[0] += r * r; 
3315 icov[1] += r * g; 
3316 icov[2] += r * b; 
3317 icov[3] += g * g; 
3318 icov[4] += g * b; 
3319 icov[5] += b * b; 
3320 } 
3321  
3322 int saxis_r = 306, saxis_g = 601, saxis_b = 117; 
3323 
3324 float xr = (float)(max_r - min_r); 
3325 float xg = (float)(max_g - min_g); 
3326 float xb = (float)(max_b - min_b); 
3327 
3328 if (icov[2] < 0) 
3329 xr = -xr; 
3330 
3331 if (icov[4] < 0) 
3332 xg = -xg; 
3333  
3334 float cov[6]; 
3335 for (uint32_t i = 0; i < 6; i++) 
3336 cov[i] = (float)(icov[i]) * (1.0f / 255.0f); 
3337 
3338 const uint32_t total_power_iters = (flags & cEncodeBC1Use6PowerIters) ? 6 : 4; 
3339 for (uint32_t power_iter = 0; power_iter < total_power_iters; power_iter++) 
3340 { 
3341 float r = xr * cov[0] + xg * cov[1] + xb * cov[2]; 
3342 float g = xr * cov[1] + xg * cov[3] + xb * cov[4]; 
3343 float b = xr * cov[2] + xg * cov[4] + xb * cov[5]; 
3344 xr = r; xg = g; xb = b; 
3345 } 
3346 
3347 float k = maximum(fabsf(xr), fabsf(xg), fabsf(xb)); 
3348 if (k >= 2) 
3349 { 
3350 float m = 2048.0f / k; 
3351 saxis_r = (int)(xr * m); 
3352 saxis_g = (int)(xg * m); 
3353 saxis_b = (int)(xb * m); 
3354 } 
3355  
3356 int low_dot = INT_MAX, high_dot = INT_MIN; 
3357 
3358 saxis_r = (int)((uint32_t)saxis_r << 4U); 
3359 saxis_g = (int)((uint32_t)saxis_g << 4U); 
3360 saxis_b = (int)((uint32_t)saxis_b << 4U); 
3361  
3362 for (uint32_t i = 0; i < 16; i += 4) 
3363 { 
3364 int dot0 = ((pSrc_pixels[i].r * saxis_r + pSrc_pixels[i].g * saxis_g + pSrc_pixels[i].b * saxis_b) & ~0xF) + i; 
3365 int dot1 = ((pSrc_pixels[i + 1].r * saxis_r + pSrc_pixels[i + 1].g * saxis_g + pSrc_pixels[i + 1].b * saxis_b) & ~0xF) + i + 1; 
3366 int dot2 = ((pSrc_pixels[i + 2].r * saxis_r + pSrc_pixels[i + 2].g * saxis_g + pSrc_pixels[i + 2].b * saxis_b) & ~0xF) + i + 2; 
3367 int dot3 = ((pSrc_pixels[i + 3].r * saxis_r + pSrc_pixels[i + 3].g * saxis_g + pSrc_pixels[i + 3].b * saxis_b) & ~0xF) + i + 3; 
3368 
3369 int min_d01 = std::min(dot0, dot1); 
3370 int max_d01 = std::max(dot0, dot1); 
3371 
3372 int min_d23 = std::min(dot2, dot3); 
3373 int max_d23 = std::max(dot2, dot3); 
3374 
3375 int min_d = std::min(min_d01, min_d23); 
3376 int max_d = std::max(max_d01, max_d23); 
3377 
3378 low_dot = std::min(low_dot, min_d); 
3379 high_dot = std::max(high_dot, max_d); 
3380 } 
3381 low_c = low_dot & 15; 
3382 high_c = high_dot & 15; 
3383 
3384 lr = to_5(pSrc_pixels[low_c].r); 
3385 lg = to_6(pSrc_pixels[low_c].g); 
3386 lb = to_5(pSrc_pixels[low_c].b); 
3387 
3388 hr = to_5(pSrc_pixels[high_c].r); 
3389 hg = to_6(pSrc_pixels[high_c].g); 
3390 hb = to_5(pSrc_pixels[high_c].b); 
3391 } 
3392 } 
3393 
3394 static const int8_t s_adjacent_voxels[16][4] =  
3395 { 
3396 { 1,0,0, 3 }, // 0 
3397 { 0,1,0, 4 }, // 1 
3398 { 0,0,1, 5 }, // 2 
3399 { -1,0,0, 0 }, // 3 
3400 { 0,-1,0, 1 }, // 4 
3401 { 0,0,-1, 2 }, // 5 
3402 { 1,1,0, 9 }, // 6 
3403 { 1,0,1, 10 }, // 7 
3404 { 0,1,1, 11 }, // 8 
3405 { -1,-1,0, 6 }, // 9 
3406 { -1,0,-1, 7 }, // 10 
3407 { 0,-1,-1, 8 }, // 11 
3408 { -1,1,0, 13 }, // 12 
3409 { 1,-1,0, 12 }, // 13 
3410 { 0,-1,1, 15 }, // 14 
3411 { 0,1,-1, 14 }, // 15 
3412 }; 
3413 
3414 // From icbc's high quality mode. 
3415 static inline void encode_bc1_endpoint_search(const color32 *pSrc_pixels, bool any_black_pixels, 
3416 uint32_t flags, bc1_encode_results &results, uint32_t cur_err) 
3417 { 
3418 int &lr = results.lr, &lg = results.lg, &lb = results.lb, &hr = results.hr, &hg = results.hg, &hb = results.hb; 
3419 uint8_t *sels = results.sels; 
3420  
3421 int prev_improvement_index = 0, forbidden_direction = -1; 
3422  
3423 const int endpoint_search_rounds = (flags & cEncodeBC1EndpointSearchRoundsMask) >> cEncodeBC1EndpointSearchRoundsShift; 
3424 for (int i = 0; i < endpoint_search_rounds; i++) 
3425 { 
3426 assert(s_adjacent_voxels[ s_adjacent_voxels[i & 15][3] ][3] == (i & 15));  
3427  
3428 if (forbidden_direction == (i & 31)) 
3429 continue; 
3430 
3431 const int8_t delta[3] = { s_adjacent_voxels[i & 15][0], s_adjacent_voxels[i & 15][1], s_adjacent_voxels[i & 15][2] }; 
3432 
3433 int trial_lr = lr, trial_lg = lg, trial_lb = lb, trial_hr = hr, trial_hg = hg, trial_hb = hb; 
3434 
3435 if ((i >> 4) & 1)  
3436 { 
3437 trial_lr = clampi(trial_lr + delta[0], 0, 31); 
3438 trial_lg = clampi(trial_lg + delta[1], 0, 63); 
3439 trial_lb = clampi(trial_lb + delta[2], 0, 31); 
3440 } 
3441 else  
3442 { 
3443 trial_hr = clampi(trial_hr + delta[0], 0, 31); 
3444 trial_hg = clampi(trial_hg + delta[1], 0, 63); 
3445 trial_hb = clampi(trial_hb + delta[2], 0, 31); 
3446 } 
3447  
3448 uint8_t trial_sels[16]; 
3449 
3450 uint32_t trial_err; 
3451 if (results.m_3color) 
3452 { 
3453 trial_err = bc1_find_sels3_fullerr( 
3454 ((any_black_pixels) && ((flags & cEncodeBC1Use3ColorBlocksForBlackPixels) != 0)), 
3455 pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, trial_sels, cur_err); 
3456 } 
3457 else 
3458 { 
3459 trial_err = bc1_find_sels4(flags, pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, trial_sels, cur_err); 
3460 } 
3461 
3462 if (trial_err < cur_err) 
3463 { 
3464 cur_err = trial_err; 
3465 
3466 forbidden_direction = s_adjacent_voxels[i & 15][3] | (i & 16); 
3467 
3468 lr = trial_lr, lg = trial_lg, lb = trial_lb, hr = trial_hr, hg = trial_hg, hb = trial_hb; 
3469 
3470 memcpy(sels, trial_sels, 16); 
3471  
3472 prev_improvement_index = i; 
3473 } 
3474 
3475 if (i - prev_improvement_index > 32)  
3476 break; 
3477 } 
3478 } 
3479  
3480 void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags, uint32_t total_orderings_to_try, uint32_t total_orderings_to_try3) 
3481 { 
3482 assert(g_initialized); 
3483  
3484 const color32* pSrc_pixels = (const color32*)pPixels; 
3485 bc1_block* pDst_block = static_cast<bc1_block*>(pDst); 
3486  
3487 int avg_r, avg_g, avg_b, min_r, min_g, min_b, max_r, max_g, max_b; 
3488  
3489 const uint32_t fr = pSrc_pixels[0].r, fg = pSrc_pixels[0].g, fb = pSrc_pixels[0].b; 
3490 
3491 uint32_t j; 
3492 for (j = 15; j >= 1; --j) 
3493 if ((pSrc_pixels[j].r != fr) || (pSrc_pixels[j].g != fg) || (pSrc_pixels[j].b != fb)) 
3494 break; 
3495 
3496 if (j == 0) 
3497 { 
3498 encode_bc1_solid_block(pDst, fr, fg, fb, (flags & (cEncodeBC1Use3ColorBlocks | cEncodeBC1Use3ColorBlocksForBlackPixels)) != 0); 
3499 return; 
3500 } 
3501 
3502 int total_r = fr, total_g = fg, total_b = fb; 
3503  
3504 max_r = fr, max_g = fg, max_b = fb; 
3505 min_r = fr, min_g = fg, min_b = fb; 
3506  
3507 uint32_t grayscale_flag = (fr == fg) && (fr == fb); 
3508 uint32_t any_black_pixels = (fr | fg | fb) < 4; 
3509 
3510 for (uint32_t i = 1; i < 16; i++) 
3511 { 
3512 const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; 
3513  
3514 grayscale_flag &= ((r == g) && (r == b)); 
3515 any_black_pixels |= ((r | g | b) < 4); 
3516 
3517 max_r = std::max(max_r, r); max_g = std::max(max_g, g); max_b = std::max(max_b, b); 
3518 min_r = std::min(min_r, r); min_g = std::min(min_g, g); min_b = std::min(min_b, b); 
3519 total_r += r; total_g += g; total_b += b; 
3520 } 
3521 
3522 avg_r = (total_r + 8) >> 4, avg_g = (total_g + 8) >> 4, avg_b = (total_b + 8) >> 4; 
3523 
3524 bc1_encode_results results; 
3525 results.m_3color = false; 
3526 
3527 uint8_t *sels = results.sels; 
3528 int &lr = results.lr, &lg = results.lg, &lb = results.lb, &hr = results.hr, &hg = results.hg, &hb = results.hb; 
3529 int orig_lr = 0, orig_lg = 0, orig_lb = 0, orig_hr = 0, orig_hg = 0, orig_hb = 0; 
3530 
3531 lr = 0, lg = 0, lb = 0, hr = 0, hg = 0, hb = 0; 
3532  
3533 const bool needs_block_error = ((flags & (cEncodeBC1UseLikelyTotalOrderings | cEncodeBC1Use3ColorBlocks | cEncodeBC1UseFullMSEEval | cEncodeBC1EndpointSearchRoundsMask)) != 0) || 
3534 (any_black_pixels && ((flags & cEncodeBC1Use3ColorBlocksForBlackPixels) != 0)); 
3535  
3536 uint32_t cur_err = UINT32_MAX; 
3537 
3538 if (!needs_block_error) 
3539 { 
3540 assert((flags & cEncodeBC1TryAllInitialEndponts) == 0); 
3541 
3542 encode_bc1_pick_initial(pSrc_pixels, flags, grayscale_flag != 0, 
3543 min_r, min_g, min_b, max_r, max_g, max_b,  
3544 avg_r, avg_g, avg_b, total_r, total_g, total_b, 
3545 lr, lg, lb, hr, hg, hb); 
3546 
3547 orig_lr = lr, orig_lg = lg, orig_lb = lb, orig_hr = hr, orig_hg = hg, orig_hb = hb; 
3548 
3549 bc1_find_sels4_noerr(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels); 
3550 
3551 const uint32_t total_ls_passes = flags & cEncodeBC1TwoLeastSquaresPasses ? 2 : 1; 
3552 for (uint32_t ls_pass = 0; ls_pass < total_ls_passes; ls_pass++) 
3553 { 
3554 int trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb; 
3555 
3556 vec3F xl, xh; 
3557 if (!compute_least_squares_endpoints4_rgb(pSrc_pixels, sels, &xl, &xh, total_r, total_g, total_b)) 
3558 { 
3559 // All selectors equal - treat it as a solid block which should always be equal or better. 
3560 trial_lr = g_bc1_match5_equals_1[avg_r].m_hi; 
3561 trial_lg = g_bc1_match6_equals_1[avg_g].m_hi; 
3562 trial_lb = g_bc1_match5_equals_1[avg_b].m_hi; 
3563 
3564 trial_hr = g_bc1_match5_equals_1[avg_r].m_lo; 
3565 trial_hg = g_bc1_match6_equals_1[avg_g].m_lo; 
3566 trial_hb = g_bc1_match5_equals_1[avg_b].m_lo; 
3567 
3568 // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge. 
3569 } 
3570 else 
3571 { 
3572 precise_round_565(xl, xh, trial_hr, trial_hg, trial_hb, trial_lr, trial_lg, trial_lb); 
3573 } 
3574 
3575 if ((lr == trial_lr) && (lg == trial_lg) && (lb == trial_lb) && (hr == trial_hr) && (hg == trial_hg) && (hb == trial_hb)) 
3576 break; 
3577  
3578 bc1_find_sels4_noerr(pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, sels); 
3579 
3580 lr = trial_lr; 
3581 lg = trial_lg; 
3582 lb = trial_lb; 
3583 hr = trial_hr; 
3584 hg = trial_hg; 
3585 hb = trial_hb; 
3586 
3587 } // ls_pass 
3588 } 
3589 else 
3590 { 
3591 const uint32_t total_rounds = (flags & cEncodeBC1TryAllInitialEndponts) ? 2 : 1; 
3592 for (uint32_t round = 0; round < total_rounds; round++) 
3593 { 
3594 uint32_t modified_flags = flags; 
3595 if (round == 1) 
3596 { 
3597 modified_flags &= ~(cEncodeBC1Use2DLS | cEncodeBC1BoundingBox); 
3598 modified_flags |= cEncodeBC1BoundingBox; 
3599 } 
3600 
3601 int round_lr, round_lg, round_lb, round_hr, round_hg, round_hb; 
3602 uint8_t round_sels[16]; 
3603 
3604 encode_bc1_pick_initial(pSrc_pixels, modified_flags, grayscale_flag != 0, 
3605 min_r, min_g, min_b, max_r, max_g, max_b,  
3606 avg_r, avg_g, avg_b, total_r, total_g, total_b, 
3607 round_lr, round_lg, round_lb, round_hr, round_hg, round_hb); 
3608 
3609 int orig_round_lr = round_lr, orig_round_lg = round_lg, orig_round_lb = round_lb, orig_round_hr = round_hr, orig_round_hg = round_hg, orig_round_hb = round_hb; 
3610 
3611 uint32_t round_err = bc1_find_sels4(flags, pSrc_pixels, round_lr, round_lg, round_lb, round_hr, round_hg, round_hb, round_sels, UINT32_MAX); 
3612  
3613 const uint32_t total_ls_passes = flags & cEncodeBC1TwoLeastSquaresPasses ? 2 : 1; 
3614 for (uint32_t ls_pass = 0; ls_pass < total_ls_passes; ls_pass++) 
3615 { 
3616 int trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb; 
3617 
3618 vec3F xl, xh; 
3619 if (!compute_least_squares_endpoints4_rgb(pSrc_pixels, round_sels, &xl, &xh, total_r, total_g, total_b)) 
3620 { 
3621 // All selectors equal - treat it as a solid block which should always be equal or better. 
3622 trial_lr = g_bc1_match5_equals_1[avg_r].m_hi; 
3623 trial_lg = g_bc1_match6_equals_1[avg_g].m_hi; 
3624 trial_lb = g_bc1_match5_equals_1[avg_b].m_hi; 
3625 
3626 trial_hr = g_bc1_match5_equals_1[avg_r].m_lo; 
3627 trial_hg = g_bc1_match6_equals_1[avg_g].m_lo; 
3628 trial_hb = g_bc1_match5_equals_1[avg_b].m_lo; 
3629 
3630 // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge. 
3631 } 
3632 else 
3633 { 
3634 precise_round_565(xl, xh, trial_hr, trial_hg, trial_hb, trial_lr, trial_lg, trial_lb); 
3635 } 
3636 
3637 if ((round_lr == trial_lr) && (round_lg == trial_lg) && (round_lb == trial_lb) && (round_hr == trial_hr) && (round_hg == trial_hg) && (round_hb == trial_hb)) 
3638 break; 
3639  
3640 uint8_t trial_sels[16]; 
3641 uint32_t trial_err = bc1_find_sels4(flags, pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, trial_sels, round_err); 
3642  
3643 if (trial_err < round_err) 
3644 { 
3645 round_lr = trial_lr; 
3646 round_lg = trial_lg; 
3647 round_lb = trial_lb; 
3648 
3649 round_hr = trial_hr; 
3650 round_hg = trial_hg; 
3651 round_hb = trial_hb; 
3652 
3653 round_err = trial_err; 
3654 memcpy(round_sels, trial_sels, 16); 
3655 } 
3656 else 
3657 break; 
3658 
3659 } // ls_pass 
3660 
3661 if (round_err <= cur_err) 
3662 { 
3663 cur_err = round_err; 
3664  
3665 lr = round_lr; 
3666 lg = round_lg; 
3667 lb = round_lb; 
3668 hr = round_hr; 
3669 hg = round_hg; 
3670 hb = round_hb; 
3671 
3672 orig_lr = orig_round_lr; 
3673 orig_lg = orig_round_lg; 
3674 orig_lb = orig_round_lb; 
3675 orig_hr = orig_round_hr; 
3676 orig_hg = orig_round_hg; 
3677 orig_hb = orig_round_hb; 
3678 
3679 memcpy(sels, round_sels, 16); 
3680 } 
3681 
3682 } // round 
3683 } 
3684  
3685 if ((cur_err) && (flags & cEncodeBC1UseLikelyTotalOrderings)) 
3686 { 
3687 assert(needs_block_error); 
3688 
3689 const uint32_t total_iters = (flags & cEncodeBC1Iterative) ? 2 : 1; 
3690 for (uint32_t iter_index = 0; iter_index < total_iters; iter_index++) 
3691 { 
3692 const uint32_t orig_err = cur_err; 
3693  
3694 hist4 h; 
3695 for (uint32_t i = 0; i < 16; i++) 
3696 { 
3697 assert(sels[i] < 4); 
3698 h.m_hist[sels[i]]++; 
3699 } 
3700 
3701 const uint32_t orig_total_order_index = h.lookup_total_ordering_index(); 
3702 
3703 int r0, g0, b0, r3, g3, b3; 
3704 r0 = (lr << 3) | (lr >> 2); g0 = (lg << 2) | (lg >> 4); b0 = (lb << 3) | (lb >> 2); 
3705 r3 = (hr << 3) | (hr >> 2); g3 = (hg << 2) | (hg >> 4); b3 = (hb << 3) | (hb >> 2); 
3706  
3707 int ar = r3 - r0, ag = g3 - g0, ab = b3 - b0; 
3708  
3709 int dots[16]; 
3710 for (uint32_t i = 0; i < 16; i++) 
3711 { 
3712 int r = pSrc_pixels[i].r; 
3713 int g = pSrc_pixels[i].g; 
3714 int b = pSrc_pixels[i].b; 
3715 int d = 0x1000000 + (r * ar + g * ag + b * ab); 
3716 assert(d >= 0); 
3717 dots[i] = (d << 4) + i; 
3718 } 
3719 
3720 std::sort(dots, dots + 16); 
3721  
3722 uint32_t r_sum[17], g_sum[17], b_sum[17]; 
3723 uint32_t r = 0, g = 0, b = 0; 
3724 for (uint32_t i = 0; i < 16; i++) 
3725 { 
3726 const uint32_t p = dots[i] & 15; 
3727 
3728 r_sum[i] = r; 
3729 g_sum[i] = g; 
3730 b_sum[i] = b; 
3731  
3732 r += pSrc_pixels[p].r; 
3733 g += pSrc_pixels[p].g; 
3734 b += pSrc_pixels[p].b; 
3735 } 
3736 
3737 r_sum[16] = total_r; 
3738 g_sum[16] = total_g; 
3739 b_sum[16] = total_b; 
3740 
3741 const uint32_t q_total = (flags & cEncodeBC1Exhaustive) ? NUM_UNIQUE_TOTAL_ORDERINGS4 : clampi(total_orderings_to_try, MIN_TOTAL_ORDERINGS, MAX_TOTAL_ORDERINGS4); 
3742 for (uint32_t q = 0; q < q_total; q++) 
3743 { 
3744 const uint32_t s = (flags & cEncodeBC1Exhaustive) ? q : g_best_total_orderings4[orig_total_order_index][q]; 
3745  
3746 int trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb; 
3747 
3748 vec3F xl, xh; 
3749 
3750 if ((s == TOTAL_ORDER_4_0_16) || (s == TOTAL_ORDER_4_1_16) || (s == TOTAL_ORDER_4_2_16) || (s == TOTAL_ORDER_4_3_16)) 
3751 { 
3752 trial_lr = g_bc1_match5_equals_1[avg_r].m_hi; 
3753 trial_lg = g_bc1_match6_equals_1[avg_g].m_hi; 
3754 trial_lb = g_bc1_match5_equals_1[avg_b].m_hi; 
3755 
3756 trial_hr = g_bc1_match5_equals_1[avg_r].m_lo; 
3757 trial_hg = g_bc1_match6_equals_1[avg_g].m_lo; 
3758 trial_hb = g_bc1_match5_equals_1[avg_b].m_lo; 
3759 } 
3760 else 
3761 { 
3762 compute_least_squares_endpoints4_rgb(&xl, &xh, total_r, total_g, total_b,  
3763 g_selector_factors4[s][0], g_selector_factors4[s][1], g_selector_factors4[s][2], s, r_sum, g_sum, b_sum); 
3764  
3765 precise_round_565(xl, xh, trial_hr, trial_hg, trial_hb, trial_lr, trial_lg, trial_lb); 
3766 } 
3767  
3768 uint8_t trial_sels[16]; 
3769  
3770 uint32_t trial_err = bc1_find_sels4(flags, pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, trial_sels, cur_err); 
3771 
3772 if (trial_err < cur_err) 
3773 { 
3774 cur_err = trial_err; 
3775 
3776 lr = trial_lr; 
3777 lg = trial_lg; 
3778 lb = trial_lb; 
3779 
3780 hr = trial_hr; 
3781 hg = trial_hg; 
3782 hb = trial_hb; 
3783 
3784 memcpy(sels, trial_sels, 16); 
3785 } 
3786 
3787 } // s 
3788 
3789 if ((!cur_err) || (cur_err == orig_err)) 
3790 break; 
3791  
3792 } // iter_index 
3793 } 
3794  
3795 if ( ((flags & (cEncodeBC1Use3ColorBlocks | cEncodeBC1Use3ColorBlocksForBlackPixels)) != 0) && (cur_err) ) 
3796 { 
3797 if (flags & cEncodeBC1Use3ColorBlocks) 
3798 { 
3799 assert(needs_block_error); 
3800 try_3color_block(pSrc_pixels, flags, cur_err, avg_r, avg_g, avg_b, orig_lr, orig_lg, orig_lb, orig_hr, orig_hg, orig_hb, total_r, total_g, total_b, total_orderings_to_try3, results); 
3801 } 
3802 
3803 if ((any_black_pixels) && ((flags & cEncodeBC1Use3ColorBlocksForBlackPixels) != 0)) 
3804 { 
3805 assert(needs_block_error); 
3806 try_3color_block_useblack(pSrc_pixels, flags, cur_err, results); 
3807 } 
3808 } 
3809  
3810 if ( (flags & cEncodeBC1EndpointSearchRoundsMask) && (cur_err) ) 
3811 { 
3812 assert(needs_block_error); 
3813 
3814 encode_bc1_endpoint_search(pSrc_pixels, any_black_pixels != 0, flags, results, cur_err); 
3815 } 
3816 
3817 if (results.m_3color) 
3818 bc1_encode3(pDst_block, results.lr, results.lg, results.lb, results.hr, results.hg, results.hb, results.sels); 
3819 else 
3820 bc1_encode4(pDst_block, results.lr, results.lg, results.lb, results.hr, results.hg, results.hb, results.sels); 
3821 } 
3822 
3823 // BC3-5 
3824 
3825 struct bc4_block 
3826 { 
3827 enum { cBC4SelectorBits = 3, cTotalSelectorBytes = 6, cMaxSelectorValues = 8 }; 
3828 uint8_t m_endpoints[2]; 
3829 
3830 uint8_t m_selectors[cTotalSelectorBytes]; 
3831 
3832 inline uint32_t get_low_alpha() const { return m_endpoints[0]; } 
3833 inline uint32_t get_high_alpha() const { return m_endpoints[1]; } 
3834 inline bool is_alpha6_block() const { return get_low_alpha() <= get_high_alpha(); } 
3835 
3836 inline uint64_t get_selector_bits() const 
3837 { 
3838 return ((uint64_t)((uint32_t)m_selectors[0] | ((uint32_t)m_selectors[1] << 8U) | ((uint32_t)m_selectors[2] << 16U) | ((uint32_t)m_selectors[3] << 24U))) | 
3839 (((uint64_t)m_selectors[4]) << 32U) | 
3840 (((uint64_t)m_selectors[5]) << 40U); 
3841 } 
3842 
3843 inline uint32_t get_selector(uint32_t x, uint32_t y, uint64_t selector_bits) const 
3844 { 
3845 assert((x < 4U) && (y < 4U)); 
3846 return (selector_bits >> (((y * 4) + x) * cBC4SelectorBits))& (cMaxSelectorValues - 1); 
3847 } 
3848 
3849 static inline uint32_t get_block_values6(uint8_t* pDst, uint32_t l, uint32_t h) 
3850 { 
3851 pDst[0] = static_cast<uint8_t>(l); 
3852 pDst[1] = static_cast<uint8_t>(h); 
3853 pDst[2] = static_cast<uint8_t>((l * 4 + h) / 5); 
3854 pDst[3] = static_cast<uint8_t>((l * 3 + h * 2) / 5); 
3855 pDst[4] = static_cast<uint8_t>((l * 2 + h * 3) / 5); 
3856 pDst[5] = static_cast<uint8_t>((l + h * 4) / 5); 
3857 pDst[6] = 0; 
3858 pDst[7] = 255; 
3859 return 6; 
3860 } 
3861 
3862 static inline uint32_t get_block_values8(uint8_t* pDst, uint32_t l, uint32_t h) 
3863 { 
3864 pDst[0] = static_cast<uint8_t>(l); 
3865 pDst[1] = static_cast<uint8_t>(h); 
3866 pDst[2] = static_cast<uint8_t>((l * 6 + h) / 7); 
3867 pDst[3] = static_cast<uint8_t>((l * 5 + h * 2) / 7); 
3868 pDst[4] = static_cast<uint8_t>((l * 4 + h * 3) / 7); 
3869 pDst[5] = static_cast<uint8_t>((l * 3 + h * 4) / 7); 
3870 pDst[6] = static_cast<uint8_t>((l * 2 + h * 5) / 7); 
3871 pDst[7] = static_cast<uint8_t>((l + h * 6) / 7); 
3872 return 8; 
3873 } 
3874 
3875 static inline uint32_t get_block_values(uint8_t* pDst, uint32_t l, uint32_t h) 
3876 { 
3877 if (l > h) 
3878 return get_block_values8(pDst, l, h); 
3879 else 
3880 return get_block_values6(pDst, l, h); 
3881 } 
3882 }; 
3883 
3884 void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride) 
3885 { 
3886 assert(g_initialized); 
3887 
3888 uint32_t min0_v, max0_v, min1_v, max1_v, min2_v, max2_v, min3_v, max3_v; 
3889 
3890 { 
3891 min0_v = max0_v = pPixels[0 * stride]; 
3892 min1_v = max1_v = pPixels[1 * stride]; 
3893 min2_v = max2_v = pPixels[2 * stride]; 
3894 min3_v = max3_v = pPixels[3 * stride]; 
3895 } 
3896 
3897 { 
3898 uint32_t v0 = pPixels[4 * stride]; min0_v = std::min(min0_v, v0); max0_v = std::max(max0_v, v0); 
3899 uint32_t v1 = pPixels[5 * stride]; min1_v = std::min(min1_v, v1); max1_v = std::max(max1_v, v1); 
3900 uint32_t v2 = pPixels[6 * stride]; min2_v = std::min(min2_v, v2); max2_v = std::max(max2_v, v2); 
3901 uint32_t v3 = pPixels[7 * stride]; min3_v = std::min(min3_v, v3); max3_v = std::max(max3_v, v3); 
3902 } 
3903 
3904 { 
3905 uint32_t v0 = pPixels[8 * stride]; min0_v = std::min(min0_v, v0); max0_v = std::max(max0_v, v0); 
3906 uint32_t v1 = pPixels[9 * stride]; min1_v = std::min(min1_v, v1); max1_v = std::max(max1_v, v1); 
3907 uint32_t v2 = pPixels[10 * stride]; min2_v = std::min(min2_v, v2); max2_v = std::max(max2_v, v2); 
3908 uint32_t v3 = pPixels[11 * stride]; min3_v = std::min(min3_v, v3); max3_v = std::max(max3_v, v3); 
3909 } 
3910 
3911 { 
3912 uint32_t v0 = pPixels[12 * stride]; min0_v = std::min(min0_v, v0); max0_v = std::max(max0_v, v0); 
3913 uint32_t v1 = pPixels[13 * stride]; min1_v = std::min(min1_v, v1); max1_v = std::max(max1_v, v1); 
3914 uint32_t v2 = pPixels[14 * stride]; min2_v = std::min(min2_v, v2); max2_v = std::max(max2_v, v2); 
3915 uint32_t v3 = pPixels[15 * stride]; min3_v = std::min(min3_v, v3); max3_v = std::max(max3_v, v3); 
3916 } 
3917 
3918 const uint32_t min_v = minimum(min0_v, min1_v, min2_v, min3_v); 
3919 const uint32_t max_v = maximum(max0_v, max1_v, max2_v, max3_v); 
3920 
3921 uint8_t* pDst_bytes = static_cast<uint8_t*>(pDst); 
3922 pDst_bytes[0] = (uint8_t)max_v; 
3923 pDst_bytes[1] = (uint8_t)min_v; 
3924 
3925 if (max_v == min_v) 
3926 { 
3927 memset(pDst_bytes + 2, 0, 6); 
3928 return; 
3929 } 
3930 
3931 const uint32_t delta = max_v - min_v; 
3932 
3933 // min_v is now 0. Compute thresholds between values by scaling max_v. It's x14 because we're adding two x7 scale factors. 
3934 const int t0 = delta * 13; 
3935 const int t1 = delta * 11; 
3936 const int t2 = delta * 9; 
3937 const int t3 = delta * 7; 
3938 const int t4 = delta * 5; 
3939 const int t5 = delta * 3; 
3940 const int t6 = delta * 1; 
3941 
3942 // BC4 floors in its divisions, which we compensate for with the 4 bias. 
3943 // This function is optimal for all possible inputs (i.e. it outputs the same results as checking all 8 values and choosing the closest one). 
3944 const int bias = 4 - min_v * 14; 
3945 
3946 static const uint32_t s_tran0[8] = { 1U , 7U , 6U , 5U , 4U , 3U , 2U , 0U }; 
3947 static const uint32_t s_tran1[8] = { 1U << 3U, 7U << 3U, 6U << 3U, 5U << 3U, 4U << 3U, 3U << 3U, 2U << 3U, 0U << 3U }; 
3948 static const uint32_t s_tran2[8] = { 1U << 6U, 7U << 6U, 6U << 6U, 5U << 6U, 4U << 6U, 3U << 6U, 2U << 6U, 0U << 6U }; 
3949 static const uint32_t s_tran3[8] = { 1U << 9U, 7U << 9U, 6U << 9U, 5U << 9U, 4U << 9U, 3U << 9U, 2U << 9U, 0U << 9U }; 
3950 
3951 uint64_t a0, a1, a2, a3; 
3952 { 
3953 const int v0 = pPixels[0 * stride] * 14 + bias; 
3954 const int v1 = pPixels[1 * stride] * 14 + bias; 
3955 const int v2 = pPixels[2 * stride] * 14 + bias; 
3956 const int v3 = pPixels[3 * stride] * 14 + bias; 
3957 a0 = s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]; 
3958 a1 = s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]; 
3959 a2 = s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]; 
3960 a3 = s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]; 
3961 } 
3962 
3963 { 
3964 const int v0 = pPixels[4 * stride] * 14 + bias; 
3965 const int v1 = pPixels[5 * stride] * 14 + bias; 
3966 const int v2 = pPixels[6 * stride] * 14 + bias; 
3967 const int v3 = pPixels[7 * stride] * 14 + bias; 
3968 a0 |= (uint64_t)(s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)] << 12U); 
3969 a1 |= (uint64_t)(s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)] << 12U); 
3970 a2 |= (uint64_t)(s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)] << 12U); 
3971 a3 |= (uint64_t)(s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)] << 12U); 
3972 } 
3973 
3974 { 
3975 const int v0 = pPixels[8 * stride] * 14 + bias; 
3976 const int v1 = pPixels[9 * stride] * 14 + bias; 
3977 const int v2 = pPixels[10 * stride] * 14 + bias; 
3978 const int v3 = pPixels[11 * stride] * 14 + bias; 
3979 a0 |= (((uint64_t)s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]) << 24U); 
3980 a1 |= (((uint64_t)s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]) << 24U); 
3981 a2 |= (((uint64_t)s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]) << 24U); 
3982 a3 |= (((uint64_t)s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]) << 24U); 
3983 } 
3984 
3985 { 
3986 const int v0 = pPixels[12 * stride] * 14 + bias; 
3987 const int v1 = pPixels[13 * stride] * 14 + bias; 
3988 const int v2 = pPixels[14 * stride] * 14 + bias; 
3989 const int v3 = pPixels[15 * stride] * 14 + bias; 
3990 a0 |= (((uint64_t)s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]) << 36U); 
3991 a1 |= (((uint64_t)s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]) << 36U); 
3992 a2 |= (((uint64_t)s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]) << 36U); 
3993 a3 |= (((uint64_t)s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]) << 36U); 
3994 } 
3995 
3996 const uint64_t f = a0 | a1 | a2 | a3; 
3997 
3998 pDst_bytes[2] = (uint8_t)f; 
3999 pDst_bytes[3] = (uint8_t)(f >> 8U); 
4000 pDst_bytes[4] = (uint8_t)(f >> 16U); 
4001 pDst_bytes[5] = (uint8_t)(f >> 24U); 
4002 pDst_bytes[6] = (uint8_t)(f >> 32U); 
4003 pDst_bytes[7] = (uint8_t)(f >> 40U); 
4004 } 
4005 
4006 void encode_bc3(void* pDst, const uint8_t* pPixels, uint32_t flags, uint32_t total_orderings_to_try) 
4007 { 
4008 assert(g_initialized); 
4009 
4010 // 3-color blocks are not allowed with BC3 (on most GPU's). 
4011 flags &= ~(cEncodeBC1Use3ColorBlocksForBlackPixels | cEncodeBC1Use3ColorBlocks); 
4012 
4013 encode_bc4(pDst, pPixels + 3, 4); 
4014 encode_bc1(static_cast<uint8_t*>(pDst) + 8, pPixels, flags, total_orderings_to_try); 
4015 } 
4016 
4017 void encode_bc3(uint32_t level, void* pDst, const uint8_t* pPixels) 
4018 { 
4019 assert(g_initialized); 
4020 
4021 encode_bc4(pDst, pPixels + 3, 4); 
4022 encode_bc1(level, static_cast<uint8_t*>(pDst) + 8, pPixels, false, false); 
4023 } 
4024 
4025 void encode_bc5(void* pDst, const uint8_t* pPixels, uint32_t chan0, uint32_t chan1, uint32_t stride) 
4026 { 
4027 assert(g_initialized); 
4028 
4029 encode_bc4(pDst, pPixels + chan0, stride); 
4030 encode_bc4(static_cast<uint8_t*>(pDst) + 8, pPixels + chan1, stride); 
4031 } 
4032  
4033 // Returns true if the block uses 3 color punchthrough alpha mode. 
4034 bool unpack_bc1(const void* pBlock_bits, void* pPixels, bool set_alpha, bc1_approx_mode mode) 
4035 { 
4036 color32* pDst_pixels = static_cast<color32*>(pPixels); 
4037 
4038 static_assert(sizeof(bc1_block) == 8, "sizeof(bc1_block) == 8"); 
4039 static_assert(sizeof(bc4_block) == 8, "sizeof(bc4_block) == 8"); 
4040 
4041 const bc1_block* pBlock = static_cast<const bc1_block*>(pBlock_bits); 
4042 
4043 const uint32_t l = pBlock->get_low_color(); 
4044 const uint32_t h = pBlock->get_high_color(); 
4045 
4046 color32 c[4]; 
4047 
4048 const int cr0 = (l >> 11) & 31; 
4049 const int cg0 = (l >> 5) & 63; 
4050 const int cb0 = l & 31; 
4051 const int r0 = (cr0 << 3) | (cr0 >> 2); 
4052 const int g0 = (cg0 << 2) | (cg0 >> 4); 
4053 const int b0 = (cb0 << 3) | (cb0 >> 2); 
4054 
4055 const int cr1 = (h >> 11) & 31; 
4056 const int cg1 = (h >> 5) & 63; 
4057 const int cb1 = h & 31; 
4058 const int r1 = (cr1 << 3) | (cr1 >> 2); 
4059 const int g1 = (cg1 << 2) | (cg1 >> 4); 
4060 const int b1 = (cb1 << 3) | (cb1 >> 2); 
4061 
4062 bool used_punchthrough = false; 
4063  
4064 if (l > h) 
4065 { 
4066 c[0].set_noclamp_rgba(r0, g0, b0, 255); 
4067 c[1].set_noclamp_rgba(r1, g1, b1, 255); 
4068 switch (mode) 
4069 { 
4070 case bc1_approx_mode::cBC1Ideal: 
4071 c[2].set_noclamp_rgba((r0 * 2 + r1) / 3, (g0 * 2 + g1) / 3, (b0 * 2 + b1) / 3, 255); 
4072 c[3].set_noclamp_rgba((r1 * 2 + r0) / 3, (g1 * 2 + g0) / 3, (b1 * 2 + b0) / 3, 255); 
4073 break; 
4074 case bc1_approx_mode::cBC1IdealRound4: 
4075 c[2].set_noclamp_rgba((r0 * 2 + r1 + 1) / 3, (g0 * 2 + g1 + 1) / 3, (b0 * 2 + b1 + 1) / 3, 255); 
4076 c[3].set_noclamp_rgba((r1 * 2 + r0 + 1) / 3, (g1 * 2 + g0 + 1) / 3, (b1 * 2 + b0 + 1) / 3, 255); 
4077 break; 
4078 case bc1_approx_mode::cBC1NVidia: 
4079 c[2].set_noclamp_rgba(interp_5_nv(cr0, cr1), interp_6_nv(g0, g1), interp_5_nv(cb0, cb1), 255); 
4080 c[3].set_noclamp_rgba(interp_5_nv(cr1, cr0), interp_6_nv(g1, g0), interp_5_nv(cb1, cb0), 255); 
4081 break; 
4082 case bc1_approx_mode::cBC1AMD: 
4083 c[2].set_noclamp_rgba(interp_5_6_amd(r0, r1), interp_5_6_amd(g0, g1), interp_5_6_amd(b0, b1), 255); 
4084 c[3].set_noclamp_rgba(interp_5_6_amd(r1, r0), interp_5_6_amd(g1, g0), interp_5_6_amd(b1, b0), 255); 
4085 break; 
4086 } 
4087 } 
4088 else 
4089 { 
4090 c[0].set_noclamp_rgba(r0, g0, b0, 255); 
4091 c[1].set_noclamp_rgba(r1, g1, b1, 255); 
4092 switch (mode) 
4093 { 
4094 case bc1_approx_mode::cBC1Ideal: 
4095 case bc1_approx_mode::cBC1IdealRound4: 
4096 c[2].set_noclamp_rgba((r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2, 255); 
4097 break; 
4098 case bc1_approx_mode::cBC1NVidia: 
4099 c[2].set_noclamp_rgba(interp_half_5_nv(cr0, cr1), interp_half_6_nv(g0, g1), interp_half_5_nv(cb0, cb1), 255); 
4100 break; 
4101 case bc1_approx_mode::cBC1AMD: 
4102 c[2].set_noclamp_rgba(interp_half_5_6_amd(r0, r1), interp_half_5_6_amd(g0, g1), interp_half_5_6_amd(b0, b1), 255); 
4103 break; 
4104 } 
4105 
4106 c[3].set_noclamp_rgba(0, 0, 0, 0); 
4107 used_punchthrough = true; 
4108 } 
4109 
4110 if (set_alpha) 
4111 { 
4112 for (uint32_t y = 0; y < 4; y++, pDst_pixels += 4) 
4113 { 
4114 pDst_pixels[0] = c[pBlock->get_selector(0, y)]; 
4115 pDst_pixels[1] = c[pBlock->get_selector(1, y)]; 
4116 pDst_pixels[2] = c[pBlock->get_selector(2, y)]; 
4117 pDst_pixels[3] = c[pBlock->get_selector(3, y)]; 
4118 } 
4119 } 
4120 else 
4121 { 
4122 for (uint32_t y = 0; y < 4; y++, pDst_pixels += 4) 
4123 { 
4124 pDst_pixels[0].set_rgb(c[pBlock->get_selector(0, y)]); 
4125 pDst_pixels[1].set_rgb(c[pBlock->get_selector(1, y)]); 
4126 pDst_pixels[2].set_rgb(c[pBlock->get_selector(2, y)]); 
4127 pDst_pixels[3].set_rgb(c[pBlock->get_selector(3, y)]); 
4128 } 
4129 } 
4130 
4131 return used_punchthrough; 
4132 } 
4133 
4134 void unpack_bc4(const void* pBlock_bits, uint8_t* pPixels, uint32_t stride) 
4135 { 
4136 static_assert(sizeof(bc4_block) == 8, "sizeof(bc4_block) == 8"); 
4137 
4138 const bc4_block* pBlock = static_cast<const bc4_block*>(pBlock_bits); 
4139 
4140 uint8_t sel_values[8]; 
4141 bc4_block::get_block_values(sel_values, pBlock->get_low_alpha(), pBlock->get_high_alpha()); 
4142 
4143 const uint64_t selector_bits = pBlock->get_selector_bits(); 
4144 
4145 for (uint32_t y = 0; y < 4; y++, pPixels += (stride * 4U)) 
4146 { 
4147 pPixels[0] = sel_values[pBlock->get_selector(0, y, selector_bits)]; 
4148 pPixels[stride * 1] = sel_values[pBlock->get_selector(1, y, selector_bits)]; 
4149 pPixels[stride * 2] = sel_values[pBlock->get_selector(2, y, selector_bits)]; 
4150 pPixels[stride * 3] = sel_values[pBlock->get_selector(3, y, selector_bits)]; 
4151 } 
4152 } 
4153 
4154 // Returns false if the block uses 3-color punchthrough alpha mode, which isn't supported on some GPU's for BC3. 
4155 bool unpack_bc3(const void* pBlock_bits, void* pPixels, bc1_approx_mode mode) 
4156 { 
4157 color32* pDst_pixels = static_cast<color32*>(pPixels); 
4158 
4159 bool success = true; 
4160 
4161 if (unpack_bc1((const uint8_t*)pBlock_bits + sizeof(bc4_block), pDst_pixels, true, mode)) 
4162 success = false; 
4163 
4164 unpack_bc4(pBlock_bits, &pDst_pixels[0].a, sizeof(color32)); 
4165 
4166 return success; 
4167 } 
4168 
4169 // writes RG 
4170 void unpack_bc5(const void* pBlock_bits, void* pPixels, uint32_t chan0, uint32_t chan1, uint32_t stride) 
4171 { 
4172 unpack_bc4(pBlock_bits, (uint8_t *)pPixels + chan0, stride); 
4173 unpack_bc4((const uint8_t*)pBlock_bits + sizeof(bc4_block), (uint8_t *)pPixels + chan1, stride); 
4174 } 
4175 
4176} // namespace rgbcx 
4177 
4178#endif //#ifdef RGBCX_IMPLEMENTATION 
4179 
4180/* 
4181------------------------------------------------------------------------------ 
4182This software is available under 2 licenses -- choose whichever you prefer. 
4183------------------------------------------------------------------------------ 
4184ALTERNATIVE A - MIT License 
4185Copyright(c) 2020 Richard Geldreich, Jr. 
4186Permission is hereby granted, free of charge, to any person obtaining a copy of 
4187this software and associated documentation files(the "Software"), to deal in 
4188the Software without restriction, including without limitation the rights to 
4189use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies 
4190of the Software, and to permit persons to whom the Software is furnished to do 
4191so, subject to the following conditions : 
4192The above copyright notice and this permission notice shall be included in all 
4193copies or substantial portions of the Software. 
4194THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
4195IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
4196FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 
4197AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
4198LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
4199OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
4200SOFTWARE. 
4201------------------------------------------------------------------------------ 
4202ALTERNATIVE B - Public Domain(www.unlicense.org) 
4203This is free and unencumbered software released into the public domain. 
4204Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 
4205software, either in source code form or as a compiled binary, for any purpose, 
4206commercial or non - commercial, and by any means. 
4207In jurisdictions that recognize copyright laws, the author or authors of this 
4208software dedicate any and all copyright interest in the software to the public 
4209domain.We make this dedication for the benefit of the public at large and to 
4210the detriment of our heirs and successors.We intend this dedication to be an 
4211overt act of relinquishment in perpetuity of all present and future rights to 
4212this software under copyright law. 
4213THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
4214IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
4215FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 
4216AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
4217ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
4218WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
4219------------------------------------------------------------------------------ 
4220*/ 
4221 
4222