emf-converter 4.6.8 → 4.6.9

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 CHANGED
@@ -16485,11 +16485,11 @@ function mirror(p, n) {
16485
16485
  }
16486
16486
  return p;
16487
16487
  }
16488
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
16488
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
16489
16489
  const k = blurKernel(radius);
16490
16490
  const taps = (k.length - 1) / 2;
16491
- const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16492
- const verticalIndex = taps >= edgeHeight ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16491
+ const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16492
+ const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16493
16493
  const out = new Float64Array(w * h * 4);
16494
16494
  for (let y = 0; y < h; y++) {
16495
16495
  const row2 = y * w * 4;
@@ -16500,22 +16500,22 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16500
16500
  let s3 = 0;
16501
16501
  for (let j = -taps; j <= taps; j++) {
16502
16502
  const p = row2 + horizontalIndex(x + j) * 4;
16503
- const kw = k[j + taps];
16504
- s0 += kw * src[p];
16505
- s1 += kw * src[p + 1];
16506
- s2 += kw * src[p + 2];
16507
- s3 += kw * src[p + 3];
16503
+ const kw = k[j + taps] * 256;
16504
+ s0 += Math.round(kw * src[p]);
16505
+ s1 += Math.round(kw * src[p + 1]);
16506
+ s2 += Math.round(kw * src[p + 2]);
16507
+ s3 += Math.round(kw * src[p + 3]);
16508
16508
  }
16509
16509
  const o = row2 + x * 4;
16510
- out[o] = Math.round(s0);
16511
- out[o + 1] = Math.round(s1);
16512
- out[o + 2] = Math.round(s2);
16513
- out[o + 3] = Math.round(s3);
16510
+ out[o] = Math.floor((s0 + 128) / 256);
16511
+ out[o + 1] = Math.floor((s1 + 128) / 256);
16512
+ out[o + 2] = Math.floor((s2 + 128) / 256);
16513
+ out[o + 3] = Math.floor((s3 + 128) / 256);
16514
16514
  }
16515
16515
  }
16516
16516
  if (taps > 0 && vRow >= 0 && vRow < h) {
16517
16517
  const horizontal = out.slice();
16518
- const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
16518
+ const endRow = Math.min(h, vRow + verticalRows);
16519
16519
  for (let row2 = vRow; row2 < endRow; row2++) {
16520
16520
  const col = new Float64Array(w * 4);
16521
16521
  for (let j = -taps; j <= taps; j++) {
@@ -16525,7 +16525,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16525
16525
  }
16526
16526
  const base = verticalIndex(yy) * w * 4;
16527
16527
  for (let i = 0; i < w * 4; i++) {
16528
- col[i] += k[j + taps] * horizontal[base + i];
16528
+ col[i] += Math.round(k[j + taps] * horizontal[base + i] * 256) / 256;
16529
16529
  }
16530
16530
  }
16531
16531
  out.set(col, row2 * w * 4);
@@ -16536,48 +16536,56 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16536
16536
  function blurReduction(radius) {
16537
16537
  return radius < 20 ? 1 : radius < 40 ? 2 : radius <= 80 ? 4 : radius < 160 ? 8 : 16;
16538
16538
  }
16539
- function effectBlur(src, width, height, radius, expanded = false) {
16540
- const factor = blurReduction(radius);
16541
- if (factor === 1 || (width < 4 || height < 4) && (width % factor !== 0 || height % factor !== 0)) {
16542
- return gdipBlur(src, width, height, radius);
16543
- }
16544
- const w = Math.ceil(width / factor);
16545
- const h = Math.ceil(height / factor);
16546
- const reduced = new Uint8ClampedArray(w * h * 4);
16547
- for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
16548
- const x1 = Math.min(width, (x + 1) * factor), y1 = Math.min(height, (y + 1) * factor);
16549
- const count = (x1 - x * factor) * (y1 - y * factor);
16550
- for (let c = 0; c < 4; c++) {
16539
+ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start: 0, size: length, pad: 0 }) {
16540
+ const inner = Math.ceil(span.size / factor);
16541
+ const n = inner + 2 * span.pad;
16542
+ const taps = (k.length - 1) / 2;
16543
+ const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
16544
+ const reduced = new Float64Array(n);
16545
+ const filtered = new Float64Array(n);
16546
+ const k256 = k.map((w) => w * 256);
16547
+ for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
16548
+ for (let b = span.pad; b < span.pad + inner; b++) {
16549
+ const from = span.start + (b - span.pad) * factor;
16550
+ const end = Math.min(span.start + span.size, from + factor);
16551
16551
  let sum = 0;
16552
- for (let yy = y * factor; yy < y1; yy++) for (let xx = x * factor; xx < x1; xx++) sum += src[(yy * width + xx) * 4 + c];
16553
- reduced[(y * w + x) * 4 + c] = Math.floor(sum / count);
16552
+ for (let i = from; i < end; i++) sum += get(i, lane, c);
16553
+ reduced[b] = Math.floor(sum / (end - from));
16554
16554
  }
16555
- }
16556
- const filtered = gdipBlur(reduced, w, h, radius / factor, 0, false, true, Math.floor(width / factor), Math.floor(height / factor));
16557
- if (!expanded) {
16558
- const out2 = new Float64Array(src.length);
16559
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16560
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16561
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16562
- const x1 = Math.min(w - 1, ix + 1), y1 = Math.min(h - 1, iy + 1);
16563
- for (let c = 0; c < 4; c++) {
16564
- const at = (xx, yy) => filtered[(yy * w + xx) * 4 + c];
16565
- const top = Math.floor((1 - fx) * at(ix, iy) + fx * at(x1, iy));
16566
- const bottom = Math.floor((1 - fx) * at(ix, y1) + fx * at(x1, y1));
16567
- out2[(y * width + x) * 4 + c] = Math.floor((1 - fy) * top + fy * bottom);
16555
+ for (let b = 0; b < n; b++) {
16556
+ let sum = 0;
16557
+ if (b >= taps && b + taps < n) {
16558
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
16559
+ } else {
16560
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[index(b - taps + j)]);
16568
16561
  }
16562
+ filtered[b] = Math.floor((sum + 128) / 256);
16563
+ }
16564
+ for (let i = 0; i < length; i++) {
16565
+ const p = (i - span.start + 0.5) / factor - 0.5 + span.pad;
16566
+ const a = clamp(Math.floor(p), 0, Math.max(0, n - 2));
16567
+ const t = p - a;
16568
+ put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(n - 1, a + 1)] + 1e-9), 0, 255));
16569
16569
  }
