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.
Files changed (76) hide show
  1. package/dist/image-js.esm.js +866 -198
  2. package/dist/image-js.esm.js.map +1 -1
  3. package/dist/image-js.esm.min.js +2 -2
  4. package/dist/image-js.esm.min.js.map +1 -1
  5. package/dist/image-js.umd.js +866 -198
  6. package/dist/image-js.umd.js.map +1 -1
  7. package/dist/image-js.umd.min.js +2 -2
  8. package/dist/image-js.umd.min.js.map +1 -1
  9. package/dist-types/image-js.d.ts +2 -3
  10. package/lib/Mask.d.ts +1 -1
  11. package/lib/Mask.js +1 -1
  12. package/lib/featureMatching/matching/filterEuclideanDistance.d.ts.map +1 -1
  13. package/lib/featureMatching/matching/filterEuclideanDistance.js +6 -7
  14. package/lib/featureMatching/matching/filterEuclideanDistance.js.map +1 -1
  15. package/lib/featureMatching/matching/filterSmallestDistanceMatches.d.ts.map +1 -1
  16. package/lib/featureMatching/matching/filterSmallestDistanceMatches.js +6 -3
  17. package/lib/featureMatching/matching/filterSmallestDistanceMatches.js.map +1 -1
  18. package/lib/featureMatching/utils/sortByDistance.d.ts.map +1 -1
  19. package/lib/featureMatching/utils/sortByDistance.js +3 -1
  20. package/lib/featureMatching/utils/sortByDistance.js.map +1 -1
  21. package/lib/featureMatching/utils/sortBySourceDest.d.ts.map +1 -1
  22. package/lib/featureMatching/utils/sortBySourceDest.js +6 -2
  23. package/lib/featureMatching/utils/sortBySourceDest.js.map +1 -1
  24. package/lib/load/decode.d.ts.map +1 -1
  25. package/lib/load/decode.js +2 -0
  26. package/lib/load/decode.js.map +1 -1
  27. package/lib/load/decodeBmp.d.ts +8 -0
  28. package/lib/load/decodeBmp.d.ts.map +1 -0
  29. package/lib/load/decodeBmp.js +36 -0
  30. package/lib/load/decodeBmp.js.map +1 -0
  31. package/lib/load/decodePng.d.ts.map +1 -1
  32. package/lib/load/decodePng.js +29 -5
  33. package/lib/load/decodePng.js.map +1 -1
  34. package/lib/load/decodeTiff.d.ts.map +1 -1
  35. package/lib/load/decodeTiff.js +44 -21
  36. package/lib/load/decodeTiff.js.map +1 -1
  37. package/lib/maskAnalysis/utils/getMbrAngle.d.ts.map +1 -1
  38. package/lib/maskAnalysis/utils/getMbrAngle.js +2 -1
  39. package/lib/maskAnalysis/utils/getMbrAngle.js.map +1 -1
  40. package/lib/maskAnalysis/utils/monotoneChainConvexHull.d.ts.map +1 -1
  41. package/lib/maskAnalysis/utils/monotoneChainConvexHull.js +2 -1
  42. package/lib/maskAnalysis/utils/monotoneChainConvexHull.js.map +1 -1
  43. package/lib/save/encodeBmp.d.ts +4 -4
  44. package/lib/save/encodeBmp.d.ts.map +1 -1
  45. package/lib/save/encodeBmp.js +22 -14
  46. package/lib/save/encodeBmp.js.map +1 -1
  47. package/lib/stack/load/decodeApng.d.ts +8 -0
  48. package/lib/stack/load/decodeApng.d.ts.map +1 -0
  49. package/lib/stack/load/decodeApng.js +60 -0
  50. package/lib/stack/load/decodeApng.js.map +1 -0
  51. package/lib/stack/load/decodeStack.d.ts.map +1 -1
  52. package/lib/stack/load/decodeStack.js +2 -0
  53. package/lib/stack/load/decodeStack.js.map +1 -1
  54. package/lib/utils/geometry/points.d.ts.map +1 -1
  55. package/lib/utils/geometry/points.js +3 -1
  56. package/lib/utils/geometry/points.js.map +1 -1
  57. package/lib/utils/geometry/removeClosePoints.d.ts.map +1 -1
  58. package/lib/utils/geometry/removeClosePoints.js +2 -1
  59. package/lib/utils/geometry/removeClosePoints.js.map +1 -1
  60. package/package.json +27 -27
  61. package/src/Mask.ts +1 -1
  62. package/src/featureMatching/matching/filterEuclideanDistance.ts +6 -13
  63. package/src/featureMatching/matching/filterSmallestDistanceMatches.ts +6 -9
  64. package/src/featureMatching/utils/sortByDistance.ts +3 -1
  65. package/src/featureMatching/utils/sortBySourceDest.ts +6 -2
  66. package/src/load/decode.ts +2 -1
  67. package/src/load/decodeBmp.ts +37 -0
  68. package/src/load/decodePng.ts +39 -7
  69. package/src/load/decodeTiff.ts +53 -22
  70. package/src/maskAnalysis/utils/getMbrAngle.ts +2 -1
  71. package/src/maskAnalysis/utils/monotoneChainConvexHull.ts +2 -1
  72. package/src/save/encodeBmp.ts +22 -15
  73. package/src/stack/load/decodeApng.ts +71 -0
  74. package/src/stack/load/decodeStack.ts +2 -0
  75. package/src/utils/geometry/points.ts +3 -1
  76. 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;AAGhC,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAkB;IAC1C,IAAI,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,GAAG,CAAC,MAAM,CAAC;QAChB,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,CAAC;QACf,QAAQ,EAAE,CAAC;QACX,IAAI,EAAE,SAAS,CAAC,IAAI;KACrB,CAAC,CAAC;AACL,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,8 @@
