211 lines
8.4 KiB
JavaScript
211 lines
8.4 KiB
JavaScript
/*
|
|
* FORBION
|
|
*
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
/* global L */
|
|
var cool;
|
|
(function (cool) {
|
|
var RawDelta = /** @class */ (function () {
|
|
function RawDelta(delta, id, isKeyframe) {
|
|
this._delta = delta;
|
|
this._id = id;
|
|
this._isKeyframe = isKeyframe;
|
|
}
|
|
Object.defineProperty(RawDelta.prototype, "length", {
|
|
get: function () {
|
|
return this.delta.length;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(RawDelta.prototype, "delta", {
|
|
get: function () {
|
|
return this._delta;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(RawDelta.prototype, "id", {
|
|
get: function () {
|
|
return this._id;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(RawDelta.prototype, "isKeyframe", {
|
|
get: function () {
|
|
return this._isKeyframe;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
return RawDelta;
|
|
}());
|
|
cool.RawDelta = RawDelta;
|
|
var CanvasTileUtils = /** @class */ (function () {
|
|
function CanvasTileUtils() {
|
|
}
|
|
CanvasTileUtils.unrle = function (data, width, height, output, outputOffset) {
|
|
if (outputOffset === void 0) { outputOffset = 0; }
|
|
// Byte bashing fun
|
|
var offset = 0;
|
|
for (var y = 0; y < height; ++y) {
|
|
var rleSize = data[offset] + data[offset + 1] * 256;
|
|
offset += 2;
|
|
var rleMask = offset;
|
|
var rleMaskSizeBytes = 256 / 8;
|
|
offset += rleMaskSizeBytes;
|
|
// It would be rather nice to have real 64bit types [!]
|
|
this.lastPixel.fill(0);
|
|
var lastMask = 0;
|
|
var bitToCheck = 256;
|
|
var rleMaskOffset = rleMask;
|
|
var pixOffset = y * width * 4 + outputOffset;
|
|
var pixSrc = offset;
|
|
for (var x = 0; x < width; ++x) {
|
|
if (bitToCheck > 128) {
|
|
bitToCheck = 1;
|
|
lastMask = data[rleMaskOffset++];
|
|
}
|
|
if (!(lastMask & bitToCheck)) {
|
|
// subarray has a significant overhead on Firefox
|
|
//this.lastPixel.set(data.subarray(pixSrc, pixSrc + 4));
|
|
this.lastPixel[0] = data[pixSrc];
|
|
this.lastPixel[1] = data[pixSrc + 1];
|
|
this.lastPixel[2] = data[pixSrc + 2];
|
|
this.lastPixel[3] = data[pixSrc + 3];
|
|
pixSrc += 4;
|
|
}
|
|
bitToCheck = bitToCheck << 1;
|
|
output.set(this.lastPixel, pixOffset);
|
|
pixOffset += 4;
|
|
}
|
|
offset += rleSize * 4;
|
|
}
|
|
return offset;
|
|
};
|
|
CanvasTileUtils.updateImageFromDeltas = function (imageData, deltas, keyframeDeltaSize, tileSize, debug) {
|
|
if (debug === void 0) { debug = false; }
|
|
var nDelta = 0;
|
|
var offset = keyframeDeltaSize;
|
|
while (offset < deltas.length) {
|
|
if (debug)
|
|
console.debug('Next delta at ' + offset + ' length ' + (deltas.length - offset));
|
|
var delta = !offset ? deltas : deltas.subarray(offset);
|
|
// Debugging paranoia: if we get this wrong bad things happen.
|
|
var susDeltaSize = tileSize * tileSize * 4;
|
|
if (debug && delta.length >= susDeltaSize) {
|
|
console.warn('Unusual delta possibly mis-tagged, suspicious size vs. type ' +
|
|
delta.length +
|
|
' vs. ' +
|
|
susDeltaSize);
|
|
}
|
|
// copy old data to work from:
|
|
var oldData = new Uint8Array(imageData);
|
|
if (debug)
|
|
console.debug('Applying delta chunk ' +
|
|
nDelta++ +
|
|
' of total size ' +
|
|
delta.length +
|
|
' at stream offset ' +
|
|
offset);
|
|
// + ' hex: ' + hex2string(delta, delta.length));
|
|
var len = this.applyDeltaChunk(imageData, delta, oldData, tileSize, tileSize, debug);
|
|
if (debug)
|
|
console.debug('Applied delta chunk of size ' + len);
|
|
offset += len;
|
|
}
|
|
};
|
|
CanvasTileUtils.applyDeltaChunk = function (imgData, delta, oldData, width, height, debug) {
|
|
if (debug === void 0) { debug = false; }
|
|
var pixSize = width * height * 4;
|
|
var offset = 0;
|
|
// Green-tinge the old-Data ...
|
|
if (0) {
|
|
for (var i_1 = 0; i_1 < pixSize; ++i_1)
|
|
oldData[i_1 * 4 + 1] = 128;
|
|
}
|
|
// wipe to grey.
|
|
if (0) {
|
|
for (var i_2 = 0; i_2 < pixSize * 4; ++i_2)
|
|
imgData[i_2] = 128;
|
|
}
|
|
// Apply delta.
|
|
var i = 0;
|
|
for (var stop_1 = false; i < delta.length && !stop_1;) {
|
|
switch (delta[i]) {
|
|
case 99: {
|
|
// 'c': // copy row
|
|
var count = delta[i + 1];
|
|
var srcRow = delta[i + 2];
|
|
var destRow = delta[i + 3];
|
|
if (debug)
|
|
console.debug('[' +
|
|
i +
|
|
']: copy ' +
|
|
count +
|
|
' row(s) ' +
|
|
srcRow +
|
|
' to ' +
|
|
destRow);
|
|
i += 4;
|
|
for (var cnt = 0; cnt < count; ++cnt) {
|
|
var src = (srcRow + cnt) * width * 4;
|
|
var dest = (destRow + cnt) * width * 4;
|
|
for (var j = 0; j < width * 4; ++j) {
|
|
imgData[dest + j] = oldData[src + j];
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 100: {
|
|
// 'd': // new run
|
|
var destRow = delta[i + 1];
|
|
var destCol = delta[i + 2];
|
|
var span = delta[i + 3];
|
|
offset = destRow * width * 4 + destCol * 4;
|
|
if (debug)
|
|
console.debug('[' +
|
|
i +
|
|
']: apply new span of size ' +
|
|
span +
|
|
' at pos ' +
|
|
destCol +
|
|
', ' +
|
|
destRow +
|
|
' into delta at byte: ' +
|
|
offset);
|
|
i += 4;
|
|
span *= 4;
|
|
for (var j = 0; j < span; ++j)
|
|
imgData[offset++] = delta[i + j];
|
|
i += span;
|
|
// imgData.data[offset - 2] = 256; // debug - blue terminator
|
|
break;
|
|
}
|
|
case 116: {
|
|
// 't': // terminate delta new one next
|
|
stop_1 = true;
|
|
i++;
|
|
break;
|
|
}
|
|
default: {
|
|
console.error('[' + i + ']: ERROR: Unknown delta code ' + delta[i]);
|
|
i = delta.length;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return i;
|
|
};
|
|
CanvasTileUtils.lastPixel = new Uint8Array(4);
|
|
return CanvasTileUtils;
|
|
}());
|
|
cool.CanvasTileUtils = CanvasTileUtils;
|
|
})(cool || (cool = {})); // namespace cool
|