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