srecord noeq G22_RegionToSSIs_v2(IImageRegion region) { RGB color; L ssis; new L growingSSIs; settable bool withDiagonals; class GrowingSSI { settable int y1; new ShortBuffer data; int y2() { ret y1+l(data)/2; } SSI finish() { ret 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); } void add(int x1, int x2) { data.add(toShort_enforce(x1)); data.add(toShort_enforce(x2)); } } L get() { if (region == null) null; color = region.color(); ssis = new L; Rect r = region.bounds(); int x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2-y1, w = r.w; for (int y = y1; y < y2; y++) { reMutable y; L streaks = genericStreaks(w, x -> region.contains(x1+x, y)); // advance iGrowingSSIs & iStreaks simultaneously int iStreak = 0, iSSI = 0; while (iStreak < l(streaks)) { var range = streaks.get(iStreak); var ssi = get(growingSSIs, iSSI); // insert new SSI left of current SSI (or to the right of everything) if (ssi == null || range.end < ssi.lastx1()) { var ssi = new GrowingSSI().y1(y); ssi.add(x1+range.start, x1+range.end); growingSSIs.insert(iSSI, ssi); ++iStreak; continue; } todo(); } } for (ssi : cloneAndClear(growingSSIs)) ssis.add(ssi.finish()); ret ssis; } }