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