Warning: session_start(): open(/var/lib/php/sessions/sess_h3l8irs8a4cs01r4t4ru71o8eq, 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
// from https://rosettacode.org/wiki/Zhang-Suen_thinning_algorithm#Java
// each array element is one pixel (0 = background, anything else = foreground)
srecord noeq ZhangSuenThinner_byteArray(int w, int h, byte[] pixels) {
static final int[][] nbrs = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1},
{-1, 1}, {-1, 0}, {-1, -1}, {0, -1}};
static final int[][][] nbrGroups = {
{{0, 2, 4}, {2, 4, 6}},
{{0, 2, 6}, {0, 4, 6}}};
new PtBuffer toWhite;
run {
bool firstStep;
while ping (true) {
firstStep = !firstStep;
for (int r = 1; r < h - 1; r++)
for (int c = 1; c < w - 1; c++) {
if (!getPixel(c, r))
continue;
int nn = numNeighbors(r, c);
if (nn < 2 || nn > 6)
continue;
if (numTransitions(r, c) != 1)
continue;
if (!atLeastOneIsWhite(r, c, firstStep ? 0 : 1))
continue;
toWhite.add(c, r);
}
if (!firstStep && empty(toWhite)) break;
for (Pt p : toWhite)
clearPixel(p.x, p.y);
toWhite.clear();
}
}
int numNeighbors(int r, int c) {
int count = 0;
for (int i = 0; i < nbrs.length - 1; i++)
if (getPixel(c + nbrs[i][0], r + nbrs[i][1]))
count++;
ret count;
}
int numTransitions(int r, int c) {
int count = 0;
for (int i = 0; i < nbrs.length - 1; i++)
if (!getPixel(c + nbrs[i][0], r + nbrs[i][1])
&& getPixel(c + nbrs[i+1][0], r + nbrs[i+1][1]))
count++;
ret count;
}
bool atLeastOneIsWhite(int r, int c, int step) {
int count = 0;
int[][] group = nbrGroups[step];
for (int i = 0; i < 2; i++)
for (int j = 0; j < group[i].length; j++) {
int[] nbr = nbrs[group[i][j]];
if (!getPixel(c + nbr[0], r + nbr[1])) {
count++;
break;
}
}
ret count > 1;
}
bool getPixel(int x, int y) {
ret pixels[y*w+x] != 0;
}
void clearPixel(int x, int y) {
pixels[y*w+x] = 0;
}
}