2 // High-performance scalar BC1-5 encoders. Public Domain or MIT license (you choose - see below), written by Richard Geldreich 2020 <richgel99@gmail.com>.
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
11 // This is a single header file library. Be sure to "#define RGBCX_IMPLEMENTATION" in one .cpp file somewhere.
15 // The library MUST be initialized by calling this function at least once before using any encoder or decoder functions:
17 // void rgbcx::init(bc1_approx_mode mode = cBC1Ideal);
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.
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);
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.
35 // - pDst is a pointer to the 8-byte (BC1/4) or 16-byte (BC3/5) destination block.
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().
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.
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.
48 // - stride is the source pixel stride, in bytes. It's typically 4.
50 // - chan0 and chan1 are the source channels. Typically they will be 0 and 1.
52 // All encoding and decoding functions are threade-safe.
54 // To reduce the compiled size of the encoder, set #define RGBCX_USE_SMALLER_TABLES to 1 before including this header.
56 #ifndef RGBCX_INCLUDE_H
57 #define RGBCX_INCLUDE_H
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 1
73 enum class bc1_approx_mode
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.
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.
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
);
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
);
100 // BC1 low-level API encoder flags. You can ignore this if you use the simple level API.
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,
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,
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,
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,
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,
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,
132 // Use a slightly lower quality, but ~30% faster MSE evaluation function for 4-color blocks.
133 cEncodeBC1UseFasterMSEEval
= 128,
135 // Examine all colors to compute selectors/MSE (slower than default)
136 cEncodeBC1UseFullMSEEval
= 256,
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,
142 // Use 6 power iterations vs. 4 for PCA.
143 cEncodeBC1Use6PowerIters
= 2048,
145 // Check all total orderings - *very* slow. The encoder is not designed to be used in this way.
146 cEncodeBC1Exhaustive
= 8192,
148 // Try 2 different ways of choosing the initial endpoints.
149 cEncodeBC1TryAllInitialEndponts
= 16384,
151 // Same as cEncodeBC1BoundingBox, but implemented using integer math (faster, slightly less quality)
152 cEncodeBC1BoundingBoxInt
= 32768,
154 // Try refining the final endpoints by examining nearby colors.
155 cEncodeBC1EndpointSearchRoundsShift
= 22,
156 cEncodeBC1EndpointSearchRoundsMask
= 1023U << cEncodeBC1EndpointSearchRoundsShift
,
159 const uint32_t MIN_TOTAL_ORDERINGS
= 1;
160 const uint32_t MAX_TOTAL_ORDERINGS3
= 32;
162 #if RGBCX_USE_SMALLER_TABLES
163 const uint32_t MAX_TOTAL_ORDERINGS4
= 32;
165 const uint32_t MAX_TOTAL_ORDERINGS4
= 128;
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;
171 const uint32_t DEFAULT_TOTAL_ORDERINGS_TO_TRY3
= 1;
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
);
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
);
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
);
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);
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);
203 // Decompression functions.
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
);
208 void unpack_bc4(const void* pBlock_bits
, uint8_t* pPixels
, uint32_t stride
= 4);
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
);
213 void unpack_bc5(const void* pBlock_bits
, void* pPixels
, uint32_t chan0
= 0, uint32_t chan1
= 1, uint32_t stride
= 4);
215 #endif // #ifndef RGBCX_INCLUDE_H
217 #ifdef RGBCX_IMPLEMENTATION
220 const uint32_t NUM_UNIQUE_TOTAL_ORDERINGS4
= 969;
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] =
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}
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] =
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}
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
] =
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 }
1251 #include "rgbcx_table4.h"
1255 static uint8_t g_best_total_orderings3
[NUM_UNIQUE_TOTAL_ORDERINGS3
][32] =
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 }
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
); }
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); }
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
); }
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
); }
1426 template<typename T
> inline T
square(T a
) { return a
* a
; }
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
); }
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
; }
1434 static inline int squarei(int a
) { return a
* a
; }
1435 static inline int absi(int a
) { return (a
< 0) ? -a
: a
; }
1437 template<typename F
> inline F
lerp(F a
, F b
, F s
) { return a
+ (b
- a
) * s
; }
1439 enum class eNoClamp
{ cNoClamp
};
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
); }
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
); }
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
); }
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
); }
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
]; }
1473 bool operator== (const color32
&rhs
) const { return m
== rhs
.m
; }
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]); }
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])); }
1483 cDXT1SelectorBits
= 2U, cDXT1SelectorValues
= 1U << cDXT1SelectorBits
, cDXT1SelectorMask
= cDXT1SelectorValues
- 1U,
1484 cDXT5SelectorBits
= 3U, cDXT5SelectorValues
= 1U << cDXT5SelectorBits
, cDXT5SelectorMask
= cDXT5SelectorValues
- 1U,
1489 enum { cTotalEndpointBytes
= 2, cTotalSelectorBytes
= 4 };
1491 uint8_t m_low_color
[cTotalEndpointBytes
];
1492 uint8_t m_high_color
[cTotalEndpointBytes
];
1493 uint8_t m_selectors
[cTotalSelectorBytes
];
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
)); }
1503 static inline uint16_t pack_color(const color32
& color
, bool scaled
, uint32_t bias
= 127U)
1505 uint32_t r
= color
.r
, g
= color
.g
, b
= color
.b
;
1508 r
= (r
* 31U + bias
) / 255U;
1509 g
= (g
* 63U + bias
) / 255U;
1510 b
= (b
* 31U + bias
) / 255U;
1512 return static_cast<uint16_t>(minimum(b
, 31U) | (minimum(g
, 63U) << 5U) | (minimum(r
, 31U) << 11U));
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)); }
1517 static inline void unpack_color(uint32_t c
, uint32_t& r
, uint32_t& g
, uint32_t& b
)
1523 r
= (r
<< 3) | (r
>> 2);
1524 g
= (g
<< 2) | (g
>> 4);
1525 b
= (b
<< 3) | (b
>> 2);
1528 static inline void unpack_color_unscaled(uint32_t c
, uint32_t& r
, uint32_t& g
, uint32_t& b
)
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];
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];
1555 memset(m_hist
, 0, sizeof(m_hist
));
1558 hist4(uint32_t i
, uint32_t j
, uint32_t k
, uint32_t l
)
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
;
1566 inline bool operator== (const hist4
&h
) const
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;
1575 inline bool any_16() const
1577 return (m_hist
[0] == 16) || (m_hist
[1] == 16) || (m_hist
[2] == 16) || (m_hist
[3] == 16);
1580 inline uint32_t lookup_total_ordering_index() const
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
;
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)];
1602 memset(m_hist
, 0, sizeof(m_hist
));
1605 hist3(uint32_t i
, uint32_t j
, uint32_t k
)
1607 m_hist
[0] = (uint8_t)i
;
1608 m_hist
[1] = (uint8_t)j
;
1609 m_hist
[2] = (uint8_t)k
;
1612 inline bool operator== (const hist3
&h
) const
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;
1620 inline bool any_16() const
1622 return (m_hist
[0] == 16) || (m_hist
[1] == 16) || (m_hist
[2] == 16);
1625 inline uint32_t lookup_total_ordering_index() const
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
;
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)];
1639 struct bc1_match_entry
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];
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); }
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; }
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; }
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; }
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; }
1668 static inline int interp_5(int v0
, int v1
, int c0
, int c1
, bc1_approx_mode mode
)
1670 assert(scale_5_to_8(v0
) == c0
&& scale_5_to_8(v1
) == c1
);
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
);
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
);
1681 static inline int interp_6(int v0
, int v1
, int c0
, int c1
, bc1_approx_mode mode
)
1684 assert(scale_6_to_8(v0
) == c0
&& scale_6_to_8(v1
) == c1
);
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
);
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
);
1695 static inline int interp_half_5(int v0
, int v1
, int c0
, int c1
, bc1_approx_mode mode
)
1697 assert(scale_5_to_8(v0
) == c0
&& scale_5_to_8(v1
) == c1
);
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
:
1705 return interp_half_5_6_ideal(c0
, c1
);
1709 static inline int interp_half_6(int v0
, int v1
, int c0
, int c1
, bc1_approx_mode mode
)
1712 assert(scale_6_to_8(v0
) == c0
&& scale_6_to_8(v1
) == c1
);
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
:
1720 return interp_half_5_6_ideal(c0
, c1
);
1724 static void prepare_bc1_single_color_table_half(bc1_match_entry
* pTable
, const uint8_t* pExpand
, int size
, bc1_approx_mode mode
)
1726 for (int i
= 0; i
< 256; i
++)
1729 for (int lo
= 0; lo
< size
; lo
++)
1731 const int lo_e
= pExpand
[lo
];
1733 for (int hi
= 0; hi
< size
; hi
++)
1735 const int hi_e
= pExpand
[hi
];
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
);
1739 int e
= iabs(v
- i
);
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;
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
)))
1748 pTable
[i
].m_hi
= static_cast<uint8_t>(hi
);
1749 pTable
[i
].m_lo
= static_cast<uint8_t>(lo
);
1751 assert(e
<= UINT8_MAX
);
1752 pTable
[i
].m_e
= static_cast<uint8_t>(e
);
1762 static void prepare_bc1_single_color_table(bc1_match_entry
* pTable
, const uint8_t* pExpand
, int size
, bc1_approx_mode mode
)
1764 for (int i
= 0; i
< 256; i
++)
1767 for (int lo
= 0; lo
< size
; lo
++)
1769 const int lo_e
= pExpand
[lo
];
1771 for (int hi
= 0; hi
< size
; hi
++)
1773 const int hi_e
= pExpand
[hi
];
1775 const int v
= (size
== 32) ? interp_5(hi
, lo
, hi_e
, lo_e
, mode
) : interp_6(hi
, lo
, hi_e
, lo_e
, mode
);
1777 int e
= iabs(v
- i
);
1779 if ((mode
== bc1_approx_mode::cBC1Ideal
) || (mode
== bc1_approx_mode::cBC1IdealRound4
))
1780 e
+= (iabs(hi_e
- lo_e
) * 3) / 100;
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
)))
1785 pTable
[i
].m_hi
= static_cast<uint8_t>(hi
);
1786 pTable
[i
].m_lo
= static_cast<uint8_t>(lo
);
1788 assert(e
<= UINT8_MAX
);
1789 pTable
[i
].m_e
= static_cast<uint8_t>(e
);
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 };
1803 // multiplier is 4 for 3-color
1804 static const uint32_t g_weight_vals3
[3] = { 0x000004, 0x040000, 0x010101 };
1806 static inline void compute_selector_factors4(const hist4
&h
, float &iz00
, float &iz10
, float &iz11
)
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
];
1812 float z00
= (float)((weight_accum
>> 16) & 0xFF);
1813 float z10
= (float)((weight_accum
>> 8) & 0xFF);
1814 float z11
= (float)(weight_accum
& 0xFF);
1817 float det
= z00
* z11
- z01
* z10
;
1818 if (fabs(det
) < 1e-8f
)
1821 det
= (3.0f
/ 255.0f
) / det
;
1828 static inline void compute_selector_factors3(const hist3
&h
, float &iz00
, float &iz10
, float &iz11
)
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
];
1834 float z00
= (float)((weight_accum
>> 16) & 0xFF);
1835 float z10
= (float)((weight_accum
>> 8) & 0xFF);
1836 float z11
= (float)(weight_accum
& 0xFF);
1839 float det
= z00
* z11
- z01
* z10
;
1840 if (fabs(det
) < 1e-8f
)
1843 det
= (2.0f
/ 255.0f
) / det
;
1850 static bool g_initialized
;
1852 void init(bc1_approx_mode mode
)
1854 g_bc1_approx_mode
= mode
;
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
);
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
);
1868 for (uint32_t i
= 0; i
< NUM_UNIQUE_TOTAL_ORDERINGS4
; i
++)
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];
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
;
1883 compute_selector_factors4(h
, g_selector_factors4
[i
][0], g_selector_factors4
[i
][1], g_selector_factors4
[i
][2]);
1886 for (uint32_t i
= 0; i
< NUM_UNIQUE_TOTAL_ORDERINGS3
; i
++)
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];
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
;
1900 compute_selector_factors3(h
, g_selector_factors3
[i
][0], g_selector_factors3
[i
][1], g_selector_factors3
[i
][2]);
1903 g_initialized
= true;
1906 void encode_bc1_solid_block(void* pDst
, uint32_t fr
, uint32_t fg
, uint32_t fb
, bool allow_3color
)
1908 bc1_block
* pDst_block
= static_cast<bc1_block
*>(pDst
);
1910 uint32_t mask
= 0xAA;
1911 int max16
= -1, min16
= 0;
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
;
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
;
1924 std::swap(max16
, min16
);
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
;
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.
1945 assert(min16
== max16
&& max16
== 0);
1952 assert(max16
> min16
);
1957 std::swap(max16
, min16
);
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
);
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
};
1973 struct vec3F
{ float c
[3]; };
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])
1981 const float iz01
= iz10
;
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;
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
);
1994 pXl
->c
[0] = iz00
* (float)uq00_r
+ iz01
* q10_r
;
1995 pXh
->c
[0] = iz10
* (float)uq00_r
+ iz11
* q10_r
;
1997 pXl
->c
[1] = iz00
* (float)uq00_g
+ iz01
* q10_g
;
1998 pXh
->c
[1] = iz10
* (float)uq00_g
+ iz11
* q10_g
;
2000 pXl
->c
[2] = iz00
* (float)uq00_b
+ iz01
* q10_b
;
2001 pXh
->c
[2] = iz10
* (float)uq00_b
+ iz11
* q10_b
;
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
)
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
++)
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
];
2013 weight_accum
+= g_weight_vals4
[sel
];
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
;
2023 float z00
= (float)((weight_accum
>> 16) & 0xFF);
2024 float z10
= (float)((weight_accum
>> 8) & 0xFF);
2025 float z11
= (float)(weight_accum
& 0xFF);
2028 float det
= z00
* z11
- z01
* z10
;
2029 if (fabs(det
) < 1e-8f
)
2032 det
= (3.0f
/ 255.0f
) / det
;
2034 float iz00
, iz01
, iz10
, iz11
;
2040 pXl
->c
[0] = iz00
* (float)uq00_r
+ iz01
* q10_r
;
2041 pXh
->c
[0] = iz10
* (float)uq00_r
+ iz11
* q10_r
;
2043 pXl
->c
[1] = iz00
* (float)uq00_g
+ iz01
* q10_g
;
2044 pXh
->c
[1] = iz10
* (float)uq00_g
+ iz11
* q10_g
;
2046 pXl
->c
[2] = iz00
* (float)uq00_b
+ iz01
* q10_b
;
2047 pXh
->c
[2] = iz10
* (float)uq00_b
+ iz11
* q10_b
;
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])
2058 const float iz01
= iz10
;
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
]);
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
);
2071 pXl
->c
[0] = iz00
* (float)uq00_r
+ iz01
* q10_r
;
2072 pXh
->c
[0] = iz10
* (float)uq00_r
+ iz11
* q10_r
;
2074 pXl
->c
[1] = iz00
* (float)uq00_g
+ iz01
* q10_g
;
2075 pXh
->c
[1] = iz10
* (float)uq00_g
+ iz11
* q10_g
;
2077 pXl
->c
[2] = iz00
* (float)uq00_b
+ iz01
* q10_b
;
2078 pXh
->c
[2] = iz10
* (float)uq00_b
+ iz11
* q10_b
;
2081 static inline bool compute_least_squares_endpoints3_rgb(bool use_black
, const color32
* pColors
, const uint8_t* pSelectors
, vec3F
* pXl
, vec3F
* pXh
)
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
++)
2088 const uint8_t r
= pColors
[i
].c
[0], g
= pColors
[i
].c
[1], b
= pColors
[i
].c
[2];
2091 if ((r
| g
| b
) < 4)
2095 const uint8_t sel
= pSelectors
[i
];
2100 weight_accum
+= g_weight_vals3
[sel
];
2102 static const uint8_t s_tran
[3] = { 0, 2, 1 };
2103 const uint8_t tsel
= s_tran
[sel
];
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
;
2117 float z00
= (float)((weight_accum
>> 16) & 0xFF);
2118 float z10
= (float)((weight_accum
>> 8) & 0xFF);
2119 float z11
= (float)(weight_accum
& 0xFF);
2122 float det
= z00
* z11
- z01
* z10
;
2123 if (fabs(det
) < 1e-8f
)
2126 det
= (2.0f
/ 255.0f
) / det
;
2128 float iz00
, iz01
, iz10
, iz11
;
2134 pXl
->c
[0] = iz00
* (float)uq00_r
+ iz01
* q10_r
;
2135 pXh
->c
[0] = iz10
* (float)uq00_r
+ iz11
* q10_r
;
2137 pXl
->c
[1] = iz00
* (float)uq00_g
+ iz01
* q10_g
;
2138 pXh
->c
[1] = iz10
* (float)uq00_g
+ iz11
* q10_g
;
2140 pXl
->c
[2] = iz00
* (float)uq00_b
+ iz01
* q10_b
;
2141 pXh
->c
[2] = iz10
* (float)uq00_b
+ iz11
* q10_b
;
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
)
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);
2151 if (g_bc1_approx_mode
== bc1_approx_mode::cBC1Ideal
)
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;
2156 else if (g_bc1_approx_mode
== bc1_approx_mode::cBC1IdealRound4
)
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;
2161 else if (g_bc1_approx_mode
== bc1_approx_mode::cBC1AMD
)
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]);
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
);
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
)
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);
2178 if ((g_bc1_approx_mode
== bc1_approx_mode::cBC1Ideal
) || (g_bc1_approx_mode
== bc1_approx_mode::cBC1IdealRound4
))
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;
2182 else if (g_bc1_approx_mode
== bc1_approx_mode::cBC1AMD
)
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]);
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
);
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])
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
);
2197 int ar
= block_r
[3] - block_r
[0], ag
= block_g
[3] - block_g
[0], ab
= block_b
[3] - block_b
[0];
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
;
2203 int t0
= dots
[0] + dots
[1], t1
= dots
[1] + dots
[2], t2
= dots
[2] + dots
[3];
2205 ar
*= 2; ag
*= 2; ab
*= 2;
2207 static const uint8_t s_sels
[4] = { 3, 2, 1, 0 };
2209 for (uint32_t i
= 0; i
< 16; i
+= 4)
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
;
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
)];
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
)
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
);
2228 int ar
= block_r
[3] - block_r
[0], ag
= block_g
[3] - block_g
[0], ab
= block_b
[3] - block_b
[0];
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
;
2234 int t0
= dots
[0] + dots
[1], t1
= dots
[1] + dots
[2], t2
= dots
[2] + dots
[3];
2236 ar
*= 2; ag
*= 2; ab
*= 2;
2238 static const uint8_t s_sels
[4] = { 3, 2, 1, 0 };
2240 uint32_t total_err
= 0;
2242 for (uint32_t i
= 0; i
< 16; i
+= 4)
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
;
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
)];
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
]);
2264 if (total_err
>= cur_err
)
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
)
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
);
2276 int dr
= block_r
[3] - block_r
[0], dg
= block_g
[3] - block_g
[0], db
= block_b
[3] - block_b
[0];
2278 const float f
= 4.0f
/ (float)(squarei(dr
) + squarei(dg
) + squarei(db
) + .00000125f
);
2280 uint32_t total_err
= 0;
2282 for (uint32_t i
= 0; i
< 16; i
++)
2284 const int r
= pSrc_pixels
[i
].r
;
2285 const int g
= pSrc_pixels
[i
].g
;
2286 const int b
= pSrc_pixels
[i
].b
;
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);
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
);
2295 uint32_t best_err
= err1
;
2298 // Prefer non-interpolation
2299 if ((best_sel
- 1) == 0)
2302 else if (err0
< best_err
)
2308 total_err
+= best_err
;
2310 if (total_err
>= cur_err
)
2313 sels
[i
] = (uint8_t)best_sel
;
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
)
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
);
2323 uint32_t total_err
= 0;
2325 for (uint32_t i
= 0; i
< 16; i
++)
2327 const int r
= pSrc_pixels
[i
].r
;
2328 const int g
= pSrc_pixels
[i
].g
;
2329 const int b
= pSrc_pixels
[i
].b
;
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;
2334 for (uint32_t j
= 1; (j
< 4) && best_err
; j
++)
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)) )
2340 best_sel
= (uint8_t)j
;
2344 total_err
+= best_err
;
2346 if (total_err
>= cur_err
)
2349 sels
[i
] = (uint8_t)best_sel
;
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
)
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
);
2363 err
= bc1_find_sels4_check2_err(pSrc_pixels
, lr
, lg
, lb
, hr
, hg
, hb
, sels
, cur_err
);
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
)
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
);
2373 uint32_t total_err
= 0;
2375 for (uint32_t i
= 0; i
< 16; i
++)
2377 const int r
= pSrc_pixels
[i
].r
;
2378 const int g
= pSrc_pixels
[i
].g
;
2379 const int b
= pSrc_pixels
[i
].b
;
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;
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
)
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
)
2400 uint32_t err3
= squarei(r
) + squarei(g
) + squarei(b
);
2401 if (err3
< best_err
)
2408 total_err
+= best_err
;
2409 if (total_err
>= cur_err
)
2412 sels
[i
] = (uint8_t)best_sel
;
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
)
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
);
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
);
2430 if ((uint32_t)(trial_lr
| trial_lb
| trial_hr
| trial_hb
) > 31U)
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
;
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
;
2439 if ((uint32_t)(trial_lg
| trial_hg
) > 63U)
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
;
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;
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;
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
)
2458 xl
.c
[0] *= 1.0f
/255.0f
;
2459 xl
.c
[1] *= 1.0f
/255.0f
;
2460 xl
.c
[2] *= 1.0f
/255.0f
;
2462 xh
.c
[0] *= 1.0f
/255.0f
;
2463 xh
.c
[1] *= 1.0f
/255.0f
;
2464 xh
.c
[2] *= 1.0f
/255.0f
;
2466 precise_round_565(xl
, xh
, trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
);
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])
2471 uint32_t lc16
= bc1_block::pack_unscaled_color(lr
, lg
, lb
);
2472 uint32_t hc16
= bc1_block::pack_unscaled_color(hr
, hg
, hb
);
2474 // Always forbid 3 color blocks
2485 assert(lc16
== hc16
&& hc16
== 0);
2489 mask
= 0x55; // select hc16
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
));
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
;
2503 uint8_t invert_mask
= 0;
2506 std::swap(lc16
, hc16
);
2510 assert(lc16
> hc16
);
2511 pDst_block
->set_low_color((uint16_t)lc16
);
2512 pDst_block
->set_high_color((uint16_t)hc16
);
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));
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
;
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])
2528 uint32_t lc16
= bc1_block::pack_unscaled_color(lr
, lg
, lb
);
2529 uint32_t hc16
= bc1_block::pack_unscaled_color(hr
, hg
, hb
);
2531 bool invert_flag
= false;
2534 std::swap(lc16
, hc16
);
2538 assert(lc16
<= hc16
);
2540 pDst_block
->set_low_color((uint16_t)lc16
);
2541 pDst_block
->set_high_color((uint16_t)hc16
);
2543 uint32_t packed_sels
= 0;
2547 static const uint8_t s_sel_trans_inv
[4] = { 1, 0, 2, 3 };
2549 for (uint32_t i
= 0; i
< 16; i
++)
2550 packed_sels
|= ((uint32_t)s_sel_trans_inv
[sels
[i
]] << (i
* 2));
2554 for (uint32_t i
= 0; i
< 16; i
++)
2555 packed_sels
|= ((uint32_t)sels
[i
] << (i
* 2));
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);
2564 struct bc1_encode_results
2572 static bool try_3color_block_useblack(const color32
* pSrc_pixels
, uint32_t flags
, uint32_t &cur_err
, bc1_encode_results
&results
)
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
++)
2580 const int r
= pSrc_pixels
[i
].r
, g
= pSrc_pixels
[i
].g
, b
= pSrc_pixels
[i
].b
;
2581 if ((r
| g
| b
) < 4)
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
;
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
;
2599 uint32_t low_c
= 0, high_c
= 0;
2601 int icov
[6] = { 0, 0, 0, 0, 0, 0 };
2602 for (uint32_t i
= 0; i
< 16; i
++)
2604 int r
= (int)pSrc_pixels
[i
].r
;
2605 int g
= (int)pSrc_pixels
[i
].g
;
2606 int b
= (int)pSrc_pixels
[i
].b
;
2608 if ((r
| g
| b
) < 4)
2624 for (uint32_t i
= 0; i
< 6; i
++)
2625 cov
[i
] = (float)(icov
[i
]) * (1.0f
/ 255.0f
);
2627 float xr
= (float)(max_r
- min_r
);
2628 float xg
= (float)(max_g
- min_g
);
2629 float xb
= (float)(max_b
- min_b
);
2637 for (uint32_t power_iter
= 0; power_iter
< 4; power_iter
++)
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
;
2645 float k
= maximum(fabsf(xr
), fabsf(xg
), fabsf(xb
));
2646 int saxis_r
= 306, saxis_g
= 601, saxis_b
= 117;
2649 float m
= 1024.0f
/ k
;
2650 saxis_r
= (int)(xr
* m
);
2651 saxis_g
= (int)(xg
* m
);
2652 saxis_b
= (int)(xb
* m
);
2655 int low_dot
= INT_MAX
, high_dot
= INT_MIN
;
2656 for (uint32_t i
= 0; i
< 16; i
++)
2658 int r
= (int)pSrc_pixels
[i
].r
, g
= (int)pSrc_pixels
[i
].g
, b
= (int)pSrc_pixels
[i
].b
;
2660 if ((r
| g
| b
) < 4)
2663 int dot
= r
* saxis_r
+ g
* saxis_g
+ b
* saxis_b
;
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
);
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
);
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
);
2689 const uint32_t total_ls_passes
= flags
& cEncodeBC1TwoLeastSquaresPasses
? 2 : 1;
2690 for (uint32_t trials
= 0; trials
< total_ls_passes
; trials
++)
2693 int lr2
, lg2
, lb2
, hr2
, hg2
, hb2
;
2694 if (!compute_least_squares_endpoints3_rgb(true, pSrc_pixels
, trial_sels
, &xl
, &xh
))
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
;
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
;
2706 precise_round_565(xl
, xh
, hr2
, hg2
, hb2
, lr2
, lg2
, lb2
);
2709 if ((lr
== lr2
) && (lg
== lg2
) && (lb
== lb2
) && (hr
== hr2
) && (hg
== hg2
) && (hb
== hb2
))
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
);
2715 if (trial_err2
< trial_err
)
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
));
2727 if (trial_err
< cur_err
)
2729 results
.m_3color
= true;
2736 memcpy(results
.sels
, trial_sels
, 16);
2738 cur_err
= trial_err
;
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
)
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
);
2755 const uint32_t total_ls_passes
= flags
& cEncodeBC1TwoLeastSquaresPasses
? 2 : 1;
2756 for (uint32_t trials
= 0; trials
< total_ls_passes
; trials
++)
2759 int lr2
, lg2
, lb2
, hr2
, hg2
, hb2
;
2760 if (!compute_least_squares_endpoints3_rgb(false, pSrc_pixels
, trial_sels
, &xl
, &xh
))
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
;
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
;
2772 precise_round_565(xl
, xh
, hr2
, hg2
, hb2
, lr2
, lg2
, lb2
);
2775 if ((lr
== lr2
) && (lg
== lg2
) && (lb
== lb2
) && (hr
== hr2
) && (hg
== hg2
) && (hb
== hb2
))
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
);
2781 if (trial_err2
< trial_err
)
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
));
2793 if ((trial_err
) && (flags
& cEncodeBC1UseLikelyTotalOrderings
) && (total_orderings_to_try
))
2796 for (uint32_t i
= 0; i
< 16; i
++)
2798 assert(trial_sels
[i
] < 3);
2799 h
.m_hist
[trial_sels
[i
]]++;
2802 const uint32_t orig_total_order_index
= h
.lookup_total_ordering_index();
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);
2808 int ar
= r3
- r0
, ag
= g3
- g0
, ab
= b3
- b0
;
2811 for (uint32_t i
= 0; i
< 16; i
++)
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
);
2818 dots
[i
] = (d
<< 4) + i
;
2821 std::sort(dots
, dots
+ 16);
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
++)
2827 const uint32_t p
= dots
[i
] & 15;
2833 r
+= pSrc_pixels
[p
].r
;
2834 g
+= pSrc_pixels
[p
].g
;
2835 b
+= pSrc_pixels
[p
].b
;
2838 r_sum
[16] = total_r
;
2839 g_sum
[16] = total_g
;
2840 b_sum
[16] = total_b
;
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
++)
2845 const uint32_t s
= (flags
& cEncodeBC1Exhaustive
) ? q
: g_best_total_orderings3
[orig_total_order_index
][q
];
2847 int trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
;
2851 if ((s
== TOTAL_ORDER_3_0_16
) || (s
== TOTAL_ORDER_3_1_16
) || (s
== TOTAL_ORDER_3_2_16
))
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
;
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
;
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
);
2866 precise_round_565(xl
, xh
, trial_hr
, trial_hg
, trial_hb
, trial_lr
, trial_lg
, trial_lb
);
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
);
2872 if (trial_err2
< trial_err
)
2874 trial_err
= trial_err2
;
2884 memcpy(trial_sels
, trial_sels2
, sizeof(trial_sels
));
2890 if (trial_err
< cur_err
)
2892 results
.m_3color
= true;
2899 memcpy(results
.sels
, trial_sels
, 16);
2901 cur_err
= trial_err
;
2909 void encode_bc1(uint32_t level
, void* pDst
, const uint8_t* pPixels
, bool allow_3color
, bool allow_transparent_texels_for_black
)
2911 uint32_t flags
= 0, total_orderings4
= 1, total_orderings3
= 1;
2913 static_assert(MAX_TOTAL_ORDERINGS3
>= 32, "MAX_TOTAL_ORDERINGS3 >= 32");
2914 static_assert(MAX_TOTAL_ORDERINGS4
>= 32, "MAX_TOTAL_ORDERINGS4 >= 32");
2919 // Faster/higher quality than stb_dxt default.
2920 flags
= cEncodeBC1BoundingBoxInt
;
2923 // Faster/higher quality than stb_dxt default. A bit higher average quality vs. mode 0.
2924 flags
= cEncodeBC1Use2DLS
;
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.
2932 // Slightly stronger than stb_dxt HIGHQUAL.
2933 flags
= cEncodeBC1TwoLeastSquaresPasses
;
2936 flags
= cEncodeBC1TwoLeastSquaresPasses
| cEncodeBC1UseFullMSEEval
| cEncodeBC1Use6PowerIters
;
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);
2945 flags
= cEncodeBC1TwoLeastSquaresPasses
| cEncodeBC1UseFasterMSEEval
| cEncodeBC1UseLikelyTotalOrderings
;
2946 flags
|= (allow_3color
? cEncodeBC1Use3ColorBlocks
: 0) | (allow_transparent_texels_for_black
? cEncodeBC1Use3ColorBlocksForBlackPixels
: 0);
2949 flags
= cEncodeBC1TwoLeastSquaresPasses
| cEncodeBC1UseFasterMSEEval
| cEncodeBC1UseLikelyTotalOrderings
;
2950 flags
|= (allow_3color
? cEncodeBC1Use3ColorBlocks
: 0) | (allow_transparent_texels_for_black
? cEncodeBC1Use3ColorBlocksForBlackPixels
: 0);
2951 total_orderings4
= 4;
2954 flags
= cEncodeBC1TwoLeastSquaresPasses
| cEncodeBC1UseFasterMSEEval
| cEncodeBC1UseLikelyTotalOrderings
;
2955 flags
|= (allow_3color
? cEncodeBC1Use3ColorBlocks
: 0) | (allow_transparent_texels_for_black
? cEncodeBC1Use3ColorBlocksForBlackPixels
: 0);
2956 total_orderings4
= 8;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
3027 encode_bc1(pDst
, pPixels
, flags
, total_orderings4
, total_orderings3
);
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
)
3037 const int fr
= pSrc_pixels
[0].r
;
3039 // Grayscale blocks are a common enough case to specialize.
3040 if ((max_r
- min_r
) < 2)
3042 lr
= lb
= hr
= hb
= to_5(fr
);
3047 lr
= lb
= to_5(min_r
);
3050 hr
= hb
= to_5(max_r
);
3054 else if (flags
& cEncodeBC1Use2DLS
)
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
;
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
;
3064 int sum_xy_r
= 0, sum_xy_g
= 0, sum_xy_b
= 0;
3068 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3074 int sum_x
= total_r
;
3075 int sum_x2
= sum_xy_r
;
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
)
3082 b_y
= (16 * sum_xy_g
- sum_x
* total_g
) * div
;
3083 b_z
= (16 * sum_xy_b
- sum_x
* total_b
) * div
;
3086 float a_y
= (total_g
- b_y
* sum_x
) / 16.0f
;
3087 float a_z
= (total_b
- b_z
* sum_x
) / 16.0f
;
3089 l
.c
[1] = a_y
+ b_y
* min_chan_val
;
3090 l
.c
[2] = a_z
+ b_z
* min_chan_val
;
3092 h
.c
[1] = a_y
+ b_y
* max_chan_val
;
3093 h
.c
[2] = a_z
+ b_z
* max_chan_val
;
3095 float dg
= (h
.c
[1] - l
.c
[1]);
3096 float db
= (h
.c
[2] - l
.c
[2]);
3098 h
.c
[1] = l
.c
[1] + dg
* (15.0f
/16.0f
);
3099 h
.c
[2] = l
.c
[2] + db
* (15.0f
/16.0f
);
3101 l
.c
[1] = l
.c
[1] + dg
* (1.0f
/16.0f
);
3102 l
.c
[2] = l
.c
[2] + db
* (1.0f
/16.0f
);
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
);
3108 l
.c
[0] = fmin_chan_val
;
3109 h
.c
[0] = fmax_chan_val
;
3111 else if (big_chan
== 1)
3113 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3119 int sum_x
= total_g
;
3120 int sum_x2
= sum_xy_g
;
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
)
3127 b_x
= (16 * sum_xy_r
- sum_x
* total_r
) * div
;
3128 b_z
= (16 * sum_xy_b
- sum_x
* total_b
) * div
;
3131 float a_x
= (total_r
- b_x
* sum_x
) / 16.0f
;
3132 float a_z
= (total_b
- b_z
* sum_x
) / 16.0f
;
3134 l
.c
[0] = a_x
+ b_x
* min_chan_val
;
3135 l
.c
[2] = a_z
+ b_z
* min_chan_val
;
3137 h
.c
[0] = a_x
+ b_x
* max_chan_val
;
3138 h
.c
[2] = a_z
+ b_z
* max_chan_val
;
3140 float dr
= (h
.c
[0] - l
.c
[0]);
3141 float db
= (h
.c
[2] - l
.c
[2]);
3143 h
.c
[0] = l
.c
[0] + dr
* (15.0f
/16.0f
);
3144 h
.c
[2] = l
.c
[2] + db
* (15.0f
/16.0f
);
3146 l
.c
[0] = l
.c
[0] + dr
* (1.0f
/16.0f
);
3147 l
.c
[2] = l
.c
[2] + db
* (1.0f
/16.0f
);
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
);
3153 l
.c
[1] = fmin_chan_val
;
3154 h
.c
[1] = fmax_chan_val
;
3158 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3164 int sum_x
= total_b
;
3165 int sum_x2
= sum_xy_b
;
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
)
3172 b_x
= (16 * sum_xy_r
- sum_x
* total_r
) * div
;
3173 b_y
= (16 * sum_xy_g
- sum_x
* total_g
) * div
;
3176 float a_x
= (total_r
- b_x
* sum_x
) / 16.0f
;
3177 float a_y
= (total_g
- b_y
* sum_x
) / 16.0f
;
3179 l
.c
[0] = a_x
+ b_x
* min_chan_val
;
3180 l
.c
[1] = a_y
+ b_y
* min_chan_val
;
3182 h
.c
[0] = a_x
+ b_x
* max_chan_val
;
3183 h
.c
[1] = a_y
+ b_y
* max_chan_val
;
3185 float dr
= (h
.c
[0] - l
.c
[0]);
3186 float dg
= (h
.c
[1] - l
.c
[1]);
3188 h
.c
[0] = l
.c
[0] + dr
* (15.0f
/16.0f
);
3189 h
.c
[1] = l
.c
[1] + dg
* (15.0f
/16.0f
);
3191 l
.c
[0] = l
.c
[0] + dr
* (1.0f
/16.0f
);
3192 l
.c
[1] = l
.c
[1] + dg
* (1.0f
/16.0f
);
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
);
3198 l
.c
[2] = fmin_chan_val
;
3199 h
.c
[2] = fmax_chan_val
;
3202 precise_round_565_noscale(l
, h
, lr
, lg
, lb
, hr
, hg
, hb
);
3204 else if (flags
& cEncodeBC1BoundingBox
)
3206 // Algorithm from icbc.h compress_dxt1_fast()
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
);
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
);
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
);
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
);
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
);
3229 int icov_xz
= 0, icov_yz
= 0;
3230 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3240 std::swap(l
.c
[0], h
.c
[0]);
3243 std::swap(l
.c
[1], h
.c
[1]);
3245 precise_round_565(l
, h
, lr
, lg
, lb
, hr
, hg
, hb
);
3247 else if (flags
& cEncodeBC1BoundingBoxInt
)
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;
3257 if ((uint32_t)(min_r
| min_g
| min_b
) > 255U)
3259 min_r
= clampi(min_r
, 0, 255);
3260 min_g
= clampi(min_g
, 0, 255);
3261 min_b
= clampi(min_b
, 0, 255);
3267 if ((uint32_t)(max_r
| max_g
| max_b
) > 255U)
3269 max_r
= clampi(max_r
, 0, 255);
3270 max_g
= clampi(max_g
, 0, 255);
3271 max_b
= clampi(max_b
, 0, 255);
3274 int icov_xz
= 0, icov_yz
= 0;
3275 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3305 // Select 2 colors along the principle axis. (There must be a faster/simpler way.)
3306 uint32_t low_c
= 0, high_c
= 0;
3308 int icov
[6] = { 0, 0, 0, 0, 0, 0 };
3309 for (uint32_t i
= 0; i
< 16; i
++)
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
;
3322 int saxis_r
= 306, saxis_g
= 601, saxis_b
= 117;
3324 float xr
= (float)(max_r
- min_r
);
3325 float xg
= (float)(max_g
- min_g
);
3326 float xb
= (float)(max_b
- min_b
);
3335 for (uint32_t i
= 0; i
< 6; i
++)
3336 cov
[i
] = (float)(icov
[i
]) * (1.0f
/ 255.0f
);
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
++)
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
;
3347 float k
= maximum(fabsf(xr
), fabsf(xg
), fabsf(xb
));
3350 float m
= 2048.0f
/ k
;
3351 saxis_r
= (int)(xr
* m
);
3352 saxis_g
= (int)(xg
* m
);
3353 saxis_b
= (int)(xb
* m
);
3356 int low_dot
= INT_MAX
, high_dot
= INT_MIN
;
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);
3362 for (uint32_t i
= 0; i
< 16; i
+= 4)
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;
3369 int min_d01
= std::min(dot0
, dot1
);
3370 int max_d01
= std::max(dot0
, dot1
);
3372 int min_d23
= std::min(dot2
, dot3
);
3373 int max_d23
= std::max(dot2
, dot3
);
3375 int min_d
= std::min(min_d01
, min_d23
);
3376 int max_d
= std::max(max_d01
, max_d23
);
3378 low_dot
= std::min(low_dot
, min_d
);
3379 high_dot
= std::max(high_dot
, max_d
);
3381 low_c
= low_dot
& 15;
3382 high_c
= high_dot
& 15;
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
);
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
);
3394 static const int8_t s_adjacent_voxels
[16][4] =
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
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
)
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
;
3421 int prev_improvement_index
= 0, forbidden_direction
= -1;
3423 const int endpoint_search_rounds
= (flags
& cEncodeBC1EndpointSearchRoundsMask
) >> cEncodeBC1EndpointSearchRoundsShift
;
3424 for (int i
= 0; i
< endpoint_search_rounds
; i
++)
3426 assert(s_adjacent_voxels
[ s_adjacent_voxels
[i
& 15][3] ][3] == (i
& 15));
3428 if (forbidden_direction
== (i
& 31))
3431 const int8_t delta
[3] = { s_adjacent_voxels
[i
& 15][0], s_adjacent_voxels
[i
& 15][1], s_adjacent_voxels
[i
& 15][2] };
3433 int trial_lr
= lr
, trial_lg
= lg
, trial_lb
= lb
, trial_hr
= hr
, trial_hg
= hg
, trial_hb
= hb
;
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);
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);
3448 uint8_t trial_sels
[16];
3451 if (results
.m_3color
)
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
);
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
);
3462 if (trial_err
< cur_err
)
3464 cur_err
= trial_err
;
3466 forbidden_direction
= s_adjacent_voxels
[i
& 15][3] | (i
& 16);
3468 lr
= trial_lr
, lg
= trial_lg
, lb
= trial_lb
, hr
= trial_hr
, hg
= trial_hg
, hb
= trial_hb
;
3470 memcpy(sels
, trial_sels
, 16);
3472 prev_improvement_index
= i
;
3475 if (i
- prev_improvement_index
> 32)
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
)
3482 assert(g_initialized
);
3484 const color32
* pSrc_pixels
= (const color32
*)pPixels
;
3485 bc1_block
* pDst_block
= static_cast<bc1_block
*>(pDst
);
3487 int avg_r
, avg_g
, avg_b
, min_r
, min_g
, min_b
, max_r
, max_g
, max_b
;
3489 const uint32_t fr
= pSrc_pixels
[0].r
, fg
= pSrc_pixels
[0].g
, fb
= pSrc_pixels
[0].b
;
3492 for (j
= 15; j
>= 1; --j
)
3493 if ((pSrc_pixels
[j
].r
!= fr
) || (pSrc_pixels
[j
].g
!= fg
) || (pSrc_pixels
[j
].b
!= fb
))
3498 encode_bc1_solid_block(pDst
, fr
, fg
, fb
, (flags
& (cEncodeBC1Use3ColorBlocks
| cEncodeBC1Use3ColorBlocksForBlackPixels
)) != 0);
3502 int total_r
= fr
, total_g
= fg
, total_b
= fb
;
3504 max_r
= fr
, max_g
= fg
, max_b
= fb
;
3505 min_r
= fr
, min_g
= fg
, min_b
= fb
;
3507 uint32_t grayscale_flag
= (fr
== fg
) && (fr
== fb
);
3508 uint32_t any_black_pixels
= (fr
| fg
| fb
) < 4;
3510 for (uint32_t i
= 1; i
< 16; i
++)
3512 const int r
= pSrc_pixels
[i
].r
, g
= pSrc_pixels
[i
].g
, b
= pSrc_pixels
[i
].b
;
3514 grayscale_flag
&= ((r
== g
) && (r
== b
));
3515 any_black_pixels
|= ((r
| g
| b
) < 4);
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
;
3522 avg_r
= (total_r
+ 8) >> 4, avg_g
= (total_g
+ 8) >> 4, avg_b
= (total_b
+ 8) >> 4;
3524 bc1_encode_results results
;
3525 results
.m_3color
= false;
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;
3531 lr
= 0, lg
= 0, lb
= 0, hr
= 0, hg
= 0, hb
= 0;
3533 const bool needs_block_error
= ((flags
& (cEncodeBC1UseLikelyTotalOrderings
| cEncodeBC1Use3ColorBlocks
| cEncodeBC1UseFullMSEEval
| cEncodeBC1EndpointSearchRoundsMask
)) != 0) ||
3534 (any_black_pixels
&& ((flags
& cEncodeBC1Use3ColorBlocksForBlackPixels
) != 0));
3536 uint32_t cur_err
= UINT32_MAX
;
3538 if (!needs_block_error
)
3540 assert((flags
& cEncodeBC1TryAllInitialEndponts
) == 0);
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
);
3547 orig_lr
= lr
, orig_lg
= lg
, orig_lb
= lb
, orig_hr
= hr
, orig_hg
= hg
, orig_hb
= hb
;
3549 bc1_find_sels4_noerr(pSrc_pixels
, lr
, lg
, lb
, hr
, hg
, hb
, sels
);
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
++)
3554 int trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
;
3557 if (!compute_least_squares_endpoints4_rgb(pSrc_pixels
, sels
, &xl
, &xh
, total_r
, total_g
, total_b
))
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
;
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
;
3568 // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge.
3572 precise_round_565(xl
, xh
, trial_hr
, trial_hg
, trial_hb
, trial_lr
, trial_lg
, trial_lb
);
3575 if ((lr
== trial_lr
) && (lg
== trial_lg
) && (lb
== trial_lb
) && (hr
== trial_hr
) && (hg
== trial_hg
) && (hb
== trial_hb
))
3578 bc1_find_sels4_noerr(pSrc_pixels
, trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
, sels
);
3591 const uint32_t total_rounds
= (flags
& cEncodeBC1TryAllInitialEndponts
) ? 2 : 1;
3592 for (uint32_t round
= 0; round
< total_rounds
; round
++)
3594 uint32_t modified_flags
= flags
;
3597 modified_flags
&= ~(cEncodeBC1Use2DLS
| cEncodeBC1BoundingBox
);
3598 modified_flags
|= cEncodeBC1BoundingBox
;
3601 int round_lr
, round_lg
, round_lb
, round_hr
, round_hg
, round_hb
;
3602 uint8_t round_sels
[16];
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
);
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
;
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
);
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
++)
3616 int trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
;
3619 if (!compute_least_squares_endpoints4_rgb(pSrc_pixels
, round_sels
, &xl
, &xh
, total_r
, total_g
, total_b
))
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
;
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
;
3630 // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge.
3634 precise_round_565(xl
, xh
, trial_hr
, trial_hg
, trial_hb
, trial_lr
, trial_lg
, trial_lb
);
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
))
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
);
3643 if (trial_err
< round_err
)
3645 round_lr
= trial_lr
;
3646 round_lg
= trial_lg
;
3647 round_lb
= trial_lb
;
3649 round_hr
= trial_hr
;
3650 round_hg
= trial_hg
;
3651 round_hb
= trial_hb
;
3653 round_err
= trial_err
;
3654 memcpy(round_sels
, trial_sels
, 16);
3661 if (round_err
<= cur_err
)
3663 cur_err
= round_err
;
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
;
3679 memcpy(sels
, round_sels
, 16);
3685 if ((cur_err
) && (flags
& cEncodeBC1UseLikelyTotalOrderings
))
3687 assert(needs_block_error
);
3689 const uint32_t total_iters
= (flags
& cEncodeBC1Iterative
) ? 2 : 1;
3690 for (uint32_t iter_index
= 0; iter_index
< total_iters
; iter_index
++)
3692 const uint32_t orig_err
= cur_err
;
3695 for (uint32_t i
= 0; i
< 16; i
++)
3697 assert(sels
[i
] < 4);
3698 h
.m_hist
[sels
[i
]]++;
3701 const uint32_t orig_total_order_index
= h
.lookup_total_ordering_index();
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);
3707 int ar
= r3
- r0
, ag
= g3
- g0
, ab
= b3
- b0
;
3710 for (uint32_t i
= 0; i
< 16; i
++)
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
);
3717 dots
[i
] = (d
<< 4) + i
;
3720 std::sort(dots
, dots
+ 16);
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
++)
3726 const uint32_t p
= dots
[i
] & 15;
3732 r
+= pSrc_pixels
[p
].r
;
3733 g
+= pSrc_pixels
[p
].g
;
3734 b
+= pSrc_pixels
[p
].b
;
3737 r_sum
[16] = total_r
;
3738 g_sum
[16] = total_g
;
3739 b_sum
[16] = total_b
;
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
++)
3744 const uint32_t s
= (flags
& cEncodeBC1Exhaustive
) ? q
: g_best_total_orderings4
[orig_total_order_index
][q
];
3746 int trial_lr
, trial_lg
, trial_lb
, trial_hr
, trial_hg
, trial_hb
;
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
))
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
;
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
;
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
);
3765 precise_round_565(xl
, xh
, trial_hr
, trial_hg
, trial_hb
, trial_lr
, trial_lg
, trial_lb
);
3768 uint8_t trial_sels
[16];
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
);
3772 if (trial_err
< cur_err
)
3774 cur_err
= trial_err
;
3784 memcpy(sels
, trial_sels
, 16);
3789 if ((!cur_err
) || (cur_err
== orig_err
))
3795 if ( ((flags
& (cEncodeBC1Use3ColorBlocks
| cEncodeBC1Use3ColorBlocksForBlackPixels
)) != 0) && (cur_err
) )
3797 if (flags
& cEncodeBC1Use3ColorBlocks
)
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
);
3803 if ((any_black_pixels
) && ((flags
& cEncodeBC1Use3ColorBlocksForBlackPixels
) != 0))
3805 assert(needs_block_error
);
3806 try_3color_block_useblack(pSrc_pixels
, flags
, cur_err
, results
);
3810 if ( (flags
& cEncodeBC1EndpointSearchRoundsMask
) && (cur_err
) )
3812 assert(needs_block_error
);
3814 encode_bc1_endpoint_search(pSrc_pixels
, any_black_pixels
!= 0, flags
, results
, cur_err
);
3817 if (results
.m_3color
)
3818 bc1_encode3(pDst_block
, results
.lr
, results
.lg
, results
.lb
, results
.hr
, results
.hg
, results
.hb
, results
.sels
);
3820 bc1_encode4(pDst_block
, results
.lr
, results
.lg
, results
.lb
, results
.hr
, results
.hg
, results
.hb
, results
.sels
);
3827 enum { cBC4SelectorBits
= 3, cTotalSelectorBytes
= 6, cMaxSelectorValues
= 8 };
3828 uint8_t m_endpoints
[2];
3830 uint8_t m_selectors
[cTotalSelectorBytes
];
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(); }
3836 inline uint64_t get_selector_bits() const
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);
3843 inline uint32_t get_selector(uint32_t x
, uint32_t y
, uint64_t selector_bits
) const
3845 assert((x
< 4U) && (y
< 4U));
3846 return (selector_bits
>> (((y
* 4) + x
) * cBC4SelectorBits
))& (cMaxSelectorValues
- 1);
3849 static inline uint32_t get_block_values6(uint8_t* pDst
, uint32_t l
, uint32_t h
)
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);
3862 static inline uint32_t get_block_values8(uint8_t* pDst
, uint32_t l
, uint32_t h
)
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);
3875 static inline uint32_t get_block_values(uint8_t* pDst
, uint32_t l
, uint32_t h
)
3878 return get_block_values8(pDst
, l
, h
);
3880 return get_block_values6(pDst
, l
, h
);
3884 void encode_bc4(void* pDst
, const uint8_t* pPixels
, uint32_t stride
)
3886 assert(g_initialized
);
3888 uint32_t min0_v
, max0_v
, min1_v
, max1_v
, min2_v
, max2_v
, min3_v
, max3_v
;
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
];
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
);
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
);
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
);
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
);
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
;
3927 memset(pDst_bytes
+ 2, 0, 6);
3931 const uint32_t delta
= max_v
- min_v
;
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;
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;
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 };
3951 uint64_t a0
, a1
, a2
, a3
;
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
)];
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);
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);
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);
3996 const uint64_t f
= a0
| a1
| a2
| a3
;
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);
4006 void encode_bc3(void* pDst
, const uint8_t* pPixels
, uint32_t flags
, uint32_t total_orderings_to_try
)
4008 assert(g_initialized
);
4010 // 3-color blocks are not allowed with BC3 (on most GPU's).
4011 flags
&= ~(cEncodeBC1Use3ColorBlocksForBlackPixels
| cEncodeBC1Use3ColorBlocks
);
4013 encode_bc4(pDst
, pPixels
+ 3, 4);
4014 encode_bc1(static_cast<uint8_t*>(pDst
) + 8, pPixels
, flags
, total_orderings_to_try
);
4017 void encode_bc3(uint32_t level
, void* pDst
, const uint8_t* pPixels
)
4019 assert(g_initialized
);
4021 encode_bc4(pDst
, pPixels
+ 3, 4);
4022 encode_bc1(level
, static_cast<uint8_t*>(pDst
) + 8, pPixels
, false, false);
4025 void encode_bc5(void* pDst
, const uint8_t* pPixels
, uint32_t chan0
, uint32_t chan1
, uint32_t stride
)
4027 assert(g_initialized
);
4029 encode_bc4(pDst
, pPixels
+ chan0
, stride
);
4030 encode_bc4(static_cast<uint8_t*>(pDst
) + 8, pPixels
+ chan1
, stride
);
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
)
4036 color32
* pDst_pixels
= static_cast<color32
*>(pPixels
);
4038 static_assert(sizeof(bc1_block
) == 8, "sizeof(bc1_block) == 8");
4039 static_assert(sizeof(bc4_block
) == 8, "sizeof(bc4_block) == 8");
4041 const bc1_block
* pBlock
= static_cast<const bc1_block
*>(pBlock_bits
);
4043 const uint32_t l
= pBlock
->get_low_color();
4044 const uint32_t h
= pBlock
->get_high_color();
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);
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);
4062 bool used_punchthrough
= false;
4066 c
[0].set_noclamp_rgba(r0
, g0
, b0
, 255);
4067 c
[1].set_noclamp_rgba(r1
, g1
, b1
, 255);
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);
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);
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);
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);
4090 c
[0].set_noclamp_rgba(r0
, g0
, b0
, 255);
4091 c
[1].set_noclamp_rgba(r1
, g1
, b1
, 255);
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);
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);
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);
4106 c
[3].set_noclamp_rgba(0, 0, 0, 0);
4107 used_punchthrough
= true;
4112 for (uint32_t y
= 0; y
< 4; y
++, pDst_pixels
+= 4)
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
)];
4122 for (uint32_t y
= 0; y
< 4; y
++, pDst_pixels
+= 4)
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
)]);
4131 return used_punchthrough
;
4134 void unpack_bc4(const void* pBlock_bits
, uint8_t* pPixels
, uint32_t stride
)
4136 static_assert(sizeof(bc4_block
) == 8, "sizeof(bc4_block) == 8");
4138 const bc4_block
* pBlock
= static_cast<const bc4_block
*>(pBlock_bits
);
4140 uint8_t sel_values
[8];
4141 bc4_block::get_block_values(sel_values
, pBlock
->get_low_alpha(), pBlock
->get_high_alpha());
4143 const uint64_t selector_bits
= pBlock
->get_selector_bits();
4145 for (uint32_t y
= 0; y
< 4; y
++, pPixels
+= (stride
* 4U))
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
)];
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
)
4157 color32
* pDst_pixels
= static_cast<color32
*>(pPixels
);
4159 bool success
= true;
4161 if (unpack_bc1((const uint8_t*)pBlock_bits
+ sizeof(bc4_block
), pDst_pixels
, true, mode
))
4164 unpack_bc4(pBlock_bits
, &pDst_pixels
[0].a
, sizeof(color32
));
4170 void unpack_bc5(const void* pBlock_bits
, void* pPixels
, uint32_t chan0
, uint32_t chan1
, uint32_t stride
)
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
);
4176 } // namespace rgbcx
4178 #endif //#ifdef RGBCX_IMPLEMENTATION
4181 ------------------------------------------------------------------------------
4182 This software is available under 2 licenses -- choose whichever you prefer.
4183 ------------------------------------------------------------------------------
4184 ALTERNATIVE A - MIT License
4185 Copyright(c) 2020 Richard Geldreich, Jr.
4186 Permission is hereby granted, free of charge, to any person obtaining a copy of
4187 this software and associated documentation files(the "Software"), to deal in
4188 the Software without restriction, including without limitation the rights to
4189 use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies
4190 of the Software, and to permit persons to whom the Software is furnished to do
4191 so, subject to the following conditions :
4192 The above copyright notice and this permission notice shall be included in all
4193 copies or substantial portions of the Software.
4194 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4195 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4196 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
4197 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4198 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4199 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4201 ------------------------------------------------------------------------------
4202 ALTERNATIVE B - Public Domain(www.unlicense.org)
4203 This is free and unencumbered software released into the public domain.
4204 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
4205 software, either in source code form or as a compiled binary, for any purpose,
4206 commercial or non - commercial, and by any means.
4207 In jurisdictions that recognize copyright laws, the author or authors of this
4208 software dedicate any and all copyright interest in the software to the public
4209 domain.We make this dedication for the benefit of the public at large and to
4210 the detriment of our heirs and successors.We intend this dedication to be an
4211 overt act of relinquishment in perpetuity of all present and future rights to
4212 this software under copyright law.
4213 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4214 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4215 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
4216 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
4217 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4218 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4219 ------------------------------------------------------------------------------