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