Esempio n. 1
0
 private static long Bottom(Box cube, int direction, long[] moment)
 {
     switch (direction){
         case 0:
             return -moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)] +
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)] -
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
         case 1:
             return -moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)] +
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)] +
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)] -
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
         case 2:
             return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)] +
                     moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)] -
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)] -
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
         case 3:
             return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)] +
                     moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)] -
                     moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)] -
                     moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)] -
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)] +
                     moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
         default:
             throw new ArgumentOutOfRangeException(nameof(direction));
     }
 }
Esempio n. 2
0
        private double Maximize(Box cube, int direction, int first, int last, out int cut, double wholeR, double wholeG,
			double wholeB, double wholeA, double wholeW)
        {
            long baseR = Bottom(cube, direction, vmr);
            long baseG = Bottom(cube, direction, vmg);
            long baseB = Bottom(cube, direction, vmb);
            long baseA = Bottom(cube, direction, vma);
            long baseW = Bottom(cube, direction, vwt);
            double max = 0.0;
            cut = -1;
            for (int i = first; i < last; i++){
                double halfR = baseR + Top(cube, direction, i, vmr);
                double halfG = baseG + Top(cube, direction, i, vmg);
                double halfB = baseB + Top(cube, direction, i, vmb);
                double halfA = baseA + Top(cube, direction, i, vma);
                double halfW = baseW + Top(cube, direction, i, vwt);
                double temp;
                if (Math.Abs(halfW) < Epsilon){
                    continue;
                }
                temp = ((halfR*halfR) + (halfG*halfG) + (halfB*halfB) + (halfA*halfA))/halfW;
                halfR = wholeR - halfR;
                halfG = wholeG - halfG;
                halfB = wholeB - halfB;
                halfA = wholeA - halfA;
                halfW = wholeW - halfW;
                if (Math.Abs(halfW) < Epsilon){
                    continue;
                }
                temp += ((halfR*halfR) + (halfG*halfG) + (halfB*halfB) + (halfA*halfA))/halfW;
                if (temp > max){
                    max = temp;
                    cut = i;
                }
            }
            return max;
        }
Esempio n. 3
0
 private double Variance(Box cube)
 {
     double dr = Volume(cube, vmr);
     double dg = Volume(cube, vmg);
     double db = Volume(cube, vmb);
     double da = Volume(cube, vma);
     double xx = m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)] -
                 m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)] - m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)] +
                 m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)] - m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)] +
                 m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)] + m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)] -
                 m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)] - m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)] +
                 m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)] + m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)] -
                 m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)] + m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)] -
                 m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)] - m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)] +
                 m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
     return xx - (((dr*dr) + (dg*dg) + (db*db) + (da*da))/Volume(cube, vwt));
 }
Esempio n. 4
0
 private void Mark(Box cube, byte label)
 {
     for (int r = cube.R0 + 1; r <= cube.R1; r++){
         for (int g = cube.G0 + 1; g <= cube.G1; g++){
             for (int b = cube.B0 + 1; b <= cube.B1; b++){
                 for (int a = cube.A0 + 1; a <= cube.A1; a++){
                     tag[GetPaletteIndex(r, g, b, a)] = label;
                 }
             }
         }
     }
 }
Esempio n. 5
0
 private QuantizedImage GenerateResult(IPixelAccessor imagePixels, int colorCount, Box[] cube)
 {
     List<Color2> pallette = new List<Color2>();
     byte[] pixels = new byte[imagePixels.Width*imagePixels.Height];
     int transparentIndex = -1;
     int width = imagePixels.Width;
     int height = imagePixels.Height;
     for (int k = 0; k < colorCount; k++){
         Mark(cube[k], (byte) k);
         double weight = Volume(cube[k], vwt);
         if (Math.Abs(weight) > Epsilon){
             byte r = (byte) (Volume(cube[k], vmr)/weight);
             byte g = (byte) (Volume(cube[k], vmg)/weight);
             byte b = (byte) (Volume(cube[k], vmb)/weight);
             byte a = (byte) (Volume(cube[k], vma)/weight);
             Color2 color = Color2.FromArgb(a,r, g, b);
             if (color.Equals(default(Color2))){
                 transparentIndex = k;
             }
             pallette.Add(color);
         } else{
             pallette.Add(default(Color2));
             transparentIndex = k;
         }
     }
     Parallel.For(0, height, Bootstrapper.instance.ParallelOptions, y =>{
         for (int x = 0; x < width; x++){
             // Expected order r->g->b->a
             byte[] color = imagePixels[x, y].ToBytes();
             int r = color[0] >> (8 - IndexBits);
             int g = color[1] >> (8 - IndexBits);
             int b = color[2] >> (8 - IndexBits);
             int a = color[3] >> (8 - IndexAlphaBits);
             if (transparentIndex > -1 && color[3] <= Threshold){
                 pixels[(y*width) + x] = (byte) transparentIndex;
                 continue;
             }
             int ind = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1);
             pixels[(y*width) + x] = tag[ind];
         }
     });
     return new QuantizedImage(width, height, pallette.ToArray(), pixels, transparentIndex);
 }
