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

167
LINES

< > BotCompany Repo | #1035639 // G22_RegionToSSIs_v2 - full conversion [backup]

JavaX fragment (include)

srecord noeq G22_RegionToSSIs_v2(IImageRegion region) extends Meta {
  RGB color;
  L<SSI> ssis;
  new L<GrowingSSI> growingSSIs;
  settable bool withDiagonals;
  settable bool checkCoherence = true;
  settable bool checkStreaks = true;
  
  private int x1, y;
  
  class GrowingSSI {
    settable int y1;
    new ShortBuffer data;
    
    int y2() { ret y1+l(data)/2; }
    
    SSI finish() {
      ret addAndReturn(ssis, new SSI(y1, y2()).data(data.toArray())
        .color(color));
    }
    
    bool isEmpty() { ret data.isEmpty(); }
    int lastx1() { ret data.get(l(data)-2); }
    int lastx2() { ret data.get(l(data)-1); }
    IntRange lastRange() { ret isEmpty() ? null : intRange(lastx1(), lastx2()); }
    
    void add(int x1, int x2) {
      if (checkCoherence() && !isEmpty()
        && !intRangesOverlap(x1, x2, lastx1()-diag(), lastx2()+diag()))
        fail("Coherence fail", +lastx1(), +lastx2(), +x1, +x2);
      
      data.add(toShort_enforce(x1));
      data.add(toShort_enforce(x2));
    }
  }
  
  void finishSSI(int iSSI) {
    growingSSIs.remove(iSSI).finish();
  }
  
  private GrowingSSI startSSI(int iSSI default l(growingSSIs), IntRange range) {
    if (scaffoldingEnabled()) printVars("startSSI", +iSSI, +range);
    var ssi = new GrowingSSI().y1(y);
    ssi.add(range.start, range.end);
    ret addAndReturn(growingSSIs, iSSI, ssi);
  }
  
  L<IntRange> lastStreaks() {
    ret reallyLazyMap(growingSSIs, -> .lastRange());
  }
  
  int diag() { ret withDiagonals ? 1 : 0; }
  
  L<SSI> get() {
    if (region == null) null;
    
    color = region.color();
    ssis = new L;
    Rect r = region.bounds();
    int x1 = this.x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2-y1, w = r.w;
    bool scaff = scaffoldingEnabled();
    
    for (y = y1; y < y2; y++) {
      reMutable y;
      L<IntRange> streaks = shiftIntRanges(x1, genericStreaks(w, x -> region.contains(x1+x, y)));
      
      var lastStreaks = lastStreaks();
      if (checkStreaks())
        assertProperStreaks(lastStreaks);
      
      // advance iSSI & iStreak simultaneously
      int iStreak = 0, iSSI = 0;
      int nStreaks = l(streaks);
      
      if (scaff) printVars(+y, +lastStreaks, +streaks);

      while ping (iStreak < nStreaks) {
        var range = streaks.get(iStreak);
        var ssi = _get(growingSSIs, iSSI);
        if (scaff) printVars(+y, +iStreak, +iSSI, +range, ssi := ssi?.lastRange());
        
        // case 1:
        //           ------
        // -------
        //
        // case 2:
        //
        // -------
        // (left of current SSI or to the right of everything)
        if (ssi == null || range.end <= ssi.lastx1()-diag()) {
          startSSI(iSSI++, range);
          ++iStreak;
          continue;
        }
        
        // Now we know that we have another SSI.
        
        // case 3:
        // -------
        //          ------
        // (Just end current SSI and do streak again.)
        if (range.start >= ssi.lastx2()+diag()) {
          finishSSI(iSSI);
          continue;
        }
        
        // Find the rightmost streak still under the current SSI
        int jStreak = iStreak+1;
        while (jStreak < nStreaks && streaks.get(jStreak).start < ssi.lastx2()+diag())
          ++jStreak;
        range = streaks.get(jStreak-1);

        // Check if we have to merge with right neighbor(s)
        int jSSI = iSSI+1;
        while (jSSI < l(growingSSIs)
          && range.end > growingSSIs.get(jSSI).lastx1()-diag())
          ++jSSI;
          
        int nSSI = jSSI-iSSI, nStreak = jStreak-iStreak;
        if (scaff) printVars(+jStreak, +jSSI, +nSSI, +nStreak, +nStreaks, nSSIs := l(growingSSIs));

        if (scaff) printVars(+nSSI, +nStreak);
        
        // Now we go from [iSSI;jSSI) to [iStreak;jStreak)
        // The only case without structural changes is when
        // nSSI = nStreak = 1. Then we just add the line.
        if (nSSI == 1 && nStreak == 1) {
          ssi.add(range.start, range.end);
          iSSI = jSSI; iStreak = jStreak; continue;
        }
        
        // If 2 -> 2, we can just assign them one-to-one I think
        if (nSSI == 2 && nStreak == 2) {
          if (scaff) printVars("2->2", ssis := subList(lastStreaks(), iSSI, jSSI),
            streaks := subList(streaks, iStreak, jStreak));
            
          while (iSSI < jSSI) {
            range = streaks.get(iStreak++);
            growingSSIs.get(iSSI++).add(range.start, range.end);
          }
          continue;
        }
        
        if (nSSI > 1 && nStreak > 1)
          printVars("ANOMALY", +nSSI, +nStreak,
            ssis := subList(lastStreaks(), iSSI, jSSI),
            streaks := subList(streaks, iStreak, jStreak));
        
        // Any kind of structural change means end all involved
        // SSIs and start new ones.
        while (jSSI-- > iSSI)
          finishSSI(iSSI);
          
        while (iStreak < jStreak)
          startSSI(iSSI++, streaks.get(iStreak++));
      }
      
      // end SSIs to the right of all streaks
      while (iSSI < l(growingSSIs))
        finishSSI(iSSI);
    }
    
    for (ssi : cloneAndClear(growingSSIs)) ssi.finish();
    
    ret ssis;
  }
}

Author comment

Began life as a copy of #1035627

download  show line numbers  debug dex  old transpilations   

Travelled to 1 computer(s): mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035639
Snippet name: G22_RegionToSSIs_v2 - full conversion [backup]
Eternal ID of this version: #1035639/1
Text MD5: 0cc358c08e2c15a5366370b5fddb3c6c
Author: stefan
Category: javax / gazelle 22
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-06-27 06:56:21
Source code size: 5375 bytes / 167 lines
Pitched / IR pitched: No / No
Views / Downloads: 104 / 114
Referenced in: [show references]