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