266 static constexpr int NPALETTE_ = 256;
267 static constexpr int SAMPLE_MAX_ = NPALETTE_ - 1;
268 static constexpr int NCLASS_ = SAMPLE_MAX_ * 3 + 1;
271 static constexpr unsigned long POW2_[NPALETTE_]
274 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
275 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729,
276 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521,
277 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601,
278 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969,
279 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625,
280 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569,
281 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801,
282 10000, 10201, 10404, 10609, 10816, 11025, 11236, 11449, 11664, 11881,
283 12100, 12321, 12544, 12769, 12996, 13225, 13456, 13689, 13924, 14161,
284 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129, 16384, 16641,
285 16900, 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321,
286 19600, 19881, 20164, 20449, 20736, 21025, 21316, 21609, 21904, 22201,
287 22500, 22801, 23104, 23409, 23716, 24025, 24336, 24649, 24964, 25281,
288 25600, 25921, 26244, 26569, 26896, 27225, 27556, 27889, 28224, 28561,
289 28900, 29241, 29584, 29929, 30276, 30625, 30976, 31329, 31684, 32041,
290 32400, 32761, 33124, 33489, 33856, 34225, 34596, 34969, 35344, 35721,
291 36100, 36481, 36864, 37249, 37636, 38025, 38416, 38809, 39204, 39601,
292 40000, 40401, 40804, 41209, 41616, 42025, 42436, 42849, 43264, 43681,
293 44100, 44521, 44944, 45369, 45796, 46225, 46656, 47089, 47524, 47961,
294 48400, 48841, 49284, 49729, 50176, 50625, 51076, 51529, 51984, 52441,
295 52900, 53361, 53824, 54289, 54756, 55225, 55696, 56169, 56644, 57121,
296 57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001,
297 62500, 63001, 63504, 64009, 64516, 65025,
302 template<
class C1_,
class C2_>
303 static unsigned long distance_(
const C1_&
c1,
const C2_&
c2)
noexcept
306 POW2_[std::abs(
c1.red -
c2.red)]
307 + POW2_[std::abs(
c1.green -
c2.green)]
308 + POW2_[std::abs(
c1.blue -
c2.blue)];
313 static constexpr unsigned long SUMDIFF_[NCLASS_]
316 0, 0, 1, 3, 5, 8, 12, 16, 21, 27, 33, 40, 48, 56, 65, 75, 85, 96, 108, 120,
317 133, 147, 161, 176, 192, 208, 225, 243, 261, 280, 300, 320, 341, 363, 385,
318 408, 432, 456, 481, 507, 533, 560, 588, 616, 645, 675, 705, 736, 768, 800,
319 833, 867, 901, 936, 972, 1008, 1045, 1083, 1121, 1160, 1200, 1240, 1281,
320 1323, 1365, 1408, 1452, 1496, 1541, 1587, 1633, 1680, 1728, 1776, 1825,
321 1875, 1925, 1976, 2028, 2080, 2133, 2187, 2241, 2296, 2352, 2408, 2465,
322 2523, 2581, 2640, 2700, 2760, 2821, 2883, 2945, 3008, 3072, 3136, 3201,
323 3267, 3333, 3400, 3468, 3536, 3605, 3675, 3745, 3816, 3888, 3960, 4033,
324 4107, 4181, 4256, 4332, 4408, 4485, 4563, 4641, 4720, 4800, 4880, 4961,
325 5043, 5125, 5208, 5292, 5376, 5461, 5547, 5633, 5720, 5808, 5896, 5985,
326 6075, 6165, 6256, 6348, 6440, 6533, 6627, 6721, 6816, 6912, 7008, 7105,
327 7203, 7301, 7400, 7500, 7600, 7701, 7803, 7905, 8008, 8112, 8216, 8321,
328 8427, 8533, 8640, 8748, 8856, 8965, 9075, 9185, 9296, 9408, 9520, 9633,
329 9747, 9861, 9976, 10092, 10208, 10325, 10443, 10561, 10680, 10800, 10920,
330 11041, 11163, 11285, 11408, 11532, 11656, 11781, 11907, 12033, 12160, 12288,
331 12416, 12545, 12675, 12805, 12936, 13068, 13200, 13333, 13467, 13601, 13736,
332 13872, 14008, 14145, 14283, 14421, 14560, 14700, 14840, 14981, 15123, 15265,
333 15408, 15552, 15696, 15841, 15987, 16133, 16280, 16428, 16576, 16725, 16875,
334 17025, 17176, 17328, 17480, 17633, 17787, 17941, 18096, 18252, 18408, 18565,
335 18723, 18881, 19040, 19200, 19360, 19521, 19683, 19845, 20008, 20172, 20336,
336 20501, 20667, 20833, 21000, 21168, 21336, 21505, 21675, 21845, 22016, 22188,
337 22360, 22533, 22707, 22881, 23056, 23232, 23408, 23585, 23763, 23941, 24120,
338 24300, 24480, 24661, 24843, 25025, 25208, 25392, 25576, 25761, 25947, 26133,
339 26320, 26508, 26696, 26885, 27075, 27265, 27456, 27648, 27840, 28033, 28227,
340 28421, 28616, 28812, 29008, 29205, 29403, 29601, 29800, 30000, 30200, 30401,
341 30603, 30805, 31008, 31212, 31416, 31621, 31827, 32033, 32240, 32448, 32656,
342 32865, 33075, 33285, 33496, 33708, 33920, 34133, 34347, 34561, 34776, 34992,
343 35208, 35425, 35643, 35861, 36080, 36300, 36520, 36741, 36963, 37185, 37408,
344 37632, 37856, 38081, 38307, 38533, 38760, 38988, 39216, 39445, 39675, 39905,
345 40136, 40368, 40600, 40833, 41067, 41301, 41536, 41772, 42008, 42245, 42483,
346 42721, 42960, 43200, 43440, 43681, 43923, 44165, 44408, 44652, 44896, 45141,
347 45387, 45633, 45880, 46128, 46376, 46625, 46875, 47125, 47376, 47628, 47880,
348 48133, 48387, 48641, 48896, 49152, 49408, 49665, 49923, 50181, 50440, 50700,
349 50960, 51221, 51483, 51745, 52008, 52272, 52536, 52801, 53067, 53333, 53600,
350 53868, 54136, 54405, 54675, 54945, 55216, 55488, 55760, 56033, 56307, 56581,
351 56856, 57132, 57408, 57685, 57963, 58241, 58520, 58800, 59080, 59361, 59643,
352 59925, 60208, 60492, 60776, 61061, 61347, 61633, 61920, 62208, 62496, 62785,
353 63075, 63365, 63656, 63948, 64240, 64533, 64827, 65121, 65416, 65712, 66008,
354 66305, 66603, 66901, 67200, 67500, 67800, 68101, 68403, 68705, 69008, 69312,
355 69616, 69921, 70227, 70533, 70840, 71148, 71456, 71765, 72075, 72385, 72696,
356 73008, 73320, 73633, 73947, 74261, 74576, 74892, 75208, 75525, 75843, 76161,
357 76480, 76800, 77120, 77441, 77763, 78085, 78408, 78732, 79056, 79381, 79707,
358 80033, 80360, 80688, 81016, 81345, 81675, 82005, 82336, 82668, 83000, 83333,
359 83667, 84001, 84336, 84672, 85008, 85345, 85683, 86021, 86360, 86700, 87040,
360 87381, 87723, 88065, 88408, 88752, 89096, 89441, 89787, 90133, 90480, 90828,
361 91176, 91525, 91875, 92225, 92576, 92928, 93280, 93633, 93987, 94341, 94696,
362 95052, 95408, 95765, 96123, 96481, 96840, 97200, 97560, 97921, 98283, 98645,
363 99008, 99372, 99736, 100101, 100467, 100833, 101200, 101568, 101936, 102305,
364 102675, 103045, 103416, 103788, 104160, 104533, 104907, 105281, 105656,
365 106032, 106408, 106785, 107163, 107541, 107920, 108300, 108680, 109061,
366 109443, 109825, 110208, 110592, 110976, 111361, 111747, 112133, 112520,
367 112908, 113296, 113685, 114075, 114465, 114856, 115248, 115640, 116033,
368 116427, 116821, 117216, 117612, 118008, 118405, 118803, 119201, 119600,
369 120000, 120400, 120801, 121203, 121605, 122008, 122412, 122816, 123221,
370 123627, 124033, 124440, 124848, 125256, 125665, 126075, 126485, 126896,
371 127308, 127720, 128133, 128547, 128961, 129376, 129792, 130208, 130625,
372 131043, 131461, 131880, 132300, 132720, 133141, 133563, 133985, 134408,
373 134832, 135256, 135681, 136107, 136533, 136960, 137388, 137816, 138245,
374 138675, 139105, 139536, 139968, 140400, 140833, 141267, 141701, 142136,
375 142572, 143008, 143445, 143883, 144321, 144760, 145200, 145640, 146081,
376 146523, 146965, 147408, 147852, 148296, 148741, 149187, 149633, 150080,
377 150528, 150976, 151425, 151875, 152325, 152776, 153228, 153680, 154133,
378 154587, 155041, 155496, 155952, 156408, 156865, 157323, 157781, 158240,
379 158700, 159160, 159621, 160083, 160545, 161008, 161472, 161936, 162401,
380 162867, 163333, 163800, 164268, 164736, 165205, 165675, 166145, 166616,
381 167088, 167560, 168033, 168507, 168981, 169456, 169932, 170408, 170885,
382 171363, 171841, 172320, 172800, 173280, 173761, 174243, 174725, 175208,
383 175692, 176176, 176661, 177147, 177633, 178120, 178608, 179096, 179585,
384 180075, 180565, 181056, 181548, 182040, 182533, 183027, 183521, 184016,
385 184512, 185008, 185505, 186003, 186501, 187000, 187500, 188000, 188501,
386 189003, 189505, 190008, 190512, 191016, 191521, 192027, 192533, 193040,
387 193548, 194056, 194565, 195075
398 int next_[NPALETTE_];
405 std::fill_n(index_, NCLASS_, -1);
406 for (
int i = 0;
i < NPALETTE_; ++
i) {
407 int k = palette[
i].red + palette[
i].green + palette[
i].blue;
408 next_[
i] = index_[
k];
438 while (
p >= 0 &&
p < NPALETTE_) {
441 unsigned long diff = distance_(
color, palette[
p]);
455 while (
p >= 0 &&
p < NPALETTE_) {
458 unsigned long diff = distance_(
color, palette[
p]);