16570
- return out2;
16571
16570
  }
16572
- for (let i = 0; i < filtered.length; i++) filtered[i] = Math.round(filtered[i]);
16573
- const out = new Float64Array(src.length);
16574
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16575
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16576
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16577
- const a = (iy * w + ix) * 4, b = (iy * w + Math.min(w - 1, ix + 1)) * 4;
16578
- const d = (Math.min(h - 1, iy + 1) * w + ix) * 4, e = (Math.min(h - 1, iy + 1) * w + Math.min(w - 1, ix + 1)) * 4;
16579
- for (let c = 0; c < 4; c++) out[(y * width + x) * 4 + c] = Math.round((1 - fy) * ((1 - fx) * filtered[a + c] + fx * filtered[b + c]) + fy * ((1 - fx) * filtered[d + c] + fx * filtered[e + c]));
16571
+ }
16572
+ function effectBlur(src, width, height, radius, region) {
16573
+ const factor = blurReduction(radius);
16574
+ if (factor === 1) {
16575
+ return gdipBlur(src, width, height, radius);
16580
16576
  }
16577
+ const k = blurKernel(radius / factor);
16578
+ const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
16579
+ const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
16580
+ const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
16581
+ const rows = new Uint8Array(src.length);
16582
+ blurAxis(width, height, factor, k, Math.floor(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
16583
+ rows[(lane * width + i) * 4 + c] = v;
16584
+ }, spanX);
16585
+ const out = new Float64Array(src.length);
16586
+ blurAxis(height, width, factor, k, Math.floor(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
16587
+ out[(i * width + lane) * 4 + c] = v;
16588
+ }, spanY);
16581
16589
  return out;
16582
16590
  }
16583
16591
  function applyBlur(src, w, h, radius) {
@@ -16663,7 +16671,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16663
16671
  const gy1 = Math.min(height, y1 + r);
16664
16672
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16665
16673
  }
16666
- const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16674
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
16667
16675
  const w = x1 - x0;
16668
16676
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16669
16677
  for (let y = 0; y < y1 - y0; y++) {
package/dist/browser.mjs CHANGED
@@ -16483,11 +16483,11 @@ function mirror(p, n) {
16483
16483
  }
16484
16484
  return p;
16485
16485
  }
