You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.1 KiB
JavaScript
208 lines
6.1 KiB
JavaScript
/* @preserve ASM BEGIN */
|
|
function Skeletonizer(stdlib, foreign, buffer) {
|
|
"use asm";
|
|
|
|
var images = new stdlib.Uint8Array(buffer),
|
|
size = foreign.size | 0,
|
|
imul = stdlib.Math.imul;
|
|
|
|
function erode(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for ( v = 1; (v | 0) < ((size - 1) | 0); v = (v + 1) | 0) {
|
|
offset = (offset + size) | 0;
|
|
for ( u = 1; (u | 0) < ((size - 1) | 0); u = (u + 1) | 0) {
|
|
yStart1 = (offset - size) | 0;
|
|
yStart2 = (offset + size) | 0;
|
|
xStart1 = (u - 1) | 0;
|
|
xStart2 = (u + 1) | 0;
|
|
sum = ((images[(inImagePtr + yStart1 + xStart1) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart1 + xStart2) | 0] | 0)
|
|
+ (images[(inImagePtr + offset + u) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart2 + xStart1) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart2 + xStart2) | 0] | 0)) | 0;
|
|
if ((sum | 0) === (5 | 0)) {
|
|
images[(outImagePtr + offset + u) | 0] = 1;
|
|
} else {
|
|
images[(outImagePtr + offset + u) | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function subtract(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = (length - 1) | 0;
|
|
images[(outImagePtr + length) | 0] =
|
|
((images[(aImagePtr + length) | 0] | 0) - (images[(bImagePtr + length) | 0] | 0)) | 0;
|
|
}
|
|
}
|
|
|
|
function bitwiseOr(aImagePtr, bImagePtr, outImagePtr) {
|
|
aImagePtr = aImagePtr | 0;
|
|
bImagePtr = bImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = (length - 1) | 0;
|
|
images[(outImagePtr + length) | 0] =
|
|
((images[(aImagePtr + length) | 0] | 0) | (images[(bImagePtr + length) | 0] | 0)) | 0;
|
|
}
|
|
}
|
|
|
|
function countNonZero(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var sum = 0,
|
|
length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = (length - 1) | 0;
|
|
sum = ((sum | 0) + (images[(imagePtr + length) | 0] | 0)) | 0;
|
|
}
|
|
|
|
return (sum | 0);
|
|
}
|
|
|
|
function init(imagePtr, value) {
|
|
imagePtr = imagePtr | 0;
|
|
value = value | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = (length - 1) | 0;
|
|
images[(imagePtr + length) | 0] = value;
|
|
}
|
|
}
|
|
|
|
function dilate(inImagePtr, outImagePtr) {
|
|
inImagePtr = inImagePtr | 0;
|
|
outImagePtr = outImagePtr | 0;
|
|
|
|
var v = 0,
|
|
u = 0,
|
|
sum = 0,
|
|
yStart1 = 0,
|
|
yStart2 = 0,
|
|
xStart1 = 0,
|
|
xStart2 = 0,
|
|
offset = 0;
|
|
|
|
for ( v = 1; (v | 0) < ((size - 1) | 0); v = (v + 1) | 0) {
|
|
offset = (offset + size) | 0;
|
|
for ( u = 1; (u | 0) < ((size - 1) | 0); u = (u + 1) | 0) {
|
|
yStart1 = (offset - size) | 0;
|
|
yStart2 = (offset + size) | 0;
|
|
xStart1 = (u - 1) | 0;
|
|
xStart2 = (u + 1) | 0;
|
|
sum = ((images[(inImagePtr + yStart1 + xStart1) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart1 + xStart2) | 0] | 0)
|
|
+ (images[(inImagePtr + offset + u) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart2 + xStart1) | 0] | 0)
|
|
+ (images[(inImagePtr + yStart2 + xStart2) | 0] | 0)) | 0;
|
|
if ((sum | 0) > (0 | 0)) {
|
|
images[(outImagePtr + offset + u) | 0] = 1;
|
|
} else {
|
|
images[(outImagePtr + offset + u) | 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
function memcpy(srcImagePtr, dstImagePtr) {
|
|
srcImagePtr = srcImagePtr | 0;
|
|
dstImagePtr = dstImagePtr | 0;
|
|
|
|
var length = 0;
|
|
|
|
length = imul(size, size) | 0;
|
|
|
|
while ((length | 0) > 0) {
|
|
length = (length - 1) | 0;
|
|
images[(dstImagePtr + length) | 0] = (images[(srcImagePtr + length) | 0] | 0);
|
|
}
|
|
}
|
|
|
|
function zeroBorder(imagePtr) {
|
|
imagePtr = imagePtr | 0;
|
|
|
|
var x = 0,
|
|
y = 0;
|
|
|
|
for ( x = 0; (x | 0) < ((size - 1) | 0); x = (x + 1) | 0) {
|
|
images[(imagePtr + x) | 0] = 0;
|
|
images[(imagePtr + y) | 0] = 0;
|
|
y = ((y + size) - 1) | 0;
|
|
images[(imagePtr + y) | 0] = 0;
|
|
y = (y + 1) | 0;
|
|
}
|
|
for ( x = 0; (x | 0) < (size | 0); x = (x + 1) | 0) {
|
|
images[(imagePtr + y) | 0] = 0;
|
|
y = (y + 1) | 0;
|
|
}
|
|
}
|
|
|
|
function skeletonize() {
|
|
var subImagePtr = 0,
|
|
erodedImagePtr = 0,
|
|
tempImagePtr = 0,
|
|
skelImagePtr = 0,
|
|
sum = 0,
|
|
done = 0;
|
|
|
|
erodedImagePtr = imul(size, size) | 0;
|
|
tempImagePtr = (erodedImagePtr + erodedImagePtr) | 0;
|
|
skelImagePtr = (tempImagePtr + erodedImagePtr) | 0;
|
|
|
|
// init skel-image
|
|
init(skelImagePtr, 0);
|
|
zeroBorder(subImagePtr);
|
|
|
|
do {
|
|
erode(subImagePtr, erodedImagePtr);
|
|
dilate(erodedImagePtr, tempImagePtr);
|
|
subtract(subImagePtr, tempImagePtr, tempImagePtr);
|
|
bitwiseOr(skelImagePtr, tempImagePtr, skelImagePtr);
|
|
memcpy(erodedImagePtr, subImagePtr);
|
|
sum = countNonZero(subImagePtr) | 0;
|
|
done = ((sum | 0) === 0 | 0);
|
|
} while (!done);
|
|
}
|
|
|
|
return {
|
|
skeletonize: skeletonize
|
|
};
|
|
}
|
|
/* @preserve ASM END */
|
|
|
|
export default Skeletonizer;
|