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: | 146 / 197 |
Version history: | 2 change(s) |
Referenced in: | [show references] |