srecord noeq G22_RegionToSSIs(IImageRegion region) { RGB color; L ssis; new L growingSSIs; class GrowingSSI { settable int y1; new IntBuffer data; SSI finish() { ret new SSI(y1, y1+l(data)).data(data.toIntArray()) .color(color); } } 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)); // finish SSIs while (longerThan(growingSSIs, streaks)) ssis.add(popLast(growingSSIs).finish()); // now we know that l(growingSSIs) <= l(streaks) // start new SSIs for (int i = l(growingSSIs); i < l(streaks); i++) growingSSIs.add(new GrowingSSI().y1(y)); // continue SSIs for (ssi, range : unpair zipTwoLists(growingSSIs, streaks)) { ssi.data.add(x1+range.start); ssi.data.add(x1+range.end); } } ret ssis; } swappable IntRange selectHorizontalPart(L parts) { ret first(parts); } }