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

126
LINES

< > BotCompany Repo | #1030531 // BWIntegralImage_doubleVectorized [pre-calcs 8x8 blocks using Vector API, dev.]

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

Libraryless. Click here for Pure Java version (6331L/39K).

1  
import jdk.incubator.vector.*;
2  
3  
// TODO: image w/h not divisible by 8
4  
5  
final sclass BWIntegralImage_doubleVectorized implements MakesBufferedImage, IBWIntegralImage {
6  
  // dual logarithm of block size & corresponding int vector species
7  
  replace blockShift with 3.
8  
  replace species with IntVector.SPECIES_256.
9  
  replace blockSize with (1 << blockShift).
10  
  
11  
  int w, h; // actual image size
12  
  int blockW, blockH; // width and height of block array
13  
  Block[] blocks;
14  
  ifdef BWIntegralImage_CountAccesses
15  
    long accesses;
16  
  endifdef
17  
  
18  
  sclass Block {
19  
    int[] rowAndColSums = new[blockSize*2]; // length 16
20  
    int sum;
21  
    int[] data; // length 64 if calculated
22  
  }
23  
  
24  
  *() {}
25  
  *(File f) { this(loadImage2(f)); }
26  
  
27  
  *(MakesBufferedImage img) { this(toBufferedImage(img)); }
28  
  
29  
  *(BufferedImage image) ctex {
30  
    alloc(image.getWidth(), image.getHeight());
31  
    
32  
    // Grab image
33  
    // TODO: could use grayscale color model here (faster?)
34  
    int[] data = new[w*h];
35  
    PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, w, h, data, 0, w);
36  
    if (!pixelGrabber.grabPixels())
37  
      fail("Could not grab pixels");
38  
      
39  
    // for brightness of pixels,
40  
    // for now we cheat by just using one of the channels
41  
    
42  
    // calculate sums in each block
43  
    
44  
    int iBlock = 0;
45  
    for by to blockH: {
46  
      int iLine = (by << blockShift)*w;
47  
      for bx to blockW: {
48  
        Block block = blocks[iBlock++];
49  
        int[] sums = block.rowAndColSums;
50  
        
51  
        IntVector vColSums = by == 0 ? IntVector.zero(species) : IntVector.fromArray(species, getBlock(bx, by-1).rowAndColSums, blockSize);
52  
        int[] leftSums = bx == 0 ? null : getBlock(bx-1, by).rowAndColSums;
53  
        
54  
        for (int y = 0; y < blockSize; y++) {
55  
          IntVector v = IntVector.fromArray(species, data, y << blockShift);
56  
          int leftSum = leftSums != null ? leftSums[y] : 0;
57  
          sums[y] = v.reduceLanes(VectorOperators.ADD)+leftSum;
58  
          v = v.add(leftSum);
59  
          vColSums = vColSums.add(v);
60  
        }
61  
        vColSums.intoArray(sums, blockSize);
62  
        block.sum = vColSums.reduceLanes(VectorOperators.ADD);
63  
      }
64  
    }
65  
  }
66  
  
67  
  int blockSum(int bx, int by) {
68  
    ret bx < 0 || by < 0 ? 0 : getBlock(bx, by).sum;
69  
  }
70  
  
71  
  Block getBlock(int bx, int by) { ret blocks[by*blockW+bx]; }
72  
  
73  
  int[] getBlockData(int bx, int by) {
74  
    Block block = getBlock(bx, by);
75  
    if (block.data == null)
76  
      calcData(bx, by, block);
77  
    ret block.data;
78  
  }
79  
  
80  
  void calcData(int bx, int by, Block block) {
81  
    todo();
82  
  }
83  
  
84  
  private void alloc(int w, int h) {
85  
    if ((w % blockSize) != 0 || (h % blockSize) != 0)
86  
      fail("Need image dimensions divisible by " + blockSize + ": " + w + "*" + h);
87  
88  
    this.w = w;
89  
    this.h = h;
90  
    blockW = ratioRoundUp(w, blockSize);
91  
    blockH = ratioRoundUp(h, blockSize);
92  
    //int dataLength = blockSize*blockSize;
93  
    blocks = repF_array Block(blockW*blockH, () -> new Block);
94  
  }
95  
  
96  
  // get sum value at x, y
97  
  // pixels outside of image are considered black
98  
  public int getIIValue(int x, int y) {
99  
    ifdef BWIntegralImage_CountAccesses
100  
      ++accesses;
101  
    endifdef
102  
    if (x < 0 || y < 0 || x >= w || y >= h) ret 0;
103  
    int idx = ((x & (blockSize-1)) << blockSize) | (y & (blockSize-1));
104  
    ret idx == 0 ? getBlock(x >> blockShift, y >> blockShift).sum
105  
      : getBlockData(x >> blockShift, y >> blockShift)[idx];
106  
  }
107  
  
108  
  public double getPixelAverage(int x1, int y1, int x2, int y2) {
109  
    int area = (x2-x1)*(y2-y1);
110  
    ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area);
111  
  }
112  
  
113  
  int getPixel(int x, int y) {
114  
    ret bwIntegralImage_sumRect(this, x, y, x+1, y+1);
115  
  }
116  
  
117  
  int getPixel(Pt p) { ret getPixel(p.x, p.y); }
118  
  
119  
  public int getWidth() { ret w; }
120  
  public int getHeight() { ret h; }
121  
  
122  
  // unoptimized
123  
  public BufferedImage getBufferedImage() {
124  
    ret scaleDownUsingIntegralImageBW(this, w, h).getBufferedImage();
125  
  }
126  
}

Author comment

Began life as a copy of #1030523

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030531
Snippet name: BWIntegralImage_doubleVectorized [pre-calcs 8x8 blocks using Vector API, dev.]
Eternal ID of this version: #1030531/25
Text MD5: d2ebc86355a9d7ac84974072dc4b5104
Transpilation MD5: ff645708e94ec500942aec9e96456eab
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-01-06 20:18:18
Source code size: 4048 bytes / 126 lines
Pitched / IR pitched: No / No
Views / Downloads: 202 / 466
Version history: 24 change(s)
Referenced in: [show references]