diff --git a/src/global/helpers/messages.ts b/src/global/helpers/messages.ts index 844813856..9b84f6ee8 100644 --- a/src/global/helpers/messages.ts +++ b/src/global/helpers/messages.ts @@ -11,7 +11,7 @@ import { } from '../../config'; import { areSortedArraysIntersecting, unique } from '../../util/iteratees'; import { getServerTime } from '../../util/serverTime'; -import { IS_OPUS_SUPPORTED, isWebpSupported } from '../../util/windowEnvironment'; +import { IS_OPUS_SUPPORTED } from '../../util/windowEnvironment'; import { getGlobal } from '../index'; import { getChatTitle, isUserId } from './chats'; import { getUserFullName } from './users'; @@ -227,8 +227,7 @@ export function getMessageContentFilename(message: ApiMessage) { } if (content.sticker) { - const extension = content.sticker.isLottie ? 'tgs' : content.sticker.isVideo - ? 'webm' : isWebpSupported() ? 'webp' : 'png'; + const extension = content.sticker.isLottie ? 'tgs' : content.sticker.isVideo ? 'webm' : 'webp'; return `${content.sticker.id}.${extension}`; } diff --git a/src/hooks/useThumbnail.ts b/src/hooks/useThumbnail.ts index 3a8a3e962..54fc0887f 100644 --- a/src/hooks/useThumbnail.ts +++ b/src/hooks/useThumbnail.ts @@ -1,46 +1,24 @@ -import { useLayoutEffect, useMemo, useState } from '../lib/teact/teact'; +import { useMemo } from '../lib/teact/teact'; import { getGlobal } from '../global'; import type { ApiMessage, ApiSticker } from '../api/types'; -import { DEBUG } from '../config'; import { getMessageMediaThumbDataUri } from '../global/helpers'; import { selectTheme } from '../global/selectors'; -import { EMPTY_IMAGE_DATA_URI, webpToPngBase64 } from '../util/webpToPng'; -import { isWebpSupported } from '../util/windowEnvironment'; export default function useThumbnail(media?: ApiMessage | ApiSticker) { const isMessage = media && 'content' in media; const thumbDataUri = isMessage ? getMessageMediaThumbDataUri(media) : media?.thumbnail?.dataUri; - const sticker = isMessage ? media.content?.sticker : media; - const shouldDecodeThumbnail = thumbDataUri && sticker && !isWebpSupported() && thumbDataUri.includes('image/webp'); - const [thumbnailDecoded, setThumbnailDecoded] = useState(EMPTY_IMAGE_DATA_URI); - const id = media?.id; - - useLayoutEffect(() => { - if (!shouldDecodeThumbnail) { - return; - } - - webpToPngBase64(`b64-${id}`, thumbDataUri!) - .then(setThumbnailDecoded) - .catch((err) => { - if (DEBUG) { - // eslint-disable-next-line no-console - console.error(err); - } - }); - }, [id, shouldDecodeThumbnail, thumbDataUri]); // TODO Find a way to update thumbnail on theme change const theme = selectTheme(getGlobal()); const dataUri = useMemo(() => { - const uri = shouldDecodeThumbnail ? thumbnailDecoded : thumbDataUri; + const uri = thumbDataUri; if (!uri || theme !== 'dark') return uri; return uri.replace('1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for getValue: "+type)}return null}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":157,"maximum":157+0,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var DYNAMIC_BASE=5259680,DYNAMICTOP_PTR=16640;var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":2147483648/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="webp_wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}__ATINIT__.push({func:function(){___wasm_call_ctors()}});function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),PAGE_MULTIPLE));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var asmLibraryArg={"a":___assert_fail,"b":_emscripten_memcpy_big,"c":_emscripten_resize_heap,"memory":wasmMemory,"table":wasmTable};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["d"]).apply(null,arguments)};var _version=Module["_version"]=function(){return(_version=Module["_version"]=Module["asm"]["e"]).apply(null,arguments)};var _getInfo=Module["_getInfo"]=function(){return(_getInfo=Module["_getInfo"]=Module["asm"]["f"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["g"]).apply(null,arguments)};var _decode=Module["_decode"]=function(){return(_decode=Module["_decode"]=Module["asm"]["h"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["i"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["j"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["k"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["l"]).apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return(dynCall_vi=Module["dynCall_vi"]=Module["asm"]["m"]).apply(null,arguments)};Module["cwrap"]=cwrap;Module["getValue"]=getValue;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); diff --git a/src/lib/webp/webp_wasm.wasm b/src/lib/webp/webp_wasm.wasm deleted file mode 100644 index 33380c37d..000000000 Binary files a/src/lib/webp/webp_wasm.wasm and /dev/null differ diff --git a/src/lib/webp/webp_wasm.worker.js b/src/lib/webp/webp_wasm.worker.js deleted file mode 100644 index f8ec9cd71..000000000 --- a/src/lib/webp/webp_wasm.worker.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable */ -importScripts(new URL('./webp_wasm.js', import.meta.url)); - -Module.onRuntimeInitialized = async () => { - self.postMessage({ type: 'initialized' }); -}; - -self.onmessage = (event) => { - const { id, blob } = event.data; - const reader = new FileReader(); - - reader.addEventListener('loadend', () => { - const buffer = reader.result; - - const size = buffer.byteLength; - const thisPtr = Module._malloc(size); - Module.HEAPU8.set(new Uint8Array(buffer), thisPtr); - - const getInfo = Module.cwrap('getInfo', 'number', ['number', 'number']); - - const ptr = getInfo(thisPtr, size); - const success = !!Module.getValue(ptr, 'i32'); - if (!success) { - Module._free(ptr); - Module._free(thisPtr); - self.postMessage({ - type: 'result', id, width: 0, height: 0, result: null, - }); - return; - } - const width = Module.getValue(ptr + 4, 'i32'); - const height = Module.getValue(ptr + 8, 'i32'); - - Module._free(ptr); - - const decode = Module.cwrap('decode', 'number', ['number', 'number']); - - const resultPtr = decode(thisPtr, size); - - const resultView = new Uint8Array(Module.HEAPU8.buffer, resultPtr, width * height * 4); - const result = new Uint8ClampedArray(resultView); - Module._free(resultPtr); - Module._free(thisPtr); - - self.postMessage({ - type: 'result', id, width, height, result, - }); - }); - - reader.readAsArrayBuffer(blob); -}; diff --git a/src/util/__mocks__/webpToPng.ts b/src/util/__mocks__/webpToPng.ts deleted file mode 100644 index c592bb38c..000000000 --- a/src/util/__mocks__/webpToPng.ts +++ /dev/null @@ -1,8 +0,0 @@ -const webpToPng = { - webpToPng() { - }, - webpToPngBase64() { - }, -}; - -export default webpToPng; diff --git a/src/util/environmentWebp.ts b/src/util/environmentWebp.ts deleted file mode 100644 index 4bf20dbb3..000000000 --- a/src/util/environmentWebp.ts +++ /dev/null @@ -1,22 +0,0 @@ -let isWebpSupportedCache: boolean | undefined; - -export function isWebpSupported() { - return Boolean(isWebpSupportedCache); -} - -function testWebp(): Promise { - return new Promise((resolve) => { - const webp = new Image(); - // eslint-disable-next-line max-len - webp.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'; - const handleLoadOrError = () => { - resolve(webp.height === 2); - }; - webp.onload = handleLoadOrError; - webp.onerror = handleLoadOrError; - }); -} - -testWebp().then((hasWebp) => { - isWebpSupportedCache = hasWebp; -}); diff --git a/src/util/mediaLoader.ts b/src/util/mediaLoader.ts index 5b47c7b64..5f9f6968b 100644 --- a/src/util/mediaLoader.ts +++ b/src/util/mediaLoader.ts @@ -15,9 +15,8 @@ import { callApi, cancelApiProgress } from '../api/gramjs'; import * as cacheApi from './cacheApi'; import { fetchBlob } from './files'; import { oggToWav } from './oggToWav'; -import { webpToPng } from './webpToPng'; import { - IS_OPUS_SUPPORTED, IS_PROGRESSIVE_SUPPORTED, isWebpSupported, + IS_OPUS_SUPPORTED, IS_PROGRESSIVE_SUPPORTED, } from './windowEnvironment'; const asCacheApiType = { @@ -142,13 +141,6 @@ async function fetchFromCacheOrRemote( media = await oggToWav(media); } - if (cached.type === 'image/webp' && !isWebpSupported() && media) { - const mediaPng = await webpToPng(url, media); - if (mediaPng) { - media = mediaPng; - } - } - const prepared = prepareMedia(media); memoryCache.set(url, prepared); @@ -184,15 +176,6 @@ async function fetchFromCacheOrRemote( mimeType = media.type; } - if (mimeType === 'image/webp' && !isWebpSupported()) { - const blob = await fetchBlob(prepared as string); - URL.revokeObjectURL(prepared as string); - const media = await webpToPng(url, blob); - if (media) { - prepared = prepareMedia(media); - } - } - memoryCache.set(url, prepared); return prepared; diff --git a/src/util/webpToPng.ts b/src/util/webpToPng.ts deleted file mode 100644 index 0bdd4a194..000000000 --- a/src/util/webpToPng.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { blobToDataUri, dataUriToBlob } from './files'; -import { pause } from './schedulers'; -import { isWebpSupported } from './windowEnvironment'; - -const WORKER_INITIALIZATION_TIMEOUT = 2000; - -let canvas: HTMLCanvasElement; -let worker: IWebpWorker; - -export const EMPTY_IMAGE_DATA_URI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk' - + 'YAAAAAYAAjCB0C8AAAAASUVORK5CYII='; - -export async function webpToPng(url: string, blob: Blob): Promise { - initWebpWorker(); - - while (!worker.wasmReady) { - await pause(WORKER_INITIALIZATION_TIMEOUT); - } - - const { result, width, height } = await getDecodePromise(url, blob); - if (!width || !height) { - return undefined; - } - - return createPng({ result, width, height }); -} - -export async function webpToPngBase64(key: string, dataUri: string): Promise { - if (isWebpSupported() || dataUri.substr(0, 15) !== 'data:image/webp') { - return dataUri; - } - - initWebpWorker(); - - const pngBlob = await webpToPng(key, dataUriToBlob(dataUri)); - - if (!pngBlob) { - throw new Error(`Can't convert webp to png. Url: ${dataUri}`); - } - - return blobToDataUri(pngBlob); -} - -function initWebpWorker() { - if (!worker) { - worker = new Worker(new URL('../lib/webp/webp_wasm.worker.js', import.meta.url)) as IWebpWorker; - worker.wasmReady = false; - worker.onmessage = handleLibWebpMessage; - } -} - -function createPng({ result, width, height }: TEncodedImage): Promise { - if (!canvas) { - canvas = document.createElement('canvas'); - } - - return new Promise((resolve) => { - const img = new ImageData(result, width, height); - - canvas.width = width; - canvas.height = height; - const ctx = canvas.getContext('2d')!; - ctx.putImageData(img, 0, 0); - - canvas.toBlob((blob) => { - resolve(blob ?? undefined); - }, 'image/png', 1); - }); -} - -function handleLibWebpMessage(e: MessageEvent) { - const { id } = e.data; - switch (e.data.type) { - case 'initialized': { - worker.wasmReady = true; - break; - } - - case 'result': { - if (worker.requests.has(id)) { - const resolve = worker.requests.get(id)!; - - worker.requests.delete(id); - resolve(e.data!); - } - break; - } - } -} - -function getDecodePromise(url: string, blob: Blob): Promise { - return new Promise((resolve) => { - if (!worker.requests) { - worker.requests = new Map(); - } - - worker.requests.set(url, resolve); - worker.postMessage({ id: url, blob }); - }); -} diff --git a/src/util/windowEnvironment.ts b/src/util/windowEnvironment.ts index 2925e5438..23d68c6dc 100644 --- a/src/util/windowEnvironment.ts +++ b/src/util/windowEnvironment.ts @@ -4,8 +4,6 @@ import { PRODUCTION_HOSTNAME, } from '../config'; -export * from './environmentWebp'; - export function getPlatform() { const { userAgent, platform } = window.navigator;