Пример #1
0
            public static Block Encode(List <RGB> colors)
            {
                // regular case: just try our best to compress and minimise error
                var bestsolns = new SolutionSet();

                foreach (var flip in new[] { false, true })
                {
                    var pixels = new[] { 0, 1 }.Select(i => colors.Where((c, j) => (j / (flip ? 2 : 8)) % 2 == i).ToArray()).ToArray();
                    foreach (var diff in new[] { false, true })                     // let's again just assume no diff
                    {
                        var solns = new Solution[2];
                        int limit = diff ? 32 : 16;
                        int i;
                        for (i = 0; i < 2; i++)
                        {
                            var errorThreshold = bestsolns.TotalError;
                            if (i == 1)
                            {
                                errorThreshold -= solns[0].error;
                            }
                            var opt = new Optimizer(pixels[i], limit, errorThreshold);
                            if (i == 1 && diff)
                            {
                                opt.baseColor = solns[0].blockColor;
                                if (!opt.ComputeDeltas(-4, -3, -2, -1, 0, 1, 2, 3))
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (!opt.ComputeDeltas(-4, -3, -2, -1, 0, 1, 2, 3, 4))
                                {
                                    break;
                                }
                                // TODO: Fix fairly arbitrary/unrefined thresholds that control how far away to scan for potentially better solutions.
                                if (opt.best_soln.error > 9000)
                                {
                                    if (opt.best_soln.error > 18000)
                                    {
                                        opt.ComputeDeltas(-8, -7, -6, -5, 5, 6, 7, 8);
                                    }
                                    else
                                    {
                                        opt.ComputeDeltas(-5, 5);
                                    }
                                }
                            }
                            if (opt.best_soln.error >= errorThreshold)
                            {
                                break;
                            }
                            solns[i] = opt.best_soln;
                        }
                        if (i == 2)
                        {
                            var solnset = new SolutionSet(flip, diff, solns[0], solns[1]);
                            if (solnset.TotalError < bestsolns.TotalError)
                            {
                                bestsolns = solnset;
                            }
                        }
                    }
                }
                return(bestsolns.ToBlock());
            }