@Override
  public float get_unsafe(float x, float y) {
    int xx = (int) x;
    int yy = (int) y;

    final int radius = kernel.getRadius();
    final int width = kernel.getWidth();

    int x0 = xx - radius;
    int x1 = x0 + width;

    int y0 = yy - radius;
    int y1 = y0 + width;

    float value = 0;
    for (int i = y0; i < y1; i++) {
      int indexSrc = image.startIndex + i * image.stride + x0;
      float valueX = 0;
      for (int j = x0; j < x1; j++) {
        float w = kernel.compute(j - x);
        valueX += w * (image.data[indexSrc++] & 0xFF);
      }
      float w = kernel.compute(i - y);
      value += w * valueX;
    }

    if (value > max) return max;
    else if (value < min) return min;
    else return value;
  }
  @Override
  public float get(float x, float y) {

    int xx = (int) x;
    int yy = (int) y;

    final int radius = kernel.getRadius();
    final int width = kernel.getWidth();

    int x0 = xx - radius;
    int x1 = x0 + width;

    int y0 = yy - radius;
    int y1 = y0 + width;

    if (x0 < 0) x0 = 0;
    if (x1 > image.width) x1 = image.width;

    if (y0 < 0) y0 = 0;
    if (y1 > image.height) y1 = image.height;

    float value = 0;
    float totalWeightY = 0;
    for (int i = y0; i < y1; i++) {
      int indexSrc = image.startIndex + i * image.stride + x0;
      float totalWeightX = 0;
      float valueX = 0;
      for (int j = x0; j < x1; j++) {
        float w = kernel.compute(j - x);
        totalWeightX += w;
        valueX += w * (image.data[indexSrc++] & 0xFF);
      }
      float w = kernel.compute(i - y);
      totalWeightY += w;
      value += w * valueX / totalWeightX;
    }

    value /= totalWeightY;

    if (value > max) return max;
    else if (value < min) return min;
    else return value;
  }
 @Override
 public int getUnsafeBorderY() {
   return kernel.getRadius();
 }
  @Override
  public boolean isInSafeBounds(float x, float y) {
    float r = kernel.getRadius();

    return (x - r >= 0 && y - r >= 0 && x + r < image.width && y + r < image.height);
  }