zstddec.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * From https://github.com/donmccurdy/zstddec by Don McCurdy
  3. */
  4. interface DecoderExports {
  5. memory: Uint8Array;
  6. ZSTD_findDecompressedSize: (compressedPtr: number, compressedSize: number) => number;
  7. ZSTD_decompress: (uncompressedPtr: number, uncompressedSize: number, compressedPtr: number, compressedSize: number) => number;
  8. malloc: (ptr: number) => number;
  9. free: (ptr: number) => void;
  10. }
  11. let init: Promise<void>;
  12. let instance: {exports: DecoderExports};
  13. let heap: Uint8Array;
  14. const IMPORT_OBJECT = {
  15. env: {
  16. emscripten_notify_memory_growth: function (index: number): void {
  17. heap = new Uint8Array(instance.exports.memory.buffer);
  18. }
  19. }
  20. };
  21. /**
  22. * ZSTD (Zstandard) decoder.
  23. */
  24. export class ZSTDDecoder {
  25. public static WasmModuleURL = "https://preview.babylonjs.com/zstddec.wasm";
  26. init (): Promise<void> {
  27. if (init) { return init; }
  28. if (typeof fetch !== 'undefined') {
  29. // Web.
  30. init = fetch(ZSTDDecoder.WasmModuleURL)
  31. .then((response) => {
  32. if (response.ok) {
  33. return response.arrayBuffer();
  34. }
  35. throw new Error(`Could not fetch the wasm component for the Zstandard decompression lib: ${response.status} - ${response.statusText}`);
  36. })
  37. .then((arrayBuffer) => WebAssembly.instantiate(arrayBuffer, IMPORT_OBJECT))
  38. .then(this._init);
  39. } else {
  40. // Node.js.
  41. init = WebAssembly
  42. .instantiateStreaming(fetch(ZSTDDecoder.WasmModuleURL), IMPORT_OBJECT)
  43. .then(this._init);
  44. }
  45. return init;
  46. }
  47. _init (result: WebAssembly.WebAssemblyInstantiatedSource): void {
  48. instance = result.instance as unknown as { exports: DecoderExports };
  49. IMPORT_OBJECT.env.emscripten_notify_memory_growth(0); // initialize heap.
  50. }
  51. decode (array: Uint8Array, uncompressedSize = 0): Uint8Array {
  52. if (! instance) { throw new Error(`ZSTDDecoder: Await .init() before decoding.`); }
  53. // Write compressed data into WASM memory.
  54. const compressedSize = array.byteLength;
  55. const compressedPtr = instance.exports.malloc(compressedSize);
  56. heap.set(array, compressedPtr);
  57. // Decompress into WASM memory.
  58. uncompressedSize = uncompressedSize || Number(instance.exports.ZSTD_findDecompressedSize(compressedPtr, compressedSize));
  59. const uncompressedPtr = instance.exports.malloc(uncompressedSize);
  60. const actualSize = instance.exports.ZSTD_decompress(uncompressedPtr, uncompressedSize, compressedPtr, compressedSize);
  61. // Read decompressed data and free WASM memory.
  62. const dec = heap.slice(uncompressedPtr, uncompressedPtr + actualSize);
  63. instance.exports.free(compressedPtr);
  64. instance.exports.free(uncompressedPtr);
  65. return dec;
  66. }
  67. }
  68. /**
  69. * BSD License
  70. *
  71. * For Zstandard software
  72. *
  73. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. All rights reserved.
  74. *
  75. * Redistribution and use in source and binary forms, with or without modification,
  76. * are permitted provided that the following conditions are met:
  77. *
  78. * * Redistributions of source code must retain the above copyright notice, this
  79. * list of conditions and the following disclaimer.
  80. *
  81. * * Redistributions in binary form must reproduce the above copyright notice,
  82. * this list of conditions and the following disclaimer in the documentation
  83. * and/or other materials provided with the distribution.
  84. *
  85. * * Neither the name Facebook nor the names of its contributors may be used to
  86. * endorse or promote products derived from this software without specific
  87. * prior written permission.
  88. *
  89. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  90. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  91. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  92. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  93. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  94. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  95. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  96. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  97. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  98. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  99. */