├── README.md
├── flower.png
├── index.html
├── resize.js
└── resizeWorker.js
/README.md:
--------------------------------------------------------------------------------
1 | # JS-Image-Resizer
2 | A javascript based solution for image scaling outside of html5 canvas.
3 |
4 | ##Troubleshoot
5 | When running index.html on Chrome, only first picture loads, due to Uncaught SecurityError on line 14:
6 |
`Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.`
7 |
8 | **Solution**:
9 | + Running on a server instead (eg localhost)
10 |
11 |
--------------------------------------------------------------------------------
/flower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taisel/JS-Image-Resizer/d6bf3862951344ad75a026ea5d95afc9114f9421/flower.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Resize.js Demo
5 |
6 |
79 |
80 |
81 | Original Image:
82 |
83 |
84 | Downscaling With Context2d:
85 |
86 |
87 |
88 | Downscaling With Resize.js:
89 |
90 |
91 |
92 | Upscaling With Context2d:
93 |
94 |
95 | Upscaling With Resize.js:
96 |
97 |
98 | Upscaling With Resize.js (Crisp):
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/resize.js:
--------------------------------------------------------------------------------
1 | //JavaScript Image Resizer (c) 2012 - Grant Galitz
2 | var scripts = document.getElementsByTagName("script");
3 | var sourceOfWorker = scripts[scripts.length-1].src;
4 | function Resize(widthOriginal, heightOriginal, targetWidth, targetHeight, blendAlpha, interpolationPass, useWebWorker, resizeCallback) {
5 | this.widthOriginal = Math.abs(parseInt(widthOriginal) || 0);
6 | this.heightOriginal = Math.abs(parseInt(heightOriginal) || 0);
7 | this.targetWidth = Math.abs(parseInt(targetWidth) || 0);
8 | this.targetHeight = Math.abs(parseInt(targetHeight) || 0);
9 | this.colorChannels = (!!blendAlpha) ? 4 : 3;
10 | this.interpolationPass = !!interpolationPass;
11 | this.useWebWorker = !!useWebWorker;
12 | this.resizeCallback = (typeof resizeCallback == "function") ? resizeCallback : function (returnedArray) {};
13 | this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
14 | this.originalWidthMultipliedByChannels = this.widthOriginal * this.colorChannels;
15 | this.originalHeightMultipliedByChannels = this.heightOriginal * this.colorChannels;
16 | this.widthPassResultSize = this.targetWidthMultipliedByChannels * this.heightOriginal;
17 | this.finalResultSize = this.targetWidthMultipliedByChannels * this.targetHeight;
18 | this.initialize();
19 | }
20 | Resize.prototype.initialize = function () {
21 | //Perform some checks:
22 | if (this.widthOriginal > 0 && this.heightOriginal > 0 && this.targetWidth > 0 && this.targetHeight > 0) {
23 | if (this.useWebWorker) {
24 | this.useWebWorker = (this.widthOriginal != this.targetWidth || this.heightOriginal != this.targetHeight);
25 | if (this.useWebWorker) {
26 | this.configureWorker();
27 | }
28 | }
29 | if (!this.useWebWorker) {
30 | this.configurePasses();
31 | }
32 | }
33 | else {
34 | throw(new Error("Invalid settings specified for the resizer."));
35 | }
36 | }
37 | Resize.prototype.configureWorker = function () {
38 | try {
39 | var parentObj = this;
40 | this.worker = new Worker(sourceOfWorker.substring(0, sourceOfWorker.length - 3) + "Worker.js");
41 | this.worker.onmessage = function (event) {
42 | parentObj.heightBuffer = event.data;
43 | parentObj.resizeCallback(parentObj.heightBuffer);
44 | }
45 | this.worker.postMessage(["setup", this.widthOriginal, this.heightOriginal, this.targetWidth, this.targetHeight, this.colorChannels, this.interpolationPass]);
46 | }
47 | catch (error) {
48 | this.useWebWorker = false;
49 | }
50 | }
51 | Resize.prototype.configurePasses = function () {
52 | if (this.widthOriginal == this.targetWidth) {
53 | //Bypass the width resizer pass:
54 | this.resizeWidth = this.bypassResizer;
55 | }
56 | else {
57 | //Setup the width resizer pass:
58 | this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
59 | if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
60 | this.initializeFirstPassBuffers(true);
61 | this.resizeWidth = (this.colorChannels == 4) ? this.resizeWidthInterpolatedRGBA : this.resizeWidthInterpolatedRGB;
62 | }
63 | else {
64 | this.initializeFirstPassBuffers(false);
65 | this.resizeWidth = (this.colorChannels == 4) ? this.resizeWidthRGBA : this.resizeWidthRGB;
66 | }
67 | }
68 | if (this.heightOriginal == this.targetHeight) {
69 | //Bypass the height resizer pass:
70 | this.resizeHeight = this.bypassResizer;
71 | }
72 | else {
73 | //Setup the height resizer pass:
74 | this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
75 | if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
76 | this.initializeSecondPassBuffers(true);
77 | this.resizeHeight = this.resizeHeightInterpolated;
78 | }
79 | else {
80 | this.initializeSecondPassBuffers(false);
81 | this.resizeHeight = (this.colorChannels == 4) ? this.resizeHeightRGBA : this.resizeHeightRGB;
82 | }
83 | }
84 | }
85 | Resize.prototype.resizeWidthRGB = function (buffer) {
86 | var ratioWeight = this.ratioWeightWidthPass;
87 | var ratioWeightDivisor = 1 / ratioWeight;
88 | var weight = 0;
89 | var amountToNext = 0;
90 | var actualPosition = 0;
91 | var currentPosition = 0;
92 | var line = 0;
93 | var pixelOffset = 0;
94 | var outputOffset = 0;
95 | var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 2;
96 | var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 2;
97 | var output = this.outputWidthWorkBench;
98 | var outputBuffer = this.widthBuffer;
99 | do {
100 | for (line = 0; line < this.originalHeightMultipliedByChannels;) {
101 | output[line++] = 0;
102 | output[line++] = 0;
103 | output[line++] = 0;
104 | }
105 | weight = ratioWeight;
106 | do {
107 | amountToNext = 1 + actualPosition - currentPosition;
108 | if (weight >= amountToNext) {
109 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
110 | output[line++] += buffer[pixelOffset++] * amountToNext;
111 | output[line++] += buffer[pixelOffset++] * amountToNext;
112 | output[line++] += buffer[pixelOffset] * amountToNext;
113 | }
114 | currentPosition = actualPosition = actualPosition + 3;
115 | weight -= amountToNext;
116 | }
117 | else {
118 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
119 | output[line++] += buffer[pixelOffset++] * weight;
120 | output[line++] += buffer[pixelOffset++] * weight;
121 | output[line++] += buffer[pixelOffset] * weight;
122 | }
123 | currentPosition += weight;
124 | break;
125 | }
126 | } while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels);
127 | for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
128 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
129 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
130 | outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor;
131 | }
132 | outputOffset += 3;
133 | } while (outputOffset < this.targetWidthMultipliedByChannels);
134 | return outputBuffer;
135 | }
136 | Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
137 | var ratioWeight = this.ratioWeightWidthPass;
138 | var weight = 0;
139 | var finalOffset = 0;
140 | var pixelOffset = 0;
141 | var firstWeight = 0;
142 | var secondWeight = 0;
143 | var outputBuffer = this.widthBuffer;
144 | //Handle for only one interpolation input being valid for start calculation:
145 | for (var targetPosition = 0; weight < 1/3; targetPosition += 3, weight += ratioWeight) {
146 | for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
147 | outputBuffer[finalOffset] = buffer[pixelOffset];
148 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
149 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
150 | }
151 | }
152 | //Adjust for overshoot of the last pass's counter:
153 | weight -= 1/3;
154 | for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 3, weight += ratioWeight) {
155 | //Calculate weightings:
156 | secondWeight = weight % 1;
157 | firstWeight = 1 - secondWeight;
158 | //Interpolate:
159 | for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 3; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
160 | outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 3] * secondWeight);
161 | outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight);
162 | outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight);
163 | }
164 | }
165 | //Handle for only one interpolation input being valid for end calculation:
166 | for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - 3; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 3) {
167 | for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
168 | outputBuffer[finalOffset] = buffer[pixelOffset];
169 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
170 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
171 | }
172 | }
173 | return outputBuffer;
174 | }
175 | Resize.prototype.resizeWidthRGBA = function (buffer) {
176 | var ratioWeight = this.ratioWeightWidthPass;
177 | var ratioWeightDivisor = 1 / ratioWeight;
178 | var weight = 0;
179 | var amountToNext = 0;
180 | var actualPosition = 0;
181 | var currentPosition = 0;
182 | var line = 0;
183 | var pixelOffset = 0;
184 | var outputOffset = 0;
185 | var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 3;
186 | var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 3;
187 | var output = this.outputWidthWorkBench;
188 | var outputBuffer = this.widthBuffer;
189 | do {
190 | for (line = 0; line < this.originalHeightMultipliedByChannels;) {
191 | output[line++] = 0;
192 | output[line++] = 0;
193 | output[line++] = 0;
194 | output[line++] = 0;
195 | }
196 | weight = ratioWeight;
197 | do {
198 | amountToNext = 1 + actualPosition - currentPosition;
199 | if (weight >= amountToNext) {
200 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
201 | output[line++] += buffer[pixelOffset++] * amountToNext;
202 | output[line++] += buffer[pixelOffset++] * amountToNext;
203 | output[line++] += buffer[pixelOffset++] * amountToNext;
204 | output[line++] += buffer[pixelOffset] * amountToNext;
205 | }
206 | currentPosition = actualPosition = actualPosition + 4;
207 | weight -= amountToNext;
208 | }
209 | else {
210 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
211 | output[line++] += buffer[pixelOffset++] * weight;
212 | output[line++] += buffer[pixelOffset++] * weight;
213 | output[line++] += buffer[pixelOffset++] * weight;
214 | output[line++] += buffer[pixelOffset] * weight;
215 | }
216 | currentPosition += weight;
217 | break;
218 | }
219 | } while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels);
220 | for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
221 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
222 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
223 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
224 | outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor;
225 | }
226 | outputOffset += 4;
227 | } while (outputOffset < this.targetWidthMultipliedByChannels);
228 | return outputBuffer;
229 | }
230 | Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
231 | var ratioWeight = this.ratioWeightWidthPass;
232 | var weight = 0;
233 | var finalOffset = 0;
234 | var pixelOffset = 0;
235 | var firstWeight = 0;
236 | var secondWeight = 0;
237 | var outputBuffer = this.widthBuffer;
238 | //Handle for only one interpolation input being valid for start calculation:
239 | for (var targetPosition = 0; weight < 1/3; targetPosition += 4, weight += ratioWeight) {
240 | for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
241 | outputBuffer[finalOffset] = buffer[pixelOffset];
242 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
243 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
244 | outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
245 | }
246 | }
247 | //Adjust for overshoot of the last pass's counter:
248 | weight -= 1/3;
249 | for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 4, weight += ratioWeight) {
250 | //Calculate weightings:
251 | secondWeight = weight % 1;
252 | firstWeight = 1 - secondWeight;
253 | //Interpolate:
254 | for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 4; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
255 | outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight);
256 | outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight);
257 | outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 6] * secondWeight);
258 | outputBuffer[finalOffset + 3] = (buffer[pixelOffset + 3] * firstWeight) + (buffer[pixelOffset + 7] * secondWeight);
259 | }
260 | }
261 | //Handle for only one interpolation input being valid for end calculation:
262 | for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - 4; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 4) {
263 | for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
264 | outputBuffer[finalOffset] = buffer[pixelOffset];
265 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
266 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
267 | outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
268 | }
269 | }
270 | return outputBuffer;
271 | }
272 | Resize.prototype.resizeHeightRGB = function (buffer) {
273 | var ratioWeight = this.ratioWeightHeightPass;
274 | var ratioWeightDivisor = 1 / ratioWeight;
275 | var weight = 0;
276 | var amountToNext = 0;
277 | var actualPosition = 0;
278 | var currentPosition = 0;
279 | var pixelOffset = 0;
280 | var outputOffset = 0;
281 | var output = this.outputHeightWorkBench;
282 | var outputBuffer = this.heightBuffer;
283 | do {
284 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
285 | output[pixelOffset++] = 0;
286 | output[pixelOffset++] = 0;
287 | output[pixelOffset++] = 0;
288 | }
289 | weight = ratioWeight;
290 | do {
291 | amountToNext = 1 + actualPosition - currentPosition;
292 | if (weight >= amountToNext) {
293 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
294 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
295 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
296 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
297 | }
298 | currentPosition = actualPosition;
299 | weight -= amountToNext;
300 | }
301 | else {
302 | for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) {
303 | output[pixelOffset++] += buffer[amountToNext++] * weight;
304 | output[pixelOffset++] += buffer[amountToNext++] * weight;
305 | output[pixelOffset++] += buffer[amountToNext++] * weight;
306 | }
307 | currentPosition += weight;
308 | break;
309 | }
310 | } while (weight > 0 && actualPosition < this.widthPassResultSize);
311 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
312 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
313 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
314 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
315 | }
316 | } while (outputOffset < this.finalResultSize);
317 | return outputBuffer;
318 | }
319 | Resize.prototype.resizeHeightInterpolated = function (buffer) {
320 | var ratioWeight = this.ratioWeightHeightPass;
321 | var weight = 0;
322 | var finalOffset = 0;
323 | var pixelOffset = 0;
324 | var pixelOffsetAccumulated = 0;
325 | var pixelOffsetAccumulated2 = 0;
326 | var firstWeight = 0;
327 | var secondWeight = 0;
328 | var outputBuffer = this.heightBuffer;
329 | //Handle for only one interpolation input being valid for start calculation:
330 | for (; weight < 1/3; weight += ratioWeight) {
331 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
332 | outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
333 | }
334 | }
335 | //Adjust for overshoot of the last pass's counter:
336 | weight -= 1/3;
337 | for (var interpolationHeightSourceReadStop = this.heightOriginal - 1; weight < interpolationHeightSourceReadStop; weight += ratioWeight) {
338 | //Calculate weightings:
339 | secondWeight = weight % 1;
340 | firstWeight = 1 - secondWeight;
341 | //Interpolate:
342 | pixelOffsetAccumulated = Math.floor(weight) * this.targetWidthMultipliedByChannels;
343 | pixelOffsetAccumulated2 = pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
344 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
345 | outputBuffer[finalOffset++] = Math.round((buffer[pixelOffsetAccumulated++] * firstWeight) + (buffer[pixelOffsetAccumulated2++] * secondWeight));
346 | }
347 | }
348 | //Handle for only one interpolation input being valid for end calculation:
349 | while (finalOffset < this.finalResultSize) {
350 | for (pixelOffset = 0, pixelOffsetAccumulated = interpolationHeightSourceReadStop * this.targetWidthMultipliedByChannels; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
351 | outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++]);
352 | }
353 | }
354 | return outputBuffer;
355 | }
356 | Resize.prototype.resizeHeightRGBA = function (buffer) {
357 | var ratioWeight = this.ratioWeightHeightPass;
358 | var ratioWeightDivisor = 1 / ratioWeight;
359 | var weight = 0;
360 | var amountToNext = 0;
361 | var actualPosition = 0;
362 | var currentPosition = 0;
363 | var pixelOffset = 0;
364 | var outputOffset = 0;
365 | var output = this.outputHeightWorkBench;
366 | var outputBuffer = this.heightBuffer;
367 | do {
368 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
369 | output[pixelOffset++] = 0;
370 | output[pixelOffset++] = 0;
371 | output[pixelOffset++] = 0;
372 | output[pixelOffset++] = 0;
373 | }
374 | weight = ratioWeight;
375 | do {
376 | amountToNext = 1 + actualPosition - currentPosition;
377 | if (weight >= amountToNext) {
378 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
379 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
380 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
381 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
382 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
383 | }
384 | currentPosition = actualPosition;
385 | weight -= amountToNext;
386 | }
387 | else {
388 | for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) {
389 | output[pixelOffset++] += buffer[amountToNext++] * weight;
390 | output[pixelOffset++] += buffer[amountToNext++] * weight;
391 | output[pixelOffset++] += buffer[amountToNext++] * weight;
392 | output[pixelOffset++] += buffer[amountToNext++] * weight;
393 | }
394 | currentPosition += weight;
395 | break;
396 | }
397 | } while (weight > 0 && actualPosition < this.widthPassResultSize);
398 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
399 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
400 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
401 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
402 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
403 | }
404 | } while (outputOffset < this.finalResultSize);
405 | return outputBuffer;
406 | }
407 | Resize.prototype.resize = function (buffer) {
408 | if (this.useWebWorker) {
409 | this.worker.postMessage(["resize", buffer]);
410 | }
411 | else {
412 | this.resizeCallback(this.resizeHeight(this.resizeWidth(buffer)));
413 | }
414 | }
415 | Resize.prototype.bypassResizer = function (buffer) {
416 | //Just return the buffer passsed:
417 | return buffer;
418 | }
419 | Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
420 | //Initialize the internal width pass buffers:
421 | this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
422 | if (!BILINEARAlgo) {
423 | this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels);
424 | }
425 | }
426 | Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
427 | //Initialize the internal height pass buffers:
428 | this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
429 | if (!BILINEARAlgo) {
430 | this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels);
431 | }
432 | }
433 | Resize.prototype.generateFloatBuffer = function (bufferLength) {
434 | //Generate a float32 typed array buffer:
435 | try {
436 | return new Float32Array(bufferLength);
437 | }
438 | catch (error) {
439 | return [];
440 | }
441 | }
442 | Resize.prototype.generateUint8Buffer = function (bufferLength) {
443 | //Generate a uint8 typed array buffer:
444 | try {
445 | return new Uint8Array(bufferLength);
446 | }
447 | catch (error) {
448 | return [];
449 | }
450 | }
--------------------------------------------------------------------------------
/resizeWorker.js:
--------------------------------------------------------------------------------
1 | //JavaScript Image Resizer (c) 2012 - Grant Galitz
2 | var resizeWorker = null;
3 | self.onmessage = function (event) {
4 | switch (event.data[0]) {
5 | case "setup":
6 | resizeWorker = new Resize(event.data[1], event.data[2], event.data[3], event.data[4], event.data[5], event.data[6]);
7 | break;
8 | case "resize":
9 | resizeWorker.resize(event.data[1]);
10 | }
11 | }
12 | function Resize(widthOriginal, heightOriginal, targetWidth, targetHeight, colorChannels, interpolationPass) {
13 | this.widthOriginal = widthOriginal;
14 | this.heightOriginal = heightOriginal;
15 | this.targetWidth = targetWidth;
16 | this.targetHeight = targetHeight;
17 | this.colorChannels = colorChannels;
18 | this.interpolationPass = !!interpolationPass;
19 | this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
20 | this.originalWidthMultipliedByChannels = this.widthOriginal * this.colorChannels;
21 | this.originalHeightMultipliedByChannels = this.heightOriginal * this.colorChannels;
22 | this.widthPassResultSize = this.targetWidthMultipliedByChannels * this.heightOriginal;
23 | this.finalResultSize = this.targetWidthMultipliedByChannels * this.targetHeight;
24 | this.initialize();
25 | }
26 | Resize.prototype.initialize = function () {
27 | //Perform some checks:
28 | if (this.widthOriginal > 0 && this.heightOriginal > 0 && this.targetWidth > 0 && this.targetHeight > 0) {
29 | this.configurePasses();
30 | }
31 | else {
32 | throw(new Error("Invalid settings specified for the resizer."));
33 | }
34 | }
35 | Resize.prototype.configurePasses = function () {
36 | if (this.widthOriginal == this.targetWidth) {
37 | //Bypass the width resizer pass:
38 | this.resizeWidth = this.bypassResizer;
39 | }
40 | else {
41 | //Setup the width resizer pass:
42 | this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
43 | if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
44 | this.initializeFirstPassBuffers(true);
45 | this.resizeWidth = (this.colorChannels == 4) ? this.resizeWidthInterpolatedRGBA : this.resizeWidthInterpolatedRGB;
46 | }
47 | else {
48 | this.initializeFirstPassBuffers(false);
49 | this.resizeWidth = (this.colorChannels == 4) ? this.resizeWidthRGBA : this.resizeWidthRGB;
50 | }
51 | }
52 | if (this.heightOriginal == this.targetHeight) {
53 | //Bypass the height resizer pass:
54 | this.resizeHeight = this.bypassResizer;
55 | }
56 | else {
57 | //Setup the height resizer pass:
58 | this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
59 | if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
60 | this.initializeSecondPassBuffers(true);
61 | this.resizeHeight = this.resizeHeightInterpolated;
62 | }
63 | else {
64 | this.initializeSecondPassBuffers(false);
65 | this.resizeHeight = (this.colorChannels == 4) ? this.resizeHeightRGBA : this.resizeHeightRGB;
66 | }
67 | }
68 | }
69 | Resize.prototype.resizeWidthRGB = function (buffer) {
70 | var ratioWeight = this.ratioWeightWidthPass;
71 | var ratioWeightDivisor = 1 / ratioWeight;
72 | var weight = 0;
73 | var amountToNext = 0;
74 | var actualPosition = 0;
75 | var currentPosition = 0;
76 | var line = 0;
77 | var pixelOffset = 0;
78 | var outputOffset = 0;
79 | var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 2;
80 | var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 2;
81 | var output = this.outputWidthWorkBench;
82 | var outputBuffer = this.widthBuffer;
83 | do {
84 | for (line = 0; line < this.originalHeightMultipliedByChannels;) {
85 | output[line++] = 0;
86 | output[line++] = 0;
87 | output[line++] = 0;
88 | }
89 | weight = ratioWeight;
90 | do {
91 | amountToNext = 1 + actualPosition - currentPosition;
92 | if (weight >= amountToNext) {
93 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
94 | output[line++] += buffer[pixelOffset++] * amountToNext;
95 | output[line++] += buffer[pixelOffset++] * amountToNext;
96 | output[line++] += buffer[pixelOffset] * amountToNext;
97 | }
98 | currentPosition = actualPosition = actualPosition + 3;
99 | weight -= amountToNext;
100 | }
101 | else {
102 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
103 | output[line++] += buffer[pixelOffset++] * weight;
104 | output[line++] += buffer[pixelOffset++] * weight;
105 | output[line++] += buffer[pixelOffset] * weight;
106 | }
107 | currentPosition += weight;
108 | break;
109 | }
110 | } while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels);
111 | for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
112 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
113 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
114 | outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor;
115 | }
116 | outputOffset += 3;
117 | } while (outputOffset < this.targetWidthMultipliedByChannels);
118 | return outputBuffer;
119 | }
120 | Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
121 | var ratioWeight = this.ratioWeightWidthPass;
122 | var weight = 0;
123 | var finalOffset = 0;
124 | var pixelOffset = 0;
125 | var firstWeight = 0;
126 | var secondWeight = 0;
127 | var outputBuffer = this.widthBuffer;
128 | //Handle for only one interpolation input being valid for start calculation:
129 | for (var targetPosition = 0; weight < 1/3; targetPosition += 3, weight += ratioWeight) {
130 | for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
131 | outputBuffer[finalOffset] = buffer[pixelOffset];
132 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
133 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
134 | }
135 | }
136 | //Adjust for overshoot of the last pass's counter:
137 | weight -= 1/3;
138 | for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 3, weight += ratioWeight) {
139 | //Calculate weightings:
140 | secondWeight = weight % 1;
141 | firstWeight = 1 - secondWeight;
142 | //Interpolate:
143 | for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 3; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
144 | outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 3] * secondWeight);
145 | outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight);
146 | outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight);
147 | }
148 | }
149 | //Handle for only one interpolation input being valid for end calculation:
150 | for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - 3; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 3) {
151 | for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
152 | outputBuffer[finalOffset] = buffer[pixelOffset];
153 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
154 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
155 | }
156 | }
157 | return outputBuffer;
158 | }
159 | Resize.prototype.resizeWidthRGBA = function (buffer) {
160 | var ratioWeight = this.ratioWeightWidthPass;
161 | var ratioWeightDivisor = 1 / ratioWeight;
162 | var weight = 0;
163 | var amountToNext = 0;
164 | var actualPosition = 0;
165 | var currentPosition = 0;
166 | var line = 0;
167 | var pixelOffset = 0;
168 | var outputOffset = 0;
169 | var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 3;
170 | var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 3;
171 | var output = this.outputWidthWorkBench;
172 | var outputBuffer = this.widthBuffer;
173 | do {
174 | for (line = 0; line < this.originalHeightMultipliedByChannels;) {
175 | output[line++] = 0;
176 | output[line++] = 0;
177 | output[line++] = 0;
178 | output[line++] = 0;
179 | }
180 | weight = ratioWeight;
181 | do {
182 | amountToNext = 1 + actualPosition - currentPosition;
183 | if (weight >= amountToNext) {
184 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
185 | output[line++] += buffer[pixelOffset++] * amountToNext;
186 | output[line++] += buffer[pixelOffset++] * amountToNext;
187 | output[line++] += buffer[pixelOffset++] * amountToNext;
188 | output[line++] += buffer[pixelOffset] * amountToNext;
189 | }
190 | currentPosition = actualPosition = actualPosition + 4;
191 | weight -= amountToNext;
192 | }
193 | else {
194 | for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
195 | output[line++] += buffer[pixelOffset++] * weight;
196 | output[line++] += buffer[pixelOffset++] * weight;
197 | output[line++] += buffer[pixelOffset++] * weight;
198 | output[line++] += buffer[pixelOffset] * weight;
199 | }
200 | currentPosition += weight;
201 | break;
202 | }
203 | } while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels);
204 | for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
205 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
206 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
207 | outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor;
208 | outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor;
209 | }
210 | outputOffset += 4;
211 | } while (outputOffset < this.targetWidthMultipliedByChannels);
212 | return outputBuffer;
213 | }
214 | Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
215 | var ratioWeight = this.ratioWeightWidthPass;
216 | var weight = 0;
217 | var finalOffset = 0;
218 | var pixelOffset = 0;
219 | var firstWeight = 0;
220 | var secondWeight = 0;
221 | var outputBuffer = this.widthBuffer;
222 | //Handle for only one interpolation input being valid for start calculation:
223 | for (var targetPosition = 0; weight < 1/3; targetPosition += 4, weight += ratioWeight) {
224 | for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
225 | outputBuffer[finalOffset] = buffer[pixelOffset];
226 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
227 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
228 | outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
229 | }
230 | }
231 | //Adjust for overshoot of the last pass's counter:
232 | weight -= 1/3;
233 | for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 4, weight += ratioWeight) {
234 | //Calculate weightings:
235 | secondWeight = weight % 1;
236 | firstWeight = 1 - secondWeight;
237 | //Interpolate:
238 | for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 4; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
239 | outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight);
240 | outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight);
241 | outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 6] * secondWeight);
242 | outputBuffer[finalOffset + 3] = (buffer[pixelOffset + 3] * firstWeight) + (buffer[pixelOffset + 7] * secondWeight);
243 | }
244 | }
245 | //Handle for only one interpolation input being valid for end calculation:
246 | for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - 4; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 4) {
247 | for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) {
248 | outputBuffer[finalOffset] = buffer[pixelOffset];
249 | outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
250 | outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
251 | outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
252 | }
253 | }
254 | return outputBuffer;
255 | }
256 | Resize.prototype.resizeHeightRGB = function (buffer) {
257 | var ratioWeight = this.ratioWeightHeightPass;
258 | var ratioWeightDivisor = 1 / ratioWeight;
259 | var weight = 0;
260 | var amountToNext = 0;
261 | var actualPosition = 0;
262 | var currentPosition = 0;
263 | var pixelOffset = 0;
264 | var outputOffset = 0;
265 | var output = this.outputHeightWorkBench;
266 | var outputBuffer = this.heightBuffer;
267 | do {
268 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
269 | output[pixelOffset++] = 0;
270 | output[pixelOffset++] = 0;
271 | output[pixelOffset++] = 0;
272 | }
273 | weight = ratioWeight;
274 | do {
275 | amountToNext = 1 + actualPosition - currentPosition;
276 | if (weight >= amountToNext) {
277 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
278 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
279 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
280 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
281 | }
282 | currentPosition = actualPosition;
283 | weight -= amountToNext;
284 | }
285 | else {
286 | for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) {
287 | output[pixelOffset++] += buffer[amountToNext++] * weight;
288 | output[pixelOffset++] += buffer[amountToNext++] * weight;
289 | output[pixelOffset++] += buffer[amountToNext++] * weight;
290 | }
291 | currentPosition += weight;
292 | break;
293 | }
294 | } while (weight > 0 && actualPosition < this.widthPassResultSize);
295 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
296 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
297 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
298 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
299 | }
300 | } while (outputOffset < this.finalResultSize);
301 | return outputBuffer;
302 | }
303 | Resize.prototype.resizeHeightInterpolated = function (buffer) {
304 | var ratioWeight = this.ratioWeightHeightPass;
305 | var weight = 0;
306 | var finalOffset = 0;
307 | var pixelOffset = 0;
308 | var pixelOffsetAccumulated = 0;
309 | var pixelOffsetAccumulated2 = 0;
310 | var firstWeight = 0;
311 | var secondWeight = 0;
312 | var outputBuffer = this.heightBuffer;
313 | //Handle for only one interpolation input being valid for start calculation:
314 | for (; weight < 1/3; weight += ratioWeight) {
315 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
316 | outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
317 | }
318 | }
319 | //Adjust for overshoot of the last pass's counter:
320 | weight -= 1/3;
321 | for (var interpolationHeightSourceReadStop = this.heightOriginal - 1; weight < interpolationHeightSourceReadStop; weight += ratioWeight) {
322 | //Calculate weightings:
323 | secondWeight = weight % 1;
324 | firstWeight = 1 - secondWeight;
325 | //Interpolate:
326 | pixelOffsetAccumulated = Math.floor(weight) * this.targetWidthMultipliedByChannels;
327 | pixelOffsetAccumulated2 = pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
328 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
329 | outputBuffer[finalOffset++] = Math.round((buffer[pixelOffsetAccumulated++] * firstWeight) + (buffer[pixelOffsetAccumulated2++] * secondWeight));
330 | }
331 | }
332 | //Handle for only one interpolation input being valid for end calculation:
333 | while (finalOffset < this.finalResultSize) {
334 | for (pixelOffset = 0, pixelOffsetAccumulated = interpolationHeightSourceReadStop * this.targetWidthMultipliedByChannels; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
335 | outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++]);
336 | }
337 | }
338 | return outputBuffer;
339 | }
340 | Resize.prototype.resizeHeightRGBA = function (buffer) {
341 | var ratioWeight = this.ratioWeightHeightPass;
342 | var ratioWeightDivisor = 1 / ratioWeight;
343 | var weight = 0;
344 | var amountToNext = 0;
345 | var actualPosition = 0;
346 | var currentPosition = 0;
347 | var pixelOffset = 0;
348 | var outputOffset = 0;
349 | var output = this.outputHeightWorkBench;
350 | var outputBuffer = this.heightBuffer;
351 | do {
352 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
353 | output[pixelOffset++] = 0;
354 | output[pixelOffset++] = 0;
355 | output[pixelOffset++] = 0;
356 | output[pixelOffset++] = 0;
357 | }
358 | weight = ratioWeight;
359 | do {
360 | amountToNext = 1 + actualPosition - currentPosition;
361 | if (weight >= amountToNext) {
362 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
363 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
364 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
365 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
366 | output[pixelOffset++] += buffer[actualPosition++] * amountToNext;
367 | }
368 | currentPosition = actualPosition;
369 | weight -= amountToNext;
370 | }
371 | else {
372 | for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) {
373 | output[pixelOffset++] += buffer[amountToNext++] * weight;
374 | output[pixelOffset++] += buffer[amountToNext++] * weight;
375 | output[pixelOffset++] += buffer[amountToNext++] * weight;
376 | output[pixelOffset++] += buffer[amountToNext++] * weight;
377 | }
378 | currentPosition += weight;
379 | break;
380 | }
381 | } while (weight > 0 && actualPosition < this.widthPassResultSize);
382 | for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
383 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
384 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
385 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
386 | outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
387 | }
388 | } while (outputOffset < this.finalResultSize);
389 | return outputBuffer;
390 | }
391 | Resize.prototype.resize = function (buffer) {
392 | self.postMessage(this.resizeHeight(this.resizeWidth(buffer)));
393 | }
394 | Resize.prototype.bypassResizer = function (buffer) {
395 | //Just return the buffer passsed:
396 | return buffer;
397 | }
398 | Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
399 | //Initialize the internal width pass buffers:
400 | this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
401 | if (!BILINEARAlgo) {
402 | this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels);
403 | }
404 | }
405 | Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
406 | //Initialize the internal height pass buffers:
407 | this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
408 | if (!BILINEARAlgo) {
409 | this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels);
410 | }
411 | }
412 | Resize.prototype.generateFloatBuffer = function (bufferLength) {
413 | //Generate a float32 typed array buffer:
414 | try {
415 | return new Float32Array(bufferLength);
416 | }
417 | catch (error) {
418 | return [];
419 | }
420 | }
421 | Resize.prototype.generateUint8Buffer = function (bufferLength) {
422 | //Generate a uint8 typed array buffer:
423 | try {
424 | return new Uint8Array(bufferLength);
425 | }
426 | catch (error) {
427 | return [];
428 | }
429 | }
--------------------------------------------------------------------------------