1
+ import { Stack } from '../../Stack.ts';
2
+ /**
3
+ * Decodes APNG image into a Stack
4
+ * @param data - APNG data.
5
+ * @returns stack of frames.
6
+ */
7
+ export declare function decodeStackFromApng(data: Uint8Array): Stack;
8
+ //# sourceMappingURL=decodeApng.d.ts.map
@@ -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;AAI5C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,KAAK,CAYxD"}
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,CAMxD"}
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
- return points.slice().sort((point1, point2) => {
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,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QAC5C,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;AACL,CAAC"}
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,WAgClC"}
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().sort(getSort(image, channel, isMax));
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;IAEzE,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"}
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.0.0",
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.0",
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.17.0",
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.1",
56
- "ts-pattern": "^5.8.0",
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.52.10",
60
+ "@microsoft/api-extractor": "^7.53.3",
61
61
  "@tailwindcss/forms": "^0.5.10",
62
- "@tailwindcss/vite": "^4.1.12",
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.3.0",
66
- "@types/react": "^19.1.10",
67
- "@types/react-dom": "^19.1.7",
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.1",
70
- "@vitest/coverage-v8": "^3.2.4",
71
- "@vitest/expect": "^3.2.4",
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.0",
74
+ "cheminfo-build": "^1.3.1",
75
75
  "clsx": "^2.1.1",
76
- "cross-env": "^10.0.0",
77
- "eslint": "^9.33.0",
78
- "eslint-config-cheminfo-react": "^17.0.1",
79
- "eslint-config-cheminfo-typescript": "^19.0.0",
80
- "immer": "^10.1.1",
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.1.1",
86
- "react-dom": "^19.1.1",
87
- "react-router-dom": "^7.8.1",
88
- "rimraf": "^6.0.1",
89
- "tailwindcss": "^4.1.12",
90
- "typescript": "~5.9.2",
91
- "vite": "^7.1.3",
92
- "vitest": "^3.2.4"
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
@@ -328,7 +328,7 @@ export class Mask {
328
328
 
329
329
  /**
330
330
  * Get the number of pixels that do not have the value 0.
331
- * @returns
331
+ * @returns The number of non-zero pixels.
332
332
  */
333
333
  public getNbNonZeroPixels(): number {
334
334
  let count = 0;
@@ -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.sort(
32
- (a, b) => a.destinationIndex - b.destinationIndex,
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
- result.push(
43
- ...sameDestMatches
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
- result.push(
53
- ...sameDestMatches
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.sort(
11
- (a, b) => a.destinationIndex - b.destinationIndex,
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
- result.push(
22
- ...sameDestMatches.sort((a, b) => a.distance - b.distance).slice(0, 1),
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
- result.push(
30
- ...sameDestMatches.sort((a, b) => a.distance - b.distance).slice(0, 1),
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
- return matches.slice().sort((match1, match2) => {
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
- return matches.slice().sort((match1, match2) => {
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
- return matches.slice().sort((match1, match2) => {
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
  }
@@ -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
+ }
@@ -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 === 16 ? 16 : 8;
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 * 3);
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
- data[dataIndex++] = paletteValue[0];
71
- data[dataIndex++] = paletteValue[1];
72
- data[dataIndex++] = paletteValue[2];
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
+ }
@@ -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
- // Palette
29
- const data = new Uint16Array(3 * ifd.width * ifd.height);
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
- for (const index of ifd.data) {
33
- const color = palette[index];
34
- data[ptr++] = color[0];
35
- data[ptr++] = color[1];
36
- data[ptr++] = color[2];
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
- // TODO: handle alpha properly
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().sort(leftFirst);
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);