static ColorBox[] DoCut(ColorBox box, int[] partialSum, int[] lookAheadSum, int total, char color) { int dim1 = 0, dim2 = 0; switch (color) { case 'r': dim1 = box.R1; dim2 = box.R2; break; case 'g': dim1 = box.G1; dim2 = box.G2; break; case 'b': dim1 = box.B1; dim2 = box.B2; break; } for (int i = dim1; i <= dim2; i++) { if (partialSum[i] > (total / 2)) { ColorBox box1 = box.Copy(), box2 = box.Copy(); int left = i - dim1, right = dim2 - i, d2; if (left <= right) { d2 = Math.Min(dim2 - 1, ~~(i + right / 2)); } else { d2 = Math.Max(dim1, ~~(i - 1 - left / 2)); } while (partialSum[d2] == 0) { d2++; } int count2 = lookAheadSum[d2]; while (count2 == 0 && partialSum[d2 - 1] > 0) { count2 = lookAheadSum[--d2]; } switch (color) { case 'r': box1.R2 = d2; box2.R1 = d2 + 1; break; case 'g': box1.G2 = d2; box2.G1 = d2 + 1; break; case 'b': box1.B2 = d2; box2.B1 = d2 + 1; break; } //Console.WriteLine("cbox counts: " + (box.GetCount()) + ", " + (box1.GetCount()) + ", " + (box2.GetCount())); return(new ColorBox[2] { box1, box2 }); } } return(null); }
static ColorBox[] MedianCutApply(int[] histogram, ColorBox box) { if (box.GetCount() == 0) { return(null); } if (box.GetCount() == 1) { return new ColorBox[2] { box.Copy(), null } } ; int rw = box.R2 - box.R1 + 1, gw = box.G2 - box.G1 + 1, bw = box.B2 - box.B1 + 1, maxw = Math.Max(rw, Math.Max(gw, bw)), total = 0, sum, index; var partialSum = new int[0]; if (maxw == rw) { partialSum = new int[box.R2 + 1]; for (int r = box.R1; r <= box.R2; r++) { sum = 0; for (int g = box.G1; g <= box.G2; g++) { for (int b = box.B1; b <= box.B2; b++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[r] = total; } } else if (maxw == gw) { partialSum = new int[box.G2 + 1]; for (int g = box.G1; g <= box.G2; g++) { sum = 0; for (int r = box.R1; r <= box.R2; r++) { for (int b = box.B1; b <= box.B2; b++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[g] = total; } } else if (maxw == bw) { partialSum = new int[box.B2 + 1]; for (int b = box.B1; b <= box.B2; b++) { sum = 0; for (int r = box.R1; r <= box.R2; r++) { for (int g = box.G1; g <= box.G2; g++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[b] = total; } } var lookAheadSum = new int[partialSum.Length]; for (int i = 0; i < partialSum.Length; i++) { lookAheadSum[i] = total - partialSum[i]; } if (maxw == rw) { return(DoCut(box, partialSum, lookAheadSum, total, 'r')); } if (maxw == gw) { return(DoCut(box, partialSum, lookAheadSum, total, 'g')); } if (maxw == bw) { return(DoCut(box, partialSum, lookAheadSum, total, 'b')); } return(null); }