Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

166
LINES

< > BotCompany Repo | #1032463 // BWIntegralImage - SLOW vector api version (way slower than without vector api)

JavaX fragment (include) [tags: use-pretranspiled]

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  
}

Author comment

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