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