16486
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
16486
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
16487
16487
  const k = blurKernel(radius);
16488
16488
  const taps = (k.length - 1) / 2;
16489
- const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16490
- const verticalIndex = taps >= edgeHeight ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16489
+ const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16490
+ const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16491
16491
  const out = new Float64Array(w * h * 4);
16492
16492
  for (let y = 0; y < h; y++) {
16493
16493
  const row2 = y * w * 4;
@@ -16498,22 +16498,22 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16498
16498
  let s3 = 0;
16499
16499
  for (let j = -taps; j <= taps; j++) {
16500
16500
  const p = row2 + horizontalIndex(x + j) * 4;
16501
- const kw = k[j + taps];
16502
- s0 += kw * src[p];
16503
- s1 += kw * src[p + 1];
16504
- s2 += kw * src[p + 2];
16505
- s3 += kw * src[p + 3];
16501
+ const kw = k[j + taps] * 256;
16502
+ s0 += Math.round(kw * src[p]);
16503
+ s1 += Math.round(kw * src[p + 1]);
16504
+ s2 += Math.round(kw * src[p + 2]);
16505
+ s3 += Math.round(kw * src[p + 3]);
16506
16506
  }
16507
16507
  const o = row2 + x * 4;
16508
- out[o] = Math.round(s0);
16509
- out[o + 1] = Math.round(s1);
16510
- out[o + 2] = Math.round(s2);
16511
- out[o + 3] = Math.round(s3);
16508
+ out[o] = Math.floor((s0 + 128) / 256);
16509
+ out[o + 1] = Math.floor((s1 + 128) / 256);
16510
+ out[o + 2] = Math.floor((s2 + 128) / 256);
16511
+ out[o + 3] = Math.floor((s3 + 128) / 256);
16512
16512
  }
16513
16513
  }
16514
16514
  if (taps > 0 && vRow >= 0 && vRow < h) {
16515
16515
  const horizontal = out.slice();
16516
- const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
16516
+ const endRow = Math.min(h, vRow + verticalRows);
16517
16517
  for (let row2 = vRow; row2 < endRow; row2++) {
16518
16518
  const col = new Float64Array(w * 4);
16519
16519
  for (let j = -taps; j <= taps; j++) {
@@ -16523,7 +16523,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16523
16523
  }
16524
16524
  const base = verticalIndex(yy) * w * 4;
16525
16525
  for (let i = 0; i < w * 4; i++) {
16526
- col[i] += k[j + taps] * horizontal[base + i];
16526
+ col[i] += Math.round(k[j + taps] * horizontal[base + i] * 256) / 256;
16527
16527
  }
16528
16528
  }
16529
16529
  out.set(col, row2 * w * 4);
@@ -16534,48 +16534,56 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16534
16534
  function blurReduction(radius) {
16535
16535
  return radius < 20 ? 1 : radius < 40 ? 2 : radius <= 80 ? 4 : radius < 160 ? 8 : 16;
16536
16536
  }
16537
- function effectBlur(src, width, height, radius, expanded = false) {
16538
- const factor = blurReduction(radius);
16539
- if (factor === 1 || (width < 4 || height < 4) && (width % factor !== 0 || height % factor !== 0)) {
16540
- return gdipBlur(src, width, height, radius);
16541
- }
16542
- const w = Math.ceil(width / factor);
16543
- const h = Math.ceil(height / factor);
16544
- const reduced = new Uint8ClampedArray(w * h * 4);
16545
- for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
16546
- const x1 = Math.min(width, (x + 1) * factor), y1 = Math.min(height, (y + 1) * factor);
16547
- const count = (x1 - x * factor) * (y1 - y * factor);
16548
- for (let c = 0; c < 4; c++) {
16537
+ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start: 0, size: length, pad: 0 }) {
16538
+ const inner = Math.ceil(span.size / factor);
16539
+ const n = inner + 2 * span.pad;
16540
+ const taps = (k.length - 1) / 2;
16541
+ const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
16542
+ const reduced = new Float64Array(n);
16543
+ const filtered = new Float64Array(n);
16544
+ const k256 = k.map((w) => w * 256);
16545
+ for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
16546
+ for (let b = span.pad; b < span.pad + inner; b++) {
16547
+ const from = span.start + (b - span.pad) * factor;
16548
+ const end = Math.min(span.start + span.size, from + factor);
16549
16549
  let sum = 0;
16550
- for (let yy = y * factor; yy < y1; yy++) for (let xx = x * factor; xx < x1; xx++) sum += src[(yy * width + xx) * 4 + c];
16551
- reduced[(y * w + x) * 4 + c] = Math.floor(sum / count);
16550
+ for (let i = from; i < end; i++) sum += get(i, lane, c);
16551
+ reduced[b] = Math.floor(sum / (end - from));
16552
16552
  }
16553
- }
16554
- const filtered = gdipBlur(reduced, w, h, radius / factor, 0, false, true, Math.floor(width / factor), Math.floor(height / factor));
16555
- if (!expanded) {
16556
- const out2 = new Float64Array(src.length);
16557
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16558
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16559
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16560
- const x1 = Math.min(w - 1, ix + 1), y1 = Math.min(h - 1, iy + 1);
16561
- for (let c = 0; c < 4; c++) {
16562
- const at = (xx, yy) => filtered[(yy * w + xx) * 4 + c];
16563
- const top = Math.floor((1 - fx) * at(ix, iy) + fx * at(x1, iy));
16564
- const bottom = Math.floor((1 - fx) * at(ix, y1) + fx * at(x1, y1));
16565
- out2[(y * width + x) * 4 + c] = Math.floor((1 - fy) * top + fy * bottom);
16553
+ for (let b = 0; b < n; b++) {
16554
+ let sum = 0;
16555
+ if (b >= taps && b + taps < n) {
16556
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
16557
+ } else {
16558
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[index(b - taps + j)]);
16566
16559
  }
16560
+ filtered[b] = Math.floor((sum + 128) / 256);
16561
+ }
16562
+ for (let i = 0; i < length; i++) {
16563
+ const p = (i - span.start + 0.5) / factor - 0.5 + span.pad;
16564
+ const a = clamp(Math.floor(p), 0, Math.max(0, n - 2));
16565
+ const t = p - a;
16566
+ put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(n - 1, a + 1)] + 1e-9), 0, 255));
16567
16567
  }
