/* * 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