emf-converter 4.8.2 → 4.8.4
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/README.md +1 -1
- package/dist/browser.js +206 -71
- package/dist/browser.mjs +206 -71
- package/dist/index.js +206 -71
- package/dist/index.mjs +206 -71
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -16808,14 +16808,21 @@ function blurKernel(radius) {
|
|
|
16808
16808
|
k[0] = 1;
|
|
16809
16809
|
return k;
|
|
16810
16810
|
}
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16814
|
-
|
|
16815
|
-
|
|
16816
|
-
|
|
16817
|
-
|
|
16818
|
-
|
|
16811
|
+
const step = truncF32(truncF32(1.4) / Math.fround(radius));
|
|
16812
|
+
const w = new Float64Array(taps + 1);
|
|
16813
|
+
w[0] = 1;
|
|
16814
|
+
let offset = 0;
|
|
16815
|
+
let sum = 1;
|
|
16816
|
+
for (let i = 1; i <= taps; i++) {
|
|
16817
|
+
offset = truncF32(offset + step);
|
|
16818
|
+
w[i] = truncF32(Math.exp(-truncF32(offset * offset)));
|
|
16819
|
+
sum = truncF32(sum + truncF32(2 * w[i]));
|
|
16820
|
+
}
|
|
16821
|
+
const scale = truncF32(256 / sum);
|
|
16822
|
+
for (let i = 0; i <= taps; i++) {
|
|
16823
|
+
const weight = truncF32(w[i] * scale) / 256;
|
|
16824
|
+
k[taps + i] = weight;
|
|
16825
|
+
k[taps - i] = weight;
|
|
16819
16826
|
}
|
|
16820
16827
|
return k;
|
|
16821
16828
|
}
|
|
@@ -17037,13 +17044,17 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
|
|
|
17037
17044
|
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
17038
17045
|
const w = x1 - x0;
|
|
17039
17046
|
const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
|
|
17047
|
+
const halo = new Uint8ClampedArray((y1 - y0) * 4);
|
|
17040
17048
|
for (let y = 0; y < y1 - y0; y++) {
|
|
17041
17049
|
const from = ((y + r) * bw + r) * 4;
|
|
17042
17050
|
for (let i = 0; i < w * 4; i++) {
|
|
17043
17051
|
out[y * w * 4 + i] = Math.round(blurred[from + i]);
|
|
17044
17052
|
}
|
|
17053
|
+
for (let i = 0; i < 4; i++) {
|
|
17054
|
+
halo[y * 4 + i] = Math.round(blurred[from + w * 4 + i]);
|
|
17055
|
+
}
|
|
17045
17056
|
}
|
|
17046
|
-
return out;
|
|
17057
|
+
return { out, halo };
|
|
17047
17058
|
}
|
|
17048
17059
|
function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
17049
17060
|
if (width <= 0 || height <= 0 || rgba.length !== width * height * 4) {
|
|
@@ -17076,7 +17087,12 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
|
17076
17087
|
};
|
|
17077
17088
|
if (src && effect.kind === "blur" && effect.expandEdge) {
|
|
17078
17089
|
const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
|
|
17079
|
-
|
|
17090
|
+
const { out: out2, halo } = expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped);
|
|
17091
|
+
const region2 = result(out2);
|
|
17092
|
+
if (shownWidth === w && shownHeight === h) {
|
|
17093
|
+
region2.haloRight = halo;
|
|
17094
|
+
}
|
|
17095
|
+
return region2;
|
|
17080
17096
|
}
|
|
17081
17097
|
let region = rgba;
|
|
17082
17098
|
if (w !== width || h !== height) {
|
|
@@ -20448,6 +20464,22 @@ function cubicIntegral(t, a) {
|
|
|
20448
20464
|
}
|
|
20449
20465
|
return Math.sign(t) * v;
|
|
20450
20466
|
}
|
|
20467
|
+
var FAR_FADE = [1, 1, 0.985, 0.95, 0.91, 0.85, 0.8, 0.745, 0.69, 0.63, 0.56, 0.5, 0.43, 0.35, 0.28, 0.22, 0.16, 0.11, 0.065, 0.03, 0];
|
|
20468
|
+
function fadeAt(d, bilinear) {
|
|
20469
|
+
if (d >= 1) {
|
|
20470
|
+
return 0;
|
|
20471
|
+
}
|
|
20472
|
+
if (bilinear) {
|
|
20473
|
+
return 1 - Math.max(0, d);
|
|
20474
|
+
}
|
|
20475
|
+
const x = Math.max(0, d) * 20;
|
|
20476
|
+
const i = Math.floor(x);
|
|
20477
|
+
return FAR_FADE[i] + (FAR_FADE[i + 1] - FAR_FADE[i]) * (x - i);
|
|
20478
|
+
}
|
|
20479
|
+
function nearSourceExtent(deviceLen, srcLen) {
|
|
20480
|
+
const d = Math.ceil(deviceLen - 1e-6) - srcLen;
|
|
20481
|
+
return d >= -1 && d <= 1;
|
|
20482
|
+
}
|
|
20451
20483
|
var BICUBIC_A = -0.5;
|
|
20452
20484
|
var HQ_BICUBIC_A = -1;
|
|
20453
20485
|
function axisFilter(kernel, scale, copy) {
|
|
@@ -20552,13 +20584,39 @@ function mirroredOrigin(o) {
|
|
|
20552
20584
|
return f === 0 ? o : Math.floor(o) + 1 - f;
|
|
20553
20585
|
}
|
|
20554
20586
|
function resampleImage(rgba, width, height, spec, surface) {
|
|
20587
|
+
if (spec.rightHalo && spec.rightHalo.length === height * 4) {
|
|
20588
|
+
const grown = new Uint8ClampedArray((width + 1) * height * 4);
|
|
20589
|
+
for (let y = 0; y < height; y++) {
|
|
20590
|
+
grown.set(rgba.subarray(y * width * 4, (y + 1) * width * 4), y * (width + 1) * 4);
|
|
20591
|
+
grown.set(spec.rightHalo.subarray(y * 4, y * 4 + 4), (y * (width + 1) + width) * 4);
|
|
20592
|
+
}
|
|
20593
|
+
return resampleImage(grown, width + 1, height, { ...spec, rightHalo: void 0 }, surface);
|
|
20594
|
+
}
|
|
20555
20595
|
if (spec.kernel === "nearest" && !spec.wrap) {
|
|
20556
20596
|
return resampleNearest(rgba, width, height, spec, surface);
|
|
20557
20597
|
}
|
|
20558
20598
|
let m = snapToDeviceGrid(spec);
|
|
20559
|
-
|
|
20599
|
+
let kernel = spec.kernel;
|
|
20560
20600
|
const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
|
|
20561
20601
|
const axisAligned = m[1] === 0 && m[2] === 0;
|
|
20602
|
+
let farFade = false;
|
|
20603
|
+
let shiftX = 0;
|
|
20604
|
+
let shiftY = 0;
|
|
20605
|
+
if (hq && !axisAligned) {
|
|
20606
|
+
const extentU = Math.hypot(m[0], m[1]) * spec.srcW;
|
|
20607
|
+
const extentV = Math.hypot(m[2], m[3]) * spec.srcH;
|
|
20608
|
+
if (nearSourceExtent(extentU, spec.srcW) || nearSourceExtent(extentV, spec.srcH)) {
|
|
20609
|
+
kernel = kernel === "hq-bicubic" ? "bicubic" : "bilinear";
|
|
20610
|
+
} else {
|
|
20611
|
+
farFade = true;
|
|
20612
|
+
if (spec.halfPixelOffset) {
|
|
20613
|
+
const lu = Math.hypot(m[0], m[1]);
|
|
20614
|
+
const lv = Math.hypot(m[2], m[3]);
|
|
20615
|
+
shiftX = 0.5 * m[0] / lu + 0.5 * m[2] / lv;
|
|
20616
|
+
shiftY = 0.5 * m[1] / lu + 0.5 * m[3] / lv;
|
|
20617
|
+
}
|
|
20618
|
+
}
|
|
20619
|
+
}
|
|
20562
20620
|
if (hq && axisAligned) {
|
|
20563
20621
|
const ox = m[0] * spec.srcX + m[4];
|
|
20564
20622
|
m = [m[0], 0, 0, m[3], m[4] + mirroredOrigin(ox) - ox, m[5]];
|
|
@@ -20613,6 +20671,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20613
20671
|
const vMax = spec.srcY + spec.srcH;
|
|
20614
20672
|
const wu = [];
|
|
20615
20673
|
const wv = [];
|
|
20674
|
+
const gradU = Math.hypot(inv2[0], inv2[2]);
|
|
20675
|
+
const gradV = Math.hypot(inv2[1], inv2[3]);
|
|
20616
20676
|
const c = spec.clampArgb ?? 0;
|
|
20617
20677
|
const edge = {
|
|
20618
20678
|
wrap: spec.wrap,
|
|
@@ -20624,8 +20684,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20624
20684
|
const py = by0 + j + o;
|
|
20625
20685
|
for (let i = 0; i < w; i++) {
|
|
20626
20686
|
const px = bx0 + i + o;
|
|
20627
|
-
const u = inv2[0] * px + inv2[2] * py + inv2[4];
|
|
20628
|
-
const v = inv2[1] * px + inv2[3] * py + inv2[5];
|
|
20687
|
+
const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
|
|
20688
|
+
const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
|
|
20629
20689
|
const cx = px + COVERAGE_NUDGE_X;
|
|
20630
20690
|
const cy = py + COVERAGE_NUDGE_Y;
|
|
20631
20691
|
const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
|
|
@@ -20633,31 +20693,35 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20633
20693
|
if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
|
|
20634
20694
|
continue;
|
|
20635
20695
|
}
|
|
20636
|
-
const
|
|
20637
|
-
const
|
|
20638
|
-
|
|
20639
|
-
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20649
|
-
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
20653
|
-
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20696
|
+
const box = { x0: 0, y0: 0, x1: width, y1: height };
|
|
20697
|
+
const sampleAt = (cu, cv) => {
|
|
20698
|
+
const iu0 = Math.ceil(cu - fu.radius);
|
|
20699
|
+
const iu1 = Math.floor(cu + fu.radius);
|
|
20700
|
+
const iv0 = Math.ceil(cv - fv.radius);
|
|
20701
|
+
const iv1 = Math.floor(cv + fv.radius);
|
|
20702
|
+
wu.length = 0;
|
|
20703
|
+
wv.length = 0;
|
|
20704
|
+
for (let t = iu0; t <= iu1; t++) {
|
|
20705
|
+
wu.push(fu.weight(t, cu));
|
|
20706
|
+
}
|
|
20707
|
+
for (let t = iv0; t <= iv1; t++) {
|
|
20708
|
+
wv.push(fv.weight(t, cv));
|
|
20709
|
+
}
|
|
20710
|
+
return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
|
|
20711
|
+
};
|
|
20712
|
+
let [r, g, b, a] = sampleAt(u, v);
|
|
20713
|
+
if (farFade && !spec.wrap && a > 0) {
|
|
20714
|
+
const du = (uMax - u) / gradU;
|
|
20715
|
+
const dv = (vMax - v) / gradV;
|
|
20716
|
+
const k = 1 - (du < 1 ? fadeAt(du, kernel === "hq-bilinear") * (sampleAt(uMax, v)[3] / a) : 0) - (dv < 1 ? fadeAt(dv, kernel === "hq-bilinear") * (sampleAt(u, vMax)[3] / a) : 0);
|
|
20717
|
+
if (k < 1) {
|
|
20718
|
+
const f = Math.max(0, k);
|
|
20719
|
+
r *= f;
|
|
20720
|
+
g *= f;
|
|
20721
|
+
b *= f;
|
|
20722
|
+
a *= f;
|
|
20723
|
+
}
|
|
20724
|
+
}
|
|
20661
20725
|
if (a <= 0) {
|
|
20662
20726
|
continue;
|
|
20663
20727
|
}
|
|
@@ -23484,7 +23548,8 @@ function effectedDraw(img, bitmap, effect, draw, source) {
|
|
|
23484
23548
|
srcY,
|
|
23485
23549
|
srcW,
|
|
23486
23550
|
srcH,
|
|
23487
|
-
toDevice: mulMatrix(draw.resample.toDevice, shift)
|
|
23551
|
+
toDevice: mulMatrix(draw.resample.toDevice, shift),
|
|
23552
|
+
rightHalo: region.haloRight
|
|
23488
23553
|
}
|
|
23489
23554
|
}
|
|
23490
23555
|
};
|
|
@@ -31423,6 +31488,15 @@ function illuminantCube(index) {
|
|
|
31423
31488
|
}
|
|
31424
31489
|
return cube;
|
|
31425
31490
|
}
|
|
31491
|
+
var ILLUMINANT_MATRICES = {
|
|
31492
|
+
1: [[1.64737, -0.59174, -0.05494], [0.02963, 0.96126, 881e-5], [0.2911, 0.40189, 0.30769]],
|
|
31493
|
+
2: [[1.22319, -0.17765, -0.04515], [275e-5, 0.99054, 645e-5], [0.05514, 0.12795, 0.81816]],
|
|
31494
|
+
3: [[1.02833, -0.01775, -0.01086], [861e-5, 0.98431, 728e-5], [-0.01616, -0.0448, 1.05995]],
|
|
31495
|
+
4: [[1.17271, -0.14059, -0.03174], [-474e-5, 1.00266, 183e-5], [0.05783, 0.14663, 0.79683]],
|
|
31496
|
+
5: [[1.10431, -0.08327, -0.02067], [-336e-5, 1.0025, 67e-5], [0.03344, 0.09072, 0.87702]],
|
|
31497
|
+
7: [[0.92515, 0.05628, 0.01822], [318e-5, 0.9967, 34e-5], [-0.02086, -0.06817, 1.08783]],
|
|
31498
|
+
8: [[1.31275, -0.26259, -0.04977], [-244e-5, 0.99695, 524e-5], [0.10854, 0.23443, 0.65827]]
|
|
31499
|
+
};
|
|
31426
31500
|
function hasIlluminant(ca) {
|
|
31427
31501
|
return illuminantCube(ca.illuminant) !== null;
|
|
31428
31502
|
}
|
|
@@ -31493,9 +31567,9 @@ var BRIGHTNESS_STEP = 0.95625;
|
|
|
31493
31567
|
var COLORFULNESS_SCALE = 1 / 100;
|
|
31494
31568
|
var TINT_RADIANS = -Math.PI / 3;
|
|
31495
31569
|
var RGB_TO_XYZ = [
|
|
31496
|
-
[0.
|
|
31497
|
-
[0.
|
|
31498
|
-
[0.
|
|
31570
|
+
[0.4123908, 0.3575843, 0.1804808],
|
|
31571
|
+
[0.212639, 0.7151687, 0.0721923],
|
|
31572
|
+
[0.0193308, 0.1191948, 0.9505322]
|
|
31499
31573
|
];
|
|
31500
31574
|
var XYZ_TO_RGB = invert3(RGB_TO_XYZ);
|
|
31501
31575
|
var WHITE = RGB_TO_XYZ.map((row2) => row2[0] + row2[1] + row2[2]);
|
|
@@ -31523,13 +31597,13 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31523
31597
|
const z = RGB_TO_XYZ[2][0] * r + RGB_TO_XYZ[2][1] * g + RGB_TO_XYZ[2][2] * b;
|
|
31524
31598
|
const d = x + 15 * y + 3 * z;
|
|
31525
31599
|
if (d <= 1e-9 || y <= 1e-9) {
|
|
31526
|
-
return [r, g, b];
|
|
31600
|
+
return [clamp255(r), clamp255(g), clamp255(b)];
|
|
31527
31601
|
}
|
|
31528
31602
|
const du = 4 * x / d - WHITE_U;
|
|
31529
31603
|
const dv = 9 * y / d - WHITE_V;
|
|
31530
31604
|
const cos = Math.cos(angle) * scale;
|
|
31531
31605
|
const sin = Math.sin(angle) * scale;
|
|
31532
|
-
const u = WHITE_U + du * cos - dv * sin;
|
|
31606
|
+
const u = Math.max(0, WHITE_U + du * cos - dv * sin);
|
|
31533
31607
|
const v = Math.max(1e-6, WHITE_V + du * sin + dv * cos);
|
|
31534
31608
|
const x2 = y * 9 * u / (4 * v);
|
|
31535
31609
|
const z2 = y * (12 - 3 * u - 20 * v) / (4 * v);
|
|
@@ -31548,6 +31622,7 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31548
31622
|
}
|
|
31549
31623
|
function colorAdjustmentMapper(ca) {
|
|
31550
31624
|
const illuminant = illuminantCube(ca.illuminant);
|
|
31625
|
+
const matrix = ILLUMINANT_MATRICES[ca.illuminant];
|
|
31551
31626
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
31552
31627
|
const black = ca.referenceBlack / 1e4 * 255;
|
|
31553
31628
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 * 255 - black);
|
|
@@ -31576,16 +31651,17 @@ function colorAdjustmentMapper(ca) {
|
|
|
31576
31651
|
}
|
|
31577
31652
|
return (rgb2) => {
|
|
31578
31653
|
let c = [rgb2 >> 16 & 255, rgb2 >> 8 & 255, rgb2 & 255];
|
|
31579
|
-
if (illuminant) {
|
|
31580
|
-
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
31581
|
-
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31582
|
-
}
|
|
31583
31654
|
if (chroma) {
|
|
31584
|
-
|
|
31585
|
-
|
|
31655
|
+
c = c.map(exactPaletteLevel);
|
|
31656
|
+
if (matrix) {
|
|
31657
|
+
const [r, g, b] = c;
|
|
31658
|
+
c = matrix.map((row2) => row2[0] * r + row2[1] * g + row2[2] * b);
|
|
31586
31659
|
}
|
|
31587
|
-
c = adjustChroma(
|
|
31660
|
+
c = adjustChroma(c[0], c[1], c[2], scale, angle);
|
|
31588
31661
|
c = c.map(roundHalfUp);
|
|
31662
|
+
} else if (illuminant) {
|
|
31663
|
+
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
31664
|
+
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31589
31665
|
}
|
|
31590
31666
|
return curve(c[0], 0) << 16 | curve(c[1], 1) << 8 | curve(c[2], 2);
|
|
31591
31667
|
};
|
|
@@ -31939,20 +32015,6 @@ function halftoneDespeckle(px, w, h) {
|
|
|
31939
32015
|
}
|
|
31940
32016
|
}
|
|
31941
32017
|
}
|
|
31942
|
-
function halftoneSharpen(px, w, h) {
|
|
31943
|
-
const src = px.slice();
|
|
31944
|
-
const at = (x, y, c) => src[(Math.max(0, Math.min(h - 1, y)) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
31945
|
-
for (let y = 0; y < h; y++) {
|
|
31946
|
-
for (let x = 0; x < w; x++) {
|
|
31947
|
-
for (let c = 0; c < 3; c++) {
|
|
31948
|
-
const v = at(x, y, c);
|
|
31949
|
-
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
31950
|
-
const out = v + Math.floor((4 * v - sum) / 8);
|
|
31951
|
-
px[(y * w + x) * 3 + c] = out < 0 ? 0 : out > 255 ? 255 : out;
|
|
31952
|
-
}
|
|
31953
|
-
}
|
|
31954
|
-
}
|
|
31955
|
-
}
|
|
31956
32018
|
function halftonePairDespeckle(px, w, h, rows) {
|
|
31957
32019
|
const n = rows ? w : h;
|
|
31958
32020
|
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
@@ -31975,6 +32037,46 @@ function halftoneKeepLast(px, w, h, rows) {
|
|
|
31975
32037
|
}
|
|
31976
32038
|
return out;
|
|
31977
32039
|
}
|
|
32040
|
+
function halftoneReduceBoth(rect, sw, sh, dw, dh, flipX, flipY) {
|
|
32041
|
+
const cols = halftoneReduceTaps(sw, dw, flipX);
|
|
32042
|
+
const rows = halftoneReduceTaps(sh, dh, flipY);
|
|
32043
|
+
const wide = new Int32Array(dw * sh * 3);
|
|
32044
|
+
for (let y = 0; y < sh; y++) {
|
|
32045
|
+
for (let x = 0; x < dw; x++) {
|
|
32046
|
+
let total = 0;
|
|
32047
|
+
for (const [, w] of cols[x]) total += w;
|
|
32048
|
+
for (let c = 0; c < 3; c++) {
|
|
32049
|
+
let sum = 0;
|
|
32050
|
+
for (const [xx, w] of cols[x]) sum += rect[(y * sw + xx) * 3 + c] * w;
|
|
32051
|
+
wide[(y * dw + x) * 3 + c] = Math.floor((2 * sum + total) / (2 * total));
|
|
32052
|
+
}
|
|
32053
|
+
}
|
|
32054
|
+
}
|
|
32055
|
+
const avg = new Float64Array(dw * dh * 3);
|
|
32056
|
+
for (let y = 0; y < dh; y++) {
|
|
32057
|
+
let total = 0;
|
|
32058
|
+
for (const [, w] of rows[y]) total += w;
|
|
32059
|
+
for (let x = 0; x < dw; x++) {
|
|
32060
|
+
for (let c = 0; c < 3; c++) {
|
|
32061
|
+
let sum = 0;
|
|
32062
|
+
for (const [yy, w] of rows[y]) sum += wide[(yy * dw + x) * 3 + c] * w;
|
|
32063
|
+
avg[(y * dw + x) * 3 + c] = sum / total;
|
|
32064
|
+
}
|
|
32065
|
+
}
|
|
32066
|
+
}
|
|
32067
|
+
const at = (x, y, c) => avg[(Math.max(0, Math.min(dh - 1, y)) * dw + Math.max(0, Math.min(dw - 1, x))) * 3 + c];
|
|
32068
|
+
const out = new Int32Array(dw * dh * 3);
|
|
32069
|
+
for (let y = 0; y < dh; y++) {
|
|
32070
|
+
for (let x = 0; x < dw; x++) {
|
|
32071
|
+
for (let c = 0; c < 3; c++) {
|
|
32072
|
+
const v = at(x, y, c);
|
|
32073
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
32074
|
+
out[(y * dw + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (4 * v - sum) / 8)));
|
|
32075
|
+
}
|
|
32076
|
+
}
|
|
32077
|
+
}
|
|
32078
|
+
return out;
|
|
32079
|
+
}
|
|
31978
32080
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
31979
32081
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
31980
32082
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
@@ -32026,11 +32128,18 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32026
32128
|
}
|
|
32027
32129
|
const reducedEven = W < SW ? SW % 2 === 0 && H % SH === 0 : SH % 2 === 0 && W % SW === 0;
|
|
32028
32130
|
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && reducedEven);
|
|
32131
|
+
const extendRow = ditherAtSource && nativeMixed && W < SW && H > SH && !flipY;
|
|
32132
|
+
if (extendRow) {
|
|
32133
|
+
const bigger = new Int32Array((SH + 1) * SW * 3);
|
|
32134
|
+
bigger.set(rect);
|
|
32135
|
+
bigger.copyWithin(SH * SW * 3, (SH - 1) * SW * 3, SH * SW * 3);
|
|
32136
|
+
rect = bigger;
|
|
32137
|
+
}
|
|
32029
32138
|
if (ditherAtSource) {
|
|
32030
32139
|
ditherPixels(
|
|
32031
32140
|
rect,
|
|
32032
32141
|
SW,
|
|
32033
|
-
SH,
|
|
32142
|
+
extendRow ? SH + 1 : SH,
|
|
32034
32143
|
dither,
|
|
32035
32144
|
false,
|
|
32036
32145
|
false,
|
|
@@ -32070,7 +32179,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32070
32179
|
linear(rows, SH, H, flipY);
|
|
32071
32180
|
}
|
|
32072
32181
|
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
32073
|
-
|
|
32182
|
+
if (reducing) {
|
|
32183
|
+
out = halftoneReduceBoth(rect, SW, SH, W, H, flipX, flipY);
|
|
32184
|
+
}
|
|
32185
|
+
for (let y = 0; !reducing && y < sampleH; y++) {
|
|
32074
32186
|
const ys = rows[y];
|
|
32075
32187
|
for (let x = 0; x < sampleW; x++) {
|
|
32076
32188
|
const xs = cols[x];
|
|
@@ -32095,15 +32207,38 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32095
32207
|
out[o + 2] = round(b);
|
|
32096
32208
|
}
|
|
32097
32209
|
}
|
|
32098
|
-
if (reducing) {
|
|
32099
|
-
halftoneSharpen(out, W, H);
|
|
32100
|
-
}
|
|
32101
32210
|
if (nativeMixed) {
|
|
32102
32211
|
const reduceHorizontal = W < SW;
|
|
32212
|
+
let extension;
|
|
32213
|
+
if (extendRow) {
|
|
32214
|
+
const reduced = new Float64Array(sampleW * 3);
|
|
32215
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32216
|
+
let total = 0;
|
|
32217
|
+
const sums = [0, 0, 0];
|
|
32218
|
+
for (const [xx, wx] of cols[x]) {
|
|
32219
|
+
total += wx;
|
|
32220
|
+
for (let c = 0; c < 3; c++) sums[c] += rect[(SH * SW + xx) * 3 + c] * wx;
|
|
32221
|
+
}
|
|
32222
|
+
for (let c = 0; c < 3; c++) reduced[x * 3 + c] = sums[c] / total;
|
|
32223
|
+
}
|
|
32224
|
+
extension = reduced;
|
|
32225
|
+
}
|
|
32103
32226
|
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
32104
32227
|
const source2 = out;
|
|
32105
32228
|
out = new Int32Array(source2.length);
|
|
32106
|
-
const
|
|
32229
|
+
const ext = extension;
|
|
32230
|
+
const at = (x, y, c) => y >= sampleH && ext ? ext[Math.max(0, Math.min(sampleW - 1, x)) * 3 + c] : source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
32231
|
+
if (horizontal && ext) {
|
|
32232
|
+
const next = new Int32Array(sampleW * 3);
|
|
32233
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32234
|
+
for (let c = 0; c < 3; c++) {
|
|
32235
|
+
const v = ext[x * 3 + c];
|
|
32236
|
+
const sum = at(x - 1, sampleH, c) + at(x + 1, sampleH, c);
|
|
32237
|
+
next[x * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
32238
|
+
}
|
|
32239
|
+
}
|
|
32240
|
+
extension = next;
|
|
32241
|
+
}
|
|
32107
32242
|
for (let y = 0; y < sampleH; y++) {
|
|
32108
32243
|
for (let x = 0; x < sampleW; x++) {
|
|
32109
32244
|
for (let c = 0; c < 3; c++) {
|