16568
- return out2;
16569
16568
  }
16570
- for (let i = 0; i < filtered.length; i++) filtered[i] = Math.round(filtered[i]);
16571
- const out = new Float64Array(src.length);
16572
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16573
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16574
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16575
- const a = (iy * w + ix) * 4, b = (iy * w + Math.min(w - 1, ix + 1)) * 4;
16576
- const d = (Math.min(h - 1, iy + 1) * w + ix) * 4, e = (Math.min(h - 1, iy + 1) * w + Math.min(w - 1, ix + 1)) * 4;
16577
- for (let c = 0; c < 4; c++) out[(y * width + x) * 4 + c] = Math.round((1 - fy) * ((1 - fx) * filtered[a + c] + fx * filtered[b + c]) + fy * ((1 - fx) * filtered[d + c] + fx * filtered[e + c]));
16569
+ }
16570
+ function effectBlur(src, width, height, radius, region) {
16571
+ const factor = blurReduction(radius);
16572
+ if (factor === 1) {
16573
+ return gdipBlur(src, width, height, radius);
16578
16574
  }
16575
+ const k = blurKernel(radius / factor);
16576
+ const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
16577
+ const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
16578
+ const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
16579
+ const rows = new Uint8Array(src.length);
16580
+ blurAxis(width, height, factor, k, Math.floor(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
16581
+ rows[(lane * width + i) * 4 + c] = v;
16582
+ }, spanX);
16583
+ const out = new Float64Array(src.length);
16584
+ blurAxis(height, width, factor, k, Math.floor(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
16585
+ out[(i * width + lane) * 4 + c] = v;
16586
+ }, spanY);
16579
16587
  return out;
16580
16588
  }
16581
16589
  function applyBlur(src, w, h, radius) {
@@ -16661,7 +16669,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16661
16669
  const gy1 = Math.min(height, y1 + r);
16662
16670
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16663
16671
  }
16664
- const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16672
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
16665
16673
  const w = x1 - x0;
16666
16674
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16667
16675
  for (let y = 0; y < y1 - y0; y++) {
package/dist/index.js CHANGED
@@ -16486,11 +16486,11 @@ function mirror(p, n) {
16486
16486
  }
16487
16487
  return p;
16488
16488
  }
16489
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
16489
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
16490
16490
  const k = blurKernel(radius);
