emf-converter 4.8.2 → 4.8.3
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 +191 -63
- package/dist/browser.mjs +191 -63
- package/dist/index.js +191 -63
- package/dist/index.mjs +191 -63
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -17037,13 +17037,17 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
|
|
|
17037
17037
|
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
17038
|
const w = x1 - x0;
|
|
17039
17039
|
const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
|
|
17040
|
+
const halo = new Uint8ClampedArray((y1 - y0) * 4);
|
|
17040
17041
|
for (let y = 0; y < y1 - y0; y++) {
|
|
17041
17042
|
const from = ((y + r) * bw + r) * 4;
|
|
17042
17043
|
for (let i = 0; i < w * 4; i++) {
|
|
17043
17044
|
out[y * w * 4 + i] = Math.round(blurred[from + i]);
|
|
17044
17045
|
}
|
|
17046
|
+
for (let i = 0; i < 4; i++) {
|
|
17047
|
+
halo[y * 4 + i] = Math.round(blurred[from + w * 4 + i]);
|
|
17048
|
+
}
|
|
17045
17049
|
}
|
|
17046
|
-
return out;
|
|
17050
|
+
return { out, halo };
|
|
17047
17051
|
}
|
|
17048
17052
|
function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
17049
17053
|
if (width <= 0 || height <= 0 || rgba.length !== width * height * 4) {
|
|
@@ -17076,7 +17080,12 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
|
17076
17080
|
};
|
|
17077
17081
|
if (src && effect.kind === "blur" && effect.expandEdge) {
|
|
17078
17082
|
const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
|
|
17079
|
-
|
|
17083
|
+
const { out: out2, halo } = expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped);
|
|
17084
|
+
const region2 = result(out2);
|
|
17085
|
+
if (shownWidth === w && shownHeight === h) {
|
|
17086
|
+
region2.haloRight = halo;
|
|
17087
|
+
}
|
|
17088
|
+
return region2;
|
|
17080
17089
|
}
|
|
17081
17090
|
let region = rgba;
|
|
17082
17091
|
if (w !== width || h !== height) {
|
|
@@ -20448,6 +20457,22 @@ function cubicIntegral(t, a) {
|
|
|
20448
20457
|
}
|
|
20449
20458
|
return Math.sign(t) * v;
|
|
20450
20459
|
}
|
|
20460
|
+
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];
|
|
20461
|
+
function fadeAt(d, bilinear) {
|
|
20462
|
+
if (d >= 1) {
|
|
20463
|
+
return 0;
|
|
20464
|
+
}
|
|
20465
|
+
if (bilinear) {
|
|
20466
|
+
return 1 - Math.max(0, d);
|
|
20467
|
+
}
|
|
20468
|
+
const x = Math.max(0, d) * 20;
|
|
20469
|
+
const i = Math.floor(x);
|
|
20470
|
+
return FAR_FADE[i] + (FAR_FADE[i + 1] - FAR_FADE[i]) * (x - i);
|
|
20471
|
+
}
|
|
20472
|
+
function nearSourceExtent(deviceLen, srcLen) {
|
|
20473
|
+
const d = Math.ceil(deviceLen - 1e-6) - srcLen;
|
|
20474
|
+
return d >= -1 && d <= 1;
|
|
20475
|
+
}
|
|
20451
20476
|
var BICUBIC_A = -0.5;
|
|
20452
20477
|
var HQ_BICUBIC_A = -1;
|
|
20453
20478
|
function axisFilter(kernel, scale, copy) {
|
|
@@ -20552,13 +20577,39 @@ function mirroredOrigin(o) {
|
|
|
20552
20577
|
return f === 0 ? o : Math.floor(o) + 1 - f;
|
|
20553
20578
|
}
|
|
20554
20579
|
function resampleImage(rgba, width, height, spec, surface) {
|
|
20580
|
+
if (spec.rightHalo && spec.rightHalo.length === height * 4) {
|
|
20581
|
+
const grown = new Uint8ClampedArray((width + 1) * height * 4);
|
|
20582
|
+
for (let y = 0; y < height; y++) {
|
|
20583
|
+
grown.set(rgba.subarray(y * width * 4, (y + 1) * width * 4), y * (width + 1) * 4);
|
|
20584
|
+
grown.set(spec.rightHalo.subarray(y * 4, y * 4 + 4), (y * (width + 1) + width) * 4);
|
|
20585
|
+
}
|
|
20586
|
+
return resampleImage(grown, width + 1, height, { ...spec, rightHalo: void 0 }, surface);
|
|
20587
|
+
}
|
|
20555
20588
|
if (spec.kernel === "nearest" && !spec.wrap) {
|
|
20556
20589
|
return resampleNearest(rgba, width, height, spec, surface);
|
|
20557
20590
|
}
|
|
20558
20591
|
let m = snapToDeviceGrid(spec);
|
|
20559
|
-
|
|
20592
|
+
let kernel = spec.kernel;
|
|
20560
20593
|
const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
|
|
20561
20594
|
const axisAligned = m[1] === 0 && m[2] === 0;
|
|
20595
|
+
let farFade = false;
|
|
20596
|
+
let shiftX = 0;
|
|
20597
|
+
let shiftY = 0;
|
|
20598
|
+
if (hq && !axisAligned) {
|
|
20599
|
+
const extentU = Math.hypot(m[0], m[1]) * spec.srcW;
|
|
20600
|
+
const extentV = Math.hypot(m[2], m[3]) * spec.srcH;
|
|
20601
|
+
if (nearSourceExtent(extentU, spec.srcW) || nearSourceExtent(extentV, spec.srcH)) {
|
|
20602
|
+
kernel = kernel === "hq-bicubic" ? "bicubic" : "bilinear";
|
|
20603
|
+
} else {
|
|
20604
|
+
farFade = true;
|
|
20605
|
+
if (spec.halfPixelOffset) {
|
|
20606
|
+
const lu = Math.hypot(m[0], m[1]);
|
|
20607
|
+
const lv = Math.hypot(m[2], m[3]);
|
|
20608
|
+
shiftX = 0.5 * m[0] / lu + 0.5 * m[2] / lv;
|
|
20609
|
+
shiftY = 0.5 * m[1] / lu + 0.5 * m[3] / lv;
|
|
20610
|
+
}
|
|
20611
|
+
}
|
|
20612
|
+
}
|
|
20562
20613
|
if (hq && axisAligned) {
|
|
20563
20614
|
const ox = m[0] * spec.srcX + m[4];
|
|
20564
20615
|
m = [m[0], 0, 0, m[3], m[4] + mirroredOrigin(ox) - ox, m[5]];
|
|
@@ -20613,6 +20664,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20613
20664
|
const vMax = spec.srcY + spec.srcH;
|
|
20614
20665
|
const wu = [];
|
|
20615
20666
|
const wv = [];
|
|
20667
|
+
const gradU = Math.hypot(inv2[0], inv2[2]);
|
|
20668
|
+
const gradV = Math.hypot(inv2[1], inv2[3]);
|
|
20616
20669
|
const c = spec.clampArgb ?? 0;
|
|
20617
20670
|
const edge = {
|
|
20618
20671
|
wrap: spec.wrap,
|
|
@@ -20624,8 +20677,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20624
20677
|
const py = by0 + j + o;
|
|
20625
20678
|
for (let i = 0; i < w; i++) {
|
|
20626
20679
|
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];
|
|
20680
|
+
const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
|
|
20681
|
+
const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
|
|
20629
20682
|
const cx = px + COVERAGE_NUDGE_X;
|
|
20630
20683
|
const cy = py + COVERAGE_NUDGE_Y;
|
|
20631
20684
|
const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
|
|
@@ -20633,31 +20686,35 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20633
20686
|
if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
|
|
20634
20687
|
continue;
|
|
20635
20688
|
}
|
|
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
|
-
|
|
20689
|
+
const box = { x0: 0, y0: 0, x1: width, y1: height };
|
|
20690
|
+
const sampleAt = (cu, cv) => {
|
|
20691
|
+
const iu0 = Math.ceil(cu - fu.radius);
|
|
20692
|
+
const iu1 = Math.floor(cu + fu.radius);
|
|
20693
|
+
const iv0 = Math.ceil(cv - fv.radius);
|
|
20694
|
+
const iv1 = Math.floor(cv + fv.radius);
|
|
20695
|
+
wu.length = 0;
|
|
20696
|
+
wv.length = 0;
|
|
20697
|
+
for (let t = iu0; t <= iu1; t++) {
|
|
20698
|
+
wu.push(fu.weight(t, cu));
|
|
20699
|
+
}
|
|
20700
|
+
for (let t = iv0; t <= iv1; t++) {
|
|
20701
|
+
wv.push(fv.weight(t, cv));
|
|
20702
|
+
}
|
|
20703
|
+
return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
|
|
20704
|
+
};
|
|
20705
|
+
let [r, g, b, a] = sampleAt(u, v);
|
|
20706
|
+
if (farFade && !spec.wrap && a > 0) {
|
|
20707
|
+
const du = (uMax - u) / gradU;
|
|
20708
|
+
const dv = (vMax - v) / gradV;
|
|
20709
|
+
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);
|
|
20710
|
+
if (k < 1) {
|
|
20711
|
+
const f = Math.max(0, k);
|
|
20712
|
+
r *= f;
|
|
20713
|
+
g *= f;
|
|
20714
|
+
b *= f;
|
|
20715
|
+
a *= f;
|
|
20716
|
+
}
|
|
20717
|
+
}
|
|
20661
20718
|
if (a <= 0) {
|
|
20662
20719
|
continue;
|
|
20663
20720
|
}
|
|
@@ -23484,7 +23541,8 @@ function effectedDraw(img, bitmap, effect, draw, source) {
|
|
|
23484
23541
|
srcY,
|
|
23485
23542
|
srcW,
|
|
23486
23543
|
srcH,
|
|
23487
|
-
toDevice: mulMatrix(draw.resample.toDevice, shift)
|
|
23544
|
+
toDevice: mulMatrix(draw.resample.toDevice, shift),
|
|
23545
|
+
rightHalo: region.haloRight
|
|
23488
23546
|
}
|
|
23489
23547
|
}
|
|
23490
23548
|
};
|
|
@@ -31423,6 +31481,15 @@ function illuminantCube(index) {
|
|
|
31423
31481
|
}
|
|
31424
31482
|
return cube;
|
|
31425
31483
|
}
|
|
31484
|
+
var ILLUMINANT_MATRICES = {
|
|
31485
|
+
1: [[1.64737, -0.59174, -0.05494], [0.02963, 0.96126, 881e-5], [0.2911, 0.40189, 0.30769]],
|
|
31486
|
+
2: [[1.22319, -0.17765, -0.04515], [275e-5, 0.99054, 645e-5], [0.05514, 0.12795, 0.81816]],
|
|
31487
|
+
3: [[1.02833, -0.01775, -0.01086], [861e-5, 0.98431, 728e-5], [-0.01616, -0.0448, 1.05995]],
|
|
31488
|
+
4: [[1.17271, -0.14059, -0.03174], [-474e-5, 1.00266, 183e-5], [0.05783, 0.14663, 0.79683]],
|
|
31489
|
+
5: [[1.10431, -0.08327, -0.02067], [-336e-5, 1.0025, 67e-5], [0.03344, 0.09072, 0.87702]],
|
|
31490
|
+
7: [[0.92515, 0.05628, 0.01822], [318e-5, 0.9967, 34e-5], [-0.02086, -0.06817, 1.08783]],
|
|
31491
|
+
8: [[1.31275, -0.26259, -0.04977], [-244e-5, 0.99695, 524e-5], [0.10854, 0.23443, 0.65827]]
|
|
31492
|
+
};
|
|
31426
31493
|
function hasIlluminant(ca) {
|
|
31427
31494
|
return illuminantCube(ca.illuminant) !== null;
|
|
31428
31495
|
}
|
|
@@ -31493,9 +31560,9 @@ var BRIGHTNESS_STEP = 0.95625;
|
|
|
31493
31560
|
var COLORFULNESS_SCALE = 1 / 100;
|
|
31494
31561
|
var TINT_RADIANS = -Math.PI / 3;
|
|
31495
31562
|
var RGB_TO_XYZ = [
|
|
31496
|
-
[0.
|
|
31497
|
-
[0.
|
|
31498
|
-
[0.
|
|
31563
|
+
[0.4123908, 0.3575843, 0.1804808],
|
|
31564
|
+
[0.212639, 0.7151687, 0.0721923],
|
|
31565
|
+
[0.0193308, 0.1191948, 0.9505322]
|
|
31499
31566
|
];
|
|
31500
31567
|
var XYZ_TO_RGB = invert3(RGB_TO_XYZ);
|
|
31501
31568
|
var WHITE = RGB_TO_XYZ.map((row2) => row2[0] + row2[1] + row2[2]);
|
|
@@ -31523,13 +31590,13 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31523
31590
|
const z = RGB_TO_XYZ[2][0] * r + RGB_TO_XYZ[2][1] * g + RGB_TO_XYZ[2][2] * b;
|
|
31524
31591
|
const d = x + 15 * y + 3 * z;
|
|
31525
31592
|
if (d <= 1e-9 || y <= 1e-9) {
|
|
31526
|
-
return [r, g, b];
|
|
31593
|
+
return [clamp255(r), clamp255(g), clamp255(b)];
|
|
31527
31594
|
}
|
|
31528
31595
|
const du = 4 * x / d - WHITE_U;
|
|
31529
31596
|
const dv = 9 * y / d - WHITE_V;
|
|
31530
31597
|
const cos = Math.cos(angle) * scale;
|
|
31531
31598
|
const sin = Math.sin(angle) * scale;
|
|
31532
|
-
const u = WHITE_U + du * cos - dv * sin;
|
|
31599
|
+
const u = Math.max(0, WHITE_U + du * cos - dv * sin);
|
|
31533
31600
|
const v = Math.max(1e-6, WHITE_V + du * sin + dv * cos);
|
|
31534
31601
|
const x2 = y * 9 * u / (4 * v);
|
|
31535
31602
|
const z2 = y * (12 - 3 * u - 20 * v) / (4 * v);
|
|
@@ -31548,6 +31615,7 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31548
31615
|
}
|
|
31549
31616
|
function colorAdjustmentMapper(ca) {
|
|
31550
31617
|
const illuminant = illuminantCube(ca.illuminant);
|
|
31618
|
+
const matrix = ILLUMINANT_MATRICES[ca.illuminant];
|
|
31551
31619
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
31552
31620
|
const black = ca.referenceBlack / 1e4 * 255;
|
|
31553
31621
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 * 255 - black);
|
|
@@ -31576,16 +31644,17 @@ function colorAdjustmentMapper(ca) {
|
|
|
31576
31644
|
}
|
|
31577
31645
|
return (rgb2) => {
|
|
31578
31646
|
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
31647
|
if (chroma) {
|
|
31584
|
-
|
|
31585
|
-
|
|
31648
|
+
c = c.map(exactPaletteLevel);
|
|
31649
|
+
if (matrix) {
|
|
31650
|
+
const [r, g, b] = c;
|
|
31651
|
+
c = matrix.map((row2) => row2[0] * r + row2[1] * g + row2[2] * b);
|
|
31586
31652
|
}
|
|
31587
|
-
c = adjustChroma(
|
|
31653
|
+
c = adjustChroma(c[0], c[1], c[2], scale, angle);
|
|
31588
31654
|
c = c.map(roundHalfUp);
|
|
31655
|
+
} else if (illuminant) {
|
|
31656
|
+
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
31657
|
+
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31589
31658
|
}
|
|
31590
31659
|
return curve(c[0], 0) << 16 | curve(c[1], 1) << 8 | curve(c[2], 2);
|
|
31591
31660
|
};
|
|
@@ -31939,20 +32008,6 @@ function halftoneDespeckle(px, w, h) {
|
|
|
31939
32008
|
}
|
|
31940
32009
|
}
|
|
31941
32010
|
}
|
|
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
32011
|
function halftonePairDespeckle(px, w, h, rows) {
|
|
31957
32012
|
const n = rows ? w : h;
|
|
31958
32013
|
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
@@ -31975,6 +32030,46 @@ function halftoneKeepLast(px, w, h, rows) {
|
|
|
31975
32030
|
}
|
|
31976
32031
|
return out;
|
|
31977
32032
|
}
|
|
32033
|
+
function halftoneReduceBoth(rect, sw, sh, dw, dh, flipX, flipY) {
|
|
32034
|
+
const cols = halftoneReduceTaps(sw, dw, flipX);
|
|
32035
|
+
const rows = halftoneReduceTaps(sh, dh, flipY);
|
|
32036
|
+
const wide = new Int32Array(dw * sh * 3);
|
|
32037
|
+
for (let y = 0; y < sh; y++) {
|
|
32038
|
+
for (let x = 0; x < dw; x++) {
|
|
32039
|
+
let total = 0;
|
|
32040
|
+
for (const [, w] of cols[x]) total += w;
|
|
32041
|
+
for (let c = 0; c < 3; c++) {
|
|
32042
|
+
let sum = 0;
|
|
32043
|
+
for (const [xx, w] of cols[x]) sum += rect[(y * sw + xx) * 3 + c] * w;
|
|
32044
|
+
wide[(y * dw + x) * 3 + c] = Math.floor((2 * sum + total) / (2 * total));
|
|
32045
|
+
}
|
|
32046
|
+
}
|
|
32047
|
+
}
|
|
32048
|
+
const avg = new Float64Array(dw * dh * 3);
|
|
32049
|
+
for (let y = 0; y < dh; y++) {
|
|
32050
|
+
let total = 0;
|
|
32051
|
+
for (const [, w] of rows[y]) total += w;
|
|
32052
|
+
for (let x = 0; x < dw; x++) {
|
|
32053
|
+
for (let c = 0; c < 3; c++) {
|
|
32054
|
+
let sum = 0;
|
|
32055
|
+
for (const [yy, w] of rows[y]) sum += wide[(yy * dw + x) * 3 + c] * w;
|
|
32056
|
+
avg[(y * dw + x) * 3 + c] = sum / total;
|
|
32057
|
+
}
|
|
32058
|
+
}
|
|
32059
|
+
}
|
|
32060
|
+
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];
|
|
32061
|
+
const out = new Int32Array(dw * dh * 3);
|
|
32062
|
+
for (let y = 0; y < dh; y++) {
|
|
32063
|
+
for (let x = 0; x < dw; x++) {
|
|
32064
|
+
for (let c = 0; c < 3; c++) {
|
|
32065
|
+
const v = at(x, y, c);
|
|
32066
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
32067
|
+
out[(y * dw + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (4 * v - sum) / 8)));
|
|
32068
|
+
}
|
|
32069
|
+
}
|
|
32070
|
+
}
|
|
32071
|
+
return out;
|
|
32072
|
+
}
|
|
31978
32073
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
31979
32074
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
31980
32075
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
@@ -32026,11 +32121,18 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32026
32121
|
}
|
|
32027
32122
|
const reducedEven = W < SW ? SW % 2 === 0 && H % SH === 0 : SH % 2 === 0 && W % SW === 0;
|
|
32028
32123
|
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && reducedEven);
|
|
32124
|
+
const extendRow = ditherAtSource && nativeMixed && W < SW && H > SH && !flipY;
|
|
32125
|
+
if (extendRow) {
|
|
32126
|
+
const bigger = new Int32Array((SH + 1) * SW * 3);
|
|
32127
|
+
bigger.set(rect);
|
|
32128
|
+
bigger.copyWithin(SH * SW * 3, (SH - 1) * SW * 3, SH * SW * 3);
|
|
32129
|
+
rect = bigger;
|
|
32130
|
+
}
|
|
32029
32131
|
if (ditherAtSource) {
|
|
32030
32132
|
ditherPixels(
|
|
32031
32133
|
rect,
|
|
32032
32134
|
SW,
|
|
32033
|
-
SH,
|
|
32135
|
+
extendRow ? SH + 1 : SH,
|
|
32034
32136
|
dither,
|
|
32035
32137
|
false,
|
|
32036
32138
|
false,
|
|
@@ -32070,7 +32172,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32070
32172
|
linear(rows, SH, H, flipY);
|
|
32071
32173
|
}
|
|
32072
32174
|
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
32073
|
-
|
|
32175
|
+
if (reducing) {
|
|
32176
|
+
out = halftoneReduceBoth(rect, SW, SH, W, H, flipX, flipY);
|
|
32177
|
+
}
|
|
32178
|
+
for (let y = 0; !reducing && y < sampleH; y++) {
|
|
32074
32179
|
const ys = rows[y];
|
|
32075
32180
|
for (let x = 0; x < sampleW; x++) {
|
|
32076
32181
|
const xs = cols[x];
|
|
@@ -32095,15 +32200,38 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32095
32200
|
out[o + 2] = round(b);
|
|
32096
32201
|
}
|
|
32097
32202
|
}
|
|
32098
|
-
if (reducing) {
|
|
32099
|
-
halftoneSharpen(out, W, H);
|
|
32100
|
-
}
|
|
32101
32203
|
if (nativeMixed) {
|
|
32102
32204
|
const reduceHorizontal = W < SW;
|
|
32205
|
+
let extension;
|
|
32206
|
+
if (extendRow) {
|
|
32207
|
+
const reduced = new Float64Array(sampleW * 3);
|
|
32208
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32209
|
+
let total = 0;
|
|
32210
|
+
const sums = [0, 0, 0];
|
|
32211
|
+
for (const [xx, wx] of cols[x]) {
|
|
32212
|
+
total += wx;
|
|
32213
|
+
for (let c = 0; c < 3; c++) sums[c] += rect[(SH * SW + xx) * 3 + c] * wx;
|
|
32214
|
+
}
|
|
32215
|
+
for (let c = 0; c < 3; c++) reduced[x * 3 + c] = sums[c] / total;
|
|
32216
|
+
}
|
|
32217
|
+
extension = reduced;
|
|
32218
|
+
}
|
|
32103
32219
|
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
32104
32220
|
const source2 = out;
|
|
32105
32221
|
out = new Int32Array(source2.length);
|
|
32106
|
-
const
|
|
32222
|
+
const ext = extension;
|
|
32223
|
+
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];
|
|
32224
|
+
if (horizontal && ext) {
|
|
32225
|
+
const next = new Int32Array(sampleW * 3);
|
|
32226
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32227
|
+
for (let c = 0; c < 3; c++) {
|
|
32228
|
+
const v = ext[x * 3 + c];
|
|
32229
|
+
const sum = at(x - 1, sampleH, c) + at(x + 1, sampleH, c);
|
|
32230
|
+
next[x * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
32231
|
+
}
|
|
32232
|
+
}
|
|
32233
|
+
extension = next;
|
|
32234
|
+
}
|
|
32107
32235
|
for (let y = 0; y < sampleH; y++) {
|
|
32108
32236
|
for (let x = 0; x < sampleW; x++) {
|
|
32109
32237
|
for (let c = 0; c < 3; c++) {
|