static int[] GetHistogram(Color[] pixels)
            {
                var size      = 1 << (3 * SIGBITS);
                var histogram = new int[size];
                int index;

                foreach (var pixel in pixels)
                {
                    index = MMCQ.GetColorIndex(
                        pixel.R >> RSHIFT,
                        pixel.G >> RSHIFT,
                        pixel.B >> RSHIFT
                        );
                    histogram[index] = histogram[index] + 1;
                }

                return(histogram);
            }
            public int GetCount(bool forced = false)
            {
                if (!_count_set || forced)
                {
                    int numpix = 0, index;

                    for (int r = R1; r <= R2; r++)
                    {
                        for (int g = G1; g <= G2; g++)
                        {
                            for (int b = B1; b <= B2; b++)
                            {
                                index   = MMCQ.GetColorIndex(r, g, b);
                                numpix += _histogram[index];
                            }
                        }
                    }
                    _count_set = true;
                    _count     = numpix;
                }
                return(_count);
            }
 public Color GetAverage(bool forced = false)
 {
     if (!_average_set || forced)
     {
         int mult = 1 << (8 - MMCQ.SIGBITS), total = 0, rsum = 0, gsum = 0, bsum = 0, index, hval;
         for (int r = R1; r <= R2; r++)
         {
             for (int g = G1; g <= G2; g++)
             {
                 for (int b = B1; b <= B2; b++)
                 {
                     index  = MMCQ.GetColorIndex(r, g, b);
                     hval   = _histogram[index];
                     total += hval;
                     rsum  += (int)(hval * (r + .5) * mult);
                     gsum  += (int)(hval * (g + .5) * mult);
                     bsum  += (int)(hval * (b + .5) * mult);
                 }
             }
         }
         if (total > 0)
         {
             _average = Color.FromArgb(~~(rsum / total), ~~(gsum / total), ~~(bsum / total));
         }
         else
         {
             _average = Color.FromArgb(
                 ~~(mult * (R1 + R2 + 1) / 2) - 1,
                 ~~(mult * (G1 + G2 + 1) / 2) - 1,
                 ~~(mult * (B1 + B2 + 1) / 2) - 1
                 );
         }
     }
     _average_set = true;
     return(_average);
 }
            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);
            }