16491
16491
  const taps = (k.length - 1) / 2;
16492
- const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16493
- const verticalIndex = taps >= edgeHeight ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16492
+ const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16493
+ const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16494
16494
  const out = new Float64Array(w * h * 4);
16495
16495
  for (let y = 0; y < h; y++) {
16496
16496
  const row2 = y * w * 4;
@@ -16501,22 +16501,22 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16501
16501
  let s3 = 0;
16502
16502
  for (let j = -taps; j <= taps; j++) {
16503
16503
  const p = row2 + horizontalIndex(x + j) * 4;
16504
- const kw = k[j + taps];
16505
- s0 += kw * src[p];
16506
- s1 += kw * src[p + 1];
16507
- s2 += kw * src[p + 2];
16508
- s3 += kw * src[p + 3];
16504
+ const kw = k[j + taps] * 256;
16505
+ s0 += Math.round(kw * src[p]);
16506
+ s1 += Math.round(kw * src[p + 1]);
16507
+ s2 += Math.round(kw * src[p + 2]);
16508
+ s3 += Math.round(kw * src[p + 3]);
16509
16509
  }
16510
16510
  const o = row2 + x * 4;
16511
- out[o] = Math.round(s0);
16512
- out[o + 1] = Math.round(s1);
16513
- out[o + 2] = Math.round(s2);
16514
- out[o + 3] = Math.round(s3);
16511
+ out[o] = Math.floor((s0 + 128) / 256);
16512
+ out[o + 1] = Math.floor((s1 + 128) / 256);
16513
+ out[o + 2] = Math.floor((s2 + 128) / 256);
16514
+ out[o + 3] = Math.floor((s3 + 128) / 256);
16515
16515
  }
16516
16516
  }
16517
16517
  if (taps > 0 && vRow >= 0 && vRow < h) {
16518
16518
  const horizontal = out.slice();
16519
- const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
16519
+ const endRow = Math.min(h, vRow + verticalRows);
16520
16520
  for (let row2 = vRow; row2 < endRow; row2++) {
16521
16521
  const col = new Float64Array(w * 4);
16522
16522
  for (let j = -taps; j <= taps; j++) {
@@ -16526,7 +16526,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16526
16526
  }
16527
16527
  const base = verticalIndex(yy) * w * 4;
16528
16528
  for (let i = 0; i < w * 4; i++) {
16529
- col[i] += k[j + taps] * horizontal[base + i];
16529
+ col[i] += Math.round(k[j + taps] * horizontal[base + i] * 256) / 256;
16530
16530
  }
16531
16531
  }
16532
16532
  out.set(col, row2 * w * 4);
@@ -16537,48 +16537,56 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16537
16537
  function blurReduction(radius) {
16538
16538
  return radius < 20 ? 1 : radius < 40 ? 2 : radius <= 80 ? 4 : radius < 160 ? 8 : 16;
16539
16539
  }
16540
- function effectBlur(src, width, height, radius, expanded = false) {
16541
- const factor = blurReduction(radius);
16542
- if (factor === 1 || (width < 4 || height < 4) && (width % factor !== 0 || height % factor !== 0)) {
16543
- return gdipBlur(src, width, height, radius);
16544
- }
16545
- const w = Math.ceil(width / factor);
16546
- const h = Math.ceil(height / factor);
16547
- const reduced = new Uint8ClampedArray(w * h * 4);
16548
- for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
16549
- const x1 = Math.min(width, (x + 1) * factor), y1 = Math.min(height, (y + 1) * factor);
16550
- const count = (x1 - x * factor) * (y1 - y * factor);
16551
- for (let c = 0; c < 4; c++) {
16540
+ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start: 0, size: length, pad: 0 }) {
16541
+ const inner = Math.ceil(span.size / factor);
16542
+ const n = inner + 2 * span.pad;
16543
+ const taps = (k.length - 1) / 2;
16544
+ const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
16545
+ const reduced = new Float64Array(n);
16546
+ const filtered = new Float64Array(n);
16547
+ const k256 = k.map((w) => w * 256);
16548
+ for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
16549
+ for (let b = span.pad; b < span.pad + inner; b++) {
16550
+ const from = span.start + (b - span.pad) * factor;
16551
+ const end = Math.min(span.start + span.size, from + factor);
16552
16552
  let sum = 0;
16553
- for (let yy = y * factor; yy < y1; yy++) for (let xx = x * factor; xx < x1; xx++) sum += src[(yy * width + xx) * 4 + c];
16554
- reduced[(y * w + x) * 4 + c] = Math.floor(sum / count);
16553
+ for (let i = from; i < end; i++) sum += get(i, lane, c);
16554
+ reduced[b] = Math.floor(sum / (end - from));
16555
16555
  }
16556
- }
16557
- const filtered = gdipBlur(reduced, w, h, radius / factor, 0, false, true, Math.floor(width / factor), Math.floor(height / factor));
16558
- if (!expanded) {
16559
- const out2 = new Float64Array(src.length);
16560
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16561
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16562
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16563
- const x1 = Math.min(w - 1, ix + 1), y1 = Math.min(h - 1, iy + 1);
16564
- for (let c = 0; c < 4; c++) {
16565
- const at = (xx, yy) => filtered[(yy * w + xx) * 4 + c];
16566
- const top = Math.floor((1 - fx) * at(ix, iy) + fx * at(x1, iy));
16567
- const bottom = Math.floor((1 - fx) * at(ix, y1) + fx * at(x1, y1));
16568
- out2[(y * width + x) * 4 + c] = Math.floor((1 - fy) * top + fy * bottom);
16556
+ for (let b = 0; b < n; b++) {
16557
+ let sum = 0;
16558
+ if (b >= taps && b + taps < n) {
16559
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
16560
+ } else {
16561
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[index(b - taps + j)]);
16569
16562
  }
16563
+ filtered[b] = Math.floor((sum + 128) / 256);
16564
+ }
16565
+ for (let i = 0; i < length; i++) {
16566
+ const p = (i - span.start + 0.5) / factor - 0.5 + span.pad;
16567
+ const a = clamp(Math.floor(p), 0, Math.max(0, n - 2));
16568
+ const t = p - a;
16569
+ put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(n - 1, a + 1)] + 1e-9), 0, 255));
16570
16570
  }
