Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/node_modules/@jimp/plugin-resize/dist/modules/resize2.js
1129 views
1
"use strict";
2
3
/**
4
* Copyright (c) 2015 Guyon Roche
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:</p>
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
* THE SOFTWARE.
23
*/
24
module.exports = {
25
nearestNeighbor: function nearestNeighbor(src, dst) {
26
var wSrc = src.width;
27
var hSrc = src.height;
28
var wDst = dst.width;
29
var hDst = dst.height;
30
var bufSrc = src.data;
31
var bufDst = dst.data;
32
33
for (var i = 0; i < hDst; i++) {
34
for (var j = 0; j < wDst; j++) {
35
var posDst = (i * wDst + j) * 4;
36
var iSrc = Math.floor(i * hSrc / hDst);
37
var jSrc = Math.floor(j * wSrc / wDst);
38
var posSrc = (iSrc * wSrc + jSrc) * 4;
39
bufDst[posDst++] = bufSrc[posSrc++];
40
bufDst[posDst++] = bufSrc[posSrc++];
41
bufDst[posDst++] = bufSrc[posSrc++];
42
bufDst[posDst++] = bufSrc[posSrc++];
43
}
44
}
45
},
46
bilinearInterpolation: function bilinearInterpolation(src, dst) {
47
var wSrc = src.width;
48
var hSrc = src.height;
49
var wDst = dst.width;
50
var hDst = dst.height;
51
var bufSrc = src.data;
52
var bufDst = dst.data;
53
54
var interpolate = function interpolate(k, kMin, vMin, kMax, vMax) {
55
// special case - k is integer
56
if (kMin === kMax) {
57
return vMin;
58
}
59
60
return Math.round((k - kMin) * vMax + (kMax - k) * vMin);
61
};
62
63
var assign = function assign(pos, offset, x, xMin, xMax, y, yMin, yMax) {
64
var posMin = (yMin * wSrc + xMin) * 4 + offset;
65
var posMax = (yMin * wSrc + xMax) * 4 + offset;
66
var vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]); // special case, y is integer
67
68
if (yMax === yMin) {
69
bufDst[pos + offset] = vMin;
70
} else {
71
posMin = (yMax * wSrc + xMin) * 4 + offset;
72
posMax = (yMax * wSrc + xMax) * 4 + offset;
73
var vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
74
bufDst[pos + offset] = interpolate(y, yMin, vMin, yMax, vMax);
75
}
76
};
77
78
for (var i = 0; i < hDst; i++) {
79
for (var j = 0; j < wDst; j++) {
80
var posDst = (i * wDst + j) * 4; // x & y in src coordinates
81
82
var x = j * wSrc / wDst;
83
var xMin = Math.floor(x);
84
var xMax = Math.min(Math.ceil(x), wSrc - 1);
85
var y = i * hSrc / hDst;
86
var yMin = Math.floor(y);
87
var yMax = Math.min(Math.ceil(y), hSrc - 1);
88
assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);
89
assign(posDst, 1, x, xMin, xMax, y, yMin, yMax);
90
assign(posDst, 2, x, xMin, xMax, y, yMin, yMax);
91
assign(posDst, 3, x, xMin, xMax, y, yMin, yMax);
92
}
93
}
94
},
95
_interpolate2D: function _interpolate2D(src, dst, options, interpolate) {
96
var bufSrc = src.data;
97
var bufDst = dst.data;
98
var wSrc = src.width;
99
var hSrc = src.height;
100
var wDst = dst.width;
101
var hDst = dst.height; // when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
102
103
var wM = Math.max(1, Math.floor(wSrc / wDst));
104
var wDst2 = wDst * wM;
105
var hM = Math.max(1, Math.floor(hSrc / hDst));
106
var hDst2 = hDst * hM; // ===========================================================
107
// Pass 1 - interpolate rows
108
// buf1 has width of dst2 and height of src
109
110
var buf1 = Buffer.alloc(wDst2 * hSrc * 4);
111
112
for (var i = 0; i < hSrc; i++) {
113
for (var j = 0; j < wDst2; j++) {
114
// i in src coords, j in dst coords
115
// calculate x in src coords
116
// this interpolation requires 4 sample points and the two inner ones must be real
117
// the outer points can be fudged for the edges.
118
// therefore (wSrc-1)/wDst2
119
var x = j * (wSrc - 1) / wDst2;
120
var xPos = Math.floor(x);
121
var t = x - xPos;
122
var srcPos = (i * wSrc + xPos) * 4;
123
var buf1Pos = (i * wDst2 + j) * 4;
124
125
for (var k = 0; k < 4; k++) {
126
var kPos = srcPos + k;
127
var x0 = xPos > 0 ? bufSrc[kPos - 4] : 2 * bufSrc[kPos] - bufSrc[kPos + 4];
128
var x1 = bufSrc[kPos];
129
var x2 = bufSrc[kPos + 4];
130
var x3 = xPos < wSrc - 2 ? bufSrc[kPos + 8] : 2 * bufSrc[kPos + 4] - bufSrc[kPos];
131
buf1[buf1Pos + k] = interpolate(x0, x1, x2, x3, t);
132
}
133
}
134
} // this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");
135
// ===========================================================
136
// Pass 2 - interpolate columns
137
// buf2 has width and height of dst2
138
139
140
var buf2 = Buffer.alloc(wDst2 * hDst2 * 4);
141
142
for (var _i = 0; _i < hDst2; _i++) {
143
for (var _j = 0; _j < wDst2; _j++) {
144
// i&j in dst2 coords
145
// calculate y in buf1 coords
146
// this interpolation requires 4 sample points and the two inner ones must be real
147
// the outer points can be fudged for the edges.
148
// therefore (hSrc-1)/hDst2
149
var y = _i * (hSrc - 1) / hDst2;
150
var yPos = Math.floor(y);
151
152
var _t = y - yPos;
153
154
var _buf1Pos = (yPos * wDst2 + _j) * 4;
155
156
var buf2Pos = (_i * wDst2 + _j) * 4;
157
158
for (var _k = 0; _k < 4; _k++) {
159
var _kPos = _buf1Pos + _k;
160
161
var y0 = yPos > 0 ? buf1[_kPos - wDst2 * 4] : 2 * buf1[_kPos] - buf1[_kPos + wDst2 * 4];
162
var y1 = buf1[_kPos];
163
var y2 = buf1[_kPos + wDst2 * 4];
164
var y3 = yPos < hSrc - 2 ? buf1[_kPos + wDst2 * 8] : 2 * buf1[_kPos + wDst2 * 4] - buf1[_kPos];
165
buf2[buf2Pos + _k] = interpolate(y0, y1, y2, y3, _t);
166
}
167
}
168
} // this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");
169
// ===========================================================
170
// Pass 3 - scale to dst
171
172
173
var m = wM * hM;
174
175
if (m > 1) {
176
for (var _i2 = 0; _i2 < hDst; _i2++) {
177
for (var _j2 = 0; _j2 < wDst; _j2++) {
178
// i&j in dst bounded coords
179
var r = 0;
180
var g = 0;
181
var b = 0;
182
var a = 0;
183
var realColors = 0;
184
185
for (var _y = 0; _y < hM; _y++) {
186
var _yPos = _i2 * hM + _y;
187
188
for (var _x = 0; _x < wM; _x++) {
189
var _xPos = _j2 * wM + _x;
190
191
var xyPos = (_yPos * wDst2 + _xPos) * 4;
192
var pixelAlpha = buf2[xyPos + 3];
193
194
if (pixelAlpha) {
195
r += buf2[xyPos];
196
g += buf2[xyPos + 1];
197
b += buf2[xyPos + 2];
198
realColors++;
199
}
200
201
a += pixelAlpha;
202
}
203
}
204
205
var pos = (_i2 * wDst + _j2) * 4;
206
bufDst[pos] = realColors ? Math.round(r / realColors) : 0;
207
bufDst[pos + 1] = realColors ? Math.round(g / realColors) : 0;
208
bufDst[pos + 2] = realColors ? Math.round(b / realColors) : 0;
209
bufDst[pos + 3] = Math.round(a / m);
210
}
211
}
212
} else {
213
// replace dst buffer with buf2
214
dst.data = buf2;
215
}
216
},
217
bicubicInterpolation: function bicubicInterpolation(src, dst, options) {
218
var interpolateCubic = function interpolateCubic(x0, x1, x2, x3, t) {
219
var a0 = x3 - x2 - x0 + x1;
220
var a1 = x0 - x1 - a0;
221
var a2 = x2 - x0;
222
var a3 = x1;
223
return Math.max(0, Math.min(255, a0 * (t * t * t) + a1 * (t * t) + a2 * t + a3));
224
};
225
226
return this._interpolate2D(src, dst, options, interpolateCubic);
227
},
228
hermiteInterpolation: function hermiteInterpolation(src, dst, options) {
229
var interpolateHermite = function interpolateHermite(x0, x1, x2, x3, t) {
230
var c0 = x1;
231
var c1 = 0.5 * (x2 - x0);
232
var c2 = x0 - 2.5 * x1 + 2 * x2 - 0.5 * x3;
233
var c3 = 0.5 * (x3 - x0) + 1.5 * (x1 - x2);
234
return Math.max(0, Math.min(255, Math.round(((c3 * t + c2) * t + c1) * t + c0)));
235
};
236
237
return this._interpolate2D(src, dst, options, interpolateHermite);
238
},
239
bezierInterpolation: function bezierInterpolation(src, dst, options) {
240
// between 2 points y(n), y(n+1), use next points out, y(n-1), y(n+2)
241
// to predict control points (a & b) to be placed at n+0.5
242
// ya(n) = y(n) + (y(n+1)-y(n-1))/4
243
// yb(n) = y(n+1) - (y(n+2)-y(n))/4
244
// then use std bezier to interpolate [n,n+1)
245
// y(n+t) = y(n)*(1-t)^3 + 3 * ya(n)*(1-t)^2*t + 3 * yb(n)*(1-t)*t^2 + y(n+1)*t^3
246
// note the 3* factor for the two control points
247
// for edge cases, can choose:
248
// y(-1) = y(0) - 2*(y(1)-y(0))
249
// y(w) = y(w-1) + 2*(y(w-1)-y(w-2))
250
// but can go with y(-1) = y(0) and y(w) = y(w-1)
251
var interpolateBezier = function interpolateBezier(x0, x1, x2, x3, t) {
252
// x1, x2 are the knots, use x0 and x3 to calculate control points
253
var cp1 = x1 + (x2 - x0) / 4;
254
var cp2 = x2 - (x3 - x1) / 4;
255
var nt = 1 - t;
256
var c0 = x1 * nt * nt * nt;
257
var c1 = 3 * cp1 * nt * nt * t;
258
var c2 = 3 * cp2 * nt * t * t;
259
var c3 = x2 * t * t * t;
260
return Math.max(0, Math.min(255, Math.round(c0 + c1 + c2 + c3)));
261
};
262
263
return this._interpolate2D(src, dst, options, interpolateBezier);
264
}
265
};
266
//# sourceMappingURL=resize2.js.map
267