deflator.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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, Z_DEFAULT_COMPRESSION } 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. deflateInit(this.strm, Z_DEFAULT_COMPRESSION);
  17. }
  18. deflate(inData) {
  19. /* eslint-disable camelcase */
  20. this.strm.input = inData;
  21. this.strm.avail_in = this.strm.input.length;
  22. this.strm.next_in = 0;
  23. this.strm.output = this.outputBuffer;
  24. this.strm.avail_out = this.chunkSize;
  25. this.strm.next_out = 0;
  26. /* eslint-enable camelcase */
  27. let lastRet = deflate(this.strm, Z_FULL_FLUSH);
  28. let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
  29. if (lastRet < 0) {
  30. throw new Error("zlib deflate failed");
  31. }
  32. if (this.strm.avail_in > 0) {
  33. // Read chunks until done
  34. let chunks = [outData];
  35. let totalLen = outData.length;
  36. do {
  37. /* eslint-disable camelcase */
  38. this.strm.output = new Uint8Array(this.chunkSize);
  39. this.strm.next_out = 0;
  40. this.strm.avail_out = this.chunkSize;
  41. /* eslint-enable camelcase */
  42. lastRet = deflate(this.strm, Z_FULL_FLUSH);
  43. if (lastRet < 0) {
  44. throw new Error("zlib deflate failed");
  45. }
  46. let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
  47. totalLen += chunk.length;
  48. chunks.push(chunk);
  49. } while (this.strm.avail_in > 0);
  50. // Combine chunks into a single data
  51. let newData = new Uint8Array(totalLen);
  52. let offset = 0;
  53. for (let i = 0; i < chunks.length; i++) {
  54. newData.set(chunks[i], offset);
  55. offset += chunks[i].length;
  56. }
  57. outData = newData;
  58. }
  59. /* eslint-disable camelcase */
  60. this.strm.input = null;
  61. this.strm.avail_in = 0;
  62. this.strm.next_in = 0;
  63. /* eslint-enable camelcase */
  64. return outData;
  65. }
  66. }