16571
- return out2;
16572
16571
  }
16573
- for (let i = 0; i < filtered.length; i++) filtered[i] = Math.round(filtered[i]);
16574
- const out = new Float64Array(src.length);
16575
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16576
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16577
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16578
- const a = (iy * w + ix) * 4, b = (iy * w + Math.min(w - 1, ix + 1)) * 4;
16579
- const d = (Math.min(h - 1, iy + 1) * w + ix) * 4, e = (Math.min(h - 1, iy + 1) * w + Math.min(w - 1, ix + 1)) * 4;
16580
- for (let c = 0; c < 4; c++) out[(y * width + x) * 4 + c] = Math.round((1 - fy) * ((1 - fx) * filtered[a + c] + fx * filtered[b + c]) + fy * ((1 - fx) * filtered[d + c] + fx * filtered[e + c]));
16572
+ }
16573
+ function effectBlur(src, width, height, radius, region) {
16574
+ const factor = blurReduction(radius);
16575
+ if (factor === 1) {
16576
+ return gdipBlur(src, width, height, radius);
16581
16577
  }
16578
+ const k = blurKernel(radius / factor);
16579
+ const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
16580
+ const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
16581
+ const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
16582
+ const rows = new Uint8Array(src.length);
16583
+ blurAxis(width, height, factor, k, Math.floor(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
16584
+ rows[(lane * width + i) * 4 + c] = v;
16585
+ }, spanX);
16586
+ const out = new Float64Array(src.length);
16587
+ blurAxis(height, width, factor, k, Math.floor(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
16588
+ out[(i * width + lane) * 4 + c] = v;
16589
+ }, spanY);
16582
16590
  return out;
16583
16591
  }
16584
16592
  function applyBlur(src, w, h, radius) {
@@ -16664,7 +16672,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16664
16672
  const gy1 = Math.min(height, y1 + r);
16665
16673
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16666
16674
  }
16667
- const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16675
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
16668
16676
  const w = x1 - x0;
16669
16677
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16670
16678
  for (let y = 0; y < y1 - y0; y++) {
package/dist/index.mjs CHANGED
@@ -16484,11 +16484,11 @@ function mirror(p, n) {
16484
16484
  }
16485
16485
  return p;
16486
16486
  }
16487
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
16487
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
16488
16488
  const k = blurKernel(radius);
16489
16489
  const taps = (k.length - 1) / 2;
