private static Bc3Block FindAlphaValues(Bc3Block colorBlock, RawBlock4X4Rgba32 rawBlock, int variations)
        {
            var pixels = rawBlock.AsSpan;

            //Find min and max alpha
            byte minAlpha         = 255;
            byte maxAlpha         = 0;
            bool hasExtremeValues = false;

            for (int i = 0; i < pixels.Length; i++)
            {
                if (pixels[i].A < 255 && pixels[i].A > 0)
                {
                    if (pixels[i].A < minAlpha)
                    {
                        minAlpha = pixels[i].A;
                    }
                    if (pixels[i].A > maxAlpha)
                    {
                        maxAlpha = pixels[i].A;
                    }
                }
                else
                {
                    hasExtremeValues = true;
                }
            }


            int SelectAlphaIndices(ref Bc3Block block)
            {
                int         cumulativeError = 0;
                var         a0     = block.Alpha0;
                var         a1     = block.Alpha1;
                Span <byte> alphas = a0 > a1 ? stackalloc byte[] {
        private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0, ColorRgb565 color1, out float error, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f)
        {
            Bc3Block output = new Bc3Block();

            var pixels = rawBlock.AsSpan;

            output.color0 = color0;
            output.color1 = color1;

            var c0 = color0.ToColorRgb24();
            var c1 = color1.ToColorRgb24();

            ReadOnlySpan <ColorRgb24> colors = stackalloc ColorRgb24[] {
                c0,
                c1,
                c0 *(2.0 / 3.0) + c1 * (1.0 / 3.0),
                c0 *(1.0 / 3.0) + c1 * (2.0 / 3.0)
            };

            error = 0;
            for (int i = 0; i < 16; i++)
            {
                var color = pixels[i];
                output[i] = ColorChooser.ChooseClosestColor4(colors, color, rWeight, gWeight, bWeight, out var e);
                error    += e;
            }

            return(output);
        }
            internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock)
            {
                var pixels = rawBlock.AsSpan;

                PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa);
                PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max);

                var c0 = max;
                var c1 = min;

                Bc3Block best = TryColors(rawBlock, c0, c1, out float bestError);

                for (int i = 0; i < maxTries; i++)
                {
                    var(newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i);

                    var block = TryColors(rawBlock, newC0, newC1, out var error);

                    if (error < bestError)
                    {
                        best      = block;
                        bestError = error;
                        c0        = newC0;
                        c1        = newC1;
                    }

                    if (bestError < errorThreshold)
                    {
                        break;
                    }
                }
                best = FindAlphaValues(best, rawBlock, 5);
                return(best);
            }
            internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock)
            {
                var pixels = rawBlock.AsSpan;

                PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa);
                PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max);

                var c0 = max;
                var c1 = min;

                if (c0.data < c1.data)
                {
                    var c = c0;
                    c0 = c1;
                    c1 = c;
                }

                Bc3Block best = TryColors(rawBlock, c0, c1, out float bestError);

                int lastChanged = 0;

                for (int i = 0; i < maxTries; i++)
                {
                    var(newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i);

                    if (newC0.data < newC1.data)
                    {
                        var c = newC0;
                        newC0 = newC1;
                        newC1 = c;
                    }

                    var block = TryColors(rawBlock, newC0, newC1, out var error);

                    lastChanged++;

                    if (error < bestError)
                    {
                        best        = block;
                        bestError   = error;
                        c0          = newC0;
                        c1          = newC1;
                        lastChanged = 0;
                    }

                    if (bestError < errorThreshold || lastChanged > ColorVariationGenerator.VarPatternCount)
                    {
                        break;
                    }
                }

                best = FindAlphaValues(best, rawBlock, 8);
                return(best);
            }