@Override
  protected int[] filterPixels(int width, int height, int[] inPixels, Rect transformedSpace) {
    int index = 0;
    int[] outPixels = new int[width * height];

    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        int pixel = 0xffffffff;
        for (int dy = -ySize; dy <= ySize; dy++) {
          int iy = y + dy;
          int ioffset;
          if (0 <= iy && iy < height) {
            ioffset = iy * width;
            for (int dx = -xSize; dx <= xSize; dx++) {
              int ix = x + dx;
              if (0 <= ix && ix < width) {
                pixel = PixelUtils.combinePixels(pixel, inPixels[ioffset + ix], PixelUtils.MIN);
              }
            }
          }
        }
        outPixels[index++] = pixel;
      }
    }
    return outPixels;
  }
  public int[] filter(int[] src, int w, int h) {
    int width = w;
    int height = h;

    int[] inPixels = src;
    int[] outPixels = new int[width * height];

    // float sinAngle = (float)Math.sin(angle);
    // float cosAngle = (float)Math.cos(angle);

    // float total;
    int cx = width / 2;
    int cy = height / 2;
    int index = 0;

    float imageRadius = (float) Math.sqrt(cx * cx + cy * cy);
    float translateX = (float) (distance * Math.cos(angle));
    float translateY = (float) (distance * -Math.sin(angle));
    float maxDistance = distance + Math.abs(rotation * imageRadius) + zoom * imageRadius;
    int repetitions = (int) maxDistance;
    Matrix t = new Matrix();
    float[] p = new float[2];

    if (premultiplyAlpha) ImageMath.premultiply(inPixels, 0, inPixels.length);

    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        int a = 0, r = 0, g = 0, b = 0;
        int count = 0;
        for (int i = 0; i < repetitions; i++) {
          int newX = x, newY = y;
          float f = (float) i / repetitions;

          p[0] = x;
          p[1] = y;
          t.reset();
          t.preTranslate(cx + f * translateX, cy + f * translateY);
          float s = 1 - zoom * f;
          t.preScale(s, s);

          if (rotation != 0) {
            t.preRotate(-rotation * f);
          }

          t.preTranslate(-cx, -cy);
          t.mapPoints(p, p);
          newX = (int) p[0];
          newY = (int) p[1];

          if (newX < 0 || newX >= width) {
            if (wrapEdges) newX = ImageMath.mod(newX, width);
            else break;
          }
          if (newY < 0 || newY >= height) {
            if (wrapEdges) newY = ImageMath.mod(newY, height);
            else break;
          }

          count++;
          int rgb = inPixels[newY * width + newX];
          a += (rgb >> 24) & 0xff;
          r += (rgb >> 16) & 0xff;
          g += (rgb >> 8) & 0xff;
          b += rgb & 0xff;
        }
        if (count == 0) {
          outPixels[index] = inPixels[index];
        } else {
          a = PixelUtils.clamp((int) (a / count));
          r = PixelUtils.clamp((int) (r / count));
          g = PixelUtils.clamp((int) (g / count));
          b = PixelUtils.clamp((int) (b / count));
          outPixels[index] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        index++;
      }
    }
    if (premultiplyAlpha) {
      ImageMath.unpremultiply(outPixels, 0, inPixels.length);
    }
    return outPixels;
  }