16490
- const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16491
- const verticalIndex = taps >= edgeHeight ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16490
+ const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
16491
+ const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
16492
16492
  const out = new Float64Array(w * h * 4);
16493
16493
  for (let y = 0; y < h; y++) {
16494
16494
  const row2 = y * w * 4;
@@ -16499,22 +16499,22 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16499
16499
  let s3 = 0;
16500
16500
  for (let j = -taps; j <= taps; j++) {
16501
16501
  const p = row2 + horizontalIndex(x + j) * 4;
16502
- const kw = k[j + taps];
16503
- s0 += kw * src[p];
16504
- s1 += kw * src[p + 1];
16505
- s2 += kw * src[p + 2];
16506
- s3 += kw * src[p + 3];
16502
+ const kw = k[j + taps] * 256;
16503
+ s0 += Math.round(kw * src[p]);
16504
+ s1 += Math.round(kw * src[p + 1]);
16505
+ s2 += Math.round(kw * src[p + 2]);
16506
+ s3 += Math.round(kw * src[p + 3]);
16507
16507
  }
16508
16508
  const o = row2 + x * 4;
16509
- out[o] = Math.round(s0);
16510
- out[o + 1] = Math.round(s1);
16511
- out[o + 2] = Math.round(s2);
16512
- out[o + 3] = Math.round(s3);
16509
+ out[o] = Math.floor((s0 + 128) / 256);
16510
+ out[o + 1] = Math.floor((s1 + 128) / 256);
16511
+ out[o + 2] = Math.floor((s2 + 128) / 256);
16512
+ out[o + 3] = Math.floor((s3 + 128) / 256);
16513
16513
  }
16514
16514
  }
16515
16515
  if (taps > 0 && vRow >= 0 && vRow < h) {
16516
16516
  const horizontal = out.slice();
16517
- const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
16517
+ const endRow = Math.min(h, vRow + verticalRows);
16518
16518
  for (let row2 = vRow; row2 < endRow; row2++) {
16519
16519
  const col = new Float64Array(w * 4);
16520
16520
  for (let j = -taps; j <= taps; j++) {
@@ -16524,7 +16524,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16524
16524
  }
16525
16525
  const base = verticalIndex(yy) * w * 4;
16526
16526
  for (let i = 0; i < w * 4; i++) {
16527
- col[i] += k[j + taps] * horizontal[base + i];
16527
+ col[i] += Math.round(k[j + taps] * horizontal[base + i] * 256) / 256;
16528
16528
  }
16529
16529
  }
16530
16530
  out.set(col, row2 * w * 4);
@@ -16535,48 +16535,56 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
16535
16535
  function blurReduction(radius) {
16536
16536
  return radius < 20 ? 1 : radius < 40 ? 2 : radius <= 80 ? 4 : radius < 160 ? 8 : 16;
16537
16537
  }
16538
- function effectBlur(src, width, height, radius, expanded = false) {
16539
- const factor = blurReduction(radius);
16540
- if (factor === 1 || (width < 4 || height < 4) && (width % factor !== 0 || height % factor !== 0)) {
16541
- return gdipBlur(src, width, height, radius);
16542
- }
16543
- const w = Math.ceil(width / factor);
16544
- const h = Math.ceil(height / factor);
16545
- const reduced = new Uint8ClampedArray(w * h * 4);
16546
- for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
16547
- const x1 = Math.min(width, (x + 1) * factor), y1 = Math.min(height, (y + 1) * factor);
16548
- const count = (x1 - x * factor) * (y1 - y * factor);
16549
- for (let c = 0; c < 4; c++) {
16538
+ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start: 0, size: length, pad: 0 }) {
16539
+ const inner = Math.ceil(span.size / factor);
16540
+ const n = inner + 2 * span.pad;
16541
+ const taps = (k.length - 1) / 2;
16542
+ const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
16543
+ const reduced = new Float64Array(n);
16544
+ const filtered = new Float64Array(n);
16545
+ const k256 = k.map((w) => w * 256);
16546
+ for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
16547
+ for (let b = span.pad; b < span.pad + inner; b++) {
16548
+ const from = span.start + (b - span.pad) * factor;
16549
+ const end = Math.min(span.start + span.size, from + factor);
16550
16550
  let sum = 0;
16551
- for (let yy = y * factor; yy < y1; yy++) for (let xx = x * factor; xx < x1; xx++) sum += src[(yy * width + xx) * 4 + c];
16552
- reduced[(y * w + x) * 4 + c] = Math.floor(sum / count);
16551
+ for (let i = from; i < end; i++) sum += get(i, lane, c);
16552
+ reduced[b] = Math.floor(sum / (end - from));
16553
16553
  }
16554
- }
16555
- const filtered = gdipBlur(reduced, w, h, radius / factor, 0, false, true, Math.floor(width / factor), Math.floor(height / factor));
16556
- if (!expanded) {
16557
- const out2 = new Float64Array(src.length);
16558
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16559
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16560
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16561
- const x1 = Math.min(w - 1, ix + 1), y1 = Math.min(h - 1, iy + 1);
16562
- for (let c = 0; c < 4; c++) {
16563
- const at = (xx, yy) => filtered[(yy * w + xx) * 4 + c];
16564
- const top = Math.floor((1 - fx) * at(ix, iy) + fx * at(x1, iy));
16565
- const bottom = Math.floor((1 - fx) * at(ix, y1) + fx * at(x1, y1));
16566
- out2[(y * width + x) * 4 + c] = Math.floor((1 - fy) * top + fy * bottom);
16554
+ for (let b = 0; b < n; b++) {
16555
+ let sum = 0;
16556
+ if (b >= taps && b + taps < n) {
16557
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
16558
+ } else {
16559
+ for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[index(b - taps + j)]);
16567
16560
  }
16561
+ filtered[b] = Math.floor((sum + 128) / 256);
16562
+ }
16563
+ for (let i = 0; i < length; i++) {
16564
+ const p = (i - span.start + 0.5) / factor - 0.5 + span.pad;
16565
+ const a = clamp(Math.floor(p), 0, Math.max(0, n - 2));
16566
+ const t = p - a;
16567
+ put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(n - 1, a + 1)] + 1e-9), 0, 255));
16568
16568
  }
