@pixerate/editor 0.97.0 → 0.99.0
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/THIRD_PARTY_NOTICES.md +4 -2
- package/dist/animation-editor/index.cjs +55 -53
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +3 -2
- package/dist/animation-editor/index.d.ts +3 -2
- package/dist/animation-editor/index.js +11 -9
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/chunk-DWGZUSES.cjs +694 -0
- package/dist/chunk-DWGZUSES.cjs.map +1 -0
- package/dist/chunk-GX332W2C.js +181 -0
- package/dist/chunk-GX332W2C.js.map +1 -0
- package/dist/{chunk-7MD7C6XQ.cjs → chunk-JF5PXN7W.cjs} +96 -744
- package/dist/chunk-JF5PXN7W.cjs.map +1 -0
- package/dist/chunk-KKREERP2.js +694 -0
- package/dist/chunk-KKREERP2.js.map +1 -0
- package/dist/chunk-MUUXNRU4.cjs +181 -0
- package/dist/chunk-MUUXNRU4.cjs.map +1 -0
- package/dist/{chunk-OEVSVA6V.js → chunk-WIR377F6.js} +788 -22
- package/dist/chunk-WIR377F6.js.map +1 -0
- package/dist/{chunk-4AB5BHYK.cjs → chunk-WT6ZAWJP.cjs} +788 -22
- package/dist/chunk-WT6ZAWJP.cjs.map +1 -0
- package/dist/{chunk-4JLB2USO.js → chunk-YGZNGDIT.js} +45 -693
- package/dist/chunk-YGZNGDIT.js.map +1 -0
- package/dist/image-editor/index.cjs +1798 -333
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +482 -6
- package/dist/image-editor/index.d.ts +482 -6
- package/dist/image-editor/index.js +1488 -23
- package/dist/image-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +23 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +98 -2
- package/dist/raster/index.d.ts +98 -2
- package/dist/raster/index.js +23 -2
- package/dist/{svg-ymShkNtu.d.cts → svg-C9r284x8.d.cts} +6 -9
- package/dist/{svg-Dh17jCyA.d.ts → svg-MVKBqwD4.d.ts} +6 -9
- package/dist/types-CwMPoRMU.d.cts +40 -0
- package/dist/types-CwMPoRMU.d.ts +40 -0
- package/dist/vector/index.cjs +490 -554
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +154 -292
- package/dist/vector/index.d.ts +154 -292
- package/dist/vector/index.js +91 -155
- package/dist/vector/index.js.map +1 -1
- package/dist/warp-B8rAguzs.d.ts +165 -0
- package/dist/warp-nYs2DPrx.d.cts +165 -0
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +49 -3
- package/dist/chunk-4AB5BHYK.cjs.map +0 -1
- package/dist/chunk-4JLB2USO.js.map +0 -1
- package/dist/chunk-7MD7C6XQ.cjs.map +0 -1
- package/dist/chunk-OEVSVA6V.js.map +0 -1
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applyHomography,
|
|
3
|
+
boxQuad,
|
|
4
|
+
cornerBounds,
|
|
5
|
+
homographyFrontSide,
|
|
6
|
+
homographyW,
|
|
7
|
+
invertHomography,
|
|
8
|
+
isIdentityHomography,
|
|
9
|
+
multiplyHomographies
|
|
10
|
+
} from "./chunk-GX332W2C.js";
|
|
1
11
|
import {
|
|
2
12
|
TILE,
|
|
13
|
+
TiledSurface,
|
|
3
14
|
blendChannel,
|
|
4
15
|
blendRgb,
|
|
16
|
+
contentBounds,
|
|
5
17
|
emptySurface,
|
|
18
|
+
finishTile,
|
|
6
19
|
isBlendMode,
|
|
7
20
|
isSeparableBlendMode,
|
|
8
21
|
mixPigment8,
|
|
@@ -10,7 +23,9 @@ import {
|
|
|
10
23
|
readRegion,
|
|
11
24
|
surfaceFromPixels,
|
|
12
25
|
tileKey,
|
|
13
|
-
tilesInRect
|
|
26
|
+
tilesInRect,
|
|
27
|
+
translateSurface,
|
|
28
|
+
writeRegion
|
|
14
29
|
} from "./chunk-HEW6KDNI.js";
|
|
15
30
|
|
|
16
31
|
// src/raster/blur.ts
|
|
@@ -644,14 +659,14 @@ var PatternTile = class {
|
|
|
644
659
|
let b = 0;
|
|
645
660
|
let a = 0;
|
|
646
661
|
for (let dy = 0; dy < 2; dy++) {
|
|
647
|
-
const
|
|
648
|
-
if (
|
|
662
|
+
const wy2 = dy ? fy : 1 - fy;
|
|
663
|
+
if (wy2 === 0) continue;
|
|
649
664
|
const yi = ((y0 + dy) % this.h + this.h) % this.h;
|
|
650
665
|
for (let dx = 0; dx < 2; dx++) {
|
|
651
|
-
const
|
|
652
|
-
if (
|
|
666
|
+
const wx2 = dx ? fx : 1 - fx;
|
|
667
|
+
if (wx2 === 0) continue;
|
|
653
668
|
const xi = ((x0 + dx) % this.w + this.w) % this.w;
|
|
654
|
-
const k =
|
|
669
|
+
const k = wx2 * wy2;
|
|
655
670
|
const i = (yi * this.w + xi) * 4;
|
|
656
671
|
r += this.px[i] * k;
|
|
657
672
|
g += this.px[i + 1] * k;
|
|
@@ -1748,15 +1763,15 @@ function gradientLayout(style, angle, scale, offset, frame) {
|
|
|
1748
1763
|
const half = chordOf(a) * Math.max(scale, 1e-3) / 2;
|
|
1749
1764
|
const dx = Math.cos(a) * half;
|
|
1750
1765
|
const dy = -Math.sin(a) * half;
|
|
1751
|
-
const
|
|
1752
|
-
const end = [
|
|
1766
|
+
const snap2 = (v2) => Math.floor(v2 + 1e-4);
|
|
1767
|
+
const end = [snap2(cx + dx), snap2(cy + dy)];
|
|
1753
1768
|
let start;
|
|
1754
1769
|
let mid;
|
|
1755
1770
|
if (style === "reflected") {
|
|
1756
1771
|
start = [cx, cy];
|
|
1757
1772
|
mid = [cx, cy];
|
|
1758
1773
|
} else {
|
|
1759
|
-
start = [
|
|
1774
|
+
start = [snap2(cx - dx), snap2(cy - dy)];
|
|
1760
1775
|
mid = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2];
|
|
1761
1776
|
}
|
|
1762
1777
|
const v = [end[0] - start[0], end[1] - start[1]];
|
|
@@ -2986,6 +3001,747 @@ function changedTiles(a, b) {
|
|
|
2986
3001
|
return out;
|
|
2987
3002
|
}
|
|
2988
3003
|
|
|
3004
|
+
// src/raster/transform.ts
|
|
3005
|
+
var INTERPOLATIONS = ["nearest", "bilinear", "bicubic"];
|
|
3006
|
+
function isInterpolation(value) {
|
|
3007
|
+
return typeof value === "string" && INTERPOLATIONS.includes(value);
|
|
3008
|
+
}
|
|
3009
|
+
var MAX_TRANSFORM_PIXELS = 1 << 27;
|
|
3010
|
+
var TransformTooLargeError = class extends Error {
|
|
3011
|
+
constructor(message) {
|
|
3012
|
+
super(message);
|
|
3013
|
+
this.name = "TransformTooLargeError";
|
|
3014
|
+
}
|
|
3015
|
+
};
|
|
3016
|
+
var KEYS_A = -0.75;
|
|
3017
|
+
function keysWeight(x) {
|
|
3018
|
+
x = Math.abs(x);
|
|
3019
|
+
if (x < 1) return ((KEYS_A + 2) * x - (KEYS_A + 3)) * x * x + 1;
|
|
3020
|
+
if (x < 2) return KEYS_A * (((x - 5) * x + 8) * x - 4);
|
|
3021
|
+
return 0;
|
|
3022
|
+
}
|
|
3023
|
+
var snap = (t) => Math.abs(t - Math.round(t)) < 1e-7 ? Math.round(t) : t;
|
|
3024
|
+
var MAX_TAPS = 20;
|
|
3025
|
+
var tapI0 = 0;
|
|
3026
|
+
var tapN = 0;
|
|
3027
|
+
function cubicTaps(u, s, w) {
|
|
3028
|
+
if (s <= 1.0001) {
|
|
3029
|
+
const f = Math.floor(u);
|
|
3030
|
+
const t = u - f;
|
|
3031
|
+
w[0] = keysWeight(1 + t);
|
|
3032
|
+
w[1] = keysWeight(t);
|
|
3033
|
+
w[2] = keysWeight(1 - t);
|
|
3034
|
+
w[3] = keysWeight(2 - t);
|
|
3035
|
+
tapI0 = f - 1;
|
|
3036
|
+
tapN = 4;
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3039
|
+
const r = 2 * s;
|
|
3040
|
+
const i0 = Math.ceil(u - r);
|
|
3041
|
+
const n = Math.min(MAX_TAPS, Math.floor(u + r) - i0 + 1);
|
|
3042
|
+
let sum = 0;
|
|
3043
|
+
for (let k = 0; k < n; k++) {
|
|
3044
|
+
const v = keysWeight((i0 + k - u) / s);
|
|
3045
|
+
w[k] = v;
|
|
3046
|
+
sum += v;
|
|
3047
|
+
}
|
|
3048
|
+
if (sum !== 0) for (let k = 0; k < n; k++) w[k] /= sum;
|
|
3049
|
+
tapI0 = i0;
|
|
3050
|
+
tapN = n;
|
|
3051
|
+
}
|
|
3052
|
+
function intersect(a, b) {
|
|
3053
|
+
const x = Math.max(a.x, b.x);
|
|
3054
|
+
const y = Math.max(a.y, b.y);
|
|
3055
|
+
const x1 = Math.min(a.x + a.width, b.x + b.width);
|
|
3056
|
+
const y1 = Math.min(a.y + a.height, b.y + b.height);
|
|
3057
|
+
return x1 > x && y1 > y ? { x, y, width: x1 - x, height: y1 - y } : null;
|
|
3058
|
+
}
|
|
3059
|
+
function hasTilesIn(src, r) {
|
|
3060
|
+
for (const { tx, ty } of tilesInRect(r)) if (src.getTile(tx, ty)) return true;
|
|
3061
|
+
return false;
|
|
3062
|
+
}
|
|
3063
|
+
function readWindow(src, srcRect, rect) {
|
|
3064
|
+
const n = src.channels === 4 ? 4 : 2;
|
|
3065
|
+
const data = new Float32Array(rect.width * rect.height * n);
|
|
3066
|
+
const win = { x: rect.x, y: rect.y, w: rect.width, h: rect.height, n, data };
|
|
3067
|
+
const r = intersect(rect, srcRect);
|
|
3068
|
+
if (!r) return win;
|
|
3069
|
+
const px = readRegion(src, r);
|
|
3070
|
+
for (let y = 0; y < r.height; y++) {
|
|
3071
|
+
let s = y * r.width * src.channels;
|
|
3072
|
+
let d = ((r.y - rect.y + y) * rect.width + (r.x - rect.x)) * n;
|
|
3073
|
+
if (n === 4) {
|
|
3074
|
+
for (let x = 0; x < r.width; x++, s += 4, d += 4) {
|
|
3075
|
+
const a = px[s + 3] / 255;
|
|
3076
|
+
data[d] = px[s] * a;
|
|
3077
|
+
data[d + 1] = px[s + 1] * a;
|
|
3078
|
+
data[d + 2] = px[s + 2] * a;
|
|
3079
|
+
data[d + 3] = a;
|
|
3080
|
+
}
|
|
3081
|
+
} else {
|
|
3082
|
+
for (let x = 0; x < r.width; x++, s++, d += 2) {
|
|
3083
|
+
data[d] = px[s];
|
|
3084
|
+
data[d + 1] = 1;
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
return win;
|
|
3089
|
+
}
|
|
3090
|
+
var scratch = new Uint8ClampedArray(4);
|
|
3091
|
+
var scratchWord = new Uint32Array(scratch.buffer);
|
|
3092
|
+
var wx = new Float64Array(MAX_TAPS);
|
|
3093
|
+
var wy = new Float64Array(MAX_TAPS);
|
|
3094
|
+
function sample(win, interp, u, v, su, sv, acc) {
|
|
3095
|
+
const n = win.n;
|
|
3096
|
+
const d = win.data;
|
|
3097
|
+
for (let c = 0; c < n; c++) acc[c] = 0;
|
|
3098
|
+
if (interp === "nearest") {
|
|
3099
|
+
const ix = Math.floor(u + 0.5) - win.x;
|
|
3100
|
+
const iy = Math.floor(v + 0.5) - win.y;
|
|
3101
|
+
if (ix < 0 || iy < 0 || ix >= win.w || iy >= win.h) return;
|
|
3102
|
+
const o = (iy * win.w + ix) * n;
|
|
3103
|
+
for (let c = 0; c < n; c++) acc[c] = d[o + c];
|
|
3104
|
+
return;
|
|
3105
|
+
}
|
|
3106
|
+
if (interp === "bilinear") {
|
|
3107
|
+
const fx = Math.floor(u);
|
|
3108
|
+
const fy = Math.floor(v);
|
|
3109
|
+
const tx = u - fx;
|
|
3110
|
+
const ty = v - fy;
|
|
3111
|
+
for (let j = 0; j < 2; j++) {
|
|
3112
|
+
const iy = fy + j - win.y;
|
|
3113
|
+
if (iy < 0 || iy >= win.h) continue;
|
|
3114
|
+
const kyw = j ? ty : 1 - ty;
|
|
3115
|
+
if (!kyw) continue;
|
|
3116
|
+
for (let i = 0; i < 2; i++) {
|
|
3117
|
+
const ix = fx + i - win.x;
|
|
3118
|
+
if (ix < 0 || ix >= win.w) continue;
|
|
3119
|
+
const k = (i ? tx : 1 - tx) * kyw;
|
|
3120
|
+
if (!k) continue;
|
|
3121
|
+
const o = (iy * win.w + ix) * n;
|
|
3122
|
+
for (let c = 0; c < n; c++) acc[c] += d[o + c] * k;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
u = snap(u);
|
|
3128
|
+
v = snap(v);
|
|
3129
|
+
cubicTaps(u, su, wx);
|
|
3130
|
+
const x0 = tapI0 - win.x;
|
|
3131
|
+
const nu = tapN;
|
|
3132
|
+
cubicTaps(v, sv, wy);
|
|
3133
|
+
const y0 = tapI0 - win.y;
|
|
3134
|
+
const nv = tapN;
|
|
3135
|
+
const W = win.w;
|
|
3136
|
+
if (n === 4 && nu === 4 && nv === 4 && x0 >= 0 && y0 >= 0 && x0 + 4 <= W && y0 + 4 <= win.h) {
|
|
3137
|
+
let r = 0;
|
|
3138
|
+
let g = 0;
|
|
3139
|
+
let b = 0;
|
|
3140
|
+
let a = 0;
|
|
3141
|
+
const w0 = wx[0];
|
|
3142
|
+
const w1 = wx[1];
|
|
3143
|
+
const w2 = wx[2];
|
|
3144
|
+
const w3 = wx[3];
|
|
3145
|
+
for (let j = 0; j < 4; j++) {
|
|
3146
|
+
const kyw = wy[j];
|
|
3147
|
+
if (kyw === 0) continue;
|
|
3148
|
+
let o = ((y0 + j) * W + x0) * 4;
|
|
3149
|
+
const r0 = d[o] * w0 + d[o + 4] * w1 + d[o + 8] * w2 + d[o + 12] * w3;
|
|
3150
|
+
const g0 = d[o + 1] * w0 + d[o + 5] * w1 + d[o + 9] * w2 + d[o + 13] * w3;
|
|
3151
|
+
const b0 = d[o + 2] * w0 + d[o + 6] * w1 + d[o + 10] * w2 + d[o + 14] * w3;
|
|
3152
|
+
const a0 = d[o + 3] * w0 + d[o + 7] * w1 + d[o + 11] * w2 + d[o + 15] * w3;
|
|
3153
|
+
r += r0 * kyw;
|
|
3154
|
+
g += g0 * kyw;
|
|
3155
|
+
b += b0 * kyw;
|
|
3156
|
+
a += a0 * kyw;
|
|
3157
|
+
}
|
|
3158
|
+
acc[0] = r;
|
|
3159
|
+
acc[1] = g;
|
|
3160
|
+
acc[2] = b;
|
|
3161
|
+
acc[3] = a;
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
for (let j = 0; j < nv; j++) {
|
|
3165
|
+
const kyw = wy[j];
|
|
3166
|
+
if (kyw === 0) continue;
|
|
3167
|
+
const iy = y0 + j;
|
|
3168
|
+
if (iy < 0 || iy >= win.h) continue;
|
|
3169
|
+
const row = iy * W;
|
|
3170
|
+
for (let i = 0; i < nu; i++) {
|
|
3171
|
+
const k = wx[i] * kyw;
|
|
3172
|
+
if (k === 0) continue;
|
|
3173
|
+
const ix = x0 + i;
|
|
3174
|
+
if (ix < 0 || ix >= W) continue;
|
|
3175
|
+
const o = (row + ix) * n;
|
|
3176
|
+
if (n === 4) {
|
|
3177
|
+
acc[0] += d[o] * k;
|
|
3178
|
+
acc[1] += d[o + 1] * k;
|
|
3179
|
+
acc[2] += d[o + 2] * k;
|
|
3180
|
+
acc[3] += d[o + 3] * k;
|
|
3181
|
+
} else {
|
|
3182
|
+
acc[0] += d[o] * k;
|
|
3183
|
+
acc[1] += d[o + 1] * k;
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
function store(out, o, acc, ch, def) {
|
|
3189
|
+
if (ch === 4) {
|
|
3190
|
+
const al = acc[3] > 1 ? 1 : acc[3];
|
|
3191
|
+
if (!(al > 1e-6)) return false;
|
|
3192
|
+
out[o] = acc[0] / al;
|
|
3193
|
+
out[o + 1] = acc[1] / al;
|
|
3194
|
+
out[o + 2] = acc[2] / al;
|
|
3195
|
+
out[o + 3] = al * 255;
|
|
3196
|
+
return true;
|
|
3197
|
+
}
|
|
3198
|
+
const inside = acc[1] > 1 ? 1 : acc[1];
|
|
3199
|
+
if (!(inside > 1e-6)) return false;
|
|
3200
|
+
out[o] = acc[0] + def * (1 - inside);
|
|
3201
|
+
return true;
|
|
3202
|
+
}
|
|
3203
|
+
function boxReduce(src, srcRect, kx, ky) {
|
|
3204
|
+
const ch = src.channels;
|
|
3205
|
+
const rx0 = Math.floor(srcRect.x / kx);
|
|
3206
|
+
const ry0 = Math.floor(srcRect.y / ky);
|
|
3207
|
+
const rx1 = Math.ceil((srcRect.x + srcRect.width) / kx);
|
|
3208
|
+
const ry1 = Math.ceil((srcRect.y + srcRect.height) / ky);
|
|
3209
|
+
const rw = rx1 - rx0;
|
|
3210
|
+
const rect = { x: rx0, y: ry0, width: rw, height: ry1 - ry0 };
|
|
3211
|
+
let out = emptySurface(ch, src.defaultValue);
|
|
3212
|
+
const rowsPer = Math.max(1, Math.floor(TILE / ky));
|
|
3213
|
+
const area = kx * ky;
|
|
3214
|
+
for (let ry = ry0; ry < ry1; ry += rowsPer) {
|
|
3215
|
+
const rows = Math.min(rowsPer, ry1 - ry);
|
|
3216
|
+
const strip = { x: rx0 * kx, y: ry * ky, width: rw * kx, height: rows * ky };
|
|
3217
|
+
const px = readRegion(src, strip);
|
|
3218
|
+
const red = new Uint8ClampedArray(rw * rows * ch);
|
|
3219
|
+
for (let j = 0; j < rows; j++) {
|
|
3220
|
+
for (let i = 0; i < rw; i++) {
|
|
3221
|
+
if (ch === 4) {
|
|
3222
|
+
let a = 0;
|
|
3223
|
+
let r = 0;
|
|
3224
|
+
let g = 0;
|
|
3225
|
+
let b = 0;
|
|
3226
|
+
for (let y = 0; y < ky; y++) {
|
|
3227
|
+
let s = ((j * ky + y) * strip.width + i * kx) * 4;
|
|
3228
|
+
for (let x = 0; x < kx; x++, s += 4) {
|
|
3229
|
+
const al = px[s + 3];
|
|
3230
|
+
a += al;
|
|
3231
|
+
r += px[s] * al;
|
|
3232
|
+
g += px[s + 1] * al;
|
|
3233
|
+
b += px[s + 2] * al;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
const o = (j * rw + i) * 4;
|
|
3237
|
+
if (a > 0) {
|
|
3238
|
+
red[o] = r / a;
|
|
3239
|
+
red[o + 1] = g / a;
|
|
3240
|
+
red[o + 2] = b / a;
|
|
3241
|
+
red[o + 3] = a / area;
|
|
3242
|
+
}
|
|
3243
|
+
} else {
|
|
3244
|
+
let v = 0;
|
|
3245
|
+
for (let y = 0; y < ky; y++) {
|
|
3246
|
+
const s = (j * ky + y) * strip.width + i * kx;
|
|
3247
|
+
for (let x = 0; x < kx; x++) v += px[s + x];
|
|
3248
|
+
}
|
|
3249
|
+
red[j * rw + i] = v / area;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
out = writeRegion(out, { x: rx0, y: ry, width: rw, height: rows }, red);
|
|
3254
|
+
}
|
|
3255
|
+
return { surface: out, rect };
|
|
3256
|
+
}
|
|
3257
|
+
function reduceSurface(src, factor) {
|
|
3258
|
+
const k = Math.max(1, Math.floor(factor));
|
|
3259
|
+
const b = contentBounds(src);
|
|
3260
|
+
if (k === 1 || !b) return src;
|
|
3261
|
+
return boxReduce(src, b, k, k).surface;
|
|
3262
|
+
}
|
|
3263
|
+
function inverseStretch(inv, X, Y) {
|
|
3264
|
+
const w = inv[6] * X + inv[7] * Y + inv[8];
|
|
3265
|
+
if (!(Math.abs(w) > 1e-12)) return [1, 1];
|
|
3266
|
+
const U = (inv[0] * X + inv[1] * Y + inv[2]) / w;
|
|
3267
|
+
const V = (inv[3] * X + inv[4] * Y + inv[5]) / w;
|
|
3268
|
+
const ux = (inv[0] - U * inv[6]) / w;
|
|
3269
|
+
const uy = (inv[1] - U * inv[7]) / w;
|
|
3270
|
+
const vx = (inv[3] - V * inv[6]) / w;
|
|
3271
|
+
const vy = (inv[4] - V * inv[7]) / w;
|
|
3272
|
+
return [Math.hypot(ux, uy), Math.hypot(vx, vy)];
|
|
3273
|
+
}
|
|
3274
|
+
var reduction = (s) => s >= 2 && Number.isFinite(s) ? Math.min(64, 2 ** Math.floor(Math.log2(s))) : 1;
|
|
3275
|
+
function normalizeStep(step) {
|
|
3276
|
+
if (!step || !(step > 1)) return 1;
|
|
3277
|
+
return Math.min(64, 2 ** Math.floor(Math.log2(step)));
|
|
3278
|
+
}
|
|
3279
|
+
function checkBudget(dst, what = "result") {
|
|
3280
|
+
if (dst.width * dst.height > MAX_TRANSFORM_PIXELS) {
|
|
3281
|
+
throw new TransformTooLargeError(
|
|
3282
|
+
`The transformed ${what} would be ${dst.width} \xD7 ${dst.height} px, more than the ${MAX_TRANSFORM_PIXELS} px limit; use a smaller scale.`
|
|
3283
|
+
);
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
function assemble(src, tiles) {
|
|
3287
|
+
return new TiledSurface(src.channels, tiles, src.defaultValue);
|
|
3288
|
+
}
|
|
3289
|
+
function transformedBounds(source, h) {
|
|
3290
|
+
if (!(source.width > 0 && source.height > 0) || !invertHomography(h)) return null;
|
|
3291
|
+
const pts = boxQuad(source).map((p) => applyHomography(h, p));
|
|
3292
|
+
if (pts.some((p) => !p)) return null;
|
|
3293
|
+
return cornerBounds(pts);
|
|
3294
|
+
}
|
|
3295
|
+
function transformSurface(src, h, options = {}) {
|
|
3296
|
+
const interp = options.interpolation ?? "bicubic";
|
|
3297
|
+
const ch = src.channels;
|
|
3298
|
+
const def = src.defaultValue;
|
|
3299
|
+
const empty = emptySurface(ch, def);
|
|
3300
|
+
const given = options.source;
|
|
3301
|
+
const step = normalizeStep(options.step);
|
|
3302
|
+
if (isIdentityHomography(h, 1e-12) && !given && !options.clip) return src;
|
|
3303
|
+
const dx = h[2] / h[8];
|
|
3304
|
+
const dy = h[5] / h[8];
|
|
3305
|
+
if (!given && !options.clip && isIdentityHomography([h[0], h[1], 0, h[3], h[4], 0, h[6], h[7], h[8]], 1e-12) && Math.abs(dx - Math.round(dx)) < 1e-9 && Math.abs(dy - Math.round(dy)) < 1e-9) {
|
|
3306
|
+
return translateSurface(src, Math.round(dx), Math.round(dy));
|
|
3307
|
+
}
|
|
3308
|
+
let srcRect = given ? intersect(given, given) : contentBounds(src);
|
|
3309
|
+
if (!srcRect) return empty;
|
|
3310
|
+
let H = h;
|
|
3311
|
+
let S = src;
|
|
3312
|
+
if (interp === "bicubic") {
|
|
3313
|
+
const inv0 = invertHomography(H);
|
|
3314
|
+
const c = applyHomography(H, { x: srcRect.x + srcRect.width / 2, y: srcRect.y + srcRect.height / 2 });
|
|
3315
|
+
if (inv0 && c) {
|
|
3316
|
+
const [su, sv] = inverseStretch(inv0, c.x, c.y);
|
|
3317
|
+
const kx = reduction(su);
|
|
3318
|
+
const ky = reduction(sv);
|
|
3319
|
+
if (kx > 1 || ky > 1) {
|
|
3320
|
+
const red = boxReduce(src, srcRect, kx, ky);
|
|
3321
|
+
S = red.surface;
|
|
3322
|
+
srcRect = red.rect;
|
|
3323
|
+
H = multiplyHomographies([kx, 0, 0, 0, ky, 0, 0, 0, 1], H);
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
const inv = invertHomography(H);
|
|
3328
|
+
if (!inv) return empty;
|
|
3329
|
+
const sr = srcRect;
|
|
3330
|
+
const fwd = [
|
|
3331
|
+
{ x: sr.x - 1, y: sr.y - 1 },
|
|
3332
|
+
{ x: sr.x + sr.width + 1, y: sr.y - 1 },
|
|
3333
|
+
{ x: sr.x + sr.width + 1, y: sr.y + sr.height + 1 },
|
|
3334
|
+
{ x: sr.x - 1, y: sr.y + sr.height + 1 }
|
|
3335
|
+
].map((p) => homographyW(H, p));
|
|
3336
|
+
const side = fwd.every((w) => w > 0) ? 1 : fwd.every((w) => w < 0) ? -1 : 0;
|
|
3337
|
+
const wLo = 1 / fwd.reduce((m, w) => Math.max(m, Math.abs(w)), 0);
|
|
3338
|
+
const front = side === 0 ? homographyFrontSide(H, sr) : 0;
|
|
3339
|
+
const corners = boxQuad(sr).map((p) => applyHomography(H, p));
|
|
3340
|
+
const bounds = corners.every(Boolean) ? cornerBounds(corners) : null;
|
|
3341
|
+
let dst;
|
|
3342
|
+
if (options.clip && bounds && side !== 0) dst = intersect(bounds, options.clip);
|
|
3343
|
+
else dst = options.clip ?? bounds;
|
|
3344
|
+
if (!dst) return empty;
|
|
3345
|
+
if (!options.clip) checkBudget(dst);
|
|
3346
|
+
const affine = Math.abs(inv[6]) < 1e-15 && Math.abs(inv[7]) < 1e-15;
|
|
3347
|
+
const [su0, sv0] = inverseStretch(inv, dst.x + dst.width / 2, dst.y + dst.height / 2);
|
|
3348
|
+
const widen = (s) => interp === "bicubic" ? Math.min(4, Math.max(1, s)) : 1;
|
|
3349
|
+
const maxWiden = interp === "bicubic" ? 4 : 1;
|
|
3350
|
+
const pad = 3 + Math.ceil(2 * maxWiden);
|
|
3351
|
+
const margin = interp === "bicubic" ? Math.max(1, widen(su0), widen(sv0)) : 1;
|
|
3352
|
+
const tiles = /* @__PURE__ */ new Map();
|
|
3353
|
+
const acc = new Float64Array(4);
|
|
3354
|
+
const sx0 = sr.x;
|
|
3355
|
+
const sy0 = sr.y;
|
|
3356
|
+
const sx1 = sr.x + sr.width - 1;
|
|
3357
|
+
const sy1 = sr.y + sr.height - 1;
|
|
3358
|
+
for (const { tx, ty } of tilesInRect(dst)) {
|
|
3359
|
+
const t = intersect({ x: tx * TILE, y: ty * TILE, width: TILE, height: TILE }, dst);
|
|
3360
|
+
if (!t) continue;
|
|
3361
|
+
const tc = [
|
|
3362
|
+
{ x: t.x, y: t.y },
|
|
3363
|
+
{ x: t.x + t.width, y: t.y },
|
|
3364
|
+
{ x: t.x + t.width, y: t.y + t.height },
|
|
3365
|
+
{ x: t.x, y: t.y + t.height }
|
|
3366
|
+
];
|
|
3367
|
+
const wc = tc.map((p) => homographyW(inv, p));
|
|
3368
|
+
let poly = tc;
|
|
3369
|
+
if (side !== 0) {
|
|
3370
|
+
const dd = wc.map((w) => side * w - wLo);
|
|
3371
|
+
poly = [];
|
|
3372
|
+
for (let i = 0; i < 4; i++) {
|
|
3373
|
+
const p = tc[i];
|
|
3374
|
+
const q = tc[(i + 1) % 4];
|
|
3375
|
+
const dp = dd[i];
|
|
3376
|
+
const dq = dd[(i + 1) % 4];
|
|
3377
|
+
if (dp >= 0) poly.push(p);
|
|
3378
|
+
if (dp >= 0 !== dq >= 0) {
|
|
3379
|
+
const k = dp / (dp - dq);
|
|
3380
|
+
poly.push({ x: p.x + (q.x - p.x) * k, y: p.y + (q.y - p.y) * k });
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
if (!poly.length) continue;
|
|
3385
|
+
const straddles = side === 0 && wc.some((w) => w <= 0) && wc.some((w) => w >= 0);
|
|
3386
|
+
let foot;
|
|
3387
|
+
if (straddles) foot = sr;
|
|
3388
|
+
else {
|
|
3389
|
+
const fp = poly.map((p) => applyHomography(inv, p));
|
|
3390
|
+
if (fp.some((p) => !p)) foot = sr;
|
|
3391
|
+
else {
|
|
3392
|
+
const xs = fp.map((p) => p.x);
|
|
3393
|
+
const ys = fp.map((p) => p.y);
|
|
3394
|
+
const fx0 = Math.floor(Math.min(...xs)) - pad;
|
|
3395
|
+
const fy0 = Math.floor(Math.min(...ys)) - pad;
|
|
3396
|
+
const fx1 = Math.ceil(Math.max(...xs)) + pad;
|
|
3397
|
+
const fy1 = Math.ceil(Math.max(...ys)) + pad;
|
|
3398
|
+
foot = intersect({ x: fx0, y: fy0, width: fx1 - fx0, height: fy1 - fy0 }, { x: sr.x - pad, y: sr.y - pad, width: sr.width + 2 * pad, height: sr.height + 2 * pad });
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
if (!foot) continue;
|
|
3402
|
+
const readable = intersect(foot, sr);
|
|
3403
|
+
if (!readable || !hasTilesIn(S, readable)) continue;
|
|
3404
|
+
const win = readWindow(S, sr, foot);
|
|
3405
|
+
const out = new Uint8ClampedArray(TILE * TILE * ch);
|
|
3406
|
+
if (def) out.fill(def);
|
|
3407
|
+
let any = false;
|
|
3408
|
+
const ox = tx * TILE;
|
|
3409
|
+
const oy = ty * TILE;
|
|
3410
|
+
let su = widen(su0);
|
|
3411
|
+
let sv = widen(sv0);
|
|
3412
|
+
const ystart = t.y - ((t.y - oy) % step + step) % step;
|
|
3413
|
+
const xstart = t.x - ((t.x - ox) % step + step) % step;
|
|
3414
|
+
const blocks = Math.ceil((t.x + t.width - xstart) / step);
|
|
3415
|
+
const words = ch === 4 ? new Uint32Array(out.buffer) : null;
|
|
3416
|
+
const rowVals = new Float64Array(blocks);
|
|
3417
|
+
const rowSet = new Uint8Array(blocks);
|
|
3418
|
+
for (let y = ystart; y < t.y + t.height; y += step) {
|
|
3419
|
+
const Y = y + step / 2;
|
|
3420
|
+
let anyInRow = false;
|
|
3421
|
+
for (let bi = 0, x = xstart; bi < blocks; bi++, x += step) {
|
|
3422
|
+
rowSet[bi] = 0;
|
|
3423
|
+
const X = x + step / 2;
|
|
3424
|
+
const w = inv[6] * X + inv[7] * Y + inv[8];
|
|
3425
|
+
if (front !== 0 && front * w <= 0) continue;
|
|
3426
|
+
const u = (inv[0] * X + inv[1] * Y + inv[2]) / w - 0.5;
|
|
3427
|
+
const v = (inv[3] * X + inv[4] * Y + inv[5]) / w - 0.5;
|
|
3428
|
+
if (!(u >= sx0 - margin && v >= sy0 - margin && u <= sx1 + margin && v <= sy1 + margin)) continue;
|
|
3429
|
+
if (!affine && interp === "bicubic") {
|
|
3430
|
+
const s = inverseStretch(inv, X, Y);
|
|
3431
|
+
su = widen(s[0]);
|
|
3432
|
+
sv = widen(s[1]);
|
|
3433
|
+
}
|
|
3434
|
+
sample(win, interp, u, v, su, sv, acc);
|
|
3435
|
+
if (!store(scratch, 0, acc, ch, def)) continue;
|
|
3436
|
+
rowSet[bi] = 1;
|
|
3437
|
+
rowVals[bi] = ch === 4 ? scratchWord[0] : scratch[0];
|
|
3438
|
+
anyInRow = true;
|
|
3439
|
+
}
|
|
3440
|
+
if (!anyInRow) continue;
|
|
3441
|
+
any = true;
|
|
3442
|
+
const y0 = Math.max(y, t.y);
|
|
3443
|
+
const y1 = Math.min(y + step, t.y + t.height);
|
|
3444
|
+
for (let yy = y0; yy < y1; yy++) {
|
|
3445
|
+
const row = (yy - oy) * TILE - ox;
|
|
3446
|
+
for (let bi = 0, x = xstart; bi < blocks; bi++, x += step) {
|
|
3447
|
+
if (!rowSet[bi]) continue;
|
|
3448
|
+
const x0 = Math.max(x, t.x);
|
|
3449
|
+
const x1 = Math.min(x + step, t.x + t.width);
|
|
3450
|
+
const val = rowVals[bi];
|
|
3451
|
+
if (words) for (let xx = x0; xx < x1; xx++) words[row + xx] = val;
|
|
3452
|
+
else for (let xx = x0; xx < x1; xx++) out[row + xx] = val;
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
if (!any) continue;
|
|
3457
|
+
const tile = finishTile(out, ch, def);
|
|
3458
|
+
if (tile) tiles.set(tileKey(tx, ty), tile);
|
|
3459
|
+
}
|
|
3460
|
+
return assemble(src, tiles);
|
|
3461
|
+
}
|
|
3462
|
+
var CELL = 4;
|
|
3463
|
+
var MAX_CELLS = 512;
|
|
3464
|
+
var MAX_SS = 8;
|
|
3465
|
+
function warpSurface(src, f, options = {}) {
|
|
3466
|
+
const interp = options.interpolation ?? "bicubic";
|
|
3467
|
+
const ch = src.channels;
|
|
3468
|
+
const def = src.defaultValue;
|
|
3469
|
+
const empty = emptySurface(ch, def);
|
|
3470
|
+
const sr = options.source ? intersect(options.source, options.source) : contentBounds(src);
|
|
3471
|
+
if (!sr) return empty;
|
|
3472
|
+
const step = normalizeStep(options.step);
|
|
3473
|
+
const nx = Math.min(MAX_CELLS, Math.max(1, Math.ceil(sr.width / CELL)));
|
|
3474
|
+
const ny = Math.min(MAX_CELLS, Math.max(1, Math.ceil(sr.height / CELL)));
|
|
3475
|
+
const w1 = nx + 1;
|
|
3476
|
+
const dvx = new Float64Array(w1 * (ny + 1));
|
|
3477
|
+
const dvy = new Float64Array(w1 * (ny + 1));
|
|
3478
|
+
const svx = new Float64Array(w1 * (ny + 1));
|
|
3479
|
+
const svy = new Float64Array(w1 * (ny + 1));
|
|
3480
|
+
let x0 = Infinity;
|
|
3481
|
+
let y0 = Infinity;
|
|
3482
|
+
let x1 = -Infinity;
|
|
3483
|
+
let y1 = -Infinity;
|
|
3484
|
+
for (let j = 0; j <= ny; j++) {
|
|
3485
|
+
for (let i = 0; i <= nx; i++) {
|
|
3486
|
+
const k = j * w1 + i;
|
|
3487
|
+
const sx = sr.x + sr.width * i / nx;
|
|
3488
|
+
const sy = sr.y + sr.height * j / ny;
|
|
3489
|
+
const d = f({ x: sx, y: sy });
|
|
3490
|
+
if (!d || !Number.isFinite(d.x) || !Number.isFinite(d.y)) return empty;
|
|
3491
|
+
dvx[k] = d.x;
|
|
3492
|
+
dvy[k] = d.y;
|
|
3493
|
+
svx[k] = sx;
|
|
3494
|
+
svy[k] = sy;
|
|
3495
|
+
if (d.x < x0) x0 = d.x;
|
|
3496
|
+
if (d.y < y0) y0 = d.y;
|
|
3497
|
+
if (d.x > x1) x1 = d.x;
|
|
3498
|
+
if (d.y > y1) y1 = d.y;
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
const lim = 1 << 20;
|
|
3502
|
+
const bx0 = Math.floor(Math.max(-lim, x0)) - 1;
|
|
3503
|
+
const by0 = Math.floor(Math.max(-lim, y0)) - 1;
|
|
3504
|
+
const full = { x: bx0, y: by0, width: Math.ceil(Math.min(lim, x1)) + 1 - bx0, height: Math.ceil(Math.min(lim, y1)) + 1 - by0 };
|
|
3505
|
+
const dst = options.clip ? intersect(full, options.clip) : full;
|
|
3506
|
+
if (!dst) return empty;
|
|
3507
|
+
if (!options.clip) checkBudget(dst);
|
|
3508
|
+
const triCount = nx * ny * 2;
|
|
3509
|
+
const tris = new Int32Array(triCount * 3);
|
|
3510
|
+
for (let j = 0, t = 0; j < ny; j++) {
|
|
3511
|
+
for (let i = 0; i < nx; i++) {
|
|
3512
|
+
const a = j * w1 + i;
|
|
3513
|
+
tris[t++] = a;
|
|
3514
|
+
tris[t++] = a + 1;
|
|
3515
|
+
tris[t++] = a + w1 + 1;
|
|
3516
|
+
tris[t++] = a;
|
|
3517
|
+
tris[t++] = a + w1 + 1;
|
|
3518
|
+
tris[t++] = a + w1;
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
const tx0 = Math.floor(dst.x / TILE);
|
|
3522
|
+
const ty0 = Math.floor(dst.y / TILE);
|
|
3523
|
+
const cols = Math.floor((dst.x + dst.width - 1) / TILE) - tx0 + 1;
|
|
3524
|
+
const rows = Math.floor((dst.y + dst.height - 1) / TILE) - ty0 + 1;
|
|
3525
|
+
const bins = Array.from({ length: cols * rows }, () => []);
|
|
3526
|
+
for (let k = 0; k < triCount; k++) {
|
|
3527
|
+
const a = tris[3 * k];
|
|
3528
|
+
const b = tris[3 * k + 1];
|
|
3529
|
+
const c = tris[3 * k + 2];
|
|
3530
|
+
const tminx = Math.floor(Math.min(dvx[a], dvx[b], dvx[c]));
|
|
3531
|
+
const tminy = Math.floor(Math.min(dvy[a], dvy[b], dvy[c]));
|
|
3532
|
+
const tmaxx = Math.ceil(Math.max(dvx[a], dvx[b], dvx[c]));
|
|
3533
|
+
const tmaxy = Math.ceil(Math.max(dvy[a], dvy[b], dvy[c]));
|
|
3534
|
+
const cx0 = Math.max(0, Math.floor(Math.max(tminx, dst.x) / TILE) - tx0);
|
|
3535
|
+
const cy0 = Math.max(0, Math.floor(Math.max(tminy, dst.y) / TILE) - ty0);
|
|
3536
|
+
const cx1 = Math.min(cols - 1, Math.floor(Math.min(tmaxx, dst.x + dst.width - 1) / TILE) - tx0);
|
|
3537
|
+
const cy1 = Math.min(rows - 1, Math.floor(Math.min(tmaxy, dst.y + dst.height - 1) / TILE) - ty0);
|
|
3538
|
+
for (let cy = cy0; cy <= cy1; cy++) for (let cx = cx0; cx <= cx1; cx++) bins[cy * cols + cx].push(k);
|
|
3539
|
+
}
|
|
3540
|
+
const tiles = /* @__PURE__ */ new Map();
|
|
3541
|
+
const acc = new Float64Array(4);
|
|
3542
|
+
const one = new Float64Array(4);
|
|
3543
|
+
const n = ch === 4 ? 4 : 2;
|
|
3544
|
+
const count = (jx, jy) => interp === "nearest" ? 1 : Math.min(MAX_SS, Math.max(1, Math.round(Math.hypot(jx, jy))));
|
|
3545
|
+
for (let cy = 0; cy < rows; cy++) {
|
|
3546
|
+
for (let cx = 0; cx < cols; cx++) {
|
|
3547
|
+
const list = bins[cy * cols + cx];
|
|
3548
|
+
if (!list.length) continue;
|
|
3549
|
+
const ttx = tx0 + cx;
|
|
3550
|
+
const tty = ty0 + cy;
|
|
3551
|
+
const t = intersect({ x: ttx * TILE, y: tty * TILE, width: TILE, height: TILE }, dst);
|
|
3552
|
+
if (!t) continue;
|
|
3553
|
+
const tw = t.width;
|
|
3554
|
+
const th = t.height;
|
|
3555
|
+
const us = new Float64Array(tw * th).fill(NaN);
|
|
3556
|
+
const vs = new Float64Array(tw * th);
|
|
3557
|
+
const owner = new Int32Array(tw * th);
|
|
3558
|
+
const jac = new Float64Array(list.length * 4);
|
|
3559
|
+
const ssx = new Int32Array(list.length);
|
|
3560
|
+
const ssy = new Int32Array(list.length);
|
|
3561
|
+
for (let li = 0; li < list.length; li++) {
|
|
3562
|
+
const k = list[li];
|
|
3563
|
+
const a = tris[3 * k];
|
|
3564
|
+
const b = tris[3 * k + 1];
|
|
3565
|
+
const c = tris[3 * k + 2];
|
|
3566
|
+
const p0x = dvx[a];
|
|
3567
|
+
const p0y = dvy[a];
|
|
3568
|
+
const p1x = dvx[b];
|
|
3569
|
+
const p1y = dvy[b];
|
|
3570
|
+
const p2x = dvx[c];
|
|
3571
|
+
const p2y = dvy[c];
|
|
3572
|
+
const det = (p1x - p0x) * (p2y - p0y) - (p2x - p0x) * (p1y - p0y);
|
|
3573
|
+
ssx[li] = 1;
|
|
3574
|
+
ssy[li] = 1;
|
|
3575
|
+
if (Math.abs(det) < 1e-12) continue;
|
|
3576
|
+
const d1x = svx[b] - svx[a];
|
|
3577
|
+
const d1y = svy[b] - svy[a];
|
|
3578
|
+
const d2x = svx[c] - svx[a];
|
|
3579
|
+
const d2y = svy[c] - svy[a];
|
|
3580
|
+
const l1x = (p2y - p0y) / det;
|
|
3581
|
+
const l1y = (p0x - p2x) / det;
|
|
3582
|
+
const l2x = (p0y - p1y) / det;
|
|
3583
|
+
const l2y = (p1x - p0x) / det;
|
|
3584
|
+
const cap = (vx, vy) => {
|
|
3585
|
+
const l = Math.hypot(vx, vy);
|
|
3586
|
+
return l > MAX_SS ? [vx * MAX_SS / l, vy * MAX_SS / l] : [vx, vy];
|
|
3587
|
+
};
|
|
3588
|
+
const jx = cap(l1x * d1x + l2x * d2x, l1x * d1y + l2x * d2y);
|
|
3589
|
+
const jy = cap(l1y * d1x + l2y * d2x, l1y * d1y + l2y * d2y);
|
|
3590
|
+
const cnx = count(jx[0], jx[1]);
|
|
3591
|
+
const cny = count(jy[0], jy[1]);
|
|
3592
|
+
if (cnx * cny > 1) {
|
|
3593
|
+
jac[li * 4] = jx[0];
|
|
3594
|
+
jac[li * 4 + 1] = jx[1];
|
|
3595
|
+
jac[li * 4 + 2] = jy[0];
|
|
3596
|
+
jac[li * 4 + 3] = jy[1];
|
|
3597
|
+
ssx[li] = cnx;
|
|
3598
|
+
ssy[li] = cny;
|
|
3599
|
+
}
|
|
3600
|
+
const rx0 = Math.max(t.x, Math.floor(Math.min(p0x, p1x, p2x) - 0.5));
|
|
3601
|
+
const ry0 = Math.max(t.y, Math.floor(Math.min(p0y, p1y, p2y) - 0.5));
|
|
3602
|
+
const rx1 = Math.min(t.x + tw, Math.ceil(Math.max(p0x, p1x, p2x) + 0.5));
|
|
3603
|
+
const ry1 = Math.min(t.y + th, Math.ceil(Math.max(p0y, p1y, p2y) + 0.5));
|
|
3604
|
+
const eps = -1e-9;
|
|
3605
|
+
const ay0 = step === 1 ? ry0 : ry0 + ((t.y - ry0) % step + step) % step;
|
|
3606
|
+
const ax0 = step === 1 ? rx0 : rx0 + ((t.x - rx0) % step + step) % step;
|
|
3607
|
+
for (let y = ay0; y < ry1; y += step) {
|
|
3608
|
+
const py = y + 0.5;
|
|
3609
|
+
for (let x = ax0; x < rx1; x += step) {
|
|
3610
|
+
const px = x + 0.5;
|
|
3611
|
+
const l1 = ((px - p0x) * (p2y - p0y) - (p2x - p0x) * (py - p0y)) / det;
|
|
3612
|
+
const l2 = ((p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y)) / det;
|
|
3613
|
+
const l0 = 1 - l1 - l2;
|
|
3614
|
+
if (l0 < eps || l1 < eps || l2 < eps) continue;
|
|
3615
|
+
const o = (y - t.y) * tw + (x - t.x);
|
|
3616
|
+
us[o] = l0 * svx[a] + l1 * svx[b] + l2 * svx[c];
|
|
3617
|
+
vs[o] = l0 * svy[a] + l1 * svy[b] + l2 * svy[c];
|
|
3618
|
+
owner[o] = li;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
let fx0 = Infinity;
|
|
3623
|
+
let fy0 = Infinity;
|
|
3624
|
+
let fx1 = -Infinity;
|
|
3625
|
+
let fy1 = -Infinity;
|
|
3626
|
+
for (let o = 0; o < us.length; o++) {
|
|
3627
|
+
const u = us[o];
|
|
3628
|
+
if (Number.isNaN(u)) continue;
|
|
3629
|
+
const li = owner[o];
|
|
3630
|
+
const ex = 0.5 * (Math.abs(jac[li * 4]) + Math.abs(jac[li * 4 + 2]));
|
|
3631
|
+
const ey = 0.5 * (Math.abs(jac[li * 4 + 1]) + Math.abs(jac[li * 4 + 3]));
|
|
3632
|
+
if (u - ex < fx0) fx0 = u - ex;
|
|
3633
|
+
if (vs[o] - ey < fy0) fy0 = vs[o] - ey;
|
|
3634
|
+
if (u + ex > fx1) fx1 = u + ex;
|
|
3635
|
+
if (vs[o] + ey > fy1) fy1 = vs[o] + ey;
|
|
3636
|
+
}
|
|
3637
|
+
if (fx0 > fx1) continue;
|
|
3638
|
+
const foot = intersect({ x: Math.floor(fx0) - 3, y: Math.floor(fy0) - 3, width: Math.ceil(fx1) - Math.floor(fx0) + 6, height: Math.ceil(fy1) - Math.floor(fy0) + 6 }, sr);
|
|
3639
|
+
if (!foot || !hasTilesIn(src, foot)) continue;
|
|
3640
|
+
const win = readWindow(src, sr, foot);
|
|
3641
|
+
const out = new Uint8ClampedArray(TILE * TILE * ch);
|
|
3642
|
+
if (def) out.fill(def);
|
|
3643
|
+
let any = false;
|
|
3644
|
+
const ox = ttx * TILE;
|
|
3645
|
+
const oy = tty * TILE;
|
|
3646
|
+
const pointAt = (o, into) => {
|
|
3647
|
+
const li = owner[o];
|
|
3648
|
+
const cnx = ssx[li];
|
|
3649
|
+
const cny = ssy[li];
|
|
3650
|
+
if (cnx * cny === 1) {
|
|
3651
|
+
sample(win, interp, us[o] - 0.5, vs[o] - 0.5, 1, 1, into);
|
|
3652
|
+
return;
|
|
3653
|
+
}
|
|
3654
|
+
for (let c = 0; c < n; c++) into[c] = 0;
|
|
3655
|
+
const j0 = jac[li * 4];
|
|
3656
|
+
const j1 = jac[li * 4 + 1];
|
|
3657
|
+
const j2 = jac[li * 4 + 2];
|
|
3658
|
+
const j3 = jac[li * 4 + 3];
|
|
3659
|
+
for (let sy = 0; sy < cny; sy++) {
|
|
3660
|
+
const tt = (sy + 0.5) / cny - 0.5;
|
|
3661
|
+
for (let sx = 0; sx < cnx; sx++) {
|
|
3662
|
+
const s = (sx + 0.5) / cnx - 0.5;
|
|
3663
|
+
sample(win, "bilinear", us[o] + s * j0 + tt * j2 - 0.5, vs[o] + s * j1 + tt * j3 - 0.5, 1, 1, one);
|
|
3664
|
+
for (let c = 0; c < n; c++) into[c] += one[c];
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
const k = 1 / (cnx * cny);
|
|
3668
|
+
for (let c = 0; c < n; c++) into[c] *= k;
|
|
3669
|
+
};
|
|
3670
|
+
if (step === 1) {
|
|
3671
|
+
for (let o = 0; o < us.length; o++) {
|
|
3672
|
+
if (Number.isNaN(us[o])) continue;
|
|
3673
|
+
pointAt(o, acc);
|
|
3674
|
+
const x = t.x + o % tw;
|
|
3675
|
+
const y = t.y + Math.floor(o / tw);
|
|
3676
|
+
if (store(out, ((y - oy) * TILE + (x - ox)) * ch, acc, ch, def)) any = true;
|
|
3677
|
+
}
|
|
3678
|
+
} else {
|
|
3679
|
+
for (let by = 0; by < th; by += step) {
|
|
3680
|
+
for (let bx = 0; bx < tw; bx += step) {
|
|
3681
|
+
const o = by * tw + bx;
|
|
3682
|
+
if (Number.isNaN(us[o])) continue;
|
|
3683
|
+
pointAt(o, acc);
|
|
3684
|
+
const first = ((t.y + by - oy) * TILE + (t.x + bx - ox)) * ch;
|
|
3685
|
+
if (!store(out, first, acc, ch, def)) continue;
|
|
3686
|
+
any = true;
|
|
3687
|
+
for (let yy = by; yy < Math.min(th, by + step); yy++) {
|
|
3688
|
+
const row = ((t.y + yy - oy) * TILE + (t.x - ox)) * ch;
|
|
3689
|
+
for (let xx = bx; xx < Math.min(tw, bx + step); xx++) for (let c = 0; c < ch; c++) out[row + xx * ch + c] = out[first + c];
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
if (!any) continue;
|
|
3695
|
+
const tile = finishTile(out, ch, def);
|
|
3696
|
+
if (tile) tiles.set(tileKey(ttx, tty), tile);
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
return assemble(src, tiles);
|
|
3700
|
+
}
|
|
3701
|
+
function compositeSurfaceOver(base, top) {
|
|
3702
|
+
if (top.channels !== 4) throw new Error("compositeSurfaceOver: top must be RGBA");
|
|
3703
|
+
if (!top.tiles.size) return base;
|
|
3704
|
+
const ch = base.channels;
|
|
3705
|
+
const tiles = new Map(base.tiles);
|
|
3706
|
+
for (const [key, t] of top.tiles) {
|
|
3707
|
+
const under = base.tiles.get(key);
|
|
3708
|
+
if (!under && ch === 4) {
|
|
3709
|
+
tiles.set(key, t);
|
|
3710
|
+
continue;
|
|
3711
|
+
}
|
|
3712
|
+
const d = new Uint8ClampedArray(TILE * TILE * ch);
|
|
3713
|
+
if (under) d.set(under.data);
|
|
3714
|
+
else if (base.defaultValue) d.fill(base.defaultValue);
|
|
3715
|
+
const s = t.data;
|
|
3716
|
+
if (ch === 4) {
|
|
3717
|
+
for (let i = 0; i < d.length; i += 4) {
|
|
3718
|
+
const ta = s[i + 3] / 255;
|
|
3719
|
+
if (ta <= 0) continue;
|
|
3720
|
+
if (ta >= 1) {
|
|
3721
|
+
d[i] = s[i];
|
|
3722
|
+
d[i + 1] = s[i + 1];
|
|
3723
|
+
d[i + 2] = s[i + 2];
|
|
3724
|
+
d[i + 3] = 255;
|
|
3725
|
+
continue;
|
|
3726
|
+
}
|
|
3727
|
+
const da = d[i + 3] / 255;
|
|
3728
|
+
const oa = ta + da * (1 - ta);
|
|
3729
|
+
for (let c = 0; c < 3; c++) d[i + c] = (s[i + c] * ta + d[i + c] * da * (1 - ta)) / oa;
|
|
3730
|
+
d[i + 3] = oa * 255;
|
|
3731
|
+
}
|
|
3732
|
+
} else {
|
|
3733
|
+
for (let p = 0, i = 0; p < d.length; p++, i += 4) {
|
|
3734
|
+
const ta = s[i + 3] / 255;
|
|
3735
|
+
if (ta > 0) d[p] = s[i] * ta + d[p] * (1 - ta);
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
const tile = finishTile(d, ch, base.defaultValue);
|
|
3739
|
+
if (tile) tiles.set(key, tile);
|
|
3740
|
+
else tiles.delete(key);
|
|
3741
|
+
}
|
|
3742
|
+
return new TiledSurface(ch, tiles, base.defaultValue);
|
|
3743
|
+
}
|
|
3744
|
+
|
|
2989
3745
|
// src/raster/zlib.ts
|
|
2990
3746
|
var LENGTH_BASE = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];
|
|
2991
3747
|
var LENGTH_EXTRA = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0];
|
|
@@ -3698,7 +4454,7 @@ function decodePng(bytes, options = {}) {
|
|
|
3698
4454
|
lines[dst + x] = r & 255;
|
|
3699
4455
|
}
|
|
3700
4456
|
}
|
|
3701
|
-
const
|
|
4457
|
+
const sample2 = (y, i) => {
|
|
3702
4458
|
const row = y * stride;
|
|
3703
4459
|
if (depth === 8) return lines[row + i];
|
|
3704
4460
|
if (depth === 16) return lines[row + i * 2];
|
|
@@ -3717,36 +4473,36 @@ function decodePng(bytes, options = {}) {
|
|
|
3717
4473
|
for (let x = 0; x < width; x++) {
|
|
3718
4474
|
const d = (y * width + x) * channels;
|
|
3719
4475
|
if (type === 0) {
|
|
3720
|
-
const v =
|
|
4476
|
+
const v = sample2(y, x);
|
|
3721
4477
|
if (gray) out[d] = v;
|
|
3722
4478
|
else {
|
|
3723
4479
|
out[d] = out[d + 1] = out[d + 2] = v;
|
|
3724
4480
|
out[d + 3] = v === trnsGray && trns ? 0 : 255;
|
|
3725
4481
|
}
|
|
3726
4482
|
} else if (type === 2) {
|
|
3727
|
-
const r =
|
|
3728
|
-
const g =
|
|
3729
|
-
const b =
|
|
4483
|
+
const r = sample2(y, x * 3);
|
|
4484
|
+
const g = sample2(y, x * 3 + 1);
|
|
4485
|
+
const b = sample2(y, x * 3 + 2);
|
|
3730
4486
|
out[d] = r;
|
|
3731
4487
|
out[d + 1] = g;
|
|
3732
4488
|
out[d + 2] = b;
|
|
3733
4489
|
out[d + 3] = trnsRgb && r === trnsRgb[0] && g === trnsRgb[1] && b === trnsRgb[2] ? 0 : 255;
|
|
3734
4490
|
} else if (type === 3) {
|
|
3735
|
-
const i =
|
|
4491
|
+
const i = sample2(y, x);
|
|
3736
4492
|
if (!palette || i * 3 + 2 >= palette.length) throw new Error("PNG palette index out of range.");
|
|
3737
4493
|
out[d] = palette[i * 3];
|
|
3738
4494
|
out[d + 1] = palette[i * 3 + 1];
|
|
3739
4495
|
out[d + 2] = palette[i * 3 + 2];
|
|
3740
4496
|
out[d + 3] = trns && i < trns.length ? trns[i] : 255;
|
|
3741
4497
|
} else if (type === 4) {
|
|
3742
|
-
const v =
|
|
4498
|
+
const v = sample2(y, x * 2);
|
|
3743
4499
|
out[d] = out[d + 1] = out[d + 2] = v;
|
|
3744
|
-
out[d + 3] =
|
|
4500
|
+
out[d + 3] = sample2(y, x * 2 + 1);
|
|
3745
4501
|
} else {
|
|
3746
|
-
out[d] =
|
|
3747
|
-
out[d + 1] =
|
|
3748
|
-
out[d + 2] =
|
|
3749
|
-
out[d + 3] =
|
|
4502
|
+
out[d] = sample2(y, x * 4);
|
|
4503
|
+
out[d + 1] = sample2(y, x * 4 + 1);
|
|
4504
|
+
out[d + 2] = sample2(y, x * 4 + 2);
|
|
4505
|
+
out[d + 3] = sample2(y, x * 4 + 3);
|
|
3750
4506
|
}
|
|
3751
4507
|
}
|
|
3752
4508
|
}
|
|
@@ -3869,6 +4625,16 @@ export {
|
|
|
3869
4625
|
blendTile,
|
|
3870
4626
|
RasterCompositor,
|
|
3871
4627
|
changedTiles,
|
|
4628
|
+
INTERPOLATIONS,
|
|
4629
|
+
isInterpolation,
|
|
4630
|
+
MAX_TRANSFORM_PIXELS,
|
|
4631
|
+
TransformTooLargeError,
|
|
4632
|
+
keysWeight,
|
|
4633
|
+
reduceSurface,
|
|
4634
|
+
transformedBounds,
|
|
4635
|
+
transformSurface,
|
|
4636
|
+
warpSurface,
|
|
4637
|
+
compositeSurfaceOver,
|
|
3872
4638
|
ZlibError,
|
|
3873
4639
|
inflateRaw,
|
|
3874
4640
|
adler32,
|
|
@@ -3883,4 +4649,4 @@ export {
|
|
|
3883
4649
|
parseDataUrl,
|
|
3884
4650
|
pngDataUrl
|
|
3885
4651
|
};
|
|
3886
|
-
//# sourceMappingURL=chunk-
|
|
4652
|
+
//# sourceMappingURL=chunk-WIR377F6.js.map
|