import jdk.incubator.vector.*; final sclass BWIntegralImage_vectorized implements MakesBufferedImage, IBWIntegralImage { int w, h; int vecShift; // vector size used as dual log int[] data; // 1 entry per pixel ifdef BWIntegralImage_CountAccesses long accesses; endifdef *() {} *(File f) { this(loadImage2(f)); } *(MakesBufferedImage img) { this(toBufferedImage(img)); } //*(BufferedImage img) { this(BWImage(img)); } *(BufferedImage image) ctex { alloc(image.getWidth(), image.getHeight()); // Just grab directly into data array PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, w, h, data, 0, w); if (!pixelGrabber.grabPixels()) fail("Could not grab pixels"); VectorSpecies species = IntVector.SPECIES_PREFERRED; vecShift = dualLog(species.length()); // for brightness of pixels, // for now we cheat by just using one of the channels int[] data = new[256]; for i over data: data[i] = i + (i << 8) + (i << 16); int upperBound = species.loopBound(data.length); int i = 0, sum = 0; for (; i < upperBound; i += species.length()) { IntVector v = IntVector.fromArray(species, data, i); v = v.and(255).add(sum); v.intoArray(data, i); sum += v.reduceLanes(VectorOperators.ADD); } for (; i < data.length; i++) { data[i] = (data[i] & 255) + sum; } } private void alloc(int w, int h) { this.w = w; this.h = h; if (w*h > 8*1024*1024) fail("Image too large (more than 8 MP): " + w + "*" + h); data = new int[w*h]; } // pixels outside of image are considered black int get(int x, int y) { ifdef BWIntegralImage_CountAccesses ++accesses; endifdef ret x < 0 || y < 0 || x >= w || y >= h ? 0 : data[min(y, h-1)*w+min(x, w-1)]; } public double getPixelAverage(int x1, int y1, int x2, int y2) { int area = (x2-x1)*(y2-y1); ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area); } int getPixel(int x, int y) { ret bwIntegralImage_sumRect(this, x, y, x+1, y+1); } int getPixel(Pt p) { ret getPixel(p.x, p.y); } public int getWidth() { ret w; } public int getHeight() { ret h; } // unoptimized public BufferedImage getBufferedImage() { ret scaleDownUsingIntegralImageBW(this, w).getBufferedImage(); } }