emf-converter 4.6.7 → 4.6.8
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/browser.js +96 -45
- package/dist/browser.mjs +96 -45
- package/dist/index.js +96 -45
- package/dist/index.mjs +96 -45
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -31460,28 +31460,92 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31460
31460
|
if (reverse) taps.reverse();
|
|
31461
31461
|
return taps;
|
|
31462
31462
|
}
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
|
|
31471
|
-
|
|
31463
|
+
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31464
|
+
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31465
|
+
const taps = [];
|
|
31466
|
+
for (let i = 0; i < dstLen; i++) {
|
|
31467
|
+
const from = i * srcLen;
|
|
31468
|
+
const to = (i + 1) * srcLen;
|
|
31469
|
+
const run = [];
|
|
31470
|
+
let rest = 0;
|
|
31471
|
+
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31472
|
+
const overlap = Math.min(to, (k + 1) * dstLen) - Math.max(from, k * dstLen);
|
|
31473
|
+
if (overlap <= 0) continue;
|
|
31474
|
+
const w = Math.ceil(overlap * FIX / srcLen);
|
|
31475
|
+
run.push([k, w]);
|
|
31476
|
+
if (run.length > 1) rest += w;
|
|
31477
|
+
}
|
|
31478
|
+
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31479
|
+
taps.push(run);
|
|
31472
31480
|
}
|
|
31473
|
-
|
|
31481
|
+
if (reverse) taps.reverse();
|
|
31482
|
+
return taps;
|
|
31483
|
+
}
|
|
31484
|
+
var ENLARGE_KERNEL = [
|
|
31485
|
+
0.7598,
|
|
31486
|
+
0.7276,
|
|
31487
|
+
0.6829,
|
|
31488
|
+
0.6528,
|
|
31489
|
+
0.6106,
|
|
31490
|
+
0.5745,
|
|
31491
|
+
0.5362,
|
|
31492
|
+
0.4955,
|
|
31493
|
+
0.457,
|
|
31494
|
+
0.4121,
|
|
31495
|
+
0.3762,
|
|
31496
|
+
0.3233,
|
|
31497
|
+
0.2741,
|
|
31498
|
+
0.226,
|
|
31499
|
+
0.1822,
|
|
31500
|
+
0.1412,
|
|
31501
|
+
0.1021,
|
|
31502
|
+
0.0685,
|
|
31503
|
+
0.0382,
|
|
31504
|
+
0.0138,
|
|
31505
|
+
0
|
|
31506
|
+
];
|
|
31507
|
+
var ENLARGE_BOX = 0.2429;
|
|
31508
|
+
var ENLARGE_STEP = 0.05;
|
|
31509
|
+
function enlargeKernel(u) {
|
|
31510
|
+
const edge = u / ENLARGE_STEP;
|
|
31511
|
+
const i = Math.floor(edge);
|
|
31512
|
+
const smooth = i >= ENLARGE_KERNEL.length - 1 ? 0 : ENLARGE_KERNEL[i] + (ENLARGE_KERNEL[i + 1] - ENLARGE_KERNEL[i]) * (edge - i);
|
|
31513
|
+
return smooth + ENLARGE_BOX * (Math.abs(u - 0.5) < 1e-9 ? 0.5 : u < 0.5 ? 1 : 0);
|
|
31514
|
+
}
|
|
31515
|
+
function halftoneEnlargeTaps(src, dst) {
|
|
31516
|
+
const ratio = dst / src;
|
|
31517
|
+
const reach = Math.ceil((ENLARGE_KERNEL.length - 1) * ENLARGE_STEP * ratio);
|
|
31518
|
+
const fir = [];
|
|
31474
31519
|
let total = 0;
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31520
|
+
for (let k = 0; k <= reach; k++) {
|
|
31521
|
+
const w = enlargeKernel(k / ratio);
|
|
31522
|
+
fir.push(w);
|
|
31523
|
+
total += k === 0 ? w : 2 * w;
|
|
31524
|
+
}
|
|
31525
|
+
const cover = [];
|
|
31526
|
+
for (let x = 0; x < dst; x++) {
|
|
31527
|
+
const lo = x / ratio;
|
|
31528
|
+
const hi = (x + 1) / ratio;
|
|
31529
|
+
const run = [];
|
|
31530
|
+
for (let j = Math.max(0, Math.floor(lo)); j < Math.min(src, hi); j++) {
|
|
31531
|
+
const overlap = Math.min(hi, j + 1) - Math.max(lo, j);
|
|
31532
|
+
if (overlap > 0) run.push([j, overlap * ratio]);
|
|
31533
|
+
}
|
|
31534
|
+
cover.push(run);
|
|
31481
31535
|
}
|
|
31482
|
-
const
|
|
31483
|
-
|
|
31484
|
-
|
|
31536
|
+
const taps = [];
|
|
31537
|
+
for (let x = 0; x < dst; x++) {
|
|
31538
|
+
const weights = /* @__PURE__ */ new Map();
|
|
31539
|
+
for (let k = -reach; k <= reach; k++) {
|
|
31540
|
+
const w = fir[Math.abs(k)] / total;
|
|
31541
|
+
if (w === 0) continue;
|
|
31542
|
+
for (const [j, v] of cover[Math.max(0, Math.min(dst - 1, x + k))]) {
|
|
31543
|
+
weights.set(j, (weights.get(j) ?? 0) + w * v);
|
|
31544
|
+
}
|
|
31545
|
+
}
|
|
31546
|
+
taps.push([...weights.entries()]);
|
|
31547
|
+
}
|
|
31548
|
+
return taps;
|
|
31485
31549
|
}
|
|
31486
31550
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31487
31551
|
for (let y = 0; y < h; y++) {
|
|
@@ -31623,7 +31687,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31623
31687
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31624
31688
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31625
31689
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31626
|
-
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) &&
|
|
31690
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31627
31691
|
if ((enlarging || nearestMixed) && !directDib) {
|
|
31628
31692
|
halftoneDespeckle(rect, SW, SH);
|
|
31629
31693
|
}
|
|
@@ -31637,8 +31701,9 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31637
31701
|
}
|
|
31638
31702
|
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
31639
31703
|
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
31640
|
-
const
|
|
31641
|
-
const
|
|
31704
|
+
const axis = nativeMixed ? (n, d, r) => halftoneReduceTaps(n, d, r) : (n, d, r) => halftoneAxis(0, n, d, r);
|
|
31705
|
+
const cols = axis(SW, sampleW, flipX);
|
|
31706
|
+
const rows = axis(SH, sampleH, flipY);
|
|
31642
31707
|
if (nearestMixed) {
|
|
31643
31708
|
const nearest = (taps, src2, dst, reverse) => {
|
|
31644
31709
|
for (let i = 0; i < dst; i++) {
|
|
@@ -31710,29 +31775,15 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31710
31775
|
const source = out;
|
|
31711
31776
|
out = new Int32Array(W * H * 3);
|
|
31712
31777
|
const axisTaps = (src2, dst) => {
|
|
31713
|
-
|
|
31714
|
-
|
|
31715
|
-
|
|
31716
|
-
|
|
31717
|
-
|
|
31718
|
-
|
|
31719
|
-
|
|
31720
|
-
const pos = Math.max(0, Math.min(src2 - 1, raw));
|
|
31721
|
-
const i0 = Math.floor(pos);
|
|
31722
|
-
if (dst === 2 * src2) {
|
|
31723
|
-
r.push([[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]]);
|
|
31724
|
-
continue;
|
|
31725
|
-
}
|
|
31726
|
-
const taps = [];
|
|
31727
|
-
let total = 0;
|
|
31728
|
-
for (let k = i0 - 2; k <= i0 + 3; k++) {
|
|
31729
|
-
const w = softTent(raw - k);
|
|
31730
|
-
taps.push([Math.max(0, Math.min(src2 - 1, k)), w]);
|
|
31731
|
-
total += w;
|
|
31732
|
-
}
|
|
31733
|
-
r.push(taps.map(([k, w]) => [k, w / total]));
|
|
31778
|
+
if (src2 === dst) return Array.from({ length: dst }, (_, i) => [[i, 1]]);
|
|
31779
|
+
if (dst === 2 * src2) {
|
|
31780
|
+
return Array.from({ length: dst }, (_, i) => {
|
|
31781
|
+
const pos = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
31782
|
+
const i0 = Math.floor(pos);
|
|
31783
|
+
return [[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]];
|
|
31784
|
+
});
|
|
31734
31785
|
}
|
|
31735
|
-
return
|
|
31786
|
+
return halftoneEnlargeTaps(src2, dst);
|
|
31736
31787
|
};
|
|
31737
31788
|
const xt = axisTaps(sampleW, W), yt = axisTaps(sampleH, H);
|
|
31738
31789
|
for (let y = 0; y < H; y++) {
|
|
@@ -31740,7 +31791,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31740
31791
|
for (let c = 0; c < 3; c++) {
|
|
31741
31792
|
let v = 0;
|
|
31742
31793
|
for (const [yy, wy] of yt[y]) for (const [xx, wx] of xt[x]) v += source[(yy * sampleW + xx) * 3 + c] * wy * wx;
|
|
31743
|
-
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5)));
|
|
31794
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5 + 1e-7)));
|
|
31744
31795
|
}
|
|
31745
31796
|
}
|
|
31746
31797
|
}
|
package/dist/browser.mjs
CHANGED
|
@@ -31458,28 +31458,92 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31458
31458
|
if (reverse) taps.reverse();
|
|
31459
31459
|
return taps;
|
|
31460
31460
|
}
|
|
31461
|
-
|
|
31462
|
-
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31461
|
+
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31462
|
+
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31463
|
+
const taps = [];
|
|
31464
|
+
for (let i = 0; i < dstLen; i++) {
|
|
31465
|
+
const from = i * srcLen;
|
|
31466
|
+
const to = (i + 1) * srcLen;
|
|
31467
|
+
const run = [];
|
|
31468
|
+
let rest = 0;
|
|
31469
|
+
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31470
|
+
const overlap = Math.min(to, (k + 1) * dstLen) - Math.max(from, k * dstLen);
|
|
31471
|
+
if (overlap <= 0) continue;
|
|
31472
|
+
const w = Math.ceil(overlap * FIX / srcLen);
|
|
31473
|
+
run.push([k, w]);
|
|
31474
|
+
if (run.length > 1) rest += w;
|
|
31475
|
+
}
|
|
31476
|
+
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31477
|
+
taps.push(run);
|
|
31470
31478
|
}
|
|
31471
|
-
|
|
31479
|
+
if (reverse) taps.reverse();
|
|
31480
|
+
return taps;
|
|
31481
|
+
}
|
|
31482
|
+
var ENLARGE_KERNEL = [
|
|
31483
|
+
0.7598,
|
|
31484
|
+
0.7276,
|
|
31485
|
+
0.6829,
|
|
31486
|
+
0.6528,
|
|
31487
|
+
0.6106,
|
|
31488
|
+
0.5745,
|
|
31489
|
+
0.5362,
|
|
31490
|
+
0.4955,
|
|
31491
|
+
0.457,
|
|
31492
|
+
0.4121,
|
|
31493
|
+
0.3762,
|
|
31494
|
+
0.3233,
|
|
31495
|
+
0.2741,
|
|
31496
|
+
0.226,
|
|
31497
|
+
0.1822,
|
|
31498
|
+
0.1412,
|
|
31499
|
+
0.1021,
|
|
31500
|
+
0.0685,
|
|
31501
|
+
0.0382,
|
|
31502
|
+
0.0138,
|
|
31503
|
+
0
|
|
31504
|
+
];
|
|
31505
|
+
var ENLARGE_BOX = 0.2429;
|
|
31506
|
+
var ENLARGE_STEP = 0.05;
|
|
31507
|
+
function enlargeKernel(u) {
|
|
31508
|
+
const edge = u / ENLARGE_STEP;
|
|
31509
|
+
const i = Math.floor(edge);
|
|
31510
|
+
const smooth = i >= ENLARGE_KERNEL.length - 1 ? 0 : ENLARGE_KERNEL[i] + (ENLARGE_KERNEL[i + 1] - ENLARGE_KERNEL[i]) * (edge - i);
|
|
31511
|
+
return smooth + ENLARGE_BOX * (Math.abs(u - 0.5) < 1e-9 ? 0.5 : u < 0.5 ? 1 : 0);
|
|
31512
|
+
}
|
|
31513
|
+
function halftoneEnlargeTaps(src, dst) {
|
|
31514
|
+
const ratio = dst / src;
|
|
31515
|
+
const reach = Math.ceil((ENLARGE_KERNEL.length - 1) * ENLARGE_STEP * ratio);
|
|
31516
|
+
const fir = [];
|
|
31472
31517
|
let total = 0;
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31518
|
+
for (let k = 0; k <= reach; k++) {
|
|
31519
|
+
const w = enlargeKernel(k / ratio);
|
|
31520
|
+
fir.push(w);
|
|
31521
|
+
total += k === 0 ? w : 2 * w;
|
|
31522
|
+
}
|
|
31523
|
+
const cover = [];
|
|
31524
|
+
for (let x = 0; x < dst; x++) {
|
|
31525
|
+
const lo = x / ratio;
|
|
31526
|
+
const hi = (x + 1) / ratio;
|
|
31527
|
+
const run = [];
|
|
31528
|
+
for (let j = Math.max(0, Math.floor(lo)); j < Math.min(src, hi); j++) {
|
|
31529
|
+
const overlap = Math.min(hi, j + 1) - Math.max(lo, j);
|
|
31530
|
+
if (overlap > 0) run.push([j, overlap * ratio]);
|
|
31531
|
+
}
|
|
31532
|
+
cover.push(run);
|
|
31479
31533
|
}
|
|
31480
|
-
const
|
|
31481
|
-
|
|
31482
|
-
|
|
31534
|
+
const taps = [];
|
|
31535
|
+
for (let x = 0; x < dst; x++) {
|
|
31536
|
+
const weights = /* @__PURE__ */ new Map();
|
|
31537
|
+
for (let k = -reach; k <= reach; k++) {
|
|
31538
|
+
const w = fir[Math.abs(k)] / total;
|
|
31539
|
+
if (w === 0) continue;
|
|
31540
|
+
for (const [j, v] of cover[Math.max(0, Math.min(dst - 1, x + k))]) {
|
|
31541
|
+
weights.set(j, (weights.get(j) ?? 0) + w * v);
|
|
31542
|
+
}
|
|
31543
|
+
}
|
|
31544
|
+
taps.push([...weights.entries()]);
|
|
31545
|
+
}
|
|
31546
|
+
return taps;
|
|
31483
31547
|
}
|
|
31484
31548
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31485
31549
|
for (let y = 0; y < h; y++) {
|
|
@@ -31621,7 +31685,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31621
31685
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31622
31686
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31623
31687
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31624
|
-
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) &&
|
|
31688
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31625
31689
|
if ((enlarging || nearestMixed) && !directDib) {
|
|
31626
31690
|
halftoneDespeckle(rect, SW, SH);
|
|
31627
31691
|
}
|
|
@@ -31635,8 +31699,9 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31635
31699
|
}
|
|
31636
31700
|
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
31637
31701
|
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
31638
|
-
const
|
|
31639
|
-
const
|
|
31702
|
+
const axis = nativeMixed ? (n, d, r) => halftoneReduceTaps(n, d, r) : (n, d, r) => halftoneAxis(0, n, d, r);
|
|
31703
|
+
const cols = axis(SW, sampleW, flipX);
|
|
31704
|
+
const rows = axis(SH, sampleH, flipY);
|
|
31640
31705
|
if (nearestMixed) {
|
|
31641
31706
|
const nearest = (taps, src2, dst, reverse) => {
|
|
31642
31707
|
for (let i = 0; i < dst; i++) {
|
|
@@ -31708,29 +31773,15 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31708
31773
|
const source = out;
|
|
31709
31774
|
out = new Int32Array(W * H * 3);
|
|
31710
31775
|
const axisTaps = (src2, dst) => {
|
|
31711
|
-
|
|
31712
|
-
|
|
31713
|
-
|
|
31714
|
-
|
|
31715
|
-
|
|
31716
|
-
|
|
31717
|
-
|
|
31718
|
-
const pos = Math.max(0, Math.min(src2 - 1, raw));
|
|
31719
|
-
const i0 = Math.floor(pos);
|
|
31720
|
-
if (dst === 2 * src2) {
|
|
31721
|
-
r.push([[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]]);
|
|
31722
|
-
continue;
|
|
31723
|
-
}
|
|
31724
|
-
const taps = [];
|
|
31725
|
-
let total = 0;
|
|
31726
|
-
for (let k = i0 - 2; k <= i0 + 3; k++) {
|
|
31727
|
-
const w = softTent(raw - k);
|
|
31728
|
-
taps.push([Math.max(0, Math.min(src2 - 1, k)), w]);
|
|
31729
|
-
total += w;
|
|
31730
|
-
}
|
|
31731
|
-
r.push(taps.map(([k, w]) => [k, w / total]));
|
|
31776
|
+
if (src2 === dst) return Array.from({ length: dst }, (_, i) => [[i, 1]]);
|
|
31777
|
+
if (dst === 2 * src2) {
|
|
31778
|
+
return Array.from({ length: dst }, (_, i) => {
|
|
31779
|
+
const pos = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
31780
|
+
const i0 = Math.floor(pos);
|
|
31781
|
+
return [[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]];
|
|
31782
|
+
});
|
|
31732
31783
|
}
|
|
31733
|
-
return
|
|
31784
|
+
return halftoneEnlargeTaps(src2, dst);
|
|
31734
31785
|
};
|
|
31735
31786
|
const xt = axisTaps(sampleW, W), yt = axisTaps(sampleH, H);
|
|
31736
31787
|
for (let y = 0; y < H; y++) {
|
|
@@ -31738,7 +31789,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31738
31789
|
for (let c = 0; c < 3; c++) {
|
|
31739
31790
|
let v = 0;
|
|
31740
31791
|
for (const [yy, wy] of yt[y]) for (const [xx, wx] of xt[x]) v += source[(yy * sampleW + xx) * 3 + c] * wy * wx;
|
|
31741
|
-
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5)));
|
|
31792
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5 + 1e-7)));
|
|
31742
31793
|
}
|
|
31743
31794
|
}
|
|
31744
31795
|
}
|
package/dist/index.js
CHANGED
|
@@ -31461,28 +31461,92 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31461
31461
|
if (reverse) taps.reverse();
|
|
31462
31462
|
return taps;
|
|
31463
31463
|
}
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
|
|
31471
|
-
|
|
31472
|
-
|
|
31464
|
+
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31465
|
+
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31466
|
+
const taps = [];
|
|
31467
|
+
for (let i = 0; i < dstLen; i++) {
|
|
31468
|
+
const from = i * srcLen;
|
|
31469
|
+
const to = (i + 1) * srcLen;
|
|
31470
|
+
const run = [];
|
|
31471
|
+
let rest = 0;
|
|
31472
|
+
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31473
|
+
const overlap = Math.min(to, (k + 1) * dstLen) - Math.max(from, k * dstLen);
|
|
31474
|
+
if (overlap <= 0) continue;
|
|
31475
|
+
const w = Math.ceil(overlap * FIX / srcLen);
|
|
31476
|
+
run.push([k, w]);
|
|
31477
|
+
if (run.length > 1) rest += w;
|
|
31478
|
+
}
|
|
31479
|
+
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31480
|
+
taps.push(run);
|
|
31473
31481
|
}
|
|
31474
|
-
|
|
31482
|
+
if (reverse) taps.reverse();
|
|
31483
|
+
return taps;
|
|
31484
|
+
}
|
|
31485
|
+
var ENLARGE_KERNEL = [
|
|
31486
|
+
0.7598,
|
|
31487
|
+
0.7276,
|
|
31488
|
+
0.6829,
|
|
31489
|
+
0.6528,
|
|
31490
|
+
0.6106,
|
|
31491
|
+
0.5745,
|
|
31492
|
+
0.5362,
|
|
31493
|
+
0.4955,
|
|
31494
|
+
0.457,
|
|
31495
|
+
0.4121,
|
|
31496
|
+
0.3762,
|
|
31497
|
+
0.3233,
|
|
31498
|
+
0.2741,
|
|
31499
|
+
0.226,
|
|
31500
|
+
0.1822,
|
|
31501
|
+
0.1412,
|
|
31502
|
+
0.1021,
|
|
31503
|
+
0.0685,
|
|
31504
|
+
0.0382,
|
|
31505
|
+
0.0138,
|
|
31506
|
+
0
|
|
31507
|
+
];
|
|
31508
|
+
var ENLARGE_BOX = 0.2429;
|
|
31509
|
+
var ENLARGE_STEP = 0.05;
|
|
31510
|
+
function enlargeKernel(u) {
|
|
31511
|
+
const edge = u / ENLARGE_STEP;
|
|
31512
|
+
const i = Math.floor(edge);
|
|
31513
|
+
const smooth = i >= ENLARGE_KERNEL.length - 1 ? 0 : ENLARGE_KERNEL[i] + (ENLARGE_KERNEL[i + 1] - ENLARGE_KERNEL[i]) * (edge - i);
|
|
31514
|
+
return smooth + ENLARGE_BOX * (Math.abs(u - 0.5) < 1e-9 ? 0.5 : u < 0.5 ? 1 : 0);
|
|
31515
|
+
}
|
|
31516
|
+
function halftoneEnlargeTaps(src, dst) {
|
|
31517
|
+
const ratio = dst / src;
|
|
31518
|
+
const reach = Math.ceil((ENLARGE_KERNEL.length - 1) * ENLARGE_STEP * ratio);
|
|
31519
|
+
const fir = [];
|
|
31475
31520
|
let total = 0;
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
|
|
31521
|
+
for (let k = 0; k <= reach; k++) {
|
|
31522
|
+
const w = enlargeKernel(k / ratio);
|
|
31523
|
+
fir.push(w);
|
|
31524
|
+
total += k === 0 ? w : 2 * w;
|
|
31525
|
+
}
|
|
31526
|
+
const cover = [];
|
|
31527
|
+
for (let x = 0; x < dst; x++) {
|
|
31528
|
+
const lo = x / ratio;
|
|
31529
|
+
const hi = (x + 1) / ratio;
|
|
31530
|
+
const run = [];
|
|
31531
|
+
for (let j = Math.max(0, Math.floor(lo)); j < Math.min(src, hi); j++) {
|
|
31532
|
+
const overlap = Math.min(hi, j + 1) - Math.max(lo, j);
|
|
31533
|
+
if (overlap > 0) run.push([j, overlap * ratio]);
|
|
31534
|
+
}
|
|
31535
|
+
cover.push(run);
|
|
31482
31536
|
}
|
|
31483
|
-
const
|
|
31484
|
-
|
|
31485
|
-
|
|
31537
|
+
const taps = [];
|
|
31538
|
+
for (let x = 0; x < dst; x++) {
|
|
31539
|
+
const weights = /* @__PURE__ */ new Map();
|
|
31540
|
+
for (let k = -reach; k <= reach; k++) {
|
|
31541
|
+
const w = fir[Math.abs(k)] / total;
|
|
31542
|
+
if (w === 0) continue;
|
|
31543
|
+
for (const [j, v] of cover[Math.max(0, Math.min(dst - 1, x + k))]) {
|
|
31544
|
+
weights.set(j, (weights.get(j) ?? 0) + w * v);
|
|
31545
|
+
}
|
|
31546
|
+
}
|
|
31547
|
+
taps.push([...weights.entries()]);
|
|
31548
|
+
}
|
|
31549
|
+
return taps;
|
|
31486
31550
|
}
|
|
31487
31551
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31488
31552
|
for (let y = 0; y < h; y++) {
|
|
@@ -31624,7 +31688,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31624
31688
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31625
31689
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31626
31690
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31627
|
-
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) &&
|
|
31691
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31628
31692
|
if ((enlarging || nearestMixed) && !directDib) {
|
|
31629
31693
|
halftoneDespeckle(rect, SW, SH);
|
|
31630
31694
|
}
|
|
@@ -31638,8 +31702,9 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31638
31702
|
}
|
|
31639
31703
|
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
31640
31704
|
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
31641
|
-
const
|
|
31642
|
-
const
|
|
31705
|
+
const axis = nativeMixed ? (n, d, r) => halftoneReduceTaps(n, d, r) : (n, d, r) => halftoneAxis(0, n, d, r);
|
|
31706
|
+
const cols = axis(SW, sampleW, flipX);
|
|
31707
|
+
const rows = axis(SH, sampleH, flipY);
|
|
31643
31708
|
if (nearestMixed) {
|
|
31644
31709
|
const nearest = (taps, src2, dst, reverse) => {
|
|
31645
31710
|
for (let i = 0; i < dst; i++) {
|
|
@@ -31711,29 +31776,15 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31711
31776
|
const source = out;
|
|
31712
31777
|
out = new Int32Array(W * H * 3);
|
|
31713
31778
|
const axisTaps = (src2, dst) => {
|
|
31714
|
-
|
|
31715
|
-
|
|
31716
|
-
|
|
31717
|
-
|
|
31718
|
-
|
|
31719
|
-
|
|
31720
|
-
|
|
31721
|
-
const pos = Math.max(0, Math.min(src2 - 1, raw));
|
|
31722
|
-
const i0 = Math.floor(pos);
|
|
31723
|
-
if (dst === 2 * src2) {
|
|
31724
|
-
r.push([[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]]);
|
|
31725
|
-
continue;
|
|
31726
|
-
}
|
|
31727
|
-
const taps = [];
|
|
31728
|
-
let total = 0;
|
|
31729
|
-
for (let k = i0 - 2; k <= i0 + 3; k++) {
|
|
31730
|
-
const w = softTent(raw - k);
|
|
31731
|
-
taps.push([Math.max(0, Math.min(src2 - 1, k)), w]);
|
|
31732
|
-
total += w;
|
|
31733
|
-
}
|
|
31734
|
-
r.push(taps.map(([k, w]) => [k, w / total]));
|
|
31779
|
+
if (src2 === dst) return Array.from({ length: dst }, (_, i) => [[i, 1]]);
|
|
31780
|
+
if (dst === 2 * src2) {
|
|
31781
|
+
return Array.from({ length: dst }, (_, i) => {
|
|
31782
|
+
const pos = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
31783
|
+
const i0 = Math.floor(pos);
|
|
31784
|
+
return [[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]];
|
|
31785
|
+
});
|
|
31735
31786
|
}
|
|
31736
|
-
return
|
|
31787
|
+
return halftoneEnlargeTaps(src2, dst);
|
|
31737
31788
|
};
|
|
31738
31789
|
const xt = axisTaps(sampleW, W), yt = axisTaps(sampleH, H);
|
|
31739
31790
|
for (let y = 0; y < H; y++) {
|
|
@@ -31741,7 +31792,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31741
31792
|
for (let c = 0; c < 3; c++) {
|
|
31742
31793
|
let v = 0;
|
|
31743
31794
|
for (const [yy, wy] of yt[y]) for (const [xx, wx] of xt[x]) v += source[(yy * sampleW + xx) * 3 + c] * wy * wx;
|
|
31744
|
-
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5)));
|
|
31795
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5 + 1e-7)));
|
|
31745
31796
|
}
|
|
31746
31797
|
}
|
|
31747
31798
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -31459,28 +31459,92 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31459
31459
|
if (reverse) taps.reverse();
|
|
31460
31460
|
return taps;
|
|
31461
31461
|
}
|
|
31462
|
-
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
|
|
31462
|
+
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31463
|
+
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31464
|
+
const taps = [];
|
|
31465
|
+
for (let i = 0; i < dstLen; i++) {
|
|
31466
|
+
const from = i * srcLen;
|
|
31467
|
+
const to = (i + 1) * srcLen;
|
|
31468
|
+
const run = [];
|
|
31469
|
+
let rest = 0;
|
|
31470
|
+
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31471
|
+
const overlap = Math.min(to, (k + 1) * dstLen) - Math.max(from, k * dstLen);
|
|
31472
|
+
if (overlap <= 0) continue;
|
|
31473
|
+
const w = Math.ceil(overlap * FIX / srcLen);
|
|
31474
|
+
run.push([k, w]);
|
|
31475
|
+
if (run.length > 1) rest += w;
|
|
31476
|
+
}
|
|
31477
|
+
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31478
|
+
taps.push(run);
|
|
31471
31479
|
}
|
|
31472
|
-
|
|
31480
|
+
if (reverse) taps.reverse();
|
|
31481
|
+
return taps;
|
|
31482
|
+
}
|
|
31483
|
+
var ENLARGE_KERNEL = [
|
|
31484
|
+
0.7598,
|
|
31485
|
+
0.7276,
|
|
31486
|
+
0.6829,
|
|
31487
|
+
0.6528,
|
|
31488
|
+
0.6106,
|
|
31489
|
+
0.5745,
|
|
31490
|
+
0.5362,
|
|
31491
|
+
0.4955,
|
|
31492
|
+
0.457,
|
|
31493
|
+
0.4121,
|
|
31494
|
+
0.3762,
|
|
31495
|
+
0.3233,
|
|
31496
|
+
0.2741,
|
|
31497
|
+
0.226,
|
|
31498
|
+
0.1822,
|
|
31499
|
+
0.1412,
|
|
31500
|
+
0.1021,
|
|
31501
|
+
0.0685,
|
|
31502
|
+
0.0382,
|
|
31503
|
+
0.0138,
|
|
31504
|
+
0
|
|
31505
|
+
];
|
|
31506
|
+
var ENLARGE_BOX = 0.2429;
|
|
31507
|
+
var ENLARGE_STEP = 0.05;
|
|
31508
|
+
function enlargeKernel(u) {
|
|
31509
|
+
const edge = u / ENLARGE_STEP;
|
|
31510
|
+
const i = Math.floor(edge);
|
|
31511
|
+
const smooth = i >= ENLARGE_KERNEL.length - 1 ? 0 : ENLARGE_KERNEL[i] + (ENLARGE_KERNEL[i + 1] - ENLARGE_KERNEL[i]) * (edge - i);
|
|
31512
|
+
return smooth + ENLARGE_BOX * (Math.abs(u - 0.5) < 1e-9 ? 0.5 : u < 0.5 ? 1 : 0);
|
|
31513
|
+
}
|
|
31514
|
+
function halftoneEnlargeTaps(src, dst) {
|
|
31515
|
+
const ratio = dst / src;
|
|
31516
|
+
const reach = Math.ceil((ENLARGE_KERNEL.length - 1) * ENLARGE_STEP * ratio);
|
|
31517
|
+
const fir = [];
|
|
31473
31518
|
let total = 0;
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31519
|
+
for (let k = 0; k <= reach; k++) {
|
|
31520
|
+
const w = enlargeKernel(k / ratio);
|
|
31521
|
+
fir.push(w);
|
|
31522
|
+
total += k === 0 ? w : 2 * w;
|
|
31523
|
+
}
|
|
31524
|
+
const cover = [];
|
|
31525
|
+
for (let x = 0; x < dst; x++) {
|
|
31526
|
+
const lo = x / ratio;
|
|
31527
|
+
const hi = (x + 1) / ratio;
|
|
31528
|
+
const run = [];
|
|
31529
|
+
for (let j = Math.max(0, Math.floor(lo)); j < Math.min(src, hi); j++) {
|
|
31530
|
+
const overlap = Math.min(hi, j + 1) - Math.max(lo, j);
|
|
31531
|
+
if (overlap > 0) run.push([j, overlap * ratio]);
|
|
31532
|
+
}
|
|
31533
|
+
cover.push(run);
|
|
31480
31534
|
}
|
|
31481
|
-
const
|
|
31482
|
-
|
|
31483
|
-
|
|
31535
|
+
const taps = [];
|
|
31536
|
+
for (let x = 0; x < dst; x++) {
|
|
31537
|
+
const weights = /* @__PURE__ */ new Map();
|
|
31538
|
+
for (let k = -reach; k <= reach; k++) {
|
|
31539
|
+
const w = fir[Math.abs(k)] / total;
|
|
31540
|
+
if (w === 0) continue;
|
|
31541
|
+
for (const [j, v] of cover[Math.max(0, Math.min(dst - 1, x + k))]) {
|
|
31542
|
+
weights.set(j, (weights.get(j) ?? 0) + w * v);
|
|
31543
|
+
}
|
|
31544
|
+
}
|
|
31545
|
+
taps.push([...weights.entries()]);
|
|
31546
|
+
}
|
|
31547
|
+
return taps;
|
|
31484
31548
|
}
|
|
31485
31549
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31486
31550
|
for (let y = 0; y < h; y++) {
|
|
@@ -31622,7 +31686,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31622
31686
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31623
31687
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31624
31688
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31625
|
-
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) &&
|
|
31689
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31626
31690
|
if ((enlarging || nearestMixed) && !directDib) {
|
|
31627
31691
|
halftoneDespeckle(rect, SW, SH);
|
|
31628
31692
|
}
|
|
@@ -31636,8 +31700,9 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31636
31700
|
}
|
|
31637
31701
|
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
31638
31702
|
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
31639
|
-
const
|
|
31640
|
-
const
|
|
31703
|
+
const axis = nativeMixed ? (n, d, r) => halftoneReduceTaps(n, d, r) : (n, d, r) => halftoneAxis(0, n, d, r);
|
|
31704
|
+
const cols = axis(SW, sampleW, flipX);
|
|
31705
|
+
const rows = axis(SH, sampleH, flipY);
|
|
31641
31706
|
if (nearestMixed) {
|
|
31642
31707
|
const nearest = (taps, src2, dst, reverse) => {
|
|
31643
31708
|
for (let i = 0; i < dst; i++) {
|
|
@@ -31709,29 +31774,15 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31709
31774
|
const source = out;
|
|
31710
31775
|
out = new Int32Array(W * H * 3);
|
|
31711
31776
|
const axisTaps = (src2, dst) => {
|
|
31712
|
-
|
|
31713
|
-
|
|
31714
|
-
|
|
31715
|
-
|
|
31716
|
-
|
|
31717
|
-
|
|
31718
|
-
|
|
31719
|
-
const pos = Math.max(0, Math.min(src2 - 1, raw));
|
|
31720
|
-
const i0 = Math.floor(pos);
|
|
31721
|
-
if (dst === 2 * src2) {
|
|
31722
|
-
r.push([[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]]);
|
|
31723
|
-
continue;
|
|
31724
|
-
}
|
|
31725
|
-
const taps = [];
|
|
31726
|
-
let total = 0;
|
|
31727
|
-
for (let k = i0 - 2; k <= i0 + 3; k++) {
|
|
31728
|
-
const w = softTent(raw - k);
|
|
31729
|
-
taps.push([Math.max(0, Math.min(src2 - 1, k)), w]);
|
|
31730
|
-
total += w;
|
|
31731
|
-
}
|
|
31732
|
-
r.push(taps.map(([k, w]) => [k, w / total]));
|
|
31777
|
+
if (src2 === dst) return Array.from({ length: dst }, (_, i) => [[i, 1]]);
|
|
31778
|
+
if (dst === 2 * src2) {
|
|
31779
|
+
return Array.from({ length: dst }, (_, i) => {
|
|
31780
|
+
const pos = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
31781
|
+
const i0 = Math.floor(pos);
|
|
31782
|
+
return [[i0, 1 - (pos - i0)], [Math.min(src2 - 1, i0 + 1), pos - i0]];
|
|
31783
|
+
});
|
|
31733
31784
|
}
|
|
31734
|
-
return
|
|
31785
|
+
return halftoneEnlargeTaps(src2, dst);
|
|
31735
31786
|
};
|
|
31736
31787
|
const xt = axisTaps(sampleW, W), yt = axisTaps(sampleH, H);
|
|
31737
31788
|
for (let y = 0; y < H; y++) {
|
|
@@ -31739,7 +31790,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31739
31790
|
for (let c = 0; c < 3; c++) {
|
|
31740
31791
|
let v = 0;
|
|
31741
31792
|
for (const [yy, wy] of yt[y]) for (const [xx, wx] of xt[x]) v += source[(yy * sampleW + xx) * 3 + c] * wy * wx;
|
|
31742
|
-
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5)));
|
|
31793
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + 0.5 + 1e-7)));
|
|
31743
31794
|
}
|
|
31744
31795
|
}
|
|
31745
31796
|
}
|