package li.tengfei.apng.opt.optimizer;

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * color simulation mapper
 *
 * @author ltf
 * @since 17/1/3, 下午12:37
 */
public class ColorSimuMapper extends BaseColorMapper {
    private static final int R = 10;
    private static final int MAX_DIST = 128;
    private Random rand = new Random();

    @Override
    protected void genIndexedImage(Color[] pixels, int height, Map<Color, Color> colorMap, HashMap<Color, Integer> colorIndex, Mapping mapping) {
        super.genIndexedImage(pixels, height, colorMap, colorIndex, mapping);

        int width = pixels.length / height;

        byte[] centers = new byte[4 * R * R];
        byte[] indexes = new byte[mapping.pixelIndexes.length];
        //Color[] centers = new Color[R * R];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pa = y * width + x;
                Color A = pixels[pa];
                int yl = 0 < y - R ? y - R : 0;
                int yh = height - 1 < y + R ? height - 1 : y + R;
                int xl = 0 < x - R ? x - R : 0;
                int xh = width - 1 < x + R ? width - 1 : x + R;

                int i = 0;
                for (int yy = yl; yy < yh; yy++) {
                    for (int xx = xl; xx < xh; xx++) {
                        // calculate circle range
                        if ((xx - x) * (xx - x) + (yy - y) * (yy - y) > R * R) continue;
                        int pb = yy * width + xx;
                        Color B = mapping.colorTable[mapping.pixelIndexes[pb] & 0xff];
                        if (ColorUtils.distance(A, B) > MAX_DIST) continue;
                        centers[i++] = mapping.pixelIndexes[pb];
                    }
                }
                if (i > 0)
                    indexes[pa] = centers[rand.nextInt(i)];
                else
                    indexes[pa] = mapping.pixelIndexes[pa];
            }
        }
        mapping.pixelIndexes = indexes;
    }
}

@@ -725,16 +725,111 @@
     
-byte%5B%5D i
+int%5B%5D dists = new int%5B4 * R * R%5D;%0A        byte%5B%5D indexes = mapping.pixelIndexes;%0A        mapping.pixelI
 ndex
@@ -1333,17 +1333,34 @@
     int 
-i
+count = 0, distSum
  = 0;%0A  
@@ -1690,59 +1690,573 @@
 B = 
-mapping.colorTable%5Bmapping.pixelInde
+pixels%5Bpb%5D;%0A                        distSum += ColorUtils.distance(A, B);%0A                        count++;%0A                    %7D%0A                %7D%0A%0A                int distAvg = distSum / count + 1;%0A                int i = 0;%0A                for (int yy = yl; yy %3C yh; yy++) %7B%0A                    for (int xx = xl; xx %3C xh; xx++) %7B%0A                        // calculate circle range%0A                        if ((xx - x) * (xx - x) + (yy - y) * (yy - y) %3E R * R) continue;%0A                        int pb = yy * width + xx;%0A                        Color B = pi
 xe
+l
 s%5Bpb%5D
- & 0xff%5D
 ;%0A  
@@ -2278,19 +2278,26 @@
        i
-f (
+nt dist = 
 ColorUti
@@ -2313,16 +2313,68 @@
 ce(A, B)
+;%0A                        if (dist %3E distAvg %7C%7C dist
  %3E MAX_D
@@ -2425,28 +2425,13 @@
 rs%5Bi
-++
 %5D = 
-mapping.pixelI
+i
 ndex
@@ -2434,24 +2434,120 @@
 ndexes%5Bpb%5D;%0A
+                        dists%5Bi++%5D = (R * R) / ((xx - x) * (xx - x) + (yy - y) * (yy - y) + 1);%0A
             
@@ -2566,32 +2566,33 @@
               %7D%0A
+%0A
                 
@@ -2601,16 +2601,18 @@
  (i %3E 0)
+ %7B
 %0A       
@@ -2630,100 +2630,341 @@
   in
-dexes%5Bpa%5D = centers%5Brand.nextInt(i)%5D;%0A                else%0A                    indexes%5Bpa%5D =
+t disAll = 0;%0A                    for (int dis : dists) disAll += dis;%0A                    int idx = rand.nextInt(i);%0A                    disAll -= dists%5Bi%5D;%0A                    while (disAll %3E 0) %7B%0A                        idx = rand.nextInt(i);%0A                        disAll -= dists%5Bidx%5D;%0A                    %7D%0A                   
  map
@@ -2980,24 +2980,39 @@
 lIndexes%5Bpa%5D
+ = centers%5Bidx%5D
 ;%0A          
@@ -3005,33 +3005,44 @@
 x%5D;%0A            
-%7D
+    %7D else %7B
 %0A        %7D%0A     
@@ -3026,34 +3026,36 @@
  else %7B%0A        
-%7D%0A
+    
         mapping.
@@ -3066,16 +3066,20 @@
 lIndexes
+%5Bpa%5D
  = index
@@ -3076,22 +3076,68 @@
 a%5D = indexes
-;
+%5Bpa%5D;%0A                %7D%0A            %7D%0A        %7D
 %0A    %7D%0A%7D%0A

optimize color simulate params