deflator.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * noVNC: HTML5 VNC client
  3. * Copyright (C) 2020 The noVNC Authors
  4. * Licensed under MPL 2.0 (see LICENSE.txt)
  5. *
  6. * See README.md for usage and integration instructions.
  7. */
  8. import { deflateInit, deflate } from "../vendor/pako/lib/zlib/deflate.js";
  9. import { Z_FULL_FLUSH } from "../vendor/pako/lib/zlib/deflate.js";
  10. import ZStream from "../vendor/pako/lib/zlib/zstream.js";
  11. export default class Deflator {
  12. constructor() {
  13. this.strm = new ZStream();
  14. this.chunkSize = 1024 * 10 * 10;
  15. this.outputBuffer = new Uint8Array(this.chunkSize);
  16. this.windowBits = 5;
  17. deflateInit(this.strm, this.windowBits);
  18. }
  19. deflate(inData) {
  20. /* eslint-disable camelcase */
  21. this.strm.input = inData;
  22. this.strm.avail_in = this.strm.input.length;
  23. this.strm.next_in = 0;
  24. this.strm.output = this.outputBuffer;
  25. this.strm.avail_out = this.chunkSize;
  26. this.strm.next_out = 0;
  27. /* eslint-enable camelcase */
  28. let lastRet = deflate(this.strm, Z_FULL_FLUSH);
  29. let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
  30. if (lastRet < 0) {
  31. throw new Error("zlib deflate failed");
  32. }
  33. if (this.strm.avail_in > 0) {
  34. // Read chunks until done
  35. let chunks = [outData];
  36. let totalLen = outData.length;
  37. do {
  38. /* eslint-disable camelcase */
  39. this.strm.output = new Uint8Array(this.chunkSize);
  40. this.strm.next_out = 0;
  41. this.strm.avail_out = this.chunkSize;
  42. /* eslint-enable camelcase */
  43. lastRet = deflate(this.strm, Z_FULL_FLUSH);
  44. if (lastRet < 0) {
  45. throw new Error("zlib deflate failed");
  46. }
  47. let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
  48. totalLen += chunk.length;
  49. chunks.push(chunk);
  50. } while (this.strm.avail_in > 0);
  51. // Combine chunks into a single data
  52. let newData = new Uint8Array(totalLen);
  53. let offset = 0;
  54. for (let i = 0; i < chunks.length; i++) {
  55. newData.set(chunks[i], offset);
  56. offset += chunks[i].length;
  57. }
  58. outData = newData;
  59. }
  60. /* eslint-disable camelcase */
  61. this.strm.input = null;
  62. this.strm.avail_in = 0;
  63. this.strm.next_in = 0;
  64. /* eslint-enable camelcase */
  65. return outData;
  66. }
  67. }