1 | import jdk.incubator.vector.*; |
2 | |
3 | final sclass BWIntegralImage_vectorized implements MakesBufferedImage, IBWIntegralImage { |
4 | int w, h; |
5 | int vecShift; // vector size used as dual log |
6 | int[] data; // 1 entry per pixel |
7 | ifdef BWIntegralImage_CountAccesses |
8 | long accesses; |
9 | endifdef |
10 | |
11 | *() {} |
12 | *(File f) { this(loadImage2(f)); } |
13 | |
14 | *(MakesBufferedImage img) { this(toBufferedImage(img)); } |
15 | |
16 | //*(BufferedImage img) { this(BWImage(img)); } |
17 | |
18 | *(BufferedImage image) ctex { |
19 | alloc(image.getWidth(), image.getHeight()); |
20 | // Just grab directly into data array |
21 | PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, w, h, data, 0, w); |
22 | if (!pixelGrabber.grabPixels()) |
23 | fail("Could not grab pixels"); |
24 | |
25 | VectorSpecies<Int> species = IntVector.SPECIES_PREFERRED; |
26 | vecShift = dualLog(species.length()); |
27 | int upperBound = species.loopBound(w); |
28 | |
29 | // for brightness of pixels, |
30 | // for now we cheat by just using one of the channels |
31 | |
32 | // first row |
33 | int i = 0, sum = 0; |
34 | for (; i < upperBound; i += species.length()) { |
35 | IntVector v = IntVector.fromArray(species, data, i); |
36 | v = v.and(255).add(sum); |
37 | v.intoArray(data, i); |
38 | sum += v.reduceLanes(VectorOperators.ADD); |
39 | } |
40 | |
41 | for (; i < w; i++) |
42 | data[i] = (data[i] & 255) + sum; |
43 | |
44 | // subsequent rows |
45 | int i = w; |
46 | for (int y = 1; y < h; y++) { |
47 | sum = 0; |
48 | int x = 0; |
49 | for (; x < upperBound; x += species.length(), i += species.length()) { |
50 | IntVector v = IntVector.fromArray(species, data, i); |
51 | IntVector v_last = IntVector.fromArray(species, data, i-w); |
52 | v = v.and(255).add(v_last).add(sum); |
53 | v.intoArray(data, i); |
54 | sum += v.reduceLanes(VectorOperators.ADD); |
55 | } |
56 | |
57 | for (; x < w; x++, i++) |
58 | data[i] = (data[i] & 255) + sum; |
59 | } |
60 | } |
61 | |
62 | private void alloc(int w, int h) { |
63 | this.w = w; |
64 | this.h = h; |
65 | if (w*h > 8*1024*1024) |
66 | fail("Image too large (more than 8 MP): " + w + "*" + h); |
67 | data = new int[w*h]; |
68 | } |
69 | |
70 | // pixels outside of image are considered black |
71 | int get(int x, int y) { |
72 | ifdef BWIntegralImage_CountAccesses |
73 | ++accesses; |
74 | endifdef |
75 | ret x < 0 || y < 0 || x >= w || y >= h ? 0 |
76 | : data[min(y, h-1)*w+min(x, w-1)]; |
77 | } |
78 | |
79 | public double getPixelAverage(int x1, int y1, int x2, int y2) { |
80 | int area = (x2-x1)*(y2-y1); |
81 | ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area); |
82 | } |
83 | |
84 | int getPixel(int x, int y) { |
85 | ret bwIntegralImage_sumRect(this, x, y, x+1, y+1); |
86 | } |
87 | |
88 | int getPixel(Pt p) { ret getPixel(p.x, p.y); } |
89 | |
90 | public int getWidth() { ret w; } |
91 | public int getHeight() { ret h; } |
92 | |
93 | // unoptimized |
94 | public BufferedImage getBufferedImage() { |
95 | ret scaleDownUsingIntegralImageBW(this, w).getBufferedImage(); |
96 | } |
97 | } |
Began life as a copy of #1019595
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030523 |
Snippet name: | BWIntegralImage_vectorized [dev.] |
Eternal ID of this version: | #1030523/3 |
Text MD5: | 2dd0cd77b3fba772391f60454b1d19fd |
Author: | stefan |
Category: | javax / imaging |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-01-05 15:22:49 |
Source code size: | 2899 bytes / 97 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 218 / 253 |
Version history: | 2 change(s) |
Referenced in: | [show references] |