UNPKG

matrix-react-sdk

Version:
100 lines (96 loc) 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.blobIsAnimated = blobIsAnimated; exports.mayBeAnimated = mayBeAnimated; var _arrays = require("./arrays"); /* * Copyright 2024 New Vector Ltd. * Copyright 2022 The Matrix.org Foundation C.I.C. * * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only * Please see LICENSE files in the repository root for full details. */ function mayBeAnimated(mimeType) { // AVIF animation support at the time of writing is only available in Chrome hence not having `blobIsAnimated` check return ["image/gif", "image/webp", "image/png", "image/apng", "image/avif"].includes(mimeType); } function arrayBufferRead(arr, start, len) { return new Uint8Array(arr.slice(start, start + len)); } function arrayBufferReadInt(arr, start) { const dv = new DataView(arr, start, 4); return dv.getUint32(0); } function arrayBufferReadStr(arr, start, len) { return String.fromCharCode.apply(null, Array.from(arrayBufferRead(arr, start, len))); } async function blobIsAnimated(mimeType, blob) { switch (mimeType) { case "image/webp": { // Only extended file format WEBP images support animation, so grab the expected data range and verify header. // Based on https://developers.google.com/speed/webp/docs/riff_container#extended_file_format const arr = await blob.slice(0, 17).arrayBuffer(); if (arrayBufferReadStr(arr, 0, 4) === "RIFF" && arrayBufferReadStr(arr, 8, 4) === "WEBP" && arrayBufferReadStr(arr, 12, 4) === "VP8X") { const [flags] = arrayBufferRead(arr, 16, 1); // Flags: R R I L E X _A_ R (reversed) const animationFlagMask = 1 << 1; return (flags & animationFlagMask) != 0; } break; } case "image/gif": { // Based on https://gist.github.com/zakirt/faa4a58cec5a7505b10e3686a226f285 // More info at http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp const dv = new DataView(await blob.arrayBuffer(), 10); const globalColorTable = dv.getUint8(0); let globalColorTableSize = 0; // check first bit, if 0, then we don't have a Global Color Table if (globalColorTable & 0x80) { // grab the last 3 bits, to calculate the global color table size -> RGB * 2^(N+1) // N is the value in the last 3 bits. globalColorTableSize = 3 * Math.pow(2, (globalColorTable & 0x7) + 1); } // move on to the Graphics Control Extension const offset = 3 + globalColorTableSize; const extensionIntroducer = dv.getUint8(offset); const graphicsControlLabel = dv.getUint8(offset + 1); let delayTime = 0; // Graphics Control Extension section is where GIF animation data is stored // First 2 bytes must be 0x21 and 0xF9 if (extensionIntroducer & 0x21 && graphicsControlLabel & 0xf9) { // skip to the 2 bytes with the delay time delayTime = dv.getUint16(offset + 4); } return !!delayTime; } case "image/png": case "image/apng": { // Based on https://stackoverflow.com/a/68618296 const arr = await blob.arrayBuffer(); if ((0, _arrays.arrayHasDiff)([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], Array.from(arrayBufferRead(arr, 0, 8)))) { return false; } for (let i = 8; i < blob.size;) { const length = arrayBufferReadInt(arr, i); i += 4; const type = arrayBufferReadStr(arr, i, 4); i += 4; switch (type) { case "acTL": return true; case "IDAT": return false; } i += length + 4; } break; } } return false; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYXJyYXlzIiwicmVxdWlyZSIsIm1heUJlQW5pbWF0ZWQiLCJtaW1lVHlwZSIsImluY2x1ZGVzIiwiYXJyYXlCdWZmZXJSZWFkIiwiYXJyIiwic3RhcnQiLCJsZW4iLCJVaW50OEFycmF5Iiwic2xpY2UiLCJhcnJheUJ1ZmZlclJlYWRJbnQiLCJkdiIsIkRhdGFWaWV3IiwiZ2V0VWludDMyIiwiYXJyYXlCdWZmZXJSZWFkU3RyIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiYXBwbHkiLCJBcnJheSIsImZyb20iLCJibG9iSXNBbmltYXRlZCIsImJsb2IiLCJhcnJheUJ1ZmZlciIsImZsYWdzIiwiYW5pbWF0aW9uRmxhZ01hc2siLCJnbG9iYWxDb2xvclRhYmxlIiwiZ2V0VWludDgiLCJnbG9iYWxDb2xvclRhYmxlU2l6ZSIsIk1hdGgiLCJwb3ciLCJvZmZzZXQiLCJleHRlbnNpb25JbnRyb2R1Y2VyIiwiZ3JhcGhpY3NDb250cm9sTGFiZWwiLCJkZWxheVRpbWUiLCJnZXRVaW50MTYiLCJhcnJheUhhc0RpZmYiLCJpIiwic2l6ZSIsImxlbmd0aCIsInR5cGUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvSW1hZ2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuICogQ29weXJpZ2h0IDIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcbiAqIFBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4gKi9cblxuaW1wb3J0IHsgYXJyYXlIYXNEaWZmIH0gZnJvbSBcIi4vYXJyYXlzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXlCZUFuaW1hdGVkKG1pbWVUeXBlPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gQVZJRiBhbmltYXRpb24gc3VwcG9ydCBhdCB0aGUgdGltZSBvZiB3cml0aW5nIGlzIG9ubHkgYXZhaWxhYmxlIGluIENocm9tZSBoZW5jZSBub3QgaGF2aW5nIGBibG9iSXNBbmltYXRlZGAgY2hlY2tcbiAgICByZXR1cm4gW1wiaW1hZ2UvZ2lmXCIsIFwiaW1hZ2Uvd2VicFwiLCBcImltYWdlL3BuZ1wiLCBcImltYWdlL2FwbmdcIiwgXCJpbWFnZS9hdmlmXCJdLmluY2x1ZGVzKG1pbWVUeXBlISk7XG59XG5cbmZ1bmN0aW9uIGFycmF5QnVmZmVyUmVhZChhcnI6IEFycmF5QnVmZmVyLCBzdGFydDogbnVtYmVyLCBsZW46IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShhcnIuc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgbGVuKSk7XG59XG5cbmZ1bmN0aW9uIGFycmF5QnVmZmVyUmVhZEludChhcnI6IEFycmF5QnVmZmVyLCBzdGFydDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBkdiA9IG5ldyBEYXRhVmlldyhhcnIsIHN0YXJ0LCA0KTtcbiAgICByZXR1cm4gZHYuZ2V0VWludDMyKDApO1xufVxuXG5mdW5jdGlvbiBhcnJheUJ1ZmZlclJlYWRTdHIoYXJyOiBBcnJheUJ1ZmZlciwgc3RhcnQ6IG51bWJlciwgbGVuOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIEFycmF5LmZyb20oYXJyYXlCdWZmZXJSZWFkKGFyciwgc3RhcnQsIGxlbikpKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJsb2JJc0FuaW1hdGVkKG1pbWVUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQsIGJsb2I6IEJsb2IpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBzd2l0Y2ggKG1pbWVUeXBlKSB7XG4gICAgICAgIGNhc2UgXCJpbWFnZS93ZWJwXCI6IHtcbiAgICAgICAgICAgIC8vIE9ubHkgZXh0ZW5kZWQgZmlsZSBmb3JtYXQgV0VCUCBpbWFnZXMgc3VwcG9ydCBhbmltYXRpb24sIHNvIGdyYWIgdGhlIGV4cGVjdGVkIGRhdGEgcmFuZ2UgYW5kIHZlcmlmeSBoZWFkZXIuXG4gICAgICAgICAgICAvLyBCYXNlZCBvbiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9zcGVlZC93ZWJwL2RvY3MvcmlmZl9jb250YWluZXIjZXh0ZW5kZWRfZmlsZV9mb3JtYXRcbiAgICAgICAgICAgIGNvbnN0IGFyciA9IGF3YWl0IGJsb2Iuc2xpY2UoMCwgMTcpLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgYXJyYXlCdWZmZXJSZWFkU3RyKGFyciwgMCwgNCkgPT09IFwiUklGRlwiICYmXG4gICAgICAgICAgICAgICAgYXJyYXlCdWZmZXJSZWFkU3RyKGFyciwgOCwgNCkgPT09IFwiV0VCUFwiICYmXG4gICAgICAgICAgICAgICAgYXJyYXlCdWZmZXJSZWFkU3RyKGFyciwgMTIsIDQpID09PSBcIlZQOFhcIlxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgW2ZsYWdzXSA9IGFycmF5QnVmZmVyUmVhZChhcnIsIDE2LCAxKTtcbiAgICAgICAgICAgICAgICAvLyBGbGFnczogUiBSIEkgTCBFIFggX0FfIFIgKHJldmVyc2VkKVxuICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbkZsYWdNYXNrID0gMSA8PCAxO1xuICAgICAgICAgICAgICAgIHJldHVybiAoZmxhZ3MgJiBhbmltYXRpb25GbGFnTWFzaykgIT0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcImltYWdlL2dpZlwiOiB7XG4gICAgICAgICAgICAvLyBCYXNlZCBvbiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS96YWtpcnQvZmFhNGE1OGNlYzVhNzUwNWIxMGUzNjg2YTIyNmYyODVcbiAgICAgICAgICAgIC8vIE1vcmUgaW5mbyBhdCBodHRwOi8vd3d3Lm1hdHRoZXdmbGlja2luZ2VyLmNvbS9sYWIvd2hhdHNpbmFnaWYvYml0c19hbmRfYnl0ZXMuYXNwXG4gICAgICAgICAgICBjb25zdCBkdiA9IG5ldyBEYXRhVmlldyhhd2FpdCBibG9iLmFycmF5QnVmZmVyKCksIDEwKTtcblxuICAgICAgICAgICAgY29uc3QgZ2xvYmFsQ29sb3JUYWJsZSA9IGR2LmdldFVpbnQ4KDApO1xuICAgICAgICAgICAgbGV0IGdsb2JhbENvbG9yVGFibGVTaXplID0gMDtcbiAgICAgICAgICAgIC8vIGNoZWNrIGZpcnN0IGJpdCwgaWYgMCwgdGhlbiB3ZSBkb24ndCBoYXZlIGEgR2xvYmFsIENvbG9yIFRhYmxlXG4gICAgICAgICAgICBpZiAoZ2xvYmFsQ29sb3JUYWJsZSAmIDB4ODApIHtcbiAgICAgICAgICAgICAgICAvLyBncmFiIHRoZSBsYXN0IDMgYml0cywgdG8gY2FsY3VsYXRlIHRoZSBnbG9iYWwgY29sb3IgdGFibGUgc2l6ZSAtPiBSR0IgKiAyXihOKzEpXG4gICAgICAgICAgICAgICAgLy8gTiBpcyB0aGUgdmFsdWUgaW4gdGhlIGxhc3QgMyBiaXRzLlxuICAgICAgICAgICAgICAgIGdsb2JhbENvbG9yVGFibGVTaXplID0gMyAqIE1hdGgucG93KDIsIChnbG9iYWxDb2xvclRhYmxlICYgMHg3KSArIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBtb3ZlIG9uIHRvIHRoZSBHcmFwaGljcyBDb250cm9sIEV4dGVuc2lvblxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gMyArIGdsb2JhbENvbG9yVGFibGVTaXplO1xuXG4gICAgICAgICAgICBjb25zdCBleHRlbnNpb25JbnRyb2R1Y2VyID0gZHYuZ2V0VWludDgob2Zmc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IGdyYXBoaWNzQ29udHJvbExhYmVsID0gZHYuZ2V0VWludDgob2Zmc2V0ICsgMSk7XG4gICAgICAgICAgICBsZXQgZGVsYXlUaW1lID0gMDtcblxuICAgICAgICAgICAgLy8gR3JhcGhpY3MgQ29udHJvbCBFeHRlbnNpb24gc2VjdGlvbiBpcyB3aGVyZSBHSUYgYW5pbWF0aW9uIGRhdGEgaXMgc3RvcmVkXG4gICAgICAgICAgICAvLyBGaXJzdCAyIGJ5dGVzIG11c3QgYmUgMHgyMSBhbmQgMHhGOVxuICAgICAgICAgICAgaWYgKGV4dGVuc2lvbkludHJvZHVjZXIgJiAweDIxICYmIGdyYXBoaWNzQ29udHJvbExhYmVsICYgMHhmOSkge1xuICAgICAgICAgICAgICAgIC8vIHNraXAgdG8gdGhlIDIgYnl0ZXMgd2l0aCB0aGUgZGVsYXkgdGltZVxuICAgICAgICAgICAgICAgIGRlbGF5VGltZSA9IGR2LmdldFVpbnQxNihvZmZzZXQgKyA0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuICEhZGVsYXlUaW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcImltYWdlL3BuZ1wiOlxuICAgICAgICBjYXNlIFwiaW1hZ2UvYXBuZ1wiOiB7XG4gICAgICAgICAgICAvLyBCYXNlZCBvbiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNjg2MTgyOTZcbiAgICAgICAgICAgIGNvbnN0IGFyciA9IGF3YWl0IGJsb2IuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBhcnJheUhhc0RpZmYoWzB4ODksIDB4NTAsIDB4NGUsIDB4NDcsIDB4MGQsIDB4MGEsIDB4MWEsIDB4MGFdLCBBcnJheS5mcm9tKGFycmF5QnVmZmVyUmVhZChhcnIsIDAsIDgpKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDg7IGkgPCBibG9iLnNpemU7ICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGFycmF5QnVmZmVyUmVhZEludChhcnIsIGkpO1xuICAgICAgICAgICAgICAgIGkgKz0gNDtcbiAgICAgICAgICAgICAgICBjb25zdCB0eXBlID0gYXJyYXlCdWZmZXJSZWFkU3RyKGFyciwgaSwgNCk7XG4gICAgICAgICAgICAgICAgaSArPSA0O1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJhY1RMXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIklEQVRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaSArPSBsZW5ndGggKyA0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFRQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFJTyxTQUFTQyxhQUFhQSxDQUFDQyxRQUFpQixFQUFXO0VBQ3REO0VBQ0EsT0FBTyxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQ0MsUUFBUSxDQUFDRCxRQUFTLENBQUM7QUFDbkc7QUFFQSxTQUFTRSxlQUFlQSxDQUFDQyxHQUFnQixFQUFFQyxLQUFhLEVBQUVDLEdBQVcsRUFBYztFQUMvRSxPQUFPLElBQUlDLFVBQVUsQ0FBQ0gsR0FBRyxDQUFDSSxLQUFLLENBQUNILEtBQUssRUFBRUEsS0FBSyxHQUFHQyxHQUFHLENBQUMsQ0FBQztBQUN4RDtBQUVBLFNBQVNHLGtCQUFrQkEsQ0FBQ0wsR0FBZ0IsRUFBRUMsS0FBYSxFQUFVO0VBQ2pFLE1BQU1LLEVBQUUsR0FBRyxJQUFJQyxRQUFRLENBQUNQLEdBQUcsRUFBRUMsS0FBSyxF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