private BufferedImage parallaxBlur(BufferedImage im, BufferedImage depth, float dist, float angle){
        int[][] samplePoints = getLinePoints(dist, angle);
        
        // Populate data if not already there
        if(pixels == null || depth == null || dirty){
            pixels = pullPixelData(im);
            int[][][] allDepth = pullPixelData(depth);
            depths = new int[allDepth[0].length][allDepth[0][0].length];
            for(int x = 0; x < allDepth[0].length; x++){
                for(int y = 0; y < allDepth[0][0].length; y++){
                    depths[x][y] = (allDepth[0][x][y] + allDepth[1][x][y] + allDepth[2][x][y])/3;
                }
            }
            dirty = false;
        }
        
        int[][][] result = new int[pixels.length][pixels[0].length][pixels[0][0].length];
        
        if(!gpu){
        for (int y = 0; y < pixels[0][0].length; y++) {
            for (int x = 0; x < pixels[0].length; x++) {
                pBlur(samplePoints, pixels, depths, result, x, y, dist);
            }
        }
        } else {
        	List<Kernel> jobs = new ArrayList<Kernel>();
            for (int i = 0; i < pixels[0].length; i++) {
                jobs.add(new ParallaxKernel(samplePoints, pixels, depths, result, i,
                        pixels[0][0].length, dist));
            }
            
            Rootbeer rootbeer = new Rootbeer();
            rootbeer.runAll(jobs);
        }
        
        return packPixels(result, im.getData().getSampleModel(), im.getColorModel());
    }