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