emf-converter 4.4.14 → 4.4.16
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 +79 -14
- package/dist/browser.mjs +79 -14
- package/dist/index.js +79 -14
- package/dist/index.mjs +79 -14
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -30534,11 +30534,12 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30534
30534
|
if (dstLen <= 0 || srcLen <= 0) {
|
|
30535
30535
|
return taps;
|
|
30536
30536
|
}
|
|
30537
|
-
const at = (k) =>
|
|
30537
|
+
const at = (k) => start + k;
|
|
30538
30538
|
if (dstLen >= srcLen) {
|
|
30539
30539
|
for (let i = 0; i < dstLen; i++) {
|
|
30540
30540
|
taps.push([[at(halftoneNearest(i, srcLen, dstLen)), 1]]);
|
|
30541
30541
|
}
|
|
30542
|
+
if (reverse) taps.reverse();
|
|
30542
30543
|
return taps;
|
|
30543
30544
|
}
|
|
30544
30545
|
const step = Math.ceil(srcLen * FIX / dstLen);
|
|
@@ -30554,6 +30555,7 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30554
30555
|
}
|
|
30555
30556
|
taps.push(run);
|
|
30556
30557
|
}
|
|
30558
|
+
if (reverse) taps.reverse();
|
|
30557
30559
|
return taps;
|
|
30558
30560
|
}
|
|
30559
30561
|
var SPECKLE_OVERSHOOT = 4;
|
|
@@ -30569,8 +30571,22 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30569
30571
|
const right = x < w - 1 ? x + 1 : Math.max(0, x - 1);
|
|
30570
30572
|
let hClip = 0;
|
|
30571
30573
|
let vClip = 0;
|
|
30574
|
+
let alternating = 0;
|
|
30572
30575
|
for (let c = 0; c < 3; c++) {
|
|
30573
30576
|
const v = at(x, y, c);
|
|
30577
|
+
const axial = Math.max(
|
|
30578
|
+
Math.abs(v - at(left, y, c)),
|
|
30579
|
+
Math.abs(v - at(right, y, c)),
|
|
30580
|
+
Math.abs(v - at(x, up, c)),
|
|
30581
|
+
Math.abs(v - at(x, down, c))
|
|
30582
|
+
);
|
|
30583
|
+
const diagonal = Math.min(
|
|
30584
|
+
Math.abs(v - at(left, up, c)),
|
|
30585
|
+
Math.abs(v - at(right, up, c)),
|
|
30586
|
+
Math.abs(v - at(left, down, c)),
|
|
30587
|
+
Math.abs(v - at(right, down, c))
|
|
30588
|
+
);
|
|
30589
|
+
if (diagonal < axial) alternating++;
|
|
30574
30590
|
if (over(6 * v - at(left, y, c) - at(right, y, c))) {
|
|
30575
30591
|
hClip++;
|
|
30576
30592
|
}
|
|
@@ -30578,7 +30594,7 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30578
30594
|
vClip++;
|
|
30579
30595
|
}
|
|
30580
30596
|
}
|
|
30581
|
-
if (hClip < 2 || vClip < 2) {
|
|
30597
|
+
if (hClip < 2 || vClip < 2 || alternating < 2) {
|
|
30582
30598
|
continue;
|
|
30583
30599
|
}
|
|
30584
30600
|
for (let c = 0; c < 3; c++) {
|
|
@@ -30632,15 +30648,29 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30632
30648
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30633
30649
|
const reducing = W < SW && H < SH;
|
|
30634
30650
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30635
|
-
|
|
30651
|
+
const nearestMixed = mixed && (!adjust || adjustAfterSampling) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
30652
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling) && Math.min(SW, W) >= 2 && Math.min(SH, H) >= 2 && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
30653
|
+
if ((enlarging || nearestMixed) && !directDib) {
|
|
30636
30654
|
halftoneDespeckle(rect, SW, SH);
|
|
30637
30655
|
}
|
|
30638
30656
|
if (adjust && !adjustAfterSampling) {
|
|
30639
30657
|
adjust(rect);
|
|
30640
30658
|
}
|
|
30641
|
-
const
|
|
30642
|
-
const
|
|
30643
|
-
|
|
30659
|
+
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
30660
|
+
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
30661
|
+
const cols = halftoneAxis(0, SW, sampleW, flipX);
|
|
30662
|
+
const rows = halftoneAxis(0, SH, sampleH, flipY);
|
|
30663
|
+
if (nearestMixed) {
|
|
30664
|
+
const nearest = (taps, src2, dst, reverse) => {
|
|
30665
|
+
for (let i = 0; i < dst; i++) {
|
|
30666
|
+
const index = reverse ? dst - 1 - i : i;
|
|
30667
|
+
const k = dst < src2 ? Math.floor(((index + 1) * 2 * src2 - dst) / (2 * dst)) : halftoneNearest(index, src2, dst);
|
|
30668
|
+
taps[i] = [[Math.max(0, Math.min(src2 - 1, k)), 1]];
|
|
30669
|
+
}
|
|
30670
|
+
};
|
|
30671
|
+
nearest(cols, SW, W, flipX);
|
|
30672
|
+
nearest(rows, SH, H, flipY);
|
|
30673
|
+
} else if (mixed && !nativeMixed) {
|
|
30644
30674
|
const linear = (taps, src2, dst, reverse) => {
|
|
30645
30675
|
if (dst <= src2) return;
|
|
30646
30676
|
for (let i = 0; i < dst; i++) {
|
|
@@ -30653,10 +30683,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30653
30683
|
linear(cols, SW, W, flipX);
|
|
30654
30684
|
linear(rows, SH, H, flipY);
|
|
30655
30685
|
}
|
|
30656
|
-
|
|
30657
|
-
for (let y = 0; y <
|
|
30686
|
+
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
30687
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30658
30688
|
const ys = rows[y];
|
|
30659
|
-
for (let x = 0; x <
|
|
30689
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30660
30690
|
const xs = cols[x];
|
|
30661
30691
|
let r = 0;
|
|
30662
30692
|
let g = 0;
|
|
@@ -30672,16 +30702,51 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30672
30702
|
b += rect[i + 2] * w;
|
|
30673
30703
|
}
|
|
30674
30704
|
}
|
|
30675
|
-
const o = (y *
|
|
30676
|
-
|
|
30677
|
-
out[o
|
|
30678
|
-
out[o +
|
|
30705
|
+
const o = (y * sampleW + x) * 3;
|
|
30706
|
+
const round = (value) => nativeMixed ? value / total : mixed ? Math.ceil(value / total - 0.5) : Math.floor((2 * value + total) / (2 * total));
|
|
30707
|
+
out[o] = round(r);
|
|
30708
|
+
out[o + 1] = round(g);
|
|
30709
|
+
out[o + 2] = round(b);
|
|
30679
30710
|
}
|
|
30680
30711
|
}
|
|
30681
30712
|
if (reducing) {
|
|
30682
30713
|
halftoneSharpen(out, W, H);
|
|
30683
30714
|
}
|
|
30684
|
-
if (
|
|
30715
|
+
if (nativeMixed) {
|
|
30716
|
+
const reduceHorizontal = W < SW;
|
|
30717
|
+
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
30718
|
+
const source2 = out;
|
|
30719
|
+
out = new Int32Array(source2.length);
|
|
30720
|
+
const at = (x, y, c) => source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
30721
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30722
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30723
|
+
for (let c = 0; c < 3; c++) {
|
|
30724
|
+
const v = at(x, y, c);
|
|
30725
|
+
const sum = horizontal ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30726
|
+
out[(y * sampleW + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
30727
|
+
}
|
|
30728
|
+
}
|
|
30729
|
+
}
|
|
30730
|
+
}
|
|
30731
|
+
const source = out;
|
|
30732
|
+
out = new Int32Array(W * H * 3);
|
|
30733
|
+
for (let y = 0; y < H; y++) {
|
|
30734
|
+
const py = Math.max(0, Math.min(sampleH - 1, (y + 0.5) * sampleH / H - 0.5));
|
|
30735
|
+
const y02 = Math.floor(py), fy = py - y02;
|
|
30736
|
+
for (let x = 0; x < W; x++) {
|
|
30737
|
+
const px = Math.max(0, Math.min(sampleW - 1, (x + 0.5) * sampleW / W - 0.5));
|
|
30738
|
+
const x02 = Math.floor(px), fx = px - x02;
|
|
30739
|
+
for (let c = 0; c < 3; c++) {
|
|
30740
|
+
const at = (xx, yy) => source[(yy * sampleW + xx) * 3 + c];
|
|
30741
|
+
const x1 = Math.min(sampleW - 1, x02 + 1), y1 = Math.min(sampleH - 1, y02 + 1);
|
|
30742
|
+
const top = at(x02, y02) * (1 - fx) + at(x1, y02) * fx;
|
|
30743
|
+
const bottom = at(x02, y1) * (1 - fx) + at(x1, y1) * fx;
|
|
30744
|
+
out[(y * W + x) * 3 + c] = Math.floor(top * (1 - fy) + bottom * fy + 0.5);
|
|
30745
|
+
}
|
|
30746
|
+
}
|
|
30747
|
+
}
|
|
30748
|
+
}
|
|
30749
|
+
if (mixed && !nativeMixed && !nearestMixed) {
|
|
30685
30750
|
const source = out.slice();
|
|
30686
30751
|
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30687
30752
|
for (let y = 0; y < H; y++) {
|
package/dist/browser.mjs
CHANGED
|
@@ -30532,11 +30532,12 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30532
30532
|
if (dstLen <= 0 || srcLen <= 0) {
|
|
30533
30533
|
return taps;
|
|
30534
30534
|
}
|
|
30535
|
-
const at = (k) =>
|
|
30535
|
+
const at = (k) => start + k;
|
|
30536
30536
|
if (dstLen >= srcLen) {
|
|
30537
30537
|
for (let i = 0; i < dstLen; i++) {
|
|
30538
30538
|
taps.push([[at(halftoneNearest(i, srcLen, dstLen)), 1]]);
|
|
30539
30539
|
}
|
|
30540
|
+
if (reverse) taps.reverse();
|
|
30540
30541
|
return taps;
|
|
30541
30542
|
}
|
|
30542
30543
|
const step = Math.ceil(srcLen * FIX / dstLen);
|
|
@@ -30552,6 +30553,7 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30552
30553
|
}
|
|
30553
30554
|
taps.push(run);
|
|
30554
30555
|
}
|
|
30556
|
+
if (reverse) taps.reverse();
|
|
30555
30557
|
return taps;
|
|
30556
30558
|
}
|
|
30557
30559
|
var SPECKLE_OVERSHOOT = 4;
|
|
@@ -30567,8 +30569,22 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30567
30569
|
const right = x < w - 1 ? x + 1 : Math.max(0, x - 1);
|
|
30568
30570
|
let hClip = 0;
|
|
30569
30571
|
let vClip = 0;
|
|
30572
|
+
let alternating = 0;
|
|
30570
30573
|
for (let c = 0; c < 3; c++) {
|
|
30571
30574
|
const v = at(x, y, c);
|
|
30575
|
+
const axial = Math.max(
|
|
30576
|
+
Math.abs(v - at(left, y, c)),
|
|
30577
|
+
Math.abs(v - at(right, y, c)),
|
|
30578
|
+
Math.abs(v - at(x, up, c)),
|
|
30579
|
+
Math.abs(v - at(x, down, c))
|
|
30580
|
+
);
|
|
30581
|
+
const diagonal = Math.min(
|
|
30582
|
+
Math.abs(v - at(left, up, c)),
|
|
30583
|
+
Math.abs(v - at(right, up, c)),
|
|
30584
|
+
Math.abs(v - at(left, down, c)),
|
|
30585
|
+
Math.abs(v - at(right, down, c))
|
|
30586
|
+
);
|
|
30587
|
+
if (diagonal < axial) alternating++;
|
|
30572
30588
|
if (over(6 * v - at(left, y, c) - at(right, y, c))) {
|
|
30573
30589
|
hClip++;
|
|
30574
30590
|
}
|
|
@@ -30576,7 +30592,7 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30576
30592
|
vClip++;
|
|
30577
30593
|
}
|
|
30578
30594
|
}
|
|
30579
|
-
if (hClip < 2 || vClip < 2) {
|
|
30595
|
+
if (hClip < 2 || vClip < 2 || alternating < 2) {
|
|
30580
30596
|
continue;
|
|
30581
30597
|
}
|
|
30582
30598
|
for (let c = 0; c < 3; c++) {
|
|
@@ -30630,15 +30646,29 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30630
30646
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30631
30647
|
const reducing = W < SW && H < SH;
|
|
30632
30648
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30633
|
-
|
|
30649
|
+
const nearestMixed = mixed && (!adjust || adjustAfterSampling) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
30650
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling) && Math.min(SW, W) >= 2 && Math.min(SH, H) >= 2 && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
30651
|
+
if ((enlarging || nearestMixed) && !directDib) {
|
|
30634
30652
|
halftoneDespeckle(rect, SW, SH);
|
|
30635
30653
|
}
|
|
30636
30654
|
if (adjust && !adjustAfterSampling) {
|
|
30637
30655
|
adjust(rect);
|
|
30638
30656
|
}
|
|
30639
|
-
const
|
|
30640
|
-
const
|
|
30641
|
-
|
|
30657
|
+
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
30658
|
+
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
30659
|
+
const cols = halftoneAxis(0, SW, sampleW, flipX);
|
|
30660
|
+
const rows = halftoneAxis(0, SH, sampleH, flipY);
|
|
30661
|
+
if (nearestMixed) {
|
|
30662
|
+
const nearest = (taps, src2, dst, reverse) => {
|
|
30663
|
+
for (let i = 0; i < dst; i++) {
|
|
30664
|
+
const index = reverse ? dst - 1 - i : i;
|
|
30665
|
+
const k = dst < src2 ? Math.floor(((index + 1) * 2 * src2 - dst) / (2 * dst)) : halftoneNearest(index, src2, dst);
|
|
30666
|
+
taps[i] = [[Math.max(0, Math.min(src2 - 1, k)), 1]];
|
|
30667
|
+
}
|
|
30668
|
+
};
|
|
30669
|
+
nearest(cols, SW, W, flipX);
|
|
30670
|
+
nearest(rows, SH, H, flipY);
|
|
30671
|
+
} else if (mixed && !nativeMixed) {
|
|
30642
30672
|
const linear = (taps, src2, dst, reverse) => {
|
|
30643
30673
|
if (dst <= src2) return;
|
|
30644
30674
|
for (let i = 0; i < dst; i++) {
|
|
@@ -30651,10 +30681,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30651
30681
|
linear(cols, SW, W, flipX);
|
|
30652
30682
|
linear(rows, SH, H, flipY);
|
|
30653
30683
|
}
|
|
30654
|
-
|
|
30655
|
-
for (let y = 0; y <
|
|
30684
|
+
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
30685
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30656
30686
|
const ys = rows[y];
|
|
30657
|
-
for (let x = 0; x <
|
|
30687
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30658
30688
|
const xs = cols[x];
|
|
30659
30689
|
let r = 0;
|
|
30660
30690
|
let g = 0;
|
|
@@ -30670,16 +30700,51 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30670
30700
|
b += rect[i + 2] * w;
|
|
30671
30701
|
}
|
|
30672
30702
|
}
|
|
30673
|
-
const o = (y *
|
|
30674
|
-
|
|
30675
|
-
out[o
|
|
30676
|
-
out[o +
|
|
30703
|
+
const o = (y * sampleW + x) * 3;
|
|
30704
|
+
const round = (value) => nativeMixed ? value / total : mixed ? Math.ceil(value / total - 0.5) : Math.floor((2 * value + total) / (2 * total));
|
|
30705
|
+
out[o] = round(r);
|
|
30706
|
+
out[o + 1] = round(g);
|
|
30707
|
+
out[o + 2] = round(b);
|
|
30677
30708
|
}
|
|
30678
30709
|
}
|
|
30679
30710
|
if (reducing) {
|
|
30680
30711
|
halftoneSharpen(out, W, H);
|
|
30681
30712
|
}
|
|
30682
|
-
if (
|
|
30713
|
+
if (nativeMixed) {
|
|
30714
|
+
const reduceHorizontal = W < SW;
|
|
30715
|
+
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
30716
|
+
const source2 = out;
|
|
30717
|
+
out = new Int32Array(source2.length);
|
|
30718
|
+
const at = (x, y, c) => source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
30719
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30720
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30721
|
+
for (let c = 0; c < 3; c++) {
|
|
30722
|
+
const v = at(x, y, c);
|
|
30723
|
+
const sum = horizontal ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30724
|
+
out[(y * sampleW + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
30725
|
+
}
|
|
30726
|
+
}
|
|
30727
|
+
}
|
|
30728
|
+
}
|
|
30729
|
+
const source = out;
|
|
30730
|
+
out = new Int32Array(W * H * 3);
|
|
30731
|
+
for (let y = 0; y < H; y++) {
|
|
30732
|
+
const py = Math.max(0, Math.min(sampleH - 1, (y + 0.5) * sampleH / H - 0.5));
|
|
30733
|
+
const y02 = Math.floor(py), fy = py - y02;
|
|
30734
|
+
for (let x = 0; x < W; x++) {
|
|
30735
|
+
const px = Math.max(0, Math.min(sampleW - 1, (x + 0.5) * sampleW / W - 0.5));
|
|
30736
|
+
const x02 = Math.floor(px), fx = px - x02;
|
|
30737
|
+
for (let c = 0; c < 3; c++) {
|
|
30738
|
+
const at = (xx, yy) => source[(yy * sampleW + xx) * 3 + c];
|
|
30739
|
+
const x1 = Math.min(sampleW - 1, x02 + 1), y1 = Math.min(sampleH - 1, y02 + 1);
|
|
30740
|
+
const top = at(x02, y02) * (1 - fx) + at(x1, y02) * fx;
|
|
30741
|
+
const bottom = at(x02, y1) * (1 - fx) + at(x1, y1) * fx;
|
|
30742
|
+
out[(y * W + x) * 3 + c] = Math.floor(top * (1 - fy) + bottom * fy + 0.5);
|
|
30743
|
+
}
|
|
30744
|
+
}
|
|
30745
|
+
}
|
|
30746
|
+
}
|
|
30747
|
+
if (mixed && !nativeMixed && !nearestMixed) {
|
|
30683
30748
|
const source = out.slice();
|
|
30684
30749
|
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30685
30750
|
for (let y = 0; y < H; y++) {
|
package/dist/index.js
CHANGED
|
@@ -30535,11 +30535,12 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30535
30535
|
if (dstLen <= 0 || srcLen <= 0) {
|
|
30536
30536
|
return taps;
|
|
30537
30537
|
}
|
|
30538
|
-
const at = (k) =>
|
|
30538
|
+
const at = (k) => start + k;
|
|
30539
30539
|
if (dstLen >= srcLen) {
|
|
30540
30540
|
for (let i = 0; i < dstLen; i++) {
|
|
30541
30541
|
taps.push([[at(halftoneNearest(i, srcLen, dstLen)), 1]]);
|
|
30542
30542
|
}
|
|
30543
|
+
if (reverse) taps.reverse();
|
|
30543
30544
|
return taps;
|
|
30544
30545
|
}
|
|
30545
30546
|
const step = Math.ceil(srcLen * FIX / dstLen);
|
|
@@ -30555,6 +30556,7 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30555
30556
|
}
|
|
30556
30557
|
taps.push(run);
|
|
30557
30558
|
}
|
|
30559
|
+
if (reverse) taps.reverse();
|
|
30558
30560
|
return taps;
|
|
30559
30561
|
}
|
|
30560
30562
|
var SPECKLE_OVERSHOOT = 4;
|
|
@@ -30570,8 +30572,22 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30570
30572
|
const right = x < w - 1 ? x + 1 : Math.max(0, x - 1);
|
|
30571
30573
|
let hClip = 0;
|
|
30572
30574
|
let vClip = 0;
|
|
30575
|
+
let alternating = 0;
|
|
30573
30576
|
for (let c = 0; c < 3; c++) {
|
|
30574
30577
|
const v = at(x, y, c);
|
|
30578
|
+
const axial = Math.max(
|
|
30579
|
+
Math.abs(v - at(left, y, c)),
|
|
30580
|
+
Math.abs(v - at(right, y, c)),
|
|
30581
|
+
Math.abs(v - at(x, up, c)),
|
|
30582
|
+
Math.abs(v - at(x, down, c))
|
|
30583
|
+
);
|
|
30584
|
+
const diagonal = Math.min(
|
|
30585
|
+
Math.abs(v - at(left, up, c)),
|
|
30586
|
+
Math.abs(v - at(right, up, c)),
|
|
30587
|
+
Math.abs(v - at(left, down, c)),
|
|
30588
|
+
Math.abs(v - at(right, down, c))
|
|
30589
|
+
);
|
|
30590
|
+
if (diagonal < axial) alternating++;
|
|
30575
30591
|
if (over(6 * v - at(left, y, c) - at(right, y, c))) {
|
|
30576
30592
|
hClip++;
|
|
30577
30593
|
}
|
|
@@ -30579,7 +30595,7 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30579
30595
|
vClip++;
|
|
30580
30596
|
}
|
|
30581
30597
|
}
|
|
30582
|
-
if (hClip < 2 || vClip < 2) {
|
|
30598
|
+
if (hClip < 2 || vClip < 2 || alternating < 2) {
|
|
30583
30599
|
continue;
|
|
30584
30600
|
}
|
|
30585
30601
|
for (let c = 0; c < 3; c++) {
|
|
@@ -30633,15 +30649,29 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30633
30649
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30634
30650
|
const reducing = W < SW && H < SH;
|
|
30635
30651
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30636
|
-
|
|
30652
|
+
const nearestMixed = mixed && (!adjust || adjustAfterSampling) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
30653
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling) && Math.min(SW, W) >= 2 && Math.min(SH, H) >= 2 && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
30654
|
+
if ((enlarging || nearestMixed) && !directDib) {
|
|
30637
30655
|
halftoneDespeckle(rect, SW, SH);
|
|
30638
30656
|
}
|
|
30639
30657
|
if (adjust && !adjustAfterSampling) {
|
|
30640
30658
|
adjust(rect);
|
|
30641
30659
|
}
|
|
30642
|
-
const
|
|
30643
|
-
const
|
|
30644
|
-
|
|
30660
|
+
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
30661
|
+
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
30662
|
+
const cols = halftoneAxis(0, SW, sampleW, flipX);
|
|
30663
|
+
const rows = halftoneAxis(0, SH, sampleH, flipY);
|
|
30664
|
+
if (nearestMixed) {
|
|
30665
|
+
const nearest = (taps, src2, dst, reverse) => {
|
|
30666
|
+
for (let i = 0; i < dst; i++) {
|
|
30667
|
+
const index = reverse ? dst - 1 - i : i;
|
|
30668
|
+
const k = dst < src2 ? Math.floor(((index + 1) * 2 * src2 - dst) / (2 * dst)) : halftoneNearest(index, src2, dst);
|
|
30669
|
+
taps[i] = [[Math.max(0, Math.min(src2 - 1, k)), 1]];
|
|
30670
|
+
}
|
|
30671
|
+
};
|
|
30672
|
+
nearest(cols, SW, W, flipX);
|
|
30673
|
+
nearest(rows, SH, H, flipY);
|
|
30674
|
+
} else if (mixed && !nativeMixed) {
|
|
30645
30675
|
const linear = (taps, src2, dst, reverse) => {
|
|
30646
30676
|
if (dst <= src2) return;
|
|
30647
30677
|
for (let i = 0; i < dst; i++) {
|
|
@@ -30654,10 +30684,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30654
30684
|
linear(cols, SW, W, flipX);
|
|
30655
30685
|
linear(rows, SH, H, flipY);
|
|
30656
30686
|
}
|
|
30657
|
-
|
|
30658
|
-
for (let y = 0; y <
|
|
30687
|
+
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
30688
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30659
30689
|
const ys = rows[y];
|
|
30660
|
-
for (let x = 0; x <
|
|
30690
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30661
30691
|
const xs = cols[x];
|
|
30662
30692
|
let r = 0;
|
|
30663
30693
|
let g = 0;
|
|
@@ -30673,16 +30703,51 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30673
30703
|
b += rect[i + 2] * w;
|
|
30674
30704
|
}
|
|
30675
30705
|
}
|
|
30676
|
-
const o = (y *
|
|
30677
|
-
|
|
30678
|
-
out[o
|
|
30679
|
-
out[o +
|
|
30706
|
+
const o = (y * sampleW + x) * 3;
|
|
30707
|
+
const round = (value) => nativeMixed ? value / total : mixed ? Math.ceil(value / total - 0.5) : Math.floor((2 * value + total) / (2 * total));
|
|
30708
|
+
out[o] = round(r);
|
|
30709
|
+
out[o + 1] = round(g);
|
|
30710
|
+
out[o + 2] = round(b);
|
|
30680
30711
|
}
|
|
30681
30712
|
}
|
|
30682
30713
|
if (reducing) {
|
|
30683
30714
|
halftoneSharpen(out, W, H);
|
|
30684
30715
|
}
|
|
30685
|
-
if (
|
|
30716
|
+
if (nativeMixed) {
|
|
30717
|
+
const reduceHorizontal = W < SW;
|
|
30718
|
+
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
30719
|
+
const source2 = out;
|
|
30720
|
+
out = new Int32Array(source2.length);
|
|
30721
|
+
const at = (x, y, c) => source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
30722
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30723
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30724
|
+
for (let c = 0; c < 3; c++) {
|
|
30725
|
+
const v = at(x, y, c);
|
|
30726
|
+
const sum = horizontal ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30727
|
+
out[(y * sampleW + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
30728
|
+
}
|
|
30729
|
+
}
|
|
30730
|
+
}
|
|
30731
|
+
}
|
|
30732
|
+
const source = out;
|
|
30733
|
+
out = new Int32Array(W * H * 3);
|
|
30734
|
+
for (let y = 0; y < H; y++) {
|
|
30735
|
+
const py = Math.max(0, Math.min(sampleH - 1, (y + 0.5) * sampleH / H - 0.5));
|
|
30736
|
+
const y02 = Math.floor(py), fy = py - y02;
|
|
30737
|
+
for (let x = 0; x < W; x++) {
|
|
30738
|
+
const px = Math.max(0, Math.min(sampleW - 1, (x + 0.5) * sampleW / W - 0.5));
|
|
30739
|
+
const x02 = Math.floor(px), fx = px - x02;
|
|
30740
|
+
for (let c = 0; c < 3; c++) {
|
|
30741
|
+
const at = (xx, yy) => source[(yy * sampleW + xx) * 3 + c];
|
|
30742
|
+
const x1 = Math.min(sampleW - 1, x02 + 1), y1 = Math.min(sampleH - 1, y02 + 1);
|
|
30743
|
+
const top = at(x02, y02) * (1 - fx) + at(x1, y02) * fx;
|
|
30744
|
+
const bottom = at(x02, y1) * (1 - fx) + at(x1, y1) * fx;
|
|
30745
|
+
out[(y * W + x) * 3 + c] = Math.floor(top * (1 - fy) + bottom * fy + 0.5);
|
|
30746
|
+
}
|
|
30747
|
+
}
|
|
30748
|
+
}
|
|
30749
|
+
}
|
|
30750
|
+
if (mixed && !nativeMixed && !nearestMixed) {
|
|
30686
30751
|
const source = out.slice();
|
|
30687
30752
|
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30688
30753
|
for (let y = 0; y < H; y++) {
|
package/dist/index.mjs
CHANGED
|
@@ -30533,11 +30533,12 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30533
30533
|
if (dstLen <= 0 || srcLen <= 0) {
|
|
30534
30534
|
return taps;
|
|
30535
30535
|
}
|
|
30536
|
-
const at = (k) =>
|
|
30536
|
+
const at = (k) => start + k;
|
|
30537
30537
|
if (dstLen >= srcLen) {
|
|
30538
30538
|
for (let i = 0; i < dstLen; i++) {
|
|
30539
30539
|
taps.push([[at(halftoneNearest(i, srcLen, dstLen)), 1]]);
|
|
30540
30540
|
}
|
|
30541
|
+
if (reverse) taps.reverse();
|
|
30541
30542
|
return taps;
|
|
30542
30543
|
}
|
|
30543
30544
|
const step = Math.ceil(srcLen * FIX / dstLen);
|
|
@@ -30553,6 +30554,7 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
30553
30554
|
}
|
|
30554
30555
|
taps.push(run);
|
|
30555
30556
|
}
|
|
30557
|
+
if (reverse) taps.reverse();
|
|
30556
30558
|
return taps;
|
|
30557
30559
|
}
|
|
30558
30560
|
var SPECKLE_OVERSHOOT = 4;
|
|
@@ -30568,8 +30570,22 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30568
30570
|
const right = x < w - 1 ? x + 1 : Math.max(0, x - 1);
|
|
30569
30571
|
let hClip = 0;
|
|
30570
30572
|
let vClip = 0;
|
|
30573
|
+
let alternating = 0;
|
|
30571
30574
|
for (let c = 0; c < 3; c++) {
|
|
30572
30575
|
const v = at(x, y, c);
|
|
30576
|
+
const axial = Math.max(
|
|
30577
|
+
Math.abs(v - at(left, y, c)),
|
|
30578
|
+
Math.abs(v - at(right, y, c)),
|
|
30579
|
+
Math.abs(v - at(x, up, c)),
|
|
30580
|
+
Math.abs(v - at(x, down, c))
|
|
30581
|
+
);
|
|
30582
|
+
const diagonal = Math.min(
|
|
30583
|
+
Math.abs(v - at(left, up, c)),
|
|
30584
|
+
Math.abs(v - at(right, up, c)),
|
|
30585
|
+
Math.abs(v - at(left, down, c)),
|
|
30586
|
+
Math.abs(v - at(right, down, c))
|
|
30587
|
+
);
|
|
30588
|
+
if (diagonal < axial) alternating++;
|
|
30573
30589
|
if (over(6 * v - at(left, y, c) - at(right, y, c))) {
|
|
30574
30590
|
hClip++;
|
|
30575
30591
|
}
|
|
@@ -30577,7 +30593,7 @@ function halftoneDespeckle(px, w, h) {
|
|
|
30577
30593
|
vClip++;
|
|
30578
30594
|
}
|
|
30579
30595
|
}
|
|
30580
|
-
if (hClip < 2 || vClip < 2) {
|
|
30596
|
+
if (hClip < 2 || vClip < 2 || alternating < 2) {
|
|
30581
30597
|
continue;
|
|
30582
30598
|
}
|
|
30583
30599
|
for (let c = 0; c < 3; c++) {
|
|
@@ -30631,15 +30647,29 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30631
30647
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30632
30648
|
const reducing = W < SW && H < SH;
|
|
30633
30649
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30634
|
-
|
|
30650
|
+
const nearestMixed = mixed && (!adjust || adjustAfterSampling) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
30651
|
+
const nativeMixed = mixed && (!adjust || adjustAfterSampling) && Math.min(SW, W) >= 2 && Math.min(SH, H) >= 2 && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
30652
|
+
if ((enlarging || nearestMixed) && !directDib) {
|
|
30635
30653
|
halftoneDespeckle(rect, SW, SH);
|
|
30636
30654
|
}
|
|
30637
30655
|
if (adjust && !adjustAfterSampling) {
|
|
30638
30656
|
adjust(rect);
|
|
30639
30657
|
}
|
|
30640
|
-
const
|
|
30641
|
-
const
|
|
30642
|
-
|
|
30658
|
+
const sampleW = nativeMixed ? Math.min(SW, W) : W;
|
|
30659
|
+
const sampleH = nativeMixed ? Math.min(SH, H) : H;
|
|
30660
|
+
const cols = halftoneAxis(0, SW, sampleW, flipX);
|
|
30661
|
+
const rows = halftoneAxis(0, SH, sampleH, flipY);
|
|
30662
|
+
if (nearestMixed) {
|
|
30663
|
+
const nearest = (taps, src2, dst, reverse) => {
|
|
30664
|
+
for (let i = 0; i < dst; i++) {
|
|
30665
|
+
const index = reverse ? dst - 1 - i : i;
|
|
30666
|
+
const k = dst < src2 ? Math.floor(((index + 1) * 2 * src2 - dst) / (2 * dst)) : halftoneNearest(index, src2, dst);
|
|
30667
|
+
taps[i] = [[Math.max(0, Math.min(src2 - 1, k)), 1]];
|
|
30668
|
+
}
|
|
30669
|
+
};
|
|
30670
|
+
nearest(cols, SW, W, flipX);
|
|
30671
|
+
nearest(rows, SH, H, flipY);
|
|
30672
|
+
} else if (mixed && !nativeMixed) {
|
|
30643
30673
|
const linear = (taps, src2, dst, reverse) => {
|
|
30644
30674
|
if (dst <= src2) return;
|
|
30645
30675
|
for (let i = 0; i < dst; i++) {
|
|
@@ -30652,10 +30682,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30652
30682
|
linear(cols, SW, W, flipX);
|
|
30653
30683
|
linear(rows, SH, H, flipY);
|
|
30654
30684
|
}
|
|
30655
|
-
|
|
30656
|
-
for (let y = 0; y <
|
|
30685
|
+
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
30686
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30657
30687
|
const ys = rows[y];
|
|
30658
|
-
for (let x = 0; x <
|
|
30688
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30659
30689
|
const xs = cols[x];
|
|
30660
30690
|
let r = 0;
|
|
30661
30691
|
let g = 0;
|
|
@@ -30671,16 +30701,51 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
30671
30701
|
b += rect[i + 2] * w;
|
|
30672
30702
|
}
|
|
30673
30703
|
}
|
|
30674
|
-
const o = (y *
|
|
30675
|
-
|
|
30676
|
-
out[o
|
|
30677
|
-
out[o +
|
|
30704
|
+
const o = (y * sampleW + x) * 3;
|
|
30705
|
+
const round = (value) => nativeMixed ? value / total : mixed ? Math.ceil(value / total - 0.5) : Math.floor((2 * value + total) / (2 * total));
|
|
30706
|
+
out[o] = round(r);
|
|
30707
|
+
out[o + 1] = round(g);
|
|
30708
|
+
out[o + 2] = round(b);
|
|
30678
30709
|
}
|
|
30679
30710
|
}
|
|
30680
30711
|
if (reducing) {
|
|
30681
30712
|
halftoneSharpen(out, W, H);
|
|
30682
30713
|
}
|
|
30683
|
-
if (
|
|
30714
|
+
if (nativeMixed) {
|
|
30715
|
+
const reduceHorizontal = W < SW;
|
|
30716
|
+
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
30717
|
+
const source2 = out;
|
|
30718
|
+
out = new Int32Array(source2.length);
|
|
30719
|
+
const at = (x, y, c) => source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
30720
|
+
for (let y = 0; y < sampleH; y++) {
|
|
30721
|
+
for (let x = 0; x < sampleW; x++) {
|
|
30722
|
+
for (let c = 0; c < 3; c++) {
|
|
30723
|
+
const v = at(x, y, c);
|
|
30724
|
+
const sum = horizontal ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30725
|
+
out[(y * sampleW + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
30726
|
+
}
|
|
30727
|
+
}
|
|
30728
|
+
}
|
|
30729
|
+
}
|
|
30730
|
+
const source = out;
|
|
30731
|
+
out = new Int32Array(W * H * 3);
|
|
30732
|
+
for (let y = 0; y < H; y++) {
|
|
30733
|
+
const py = Math.max(0, Math.min(sampleH - 1, (y + 0.5) * sampleH / H - 0.5));
|
|
30734
|
+
const y02 = Math.floor(py), fy = py - y02;
|
|
30735
|
+
for (let x = 0; x < W; x++) {
|
|
30736
|
+
const px = Math.max(0, Math.min(sampleW - 1, (x + 0.5) * sampleW / W - 0.5));
|
|
30737
|
+
const x02 = Math.floor(px), fx = px - x02;
|
|
30738
|
+
for (let c = 0; c < 3; c++) {
|
|
30739
|
+
const at = (xx, yy) => source[(yy * sampleW + xx) * 3 + c];
|
|
30740
|
+
const x1 = Math.min(sampleW - 1, x02 + 1), y1 = Math.min(sampleH - 1, y02 + 1);
|
|
30741
|
+
const top = at(x02, y02) * (1 - fx) + at(x1, y02) * fx;
|
|
30742
|
+
const bottom = at(x02, y1) * (1 - fx) + at(x1, y1) * fx;
|
|
30743
|
+
out[(y * W + x) * 3 + c] = Math.floor(top * (1 - fy) + bottom * fy + 0.5);
|
|
30744
|
+
}
|
|
30745
|
+
}
|
|
30746
|
+
}
|
|
30747
|
+
}
|
|
30748
|
+
if (mixed && !nativeMixed && !nearestMixed) {
|
|
30684
30749
|
const source = out.slice();
|
|
30685
30750
|
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30686
30751
|
for (let y = 0; y < H; y++) {
|