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[(mod(srcY, srcHeight) * srcWidth) + mod(srcX, srcWidth)];
                        break;
                    case CLAMP:
                        p = inPixels[(clamp(srcY, 0, srcHeight-1) * srcWidth) + clamp(srcX, 0, srcWidth-1)];
                        break;
                    }
                    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;
    }