Warning: session_start(): open(/var/lib/php/sessions/sess_5t5bvqb1lvbj7lve11pji7hqia, 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) extends Meta {
RGB color;
L ssis;
new L 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()); }
// can add this line without breaking coherence?
bool canAdd(IntRange r) {
ret isEmpty()
|| intRangesOverlapNempty(r.start, r.end, lastx1()-diag(), lastx2()+diag());
}
void add(IntRange r) {
if (checkCoherence() && !canAdd(r))
fail("Coherence fail", +lastx1(), +lastx2(), +r);
data.add(toShort_enforce(r.start));
data.add(toShort_enforce(r.end));
}
}
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);
ret addAndReturn(growingSSIs, iSSI, ssi);
}
L lastStreaks() {
ret reallyLazyMap(growingSSIs, -> .lastRange());
}
int diag() { ret withDiagonals ? 1 : 0; }
L 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 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;
}
// Now we know the streak and the SSI overlap.
// Find out if we have a choice on the top or on the bottom.
// Check choices for streak
int jStreak = iStreak+1;
while (jStreak < nStreaks && ssi.canAdd(streaks.get(jStreak)))
++jStreak;
// Check choices for SSI
int jSSI = iSSI+1;
while (jSSI < l(growingSSIs) && growingSSIs.get(jSSI).canAdd(range))
++jSSI;
int nSSI = jSSI-iSSI, nStreak = jStreak-iStreak;
if (scaff) printVars(+nSSI, +nStreak);
new Best best;
if (nSSI > 1) {
if (nStreak > 1)
fail("ANOMALY", +nSSI, +nStreak,
ssis := subList(lastStreaks(), iSSI, jSSI),
streaks := subList(streaks, iStreak, jStreak));
// Choose longest SSI
for (int idx = iSSI; idx < jSSI; idx++)
best.put(idx, l(growingSSIs.get(idx).lastRange()));
jSSI = best!;
while (jSSI-- > iSSI) finishSSI(iSSI);
} else if (nStreak > 1) {
// Choose longest streak
for (int idx = iStreak; idx < jStreak; idx++)
best.put(idx, l(streaks.get(idx)));
jStreak = best!;
while (iStreak < jStreak)
startSSI(iSSI++, streaks.get(iStreak++));
}
// add line to SSI
growingSSIs.get(iSSI++).add(streaks.get(iStreak++));
}
// remaining SSIs are unpaired, close them
while (iSSI < l(growingSSIs)) finishSSI(iSSI);
}
// finish all remaining SSIs
for (ssi : cloneAndClear(growingSSIs)) ssi.finish();
ret ssis;
}
}