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

167
LINES

< > BotCompany Repo | #1035640 // G22_RegionToSSIs_v2 - full conversion with cohesion and fewest SSIs (backup)

JavaX fragment (include)

1  
srecord noeq G22_RegionToSSIs_v2(IImageRegion region) extends Meta {
2  
  RGB color;
3  
  L<SSI> ssis;
4  
  new L<GrowingSSI> growingSSIs;
5  
  settable bool withDiagonals;
6  
  settable bool checkCoherence = true;
7  
  settable bool checkStreaks = true;
8  
  
9  
  private int x1, y;
10  
  
11  
  class GrowingSSI {
12  
    settable int y1;
13  
    new ShortBuffer data;
14  
    
15  
    int y2() { ret y1+l(data)/2; }
16  
    
17  
    SSI finish() {
18  
      ret addAndReturn(ssis, new SSI(y1, y2()).data(data.toArray())
19  
        .color(color));
20  
    }
21  
    
22  
    bool isEmpty() { ret data.isEmpty(); }
23  
    int lastx1() { ret data.get(l(data)-2); }
24  
    int lastx2() { ret data.get(l(data)-1); }
25  
    IntRange lastRange() { ret isEmpty() ? null : intRange(lastx1(), lastx2()); }
26  
    
27  
    void add(int x1, int x2) {
28  
      if (checkCoherence() && !isEmpty()
29  
        && !intRangesOverlap(x1, x2, lastx1()-diag(), lastx2()+diag()))
30  
        fail("Coherence fail", +lastx1(), +lastx2(), +x1, +x2);
31  
      
32  
      data.add(toShort_enforce(x1));
33  
      data.add(toShort_enforce(x2));
34  
    }
35  
  }
36  
  
37  
  void finishSSI(int iSSI) {
38  
    growingSSIs.remove(iSSI).finish();
39  
  }
40  
  
41  
  private GrowingSSI startSSI(int iSSI default l(growingSSIs), IntRange range) {
42  
    if (scaffoldingEnabled()) printVars("startSSI", +iSSI, +range);
43  
    var ssi = new GrowingSSI().y1(y);
44  
    ssi.add(range.start, range.end);
45  
    ret addAndReturn(growingSSIs, iSSI, ssi);
46  
  }
47  
  
48  
  L<IntRange> lastStreaks() {
49  
    ret reallyLazyMap(growingSSIs, -> .lastRange());
50  
  }
51  
  
52  
  int diag() { ret withDiagonals ? 1 : 0; }
53  
  
54  
  L<SSI> get() {
55  
    if (region == null) null;
56  
    
57  
    color = region.color();
58  
    ssis = new L;
59  
    Rect r = region.bounds();
60  
    int x1 = this.x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2-y1, w = r.w;
61  
    bool scaff = scaffoldingEnabled();
62  
    
63  
    for (y = y1; y < y2; y++) {
64  
      reMutable y;
65  
      L<IntRange> streaks = shiftIntRanges(x1, genericStreaks(w, x -> region.contains(x1+x, y)));
66  
      
67  
      var lastStreaks = lastStreaks();
68  
      if (checkStreaks())
69  
        assertProperStreaks(lastStreaks);
70  
      
71  
      // advance iSSI & iStreak simultaneously
72  
      int iStreak = 0, iSSI = 0;
73  
      int nStreaks = l(streaks);
74  
      
75  
      if (scaff) printVars(+y, +lastStreaks, +streaks);
76  
77  
      while ping (iStreak < nStreaks) {
78  
        var range = streaks.get(iStreak);
79  
        var ssi = _get(growingSSIs, iSSI);
80  
        if (scaff) printVars(+y, +iStreak, +iSSI, +range, ssi := ssi?.lastRange());
81  
        
82  
        // case 1:
83  
        //           ------
84  
        // -------
85  
        //
86  
        // case 2:
87  
        //
88  
        // -------
89  
        // (left of current SSI or to the right of everything)
90  
        if (ssi == null || range.end <= ssi.lastx1()-diag()) {
91  
          startSSI(iSSI++, range);
92  
          ++iStreak;
93  
          continue;
94  
        }
95  
        
96  
        // Now we know that we have another SSI.
97  
        
98  
        // case 3:
99  
        // -------
100  
        //          ------
101  
        // (Just end current SSI and do streak again.)
102  
        if (range.start >= ssi.lastx2()+diag()) {
103  
          finishSSI(iSSI);
104  
          continue;
105  
        }
106  
        
107  
        // Find the rightmost streak still under the current SSI
108  
        int jStreak = iStreak+1;
109  
        while (jStreak < nStreaks && streaks.get(jStreak).start < ssi.lastx2()+diag())
110  
          ++jStreak;
111  
        range = streaks.get(jStreak-1);
112  
113  
        // Check if we have to merge with right neighbor(s)
114  
        int jSSI = iSSI+1;
115  
        while (jSSI < l(growingSSIs)
116  
          && range.end > growingSSIs.get(jSSI).lastx1()-diag())
117  
          ++jSSI;
118  
          
119  
        int nSSI = jSSI-iSSI, nStreak = jStreak-iStreak;
120  
        if (scaff) printVars(+jStreak, +jSSI, +nSSI, +nStreak, +nStreaks, nSSIs := l(growingSSIs));
121  
122  
        if (scaff) printVars(+nSSI, +nStreak);
123  
        
124  
        // Now we go from [iSSI;jSSI) to [iStreak;jStreak)
125  
        // The only case without structural changes is when
126  
        // nSSI = nStreak = 1. Then we just add the line.
127  
        if (nSSI == 1 && nStreak == 1) {
128  
          ssi.add(range.start, range.end);
129  
          iSSI = jSSI; iStreak = jStreak; continue;
130  
        }
131  
        
132  
        // If 2 -> 2, we can just assign them one-to-one I think
133  
        if (nSSI == 2 && nStreak == 2) {
134  
          if (scaff) printVars("2->2", ssis := subList(lastStreaks(), iSSI, jSSI),
135  
            streaks := subList(streaks, iStreak, jStreak));
136  
            
137  
          while (iSSI < jSSI) {
138  
            range = streaks.get(iStreak++);
139  
            growingSSIs.get(iSSI++).add(range.start, range.end);
140  
          }
141  
          continue;
142  
        }
143  
        
144  
        if (nSSI > 1 && nStreak > 1)
145  
          printVars("ANOMALY", +nSSI, +nStreak,
146  
            ssis := subList(lastStreaks(), iSSI, jSSI),
147  
            streaks := subList(streaks, iStreak, jStreak));
148  
        
149  
        // Any kind of structural change means end all involved
150  
        // SSIs and start new ones.
151  
        while (jSSI-- > iSSI)
152  
          finishSSI(iSSI);
153  
          
154  
        while (iStreak < jStreak)
155  
          startSSI(iSSI++, streaks.get(iStreak++));
156  
      }
157  
      
158  
      // end SSIs to the right of all streaks
159  
      while (iSSI < l(growingSSIs))
160  
        finishSSI(iSSI);
161  
    }
162  
    
163  
    for (ssi : cloneAndClear(growingSSIs)) ssi.finish();
164  
    
165  
    ret ssis;
166  
  }
167  
}

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: #1035640
Snippet name: G22_RegionToSSIs_v2 - full conversion with cohesion and fewest SSIs (backup)
Eternal ID of this version: #1035640/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 08:53:17
Source code size: 5375 bytes / 167 lines
Pitched / IR pitched: No / No
Views / Downloads: 55 / 56
Referenced in: [show references]