Esempio n. 6
0
 private bool Cut(Box set1, Box set2)
 {
     double wholeR = Volume(set1, vmr);
     double wholeG = Volume(set1, vmg);
     double wholeB = Volume(set1, vmb);
     double wholeA = Volume(set1, vma);
     double wholeW = Volume(set1, vwt);
     int cutr;
     int cutg;
     int cutb;
     int cuta;
     double maxr = Maximize(set1, 0, set1.R0 + 1, set1.R1, out cutr, wholeR, wholeG, wholeB, wholeA, wholeW);
     double maxg = Maximize(set1, 1, set1.G0 + 1, set1.G1, out cutg, wholeR, wholeG, wholeB, wholeA, wholeW);
     double maxb = Maximize(set1, 2, set1.B0 + 1, set1.B1, out cutb, wholeR, wholeG, wholeB, wholeA, wholeW);
     double maxa = Maximize(set1, 3, set1.A0 + 1, set1.A1, out cuta, wholeR, wholeG, wholeB, wholeA, wholeW);
     int dir;
     if ((maxr >= maxg) && (maxr >= maxb) && (maxr >= maxa)){
         dir = 0;
         if (cutr < 0){
             return false;
         }
     } else if ((maxg >= maxr) && (maxg >= maxb) && (maxg >= maxa)){
         dir = 1;
     } else if ((maxb >= maxr) && (maxb >= maxg) && (maxb >= maxa)){
         dir = 2;
     } else{
         dir = 3;
     }
     set2.R1 = set1.R1;
     set2.G1 = set1.G1;
     set2.B1 = set1.B1;
     set2.A1 = set1.A1;
     switch (dir){
         case 0:
             set2.R0 = set1.R1 = cutr;
             set2.G0 = set1.G0;
             set2.B0 = set1.B0;
             set2.A0 = set1.A0;
             break;
         case 1:
             set2.G0 = set1.G1 = cutg;
             set2.R0 = set1.R0;
             set2.B0 = set1.B0;
             set2.A0 = set1.A0;
             break;
         case 2:
             set2.B0 = set1.B1 = cutb;
             set2.R0 = set1.R0;
             set2.G0 = set1.G0;
             set2.A0 = set1.A0;
             break;
         case 3:
             set2.A0 = set1.A1 = cuta;
             set2.R0 = set1.R0;
             set2.G0 = set1.G0;
             set2.B0 = set1.B0;
             break;
     }
     set1.Volume = (set1.R1 - set1.R0)*(set1.G1 - set1.G0)*(set1.B1 - set1.B0)*(set1.A1 - set1.A0);
     set2.Volume = (set2.R1 - set2.R0)*(set2.G1 - set2.G0)*(set2.B1 - set2.B0)*(set2.A1 - set2.A0);
     return true;
 }
Esempio n. 7
0
 private void BuildCube(out Box[] cube, ref int colorCount)
 {
     cube = new Box[colorCount];
     double[] vv = new double[colorCount];
     for (int i = 0; i < colorCount; i++){
         cube[i] = new Box();
     }
     cube[0].R0 = cube[0].G0 = cube[0].B0 = cube[0].A0 = 0;
     cube[0].R1 = cube[0].G1 = cube[0].B1 = IndexCount - 1;
     cube[0].A1 = IndexAlphaCount - 1;
     int next = 0;
     for (int i = 1; i < colorCount; i++){
         if (Cut(cube[next], cube[i])){
             vv[next] = cube[next].Volume > 1 ? Variance(cube[next]) : 0.0;
             vv[i] = cube[i].Volume > 1 ? Variance(cube[i]) : 0.0;
         } else{
             vv[next] = 0.0;
             i--;
         }
         next = 0;
         double temp = vv[0];
         for (int k = 1; k <= i; k++){
             if (vv[k] > temp){
                 temp = vv[k];
                 next = k;
             }
         }
         if (temp <= 0.0){
             colorCount = i + 1;
             break;
         }
     }
 }
Esempio n. 8
0
 private static double Volume(Box cube, long[] moment)
 {
     return moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)] -
             moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)] -
             moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)] +
             moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)] -
             moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)] +
             moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)] +
             moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)] -
             moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)] -
             moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)] +
             moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)] +
             moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)] -
             moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)] +
             moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)] -
             moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)] -
             moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)] +
             moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
 }