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

83
LINES

< > BotCompany Repo | #1035898 // Hi15ScanlineIndex - a fast index of all single-color multi-pixel horizontal lines in an image

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

Libraryless. Click here for Pure Java version (10815L/62K).

// The main idea behind this data structure is that it should
// allow finding regions significantly faster than directly from
// the Hi15Image.
//
// Making this index takes about 2ms per megapixel.

sclass Hi15ScanlineIndex {
  Hi15Image image;
  int w, h;
  int[] indexed;
  
  // scanlines contains 2 consecutive ints for each scanline:
  // -index of first pixel in scanline
  // -index of last pixel in scanline + 1
  //
  // Colors are not stored and have to be gathered from the
  // original image.
  
  IntBuffer scanlines;
  
  *() {}
  *(Hi15Image *image) {}
  
  run {
    int w = this.w = image.getWidth();
    int h = this.h = image.getHeight();
    short[] pixels = image.pixels;
    
    int lineStart = 0;
    var indexed = this.indexed = new int[w*h];
    int guess = 128*1024;
    var scanlines = this.scanlines = new IntBuffer(guess);

    for y to h: {
      int i = lineStart;
      int lineEnd = lineStart+w;
      
      while (i < lineEnd) {
        short color = pixels[i];
        int j = i+1;
        if (j < lineEnd && pixels[j] == color) {
          // multi-pixel scanline found
          
          do
            ++j;
          while (j < lineEnd && pixels[j] == color);
          scanlines.add(i);
          scanlines.add(j);
        }
        
        int iScanline = scanlines.size();
        while (i < j)
          indexed[i++] = iScanline;
      }
      
      lineStart = lineEnd;
    }
  }
  
  int nScanlines() { ret scanlines.size()/2; }
  
  // Render all scanlines in an image.
  // Isolated pixels (those different from their left and right
  // neighbor) will be left transparent.
  
  BufferedImage scanlinesAsImage() {
    int[] pixels = new[w*h];
    int n = nScanlines();
    for i to n: {
      int from = scanlines.get(i*2);
      int to = scanlines.get(i*2+1);
      int color = withFullAlpha(hi15ToRGBInt_clean(image.getHi15Pixel_noRangeCheck(from)));
      for (int pixel = from; pixel < to; pixel++)
        pixels[pixel] = color;
    }
    ret bufferedImageWithAlpha(w, h, pixels);
  }
  
  // run this after run() to save some memory
  void compact {
    scanlines.trimToSize();
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035898
Snippet name: Hi15ScanlineIndex - a fast index of all single-color multi-pixel horizontal lines in an image
Eternal ID of this version: #1035898/14
Text MD5: 3c448de8d75bf392caa3488669c2a59b
Transpilation MD5: c4ca45f9ae0462afbf3d23a1adc65397
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-08-11 18:57:00
Source code size: 2226 bytes / 83 lines
Pitched / IR pitched: No / No
Views / Downloads: 152 / 260
Version history: 13 change(s)
Referenced in: [show references]