Libraryless. Click here for Pure Java version (8409L/51K).
1 | set flag BWIntegralImage_useVectorAPI. |
2 | |
3 | // grayscale, actually |
4 | final sclass BWIntegralImage extends Meta implements MakesBufferedImage, IBWIntegralImage, IIntegralImage {
|
5 | int w, h; |
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 | |
21 | pcall {
|
22 | GrabbableIntPixels gp = grabbableIntPixels(image); |
23 | if (gp != null) ret with grab(gp); |
24 | } |
25 | |
26 | // Use pixelGrabber if quick method fails |
27 | PixelGrabber pixelGrabber = new(image, 0, 0, w, h, data, 0, w); |
28 | if (!pixelGrabber.grabPixels()) |
29 | fail("Could not grab pixels");
|
30 | |
31 | grab(GrabbableIntPixels(data, w, h, 0, w)); |
32 | } |
33 | |
34 | *(GrabbableIntPixels gp) {
|
35 | alloc(gp.w, gp.h); |
36 | grab(gp); |
37 | } |
38 | |
39 | void grab(GrabbableIntPixels gp) {
|
40 | ifdef BWIntegralImage_debug |
41 | print("BWIntegralImage grabbing: " + gp);
|
42 | endifdef |
43 | int offset = gp.offset; |
44 | int[] image = gp.data; |
45 | int sum = 0; |
46 | for x to w: {
|
47 | int packed = image[offset+x]; |
48 | int brightness = packedToBrightness(packed); |
49 | data[x] = (sum += brightness); |
50 | } |
51 | |
52 | ifdef BWIntegralImage_useVectorAPI |
53 | import jdk.incubator.vector.*; |
54 | VectorSpecies<Int> species = IntVector.SPECIES_PREFERRED; |
55 | int upperBound = species.loopBound(w); |
56 | endifdef |
57 | |
58 | int scanlineExtra = gp.scanlineStride-w; |
59 | int iImage = offset+gp.scanlineStride, i = w; |
60 | for (int y = 1; y < h; y++) {
|
61 | sum = 0; |
62 | ifdef BWIntegralImage_useVectorAPI |
63 | int x = 0; |
64 | for (; x < upperBound; x += species.length(), iImage += species.length(), i += species.length()) {
|
65 | for (int sub = 0; sub < species.length(); sub++) {
|
66 | sum += packedToBrightness(image[iImage+sub]); |
67 | data[i+sub] = sum; |
68 | } |
69 | |
70 | IntVector v = IntVector.fromArray(species, data, i); |
71 | IntVector v_last = IntVector.fromArray(species, data, i-w); |
72 | v = v.add(v_last); |
73 | v.intoArray(data, i); |
74 | } |
75 | |
76 | for (; x < w; x++, iImage++, i++) {
|
77 | int packed = image[iImage]; |
78 | int brightness = packedToBrightness(packed); |
79 | sum += brightness; |
80 | data[i] = sum + data[i-w]; |
81 | } |
82 | endifdef |
83 | |
84 | ifndef BWIntegralImage_useVectorAPI |
85 | for x to w: {
|
86 | int packed = image[iImage]; |
87 | int brightness = packedToBrightness(packed); |
88 | sum += brightness; |
89 | data[i] = sum + data[i-w]; |
90 | iImage++; i++; |
91 | } |
92 | endifndef |
93 | |
94 | iImage += scanlineExtra; |
95 | } // for y |
96 | } |
97 | |
98 | *(BWImage img) {
|
99 | alloc(img.w(), img.h()); |
100 | data = new int[w*h]; |
101 | int i = 0; |
102 | for y to h: {
|
103 | int sum = 0; |
104 | for x to w: {
|
105 | sum += img.getByte(x, y) & 0xFF; |
106 | data[i] = y > 0 ? sum + data[i-w] : sum; |
107 | i++; |
108 | } |
109 | } |
110 | } |
111 | |
112 | private void alloc(int w, int h) {
|
113 | this.w = w; |
114 | this.h = h; |
115 | if (w*h > 8*1024*1024) |
116 | fail("Image too large (more than 8 MP): " + w + "*" + h);
|
117 | data = new int[w*h]; |
118 | } |
119 | |
120 | // pixels outside of image are considered black |
121 | int get(int x, int y) {
|
122 | ifdef BWIntegralImage_CountAccesses |
123 | ++accesses; |
124 | endifdef |
125 | ret x < 0 || y < 0 || x >= w || y >= h ? 0 |
126 | : data[min(y, h-1)*w+min(x, w-1)]; |
127 | } |
128 | |
129 | public int getIIValue(int x, int y) { ret get(x, y); }
|
130 | public double getIntegralValue(int x, int y, int channel) {
|
131 | ret get(x, y); |
132 | } |
133 | |
134 | public double getPixelAverage(int x1, int y1, int x2, int y2) {
|
135 | int area = (x2-x1)*(y2-y1); |
136 | ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area); |
137 | } |
138 | |
139 | public int getWidth() { ret w; }
|
140 | public int getHeight() { ret h; }
|
141 | |
142 | // unoptimized |
143 | public BufferedImage getBufferedImage() {
|
144 | ret scaleDownUsingIntegralImageBW(this, w).getBufferedImage(); |
145 | } |
146 | |
147 | int packedToBrightness(int packed) {
|
148 | int b = (packed & 0xFF); |
149 | ifdef BWIntegralImage_brightnessCheat |
150 | ret b; |
151 | endifdef |
152 | ifndef BWIntegralImage_brightnessCheat |
153 | int r = ((packed >> 16) & 0xFF); |
154 | int g = ((packed >> 8) & 0xFF); |
155 | ret (r+g+b+1)/3; |
156 | endifndef |
157 | } |
158 | |
159 | // returns RGB pixel without alpha |
160 | public int getPixel(int x, int y) {
|
161 | int r = iround(rectSum(x, y, x+1, y+1, 0)); |
162 | int g = iround(rectSum(x, y, x+1, y+1, 1)); |
163 | int b = iround(rectSum(x, y, x+1, y+1, 2)); |
164 | ret rgbInt(r, g, b); |
165 | } |
166 | } |
Began life as a copy of #1019595
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj, pyentgdyhuwx
No comments. add comment
| Snippet ID: | #1032463 |
| Snippet name: | BWIntegralImage - SLOW vector api version (way slower than without vector api) |
| Eternal ID of this version: | #1032463/3 |
| Text MD5: | 3a73db474b3c68bbe627257e83448310 |
| Transpilation MD5: | 04f7f74b752a494470a3ea7eb5e04f1f |
| Author: | stefan |
| Category: | javax / imaging |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2021-09-26 20:29:41 |
| Source code size: | 4745 bytes / 166 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 414 / 505 |
| Version history: | 2 change(s) |
| Referenced in: | [show references] |