Warning: session_start(): open(/var/lib/php/sessions/sess_ne94vs8u93eq3hf3j8pp6f9hkb, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
srecord noeq G22_RegionToSSIs_v2(IImageRegion region) {
RGB color;
L ssis;
new L growingSSIs;
settable bool withDiagonals; // TODO
private int 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); }
void add(int x1, int x2) {
data.add(toShort_enforce(x1));
data.add(toShort_enforce(x2));
}
}
private GrowingSSI startSSI(int iSSI default l(growingSSIs), IntRange range) {
var ssi = new GrowingSSI().y1(y);
ssi.add(r.x1()+range.start, r.x1()+range.end);
ret addAndReturn(growingSSIs, iSSI, ssi);
}
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 (y = y1; y < y2; y++) {
reMutable y;
L streaks = genericStreaks(w, x -> region.contains(x1+x, y));
// advance iSSI & iStreak simultaneously
int iStreak = 0, iSSI = 0;
while ping (iStreak < l(streaks)) {
var range = streaks.get(iStreak);
var ssi = _get(growingSSIs, iSSI);
// distinctly left of current SSI?
// (or to the right of everything)
if (ssi == null || range.end < ssi.lastx1()) {
startSSI(iSSI, range);
++iStreak;
continue;
}
// Now we know that ssi != null
// Find the rightmost streak still under the current SSI
int jStreak = iStreak;
while (jStreak+1 < l(streaks) && streaks.get(jStreak+1).start < ssi.lastx2())
++jStreak;
range = streaks.get(jStreak);
// Check if we have to merge with right neighbor(s)
int jSSI = iSSI;
while (jSSI+1 < l(growingSSIs)
&& range.end > growingSSIs.get(jSSI+1).lastx1())
++jSSI;
int nSSI = jSSI-iSSI, nStreak = jStreak-iStreak;
// 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(x1+range.start, x1+range.end);
iSSI = jSSI; iStreak = jStreak; continue;
}
// Any kind of structural change means end all involved
// SSIs and start new ones.
while (jSSI-- > iSSI)
growingSSIs.remove(iSSI).finish();
while (iStreak < jStreak)
startSSI(streaks.get(iStreak++));
}
}
for (ssi : cloneAndClear(growingSSIs))
ssi.finish();
ret ssis;
}
}