16569
- return out2;
16570
16569
  }
16571
- for (let i = 0; i < filtered.length; i++) filtered[i] = Math.round(filtered[i]);
16572
- const out = new Float64Array(src.length);
16573
- for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
16574
- const px = clamp((x + 0.5) / factor - 0.5, 0, w - 1), py = clamp((y + 0.5) / factor - 0.5, 0, h - 1);
16575
- const ix = Math.floor(px), iy = Math.floor(py), fx = px - ix, fy = py - iy;
16576
- const a = (iy * w + ix) * 4, b = (iy * w + Math.min(w - 1, ix + 1)) * 4;
16577
- const d = (Math.min(h - 1, iy + 1) * w + ix) * 4, e = (Math.min(h - 1, iy + 1) * w + Math.min(w - 1, ix + 1)) * 4;
16578
- for (let c = 0; c < 4; c++) out[(y * width + x) * 4 + c] = Math.round((1 - fy) * ((1 - fx) * filtered[a + c] + fx * filtered[b + c]) + fy * ((1 - fx) * filtered[d + c] + fx * filtered[e + c]));
16570
+ }
16571
+ function effectBlur(src, width, height, radius, region) {
16572
+ const factor = blurReduction(radius);
16573
+ if (factor === 1) {
16574
+ return gdipBlur(src, width, height, radius);
16579
16575
  }
16576
+ const k = blurKernel(radius / factor);
16577
+ const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
16578
+ const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
16579
+ const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
16580
+ const rows = new Uint8Array(src.length);
16581
+ blurAxis(width, height, factor, k, Math.floor(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
16582
+ rows[(lane * width + i) * 4 + c] = v;
16583
+ }, spanX);
16584
+ const out = new Float64Array(src.length);
16585
+ blurAxis(height, width, factor, k, Math.floor(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
16586
+ out[(i * width + lane) * 4 + c] = v;
16587
+ }, spanY);
16580
16588
  return out;
16581
16589
  }
16582
16590
  function applyBlur(src, w, h, radius) {
@@ -16662,7 +16670,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16662
16670
  const gy1 = Math.min(height, y1 + r);
16663
16671
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16664
16672
  }
16665
- const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16673
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
16666
16674
  const w = x1 - x0;
16667
16675
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16668
16676
  for (let y = 0; y < y1 - y0; y++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emf-converter",
3
- "version": "4.6.8",
3
+ "version": "4.6.9",
4
4
  "description": "Convert EMF/WMF metafile binaries to PNG data URLs or SVG (markup, data URL, React/JSX)",
5
5
  "keywords": [
6
6
  "canvas",