image-js 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-js.esm.js +866 -198
- package/dist/image-js.esm.js.map +1 -1
- package/dist/image-js.esm.min.js +2 -2
- package/dist/image-js.esm.min.js.map +1 -1
- package/dist/image-js.umd.js +866 -198
- package/dist/image-js.umd.js.map +1 -1
- package/dist/image-js.umd.min.js +2 -2
- package/dist/image-js.umd.min.js.map +1 -1
- package/dist-types/image-js.d.ts +2 -3
- package/lib/Mask.d.ts +1 -1
- package/lib/Mask.js +1 -1
- package/lib/featureMatching/matching/filterEuclideanDistance.d.ts.map +1 -1
- package/lib/featureMatching/matching/filterEuclideanDistance.js +6 -7
- package/lib/featureMatching/matching/filterEuclideanDistance.js.map +1 -1
- package/lib/featureMatching/matching/filterSmallestDistanceMatches.d.ts.map +1 -1
- package/lib/featureMatching/matching/filterSmallestDistanceMatches.js +6 -3
- package/lib/featureMatching/matching/filterSmallestDistanceMatches.js.map +1 -1
- package/lib/featureMatching/utils/sortByDistance.d.ts.map +1 -1
- package/lib/featureMatching/utils/sortByDistance.js +3 -1
- package/lib/featureMatching/utils/sortByDistance.js.map +1 -1
- package/lib/featureMatching/utils/sortBySourceDest.d.ts.map +1 -1
- package/lib/featureMatching/utils/sortBySourceDest.js +6 -2
- package/lib/featureMatching/utils/sortBySourceDest.js.map +1 -1
- package/lib/load/decode.d.ts.map +1 -1
- package/lib/load/decode.js +2 -0
- package/lib/load/decode.js.map +1 -1
- package/lib/load/decodeBmp.d.ts +8 -0
- package/lib/load/decodeBmp.d.ts.map +1 -0
- package/lib/load/decodeBmp.js +36 -0
- package/lib/load/decodeBmp.js.map +1 -0
- package/lib/load/decodePng.d.ts.map +1 -1
- package/lib/load/decodePng.js +29 -5
- package/lib/load/decodePng.js.map +1 -1
- package/lib/load/decodeTiff.d.ts.map +1 -1
- package/lib/load/decodeTiff.js +44 -21
- package/lib/load/decodeTiff.js.map +1 -1
- package/lib/maskAnalysis/utils/getMbrAngle.d.ts.map +1 -1
- package/lib/maskAnalysis/utils/getMbrAngle.js +2 -1
- package/lib/maskAnalysis/utils/getMbrAngle.js.map +1 -1
- package/lib/maskAnalysis/utils/monotoneChainConvexHull.d.ts.map +1 -1
- package/lib/maskAnalysis/utils/monotoneChainConvexHull.js +2 -1
- package/lib/maskAnalysis/utils/monotoneChainConvexHull.js.map +1 -1
- package/lib/save/encodeBmp.d.ts +4 -4
- package/lib/save/encodeBmp.d.ts.map +1 -1
- package/lib/save/encodeBmp.js +22 -14
- package/lib/save/encodeBmp.js.map +1 -1
- package/lib/stack/load/decodeApng.d.ts +8 -0
- package/lib/stack/load/decodeApng.d.ts.map +1 -0
- package/lib/stack/load/decodeApng.js +60 -0
- package/lib/stack/load/decodeApng.js.map +1 -0
- package/lib/stack/load/decodeStack.d.ts.map +1 -1
- package/lib/stack/load/decodeStack.js +2 -0
- package/lib/stack/load/decodeStack.js.map +1 -1
- package/lib/utils/geometry/points.d.ts.map +1 -1
- package/lib/utils/geometry/points.js +3 -1
- package/lib/utils/geometry/points.js.map +1 -1
- package/lib/utils/geometry/removeClosePoints.d.ts.map +1 -1
- package/lib/utils/geometry/removeClosePoints.js +2 -1
- package/lib/utils/geometry/removeClosePoints.js.map +1 -1
- package/package.json +27 -27
- package/src/Mask.ts +1 -1
- package/src/featureMatching/matching/filterEuclideanDistance.ts +6 -13
- package/src/featureMatching/matching/filterSmallestDistanceMatches.ts +6 -9
- package/src/featureMatching/utils/sortByDistance.ts +3 -1
- package/src/featureMatching/utils/sortBySourceDest.ts +6 -2
- package/src/load/decode.ts +2 -1
- package/src/load/decodeBmp.ts +37 -0
- package/src/load/decodePng.ts +39 -7
- package/src/load/decodeTiff.ts +53 -22
- package/src/maskAnalysis/utils/getMbrAngle.ts +2 -1
- package/src/maskAnalysis/utils/monotoneChainConvexHull.ts +2 -1
- package/src/save/encodeBmp.ts +22 -15
- package/src/stack/load/decodeApng.ts +71 -0
- package/src/stack/load/decodeStack.ts +2 -0
- package/src/utils/geometry/points.ts +3 -1
- package/src/utils/geometry/removeClosePoints.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encodeBmp.js","sourceRoot":"","sources":["../../src/save/encodeBmp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"encodeBmp.js","sourceRoot":"","sources":["../../src/save/encodeBmp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAmB;IAC3C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,GAAG,CAAC,MAAM,CAAC;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ;YAC7C,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,MAAM,CAAC;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,CAAC;YACX,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decodeApng.d.ts","sourceRoot":"","sources":["../../../src/stack/load/decodeApng.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,SAgDnD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { decodeApng } from 'fast-png';
|
|
2
|
+
import { Image } from "../../Image.js";
|
|
3
|
+
import { Stack } from "../../Stack.js";
|
|
4
|
+
/**
|
|
5
|
+
* Decodes APNG image into a Stack
|
|
6
|
+
* @param data - APNG data.
|
|
7
|
+
* @returns stack of frames.
|
|
8
|
+
*/
|
|
9
|
+
export function decodeStackFromApng(data) {
|
|
10
|
+
const decodedApng = decodeApng(data);
|
|
11
|
+
const images = [];
|
|
12
|
+
let colorModel;
|
|
13
|
+
switch (decodedApng.channels) {
|
|
14
|
+
case 1:
|
|
15
|
+
if (decodedApng.palette) {
|
|
16
|
+
colorModel = decodedApng.palette[0].length === 3 ? 'RGB' : 'RGBA';
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
colorModel = 'GREY';
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
case 2:
|
|
23
|
+
colorModel = 'GREYA';
|
|
24
|
+
break;
|
|
25
|
+
case 3:
|
|
26
|
+
colorModel = 'RGB';
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
colorModel = 'RGBA';
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
if (decodedApng.palette) {
|
|
33
|
+
for (const image of decodedApng.frames) {
|
|
34
|
+
images.push(new Image(decodedApng.width, decodedApng.height, {
|
|
35
|
+
data: convertIndexedData(image.data, decodedApng.palette),
|
|
36
|
+
colorModel,
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
for (const image of decodedApng.frames) {
|
|
42
|
+
images.push(new Image(decodedApng.width, decodedApng.height, {
|
|
43
|
+
data: image.data,
|
|
44
|
+
colorModel,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const stack = new Stack(images);
|
|
49
|
+
return stack;
|
|
50
|
+
}
|
|
51
|
+
function convertIndexedData(data, palette) {
|
|
52
|
+
const result = new Uint8Array(data.length * palette[0].length);
|
|
53
|
+
for (let i = 0; i < data.length; i++) {
|
|
54
|
+
for (let channel = 0; channel < palette[0].length; channel++) {
|
|
55
|
+
result[i * palette[0].length + channel] = palette[data[i]][channel];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=decodeApng.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decodeApng.js","sourceRoot":"","sources":["../../../src/stack/load/decodeApng.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAgB;IAClD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,IAAI,UAA2B,CAAC;IAChC,QAAQ,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC7B,KAAK,CAAC;YACJ,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACxB,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,MAAM,CAAC;YACtB,CAAC;YACD,MAAM;QACR,KAAK,CAAC;YACJ,UAAU,GAAG,OAAO,CAAC;YACrB,MAAM;QACR,KAAK,CAAC;YACJ,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM;QACR;YACE,UAAU,GAAG,MAAM,CAAC;YACpB,MAAM;IACV,CAAC;IACD,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CACT,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE;gBAC/C,IAAI,EAAE,kBAAkB,CACtB,KAAK,CAAC,IAAkB,EACxB,WAAW,CAAC,OAAO,CACpB;gBACD,UAAU;aACX,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CACT,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE;gBAC/C,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,UAAU;aACX,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAEhC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAgB,EAAE,OAAsB;IAClE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;YAC7D,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decodeStack.d.ts","sourceRoot":"","sources":["../../../src/stack/load/decodeStack.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"decodeStack.d.ts","sourceRoot":"","sources":["../../../src/stack/load/decodeStack.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAK5C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,KAAK,CAaxD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import imageType from 'image-type';
|
|
2
2
|
import { match } from 'ts-pattern';
|
|
3
|
+
import { decodeStackFromApng } from "./decodeApng.js";
|
|
3
4
|
import { decodeStackFromTiff } from './decodeTiff.js';
|
|
4
5
|
/**
|
|
5
6
|
* Decode input data and create stack. Data format is automatically detected.
|
|
@@ -12,6 +13,7 @@ export function decodeStack(data) {
|
|
|
12
13
|
const type = imageType(typedArray);
|
|
13
14
|
return match(type)
|
|
14
15
|
.with({ mime: 'image/tiff' }, () => decodeStackFromTiff(typedArray))
|
|
16
|
+
.with({ mime: 'image/png' }, () => decodeStackFromApng(typedArray))
|
|
15
17
|
.otherwise(() => {
|
|
16
18
|
throw new RangeError(`invalid data format: ${type?.mime}`);
|
|
17
19
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decodeStack.js","sourceRoot":"","sources":["../../../src/stack/load/decodeStack.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAqB;IAC/C,MAAM,UAAU,GAAG,IAAI,UAAU,CAC/B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,CAChB,CAAC;IACF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC;SACf,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;SACnE,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,IAAI,UAAU,CAAC,wBAAwB,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
1
|
+
{"version":3,"file":"decodeStack.js","sourceRoot":"","sources":["../../../src/stack/load/decodeStack.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAqB;IAC/C,MAAM,UAAU,GAAG,IAAI,UAAU,CAC/B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,CAChB,CAAC;IACF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC;SACf,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;SACnE,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;SAClE,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,IAAI,UAAU,CAAC,wBAAwB,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"points.d.ts","sourceRoot":"","sources":["../../../src/utils/geometry/points.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAG7C;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,KAAK,EAAE,CAWzE;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,UAEvC;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"points.d.ts","sourceRoot":"","sources":["../../../src/utils/geometry/points.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAG7C;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,KAAK,EAAE,CAWzE;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,UAEvC;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAQxD"}
|
|
@@ -67,12 +67,14 @@ export function round(point) {
|
|
|
67
67
|
* @returns Sorted points.
|
|
68
68
|
*/
|
|
69
69
|
export function sortByColumnRow(points) {
|
|
70
|
-
|
|
70
|
+
const sortedPoints = points.slice();
|
|
71
|
+
sortedPoints.sort((point1, point2) => {
|
|
71
72
|
if (point1.column < point2.column)
|
|
72
73
|
return -1;
|
|
73
74
|
if (point1.column > point2.column)
|
|
74
75
|
return 1;
|
|
75
76
|
return point1.row - point2.row;
|
|
76
77
|
});
|
|
78
|
+
return sortedPoints;
|
|
77
79
|
}
|
|
78
80
|
//# sourceMappingURL=points.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"points.js","sourceRoot":"","sources":["../../../src/utils/geometry/points.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAS,EAAE,EAAS;IAC7C,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,EAAS,EAAE,EAAS;IACtC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAY;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,MAAwB;IAC9D,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC;YACX,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG;YAC5C,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG;SAC1C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,EAAS,EAAE,EAAS;IACtC,OAAO,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAY;IAChC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,
|
|
1
|
+
{"version":3,"file":"points.js","sourceRoot":"","sources":["../../../src/utils/geometry/points.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAS,EAAE,EAAS;IAC7C,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,EAAS,EAAE,EAAS;IACtC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAY;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,MAAwB;IAC9D,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC;YACX,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG;YAC5C,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG;SAC1C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,EAAS,EAAE,EAAS;IACtC,OAAO,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAY;IAChC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACpC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeClosePoints.d.ts","sourceRoot":"","sources":["../../../src/utils/geometry/removeClosePoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"removeClosePoints.d.ts","sourceRoot":"","sources":["../../../src/utils/geometry/removeClosePoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,wBAAwB,WAiClC"}
|
|
@@ -13,7 +13,8 @@ export function removeClosePoints(points, image, options) {
|
|
|
13
13
|
}
|
|
14
14
|
const channel = options?.channel || 0;
|
|
15
15
|
const isMax = kind === 'maximum';
|
|
16
|
-
const sortedPoints = points.slice()
|
|
16
|
+
const sortedPoints = points.slice();
|
|
17
|
+
sortedPoints.sort(getSort(image, channel, isMax));
|
|
17
18
|
if (distance > 0) {
|
|
18
19
|
for (let i = 0; i < sortedPoints.length; i++) {
|
|
19
20
|
for (let j = i + 1; j < sortedPoints.length; j++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeClosePoints.js","sourceRoot":"","sources":["../../../src/utils/geometry/removeClosePoints.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAe,EACf,KAAY,EACZ,OAAiC;IAEjC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,SAAS,CAAC;IAExC,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC;IAEjC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"removeClosePoints.js","sourceRoot":"","sources":["../../../src/utils/geometry/removeClosePoints.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAe,EACf,KAAY,EACZ,OAAiC;IAEjC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,SAAS,CAAC;IAExC,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC;IAEjC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACpC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAElD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACjD,IACE,IAAI,CAAC,KAAK,CACR,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,EAC/C,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAC1C,GAAG,QAAQ,EACZ,CAAC;oBACD,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC1B,CAAC,EAAE,CAAC;gBACN,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,OAAO,CAAC,KAAY,EAAE,OAAe,EAAE,YAAqB;IACnE,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,SAAS,cAAc,CAAC,CAAQ,EAAE,CAAQ;YAC/C,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC;gBACxC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CACzC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,SAAS,aAAa,CAAC,CAAQ,EAAE,CAAQ;YAC9C,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC;gBACxC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CACzC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "image-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Image processing and manipulation in JavaScript",
|
|
6
6
|
"author": "Michaël Zasso",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"tsc-build": "tsc --project tsconfig.build.json"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"bresenham-zingl": "^0.2.
|
|
37
|
+
"bresenham-zingl": "^0.2.5",
|
|
38
38
|
"colord": "^2.9.3",
|
|
39
39
|
"fast-bmp": "^4.0.1",
|
|
40
40
|
"fast-jpeg": "^3.0.1",
|
|
@@ -49,47 +49,47 @@
|
|
|
49
49
|
"ml-ransac": "^1.0.0",
|
|
50
50
|
"ml-regression-multivariate-linear": "^2.0.4",
|
|
51
51
|
"ml-regression-polynomial-2d": "^1.0.0",
|
|
52
|
-
"ml-spectra-processing": "^14.
|
|
52
|
+
"ml-spectra-processing": "^14.18.0",
|
|
53
53
|
"robust-point-in-polygon": "^1.0.3",
|
|
54
54
|
"ssim.js": "^3.5.0",
|
|
55
|
-
"tiff": "^7.1.
|
|
56
|
-
"ts-pattern": "^5.
|
|
55
|
+
"tiff": "^7.1.2",
|
|
56
|
+
"ts-pattern": "^5.9.0",
|
|
57
57
|
"uint8-base64": "^1.0.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@microsoft/api-extractor": "^7.
|
|
60
|
+
"@microsoft/api-extractor": "^7.53.3",
|
|
61
61
|
"@tailwindcss/forms": "^0.5.10",
|
|
62
|
-
"@tailwindcss/vite": "^4.1.
|
|
62
|
+
"@tailwindcss/vite": "^4.1.16",
|
|
63
63
|
"@types/jest-image-snapshot": "^6.4.0",
|
|
64
64
|
"@types/js-priority-queue": "^0.0.9",
|
|
65
|
-
"@types/node": "^24.
|
|
66
|
-
"@types/react": "^19.
|
|
67
|
-
"@types/react-dom": "^19.
|
|
65
|
+
"@types/node": "^24.9.2",
|
|
66
|
+
"@types/react": "^19.2.2",
|
|
67
|
+
"@types/react-dom": "^19.2.2",
|
|
68
68
|
"@types/robust-point-in-polygon": "^1.0.4",
|
|
69
|
-
"@vitejs/plugin-react": "^5.0
|
|
70
|
-
"@vitest/coverage-v8": "^
|
|
71
|
-
"@vitest/expect": "^
|
|
69
|
+
"@vitejs/plugin-react": "^5.1.0",
|
|
70
|
+
"@vitest/coverage-v8": "^4.0.6",
|
|
71
|
+
"@vitest/expect": "^4.0.6",
|
|
72
72
|
"@zakodium/tsconfig": "^1.0.2",
|
|
73
73
|
"autoprefixer": "^10.4.21",
|
|
74
|
-
"cheminfo-build": "^1.3.
|
|
74
|
+
"cheminfo-build": "^1.3.1",
|
|
75
75
|
"clsx": "^2.1.1",
|
|
76
|
-
"cross-env": "^10.
|
|
77
|
-
"eslint": "^9.
|
|
78
|
-
"eslint-config-cheminfo-react": "^
|
|
79
|
-
"eslint-config-cheminfo-typescript": "^
|
|
80
|
-
"immer": "^10.
|
|
76
|
+
"cross-env": "^10.1.0",
|
|
77
|
+
"eslint": "^9.38.0",
|
|
78
|
+
"eslint-config-cheminfo-react": "^18.0.1",
|
|
79
|
+
"eslint-config-cheminfo-typescript": "^20.0.0",
|
|
80
|
+
"immer": "^10.2.0",
|
|
81
81
|
"jest-image-snapshot": "^6.5.1",
|
|
82
82
|
"jest-matcher-deep-close-to": "^3.0.2",
|
|
83
83
|
"postcss": "^8.5.6",
|
|
84
84
|
"prettier": "^3.6.2",
|
|
85
|
-
"react": "^19.
|
|
86
|
-
"react-dom": "^19.
|
|
87
|
-
"react-router-dom": "^7.
|
|
88
|
-
"rimraf": "^6.0
|
|
89
|
-
"tailwindcss": "^4.1.
|
|
90
|
-
"typescript": "~5.9.
|
|
91
|
-
"vite": "^7.1.
|
|
92
|
-
"vitest": "^
|
|
85
|
+
"react": "^19.2.0",
|
|
86
|
+
"react-dom": "^19.2.0",
|
|
87
|
+
"react-router-dom": "^7.9.5",
|
|
88
|
+
"rimraf": "^6.1.0",
|
|
89
|
+
"tailwindcss": "^4.1.16",
|
|
90
|
+
"typescript": "~5.9.3",
|
|
91
|
+
"vite": "^7.1.12",
|
|
92
|
+
"vitest": "^4.0.6"
|
|
93
93
|
},
|
|
94
94
|
"repository": {
|
|
95
95
|
"type": "git",
|
package/src/Mask.ts
CHANGED
|
@@ -28,9 +28,8 @@ export function filterEuclideanDistance(
|
|
|
28
28
|
): Match[] {
|
|
29
29
|
const { origin = { column: 0, row: 0 } } = options;
|
|
30
30
|
|
|
31
|
-
const sorted = matches.
|
|
32
|
-
|
|
33
|
-
);
|
|
31
|
+
const sorted = matches.slice();
|
|
32
|
+
sorted.sort((a, b) => a.destinationIndex - b.destinationIndex);
|
|
34
33
|
|
|
35
34
|
const result: Match[] = [];
|
|
36
35
|
let sameDestMatches: Match[] = [];
|
|
@@ -39,21 +38,15 @@ export function filterEuclideanDistance(
|
|
|
39
38
|
if (match.destinationIndex === currentIndex) {
|
|
40
39
|
sameDestMatches.push(match);
|
|
41
40
|
} else {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.sort((a, b) => distanceSquared(a) - distanceSquared(b))
|
|
45
|
-
.slice(0, 1),
|
|
46
|
-
);
|
|
41
|
+
sameDestMatches.sort((a, b) => distanceSquared(a) - distanceSquared(b));
|
|
42
|
+
result.push(...sameDestMatches.slice(0, 1));
|
|
47
43
|
|
|
48
44
|
currentIndex = match.destinationIndex;
|
|
49
45
|
sameDestMatches = [match];
|
|
50
46
|
}
|
|
51
47
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.sort((a, b) => distanceSquared(a) - distanceSquared(b))
|
|
55
|
-
.slice(0, 1),
|
|
56
|
-
);
|
|
48
|
+
sameDestMatches.sort((a, b) => distanceSquared(a) - distanceSquared(b));
|
|
49
|
+
result.push(...sameDestMatches.slice(0, 1));
|
|
57
50
|
return result;
|
|
58
51
|
|
|
59
52
|
function distanceSquared(match: Match): number {
|
|
@@ -7,9 +7,8 @@ import type { Match } from './bruteForceMatch.js';
|
|
|
7
7
|
* @returns Only the matches from source to destination with the smallest distance.
|
|
8
8
|
*/
|
|
9
9
|
export function filterSmallestDistanceMatches(matches: Match[]): Match[] {
|
|
10
|
-
const sorted = matches.
|
|
11
|
-
|
|
12
|
-
);
|
|
10
|
+
const sorted = matches.slice();
|
|
11
|
+
sorted.sort((a, b) => a.destinationIndex - b.destinationIndex);
|
|
13
12
|
|
|
14
13
|
const result: Match[] = [];
|
|
15
14
|
let sameDestMatches: Match[] = [];
|
|
@@ -18,16 +17,14 @@ export function filterSmallestDistanceMatches(matches: Match[]): Match[] {
|
|
|
18
17
|
if (match.destinationIndex === currentIndex) {
|
|
19
18
|
sameDestMatches.push(match);
|
|
20
19
|
} else {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
20
|
+
sameDestMatches.sort((a, b) => a.distance - b.distance);
|
|
21
|
+
result.push(...sameDestMatches.slice(0, 1));
|
|
24
22
|
|
|
25
23
|
currentIndex = match.destinationIndex;
|
|
26
24
|
sameDestMatches = [match];
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
27
|
+
sameDestMatches.sort((a, b) => a.distance - b.distance);
|
|
28
|
+
result.push(...sameDestMatches.slice(0, 1));
|
|
32
29
|
return result;
|
|
33
30
|
}
|
|
@@ -6,7 +6,9 @@ import type { Match } from '../matching/bruteForceMatch.js';
|
|
|
6
6
|
* @returns Sorted copy of the array of matches.
|
|
7
7
|
*/
|
|
8
8
|
export function sortByDistance(matches: Match[]): Match[] {
|
|
9
|
-
|
|
9
|
+
const sorted = matches.slice();
|
|
10
|
+
sorted.sort((match1, match2) => {
|
|
10
11
|
return match1.distance - match2.distance;
|
|
11
12
|
});
|
|
13
|
+
return sorted;
|
|
12
14
|
}
|
|
@@ -6,11 +6,13 @@ import type { Match } from '../matching/bruteForceMatch.js';
|
|
|
6
6
|
* @returns Sorted copy of the array of matches.
|
|
7
7
|
*/
|
|
8
8
|
export function sortBySourceDest(matches: Match[]): Match[] {
|
|
9
|
-
|
|
9
|
+
const sorted = matches.slice();
|
|
10
|
+
sorted.sort((match1, match2) => {
|
|
10
11
|
if (match1.sourceIndex < match2.sourceIndex) return -1;
|
|
11
12
|
if (match1.sourceIndex > match2.sourceIndex) return 1;
|
|
12
13
|
return match1.destinationIndex - match2.destinationIndex;
|
|
13
14
|
});
|
|
15
|
+
return sorted;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -19,9 +21,11 @@ export function sortBySourceDest(matches: Match[]): Match[] {
|
|
|
19
21
|
* @returns Sorted copy of the array of matches.
|
|
20
22
|
*/
|
|
21
23
|
export function sortByDestSource(matches: Match[]): Match[] {
|
|
22
|
-
|
|
24
|
+
const sorted = matches.slice();
|
|
25
|
+
sorted.sort((match1, match2) => {
|
|
23
26
|
if (match1.destinationIndex < match2.destinationIndex) return -1;
|
|
24
27
|
if (match1.destinationIndex > match2.destinationIndex) return 1;
|
|
25
28
|
return match1.sourceIndex - match2.sourceIndex;
|
|
26
29
|
});
|
|
30
|
+
return sorted;
|
|
27
31
|
}
|
package/src/load/decode.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { match } from 'ts-pattern';
|
|
|
3
3
|
|
|
4
4
|
import type { Image } from '../Image.js';
|
|
5
5
|
|
|
6
|
+
import { decodeBmp } from './decodeBmp.ts';
|
|
6
7
|
import { decodeJpeg } from './decodeJpeg.js';
|
|
7
8
|
import { decodePng } from './decodePng.js';
|
|
8
9
|
import { decodeTiff } from './decodeTiff.js';
|
|
9
|
-
|
|
10
10
|
/**
|
|
11
11
|
* Decode input data. Data format is automatically detected.
|
|
12
12
|
* Possible formats: png, jpeg and tiff.
|
|
@@ -24,6 +24,7 @@ export function decode(data: ArrayBufferView): Image {
|
|
|
24
24
|
.with({ mime: 'image/png' }, () => decodePng(typedArray))
|
|
25
25
|
.with({ mime: 'image/jpeg' }, () => decodeJpeg(typedArray))
|
|
26
26
|
.with({ mime: 'image/tiff' }, () => decodeTiff(typedArray))
|
|
27
|
+
.with({ mime: 'image/bmp' }, () => decodeBmp(typedArray))
|
|
27
28
|
.otherwise(() => {
|
|
28
29
|
throw new RangeError(`invalid data format: ${type?.mime}`);
|
|
29
30
|
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { decode } from 'fast-bmp';
|
|
2
|
+
|
|
3
|
+
import { Image } from '../Image.ts';
|
|
4
|
+
import { Mask } from '../Mask.ts';
|
|
5
|
+
import type { ImageColorModel } from '../utils/constants/colorModels.ts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Decode a BMP. See the fast-bmp npm module.
|
|
9
|
+
* @param data - The data to decode.
|
|
10
|
+
* @returns The decoded image or mask.
|
|
11
|
+
*/
|
|
12
|
+
export function decodeBmp(data: Uint8Array): Image {
|
|
13
|
+
const decodedData = decode(data);
|
|
14
|
+
if (decodedData.bitsPerPixel === 1) {
|
|
15
|
+
const mask = new Mask(decodedData.width, decodedData.height, {
|
|
16
|
+
data: decodedData.data as Uint8Array,
|
|
17
|
+
});
|
|
18
|
+
return mask.convertColor('GREY');
|
|
19
|
+
} else {
|
|
20
|
+
let colorModel: ImageColorModel;
|
|
21
|
+
switch (decodedData.channels) {
|
|
22
|
+
case 1:
|
|
23
|
+
colorModel = 'GREY';
|
|
24
|
+
break;
|
|
25
|
+
case 3:
|
|
26
|
+
colorModel = 'RGB';
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
colorModel = 'RGBA';
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
return new Image(decodedData.width, decodedData.height, {
|
|
33
|
+
colorModel,
|
|
34
|
+
data: decodedData.data as Uint8Array,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/load/decodePng.ts
CHANGED
|
@@ -15,12 +15,16 @@ export function decodePng(buffer: Uint8Array): Image {
|
|
|
15
15
|
const png = decode(buffer);
|
|
16
16
|
|
|
17
17
|
let colorModel: ImageColorModel;
|
|
18
|
-
const bitDepth: BitDepth = png.depth
|
|
19
|
-
|
|
18
|
+
const bitDepth: BitDepth = png.depth as BitDepth;
|
|
20
19
|
if (png.palette) {
|
|
21
20
|
return loadPalettePng(png);
|
|
22
21
|
}
|
|
23
|
-
|
|
22
|
+
if (bitDepth === 1) {
|
|
23
|
+
return new Image(png.width, png.height, {
|
|
24
|
+
data: decodeBinary(png),
|
|
25
|
+
colorModel: 'GREY',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
24
28
|
switch (png.channels) {
|
|
25
29
|
case 1:
|
|
26
30
|
colorModel = 'GREY';
|
|
@@ -37,6 +41,7 @@ export function decodePng(buffer: Uint8Array): Image {
|
|
|
37
41
|
default:
|
|
38
42
|
throw new RangeError(`invalid number of channels: ${png.channels}`);
|
|
39
43
|
}
|
|
44
|
+
|
|
40
45
|
return new Image(png.width, png.height, {
|
|
41
46
|
colorModel,
|
|
42
47
|
bitDepth,
|
|
@@ -52,7 +57,7 @@ export function decodePng(buffer: Uint8Array): Image {
|
|
|
52
57
|
function loadPalettePng(png: DecodedPng): Image {
|
|
53
58
|
assert(png.palette);
|
|
54
59
|
const pixels = png.width * png.height;
|
|
55
|
-
const data = new Uint8Array(pixels *
|
|
60
|
+
const data = new Uint8Array(pixels * png.palette[0].length);
|
|
56
61
|
const pixelsPerByte = 8 / png.depth;
|
|
57
62
|
const factor = png.depth < 8 ? pixelsPerByte : 1;
|
|
58
63
|
const mask = Number.parseInt('1'.repeat(png.depth), 2);
|
|
@@ -67,12 +72,39 @@ function loadPalettePng(png: DecodedPng): Image {
|
|
|
67
72
|
mask;
|
|
68
73
|
}
|
|
69
74
|
const paletteValue = png.palette[value];
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
for (const paletteChannel of paletteValue) {
|
|
76
|
+
data[dataIndex++] = paletteChannel;
|
|
77
|
+
}
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
return new Image(png.width, png.height, {
|
|
76
81
|
data,
|
|
82
|
+
colorModel: png.palette[0].length === 4 ? 'RGBA' : 'RGB',
|
|
77
83
|
});
|
|
78
84
|
}
|
|
85
|
+
|
|
86
|
+
function decodeBinary(png: DecodedPng): Uint8Array {
|
|
87
|
+
const totalPixels = png.width * png.height;
|
|
88
|
+
const result = new Uint8Array(totalPixels);
|
|
89
|
+
const pngData = png.data;
|
|
90
|
+
const padding = png.width % 8;
|
|
91
|
+
const bytesPerLine = Math.ceil(png.width / 8);
|
|
92
|
+
let pixelIndex = 0;
|
|
93
|
+
for (
|
|
94
|
+
let byteIndex = 0;
|
|
95
|
+
byteIndex < pngData.length && pixelIndex < totalPixels;
|
|
96
|
+
byteIndex++
|
|
97
|
+
) {
|
|
98
|
+
const byte = pngData[byteIndex];
|
|
99
|
+
const limit = byteIndex % bytesPerLine === 0 ? 8 - padding : 0;
|
|
100
|
+
for (
|
|
101
|
+
let bitIndex = 7;
|
|
102
|
+
bitIndex >= limit && pixelIndex < totalPixels;
|
|
103
|
+
bitIndex--
|
|
104
|
+
) {
|
|
105
|
+
const bit = (byte >> bitIndex) & 1;
|
|
106
|
+
result[pixelIndex++] = bit * 255;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
package/src/load/decodeTiff.ts
CHANGED
|
@@ -13,9 +13,8 @@ type TiffIfd = ReturnType<typeof decode>[number];
|
|
|
13
13
|
* @returns The decoded image.
|
|
14
14
|
*/
|
|
15
15
|
export function decodeTiff(buffer: Uint8Array): Image {
|
|
16
|
-
const result = decode(buffer);
|
|
16
|
+
const result = decode(buffer, { pages: [0] });
|
|
17
17
|
return getImageFromIFD(result[0]);
|
|
18
|
-
// TODO: optimize not to decode whole file
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -24,39 +23,71 @@ export function decodeTiff(buffer: Uint8Array): Image {
|
|
|
24
23
|
* @returns The decoded image.
|
|
25
24
|
*/
|
|
26
25
|
export function getImageFromIFD(ifd: TiffIfd): Image {
|
|
26
|
+
if (ifd.data instanceof Float32Array || ifd.data instanceof Float64Array) {
|
|
27
|
+
throw new Error('Float TIFF data is not supported.');
|
|
28
|
+
}
|
|
29
|
+
|
|
27
30
|
if (ifd.type === 3) {
|
|
28
|
-
|
|
29
|
-
const
|
|
31
|
+
const hasAlpha = ifd.samplesPerPixel === 2;
|
|
32
|
+
const pixelLength = hasAlpha ? 4 : 3;
|
|
33
|
+
const data = new Uint16Array(pixelLength * ifd.width * ifd.height);
|
|
30
34
|
const palette = ifd.palette as Array<[number, number, number]>;
|
|
31
35
|
let ptr = 0;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
if (hasAlpha) {
|
|
37
|
+
for (
|
|
38
|
+
let index = 0;
|
|
39
|
+
index < ifd.data.length;
|
|
40
|
+
index += ifd.samplesPerPixel
|
|
41
|
+
) {
|
|
42
|
+
const color = palette[ifd.data[index]];
|
|
43
|
+
data[ptr++] = color[0];
|
|
44
|
+
data[ptr++] = color[1];
|
|
45
|
+
data[ptr++] = color[2];
|
|
46
|
+
// To ensure that the value is 16 bits.
|
|
47
|
+
data[ptr++] = Math.round(
|
|
48
|
+
(ifd.data[index + 1] / 2 ** ifd.bitsPerSample) * 65535,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
for (
|
|
53
|
+
let index = 0;
|
|
54
|
+
index < ifd.data.length;
|
|
55
|
+
index += ifd.samplesPerPixel
|
|
56
|
+
) {
|
|
57
|
+
const color = palette[ifd.data[index]];
|
|
58
|
+
data[ptr++] = color[0];
|
|
59
|
+
data[ptr++] = color[1];
|
|
60
|
+
data[ptr++] = color[2];
|
|
61
|
+
}
|
|
37
62
|
}
|
|
63
|
+
|
|
38
64
|
return new Image(ifd.width, ifd.height, {
|
|
39
65
|
data,
|
|
40
|
-
|
|
41
|
-
colorModel: ifd.alpha ? 'RGBA' : 'RGB',
|
|
42
|
-
// TODO: handle other bit depths
|
|
66
|
+
colorModel: hasAlpha ? 'RGBA' : 'RGB',
|
|
43
67
|
bitDepth: 16,
|
|
44
68
|
meta: getMetadata(ifd),
|
|
45
69
|
});
|
|
70
|
+
} else if (ifd.type === 1 || ifd.type === 0) {
|
|
71
|
+
if (ifd.bitsPerSample !== 1) {
|
|
72
|
+
return new Image(ifd.width, ifd.height, {
|
|
73
|
+
data: ifd.data,
|
|
74
|
+
bitDepth: ifd.bitsPerSample as BitDepth,
|
|
75
|
+
colorModel: ifd.alpha ? 'GREYA' : 'GREY',
|
|
76
|
+
meta: getMetadata(ifd),
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
return new Image(ifd.width, ifd.height, {
|
|
80
|
+
data: ifd.data.map((pixel) => pixel * 255),
|
|
81
|
+
bitDepth: 8 as BitDepth,
|
|
82
|
+
colorModel: 'GREY',
|
|
83
|
+
meta: getMetadata(ifd),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
46
86
|
} else {
|
|
47
87
|
return new Image(ifd.width, ifd.height, {
|
|
48
|
-
// TODO: handle float data
|
|
49
|
-
// @ts-expect-error float data not handled yet
|
|
50
88
|
data: ifd.data,
|
|
51
89
|
bitDepth: ifd.bitsPerSample as BitDepth,
|
|
52
|
-
colorModel:
|
|
53
|
-
ifd.type === 2
|
|
54
|
-
? ifd.alpha
|
|
55
|
-
? 'RGBA'
|
|
56
|
-
: 'RGB'
|
|
57
|
-
: ifd.alpha
|
|
58
|
-
? 'GREYA'
|
|
59
|
-
: 'GREY',
|
|
90
|
+
colorModel: ifd.alpha ? 'RGBA' : 'RGB',
|
|
60
91
|
meta: getMetadata(ifd),
|
|
61
92
|
});
|
|
62
93
|
}
|
|
@@ -14,7 +14,8 @@ const topFirst = (mbrPoint1: Point, mbrPoint2: Point) =>
|
|
|
14
14
|
* @returns The angle in degrees.
|
|
15
15
|
*/
|
|
16
16
|
export function getMbrAngle(mbr: readonly Point[]): number {
|
|
17
|
-
const sorted = mbr.slice()
|
|
17
|
+
const sorted = mbr.slice();
|
|
18
|
+
sorted.sort(leftFirst);
|
|
18
19
|
const left = sorted.slice(0, 2);
|
|
19
20
|
const right = sorted.slice(2, 4);
|
|
20
21
|
left.sort(topFirst);
|