protected BufferedImage filterPixelsNN( BufferedImage dst, int width, int height, int[] inPixels, Rectangle transformedSpace) { int srcWidth = width; int srcHeight = height; int outWidth = transformedSpace.width; int outHeight = transformedSpace.height; int outX, outY, srcX, srcY; int[] outPixels = new int[outWidth]; outX = transformedSpace.x; outY = transformedSpace.y; int[] rgb = new int[4]; float[] out = new float[2]; for (int y = 0; y < outHeight; y++) { for (int x = 0; x < outWidth; x++) { transformInverse(outX + x, outY + y, out); srcX = (int) out[0]; srcY = (int) out[1]; // int casting rounds towards zero, so we check out[0] < 0, not srcX < 0 if (out[0] < 0 || srcX >= srcWidth || out[1] < 0 || srcY >= srcHeight) { int p; switch (edgeAction) { case ZERO: default: p = 0; break; case WRAP: p = inPixels[ (ImageMath.mod(srcY, srcHeight) * srcWidth) + ImageMath.mod(srcX, srcWidth)]; break; case CLAMP: p = inPixels[ (ImageMath.clamp(srcY, 0, srcHeight - 1) * srcWidth) + ImageMath.clamp(srcX, 0, srcWidth - 1)]; break; case RGB_CLAMP: p = inPixels[ (ImageMath.clamp(srcY, 0, srcHeight - 1) * srcWidth) + ImageMath.clamp(srcX, 0, srcWidth - 1)] & 0x00ffffff; } outPixels[x] = p; } else { int i = srcWidth * srcY + srcX; rgb[0] = inPixels[i]; outPixels[x] = inPixels[i]; } } setRGB(dst, 0, y, transformedSpace.width, 1, outPixels); } return dst; }
private final int getPixel(int[] pixels, int x, int y, int width, int height) { if (x < 0 || x >= width || y < 0 || y >= height) { switch (edgeAction) { case ZERO: default: return 0; case WRAP: return pixels[(ImageMath.mod(y, height) * width) + ImageMath.mod(x, width)]; case CLAMP: return pixels[ (ImageMath.clamp(y, 0, height - 1) * width) + ImageMath.clamp(x, 0, width - 1)]; case RGB_CLAMP: return pixels[ (ImageMath.clamp(y, 0, height - 1) * width) + ImageMath.clamp(x, 0, width - 1)] & 0x00ffffff; } } return pixels[y * width + x]; }
@Override protected void transformInverse(int x, int y, float[] out) { float dx = x - icentreX; float dy = y - icentreY; float theta = (float) Math.atan2(-dy, -dx) + angle; float r = (float) Math.sqrt(dx * dx + dy * dy); theta = ImageMath.mod(theta, 2 * (float) Math.PI); out[0] = iWidth * theta / (spreadAngle + 0.00001f); out[1] = iHeight * (1 - (r - radius) / (height + 0.00001f)); }