// This is currently still very brute-forcey. Can be improved in the future public static bool RepackEtc1CompressedBlock(List <RGB> colors, out Block block) { foreach (var flip in new[] { false, true }) { var allpixels0 = colors.Where((c, j) => (j / (flip ? 2 : 8)) % 2 == 0).ToArray(); var pixels0 = allpixels0.Distinct().ToArray(); if (pixels0.Count() > 4) { continue; } var allpixels1 = colors.Where((c, j) => (j / (flip ? 2 : 8)) % 2 == 1).ToArray(); var pixels1 = allpixels1.Distinct().ToArray(); if (pixels1.Count() > 4) { continue; } foreach (var diff in new[] { false, true }) { if (!diff) { var tables0 = Enumerable.Range(0, 8).Where(i => pixels0.All(c => lookup16[i][c.R] && lookup16[i][c.G] && lookup16[i][c.B])).ToList(); if (!tables0.Any()) { continue; } var tables1 = Enumerable.Range(0, 8).Where(i => pixels1.All(c => lookup16[i][c.R] && lookup16[i][c.G] && lookup16[i][c.B])).ToList(); if (!tables1.Any()) { continue; } var opt0 = new Optimizer(allpixels0, 16, 1); Solution soln0 = null; foreach (var ti in tables0) { var rs = Enumerable.Range(0, 16).Where(a => pixels0.All(c => lookup16big[ti][a].Contains(c.R))).ToArray(); var gs = Enumerable.Range(0, 16).Where(a => pixels0.All(c => lookup16big[ti][a].Contains(c.G))).ToArray(); var bs = Enumerable.Range(0, 16).Where(a => pixels0.All(c => lookup16big[ti][a].Contains(c.B))).ToArray(); soln0 = opt0.FindExactMatches(from r in rs from g in gs from b in bs select new RGB(r, g, b), modifiers[ti]).FirstOrDefault(); if (soln0 != null) { break; } } if (soln0 == null) { continue; } var opt1 = new Optimizer(allpixels1, 16, 1); Solution soln1 = null; foreach (var ti in tables1) { var rs = Enumerable.Range(0, 16).Where(a => pixels1.All(c => lookup16big[ti][a].Contains(c.R))).ToArray(); var gs = Enumerable.Range(0, 16).Where(a => pixels1.All(c => lookup16big[ti][a].Contains(c.G))).ToArray(); var bs = Enumerable.Range(0, 16).Where(a => pixels1.All(c => lookup16big[ti][a].Contains(c.B))).ToArray(); soln1 = opt1.FindExactMatches(from r in rs from g in gs from b in bs select new RGB(r, g, b), modifiers[ti]).FirstOrDefault(); if (soln1 != null) { block = new SolutionSet(flip, diff, soln0, soln1).ToBlock(); return(true); } } } else { var tables0 = Enumerable.Range(0, 8).Where(i => pixels0.All(c => lookup32[i][c.R] && lookup32[i][c.G] && lookup32[i][c.B])).ToList(); if (!tables0.Any()) { continue; } var tables1 = Enumerable.Range(0, 8).Where(i => pixels1.All(c => lookup32[i][c.R] && lookup32[i][c.G] && lookup32[i][c.B])).ToList(); if (!tables1.Any()) { continue; } var opt0 = new Optimizer(allpixels0, 32, 1); var solns0 = new List <Solution>(); foreach (var ti in tables0) { var rs = Enumerable.Range(0, 32).Where(a => pixels0.All(c => lookup32big[ti][a].Contains(c.R))).ToArray(); var gs = Enumerable.Range(0, 32).Where(a => pixels0.All(c => lookup32big[ti][a].Contains(c.G))).ToArray(); var bs = Enumerable.Range(0, 32).Where(a => pixels0.All(c => lookup32big[ti][a].Contains(c.B))).ToArray(); solns0.AddRange(opt0.FindExactMatches(from r in rs from g in gs from b in bs select new RGB(r, g, b), modifiers[ti])); } if (!solns0.Any()) { continue; } var opt1 = new Optimizer(allpixels1, 32, 1); foreach (var ti in tables1) { var rs = Enumerable.Range(0, 32).Where(a => pixels1.All(c => lookup32big[ti][a].Contains(c.R))).ToArray(); var gs = Enumerable.Range(0, 32).Where(a => pixels1.All(c => lookup32big[ti][a].Contains(c.G))).ToArray(); var bs = Enumerable.Range(0, 32).Where(a => pixels1.All(c => lookup32big[ti][a].Contains(c.B))).ToArray(); foreach (var soln0 in solns0) { var q = (from r in rs let dr = r - soln0.blockColor.R where dr >= -4 && dr < 4 from g in gs let dg = g - soln0.blockColor.G where dg >= -4 && dg < 4 from b in bs let db = b - soln0.blockColor.B where db >= -4 && db < 4 select new RGB(r, g, b)); var soln1 = opt1.FindExactMatches(q, modifiers[ti]).FirstOrDefault(); if (soln1 != null) { block = new SolutionSet(flip, diff, soln0, soln1).ToBlock(); return(true); } } } } } } block = default(Block); return(false); }