RawInflate.mjs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * @author n1474335 [n1474335@gmail.com]
  3. * @copyright Crown Copyright 2016
  4. * @license Apache-2.0
  5. */
  6. import Operation from "../Operation";
  7. import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
  8. import rawinflate from "zlibjs/bin/rawinflate.min";
  9. const Zlib = rawinflate.Zlib;
  10. const RAW_BUFFER_TYPE_LOOKUP = {
  11. "Adaptive": Zlib.RawInflate.BufferType.ADAPTIVE,
  12. "Block": Zlib.RawInflate.BufferType.BLOCK,
  13. };
  14. /**
  15. * Raw Inflate operation
  16. */
  17. class RawInflate extends Operation {
  18. /**
  19. * RawInflate constructor
  20. */
  21. constructor() {
  22. super();
  23. this.name = "Raw Inflate";
  24. this.module = "Compression";
  25. this.description = "Decompresses data which has been compressed using the deflate algorithm with no headers.";
  26. this.inputType = "ArrayBuffer";
  27. this.outputType = "ArrayBuffer";
  28. this.args = [
  29. {
  30. name: "Start index",
  31. type: "number",
  32. value: 0
  33. },
  34. {
  35. name: "Initial output buffer size",
  36. type: "number",
  37. value: 0
  38. },
  39. {
  40. name: "Buffer expansion type",
  41. type: "option",
  42. value: INFLATE_BUFFER_TYPE
  43. },
  44. {
  45. name: "Resize buffer after decompression",
  46. type: "boolean",
  47. value: false
  48. },
  49. {
  50. name: "Verify result",
  51. type: "boolean",
  52. value: false
  53. }
  54. ];
  55. }
  56. /**
  57. * @param {ArrayBuffer} input
  58. * @param {Object[]} args
  59. * @returns {ArrayBuffer}
  60. */
  61. run(input, args) {
  62. const inflate = new Zlib.RawInflate(new Uint8Array(input), {
  63. index: args[0],
  64. bufferSize: args[1],
  65. bufferType: RAW_BUFFER_TYPE_LOOKUP[args[2]],
  66. resize: args[3],
  67. verify: args[4]
  68. }),
  69. result = new Uint8Array(inflate.decompress());
  70. // Raw Inflate somethimes messes up and returns nonsense like this:
  71. // ]....]....]....]....]....]....]....]....]....]....]....]....]....]...
  72. // e.g. Input data of [8b, 1d, dc, 44]
  73. // Look for the first two square brackets:
  74. if (result.length > 158 && result[0] === 93 && result[5] === 93) {
  75. // If the first two square brackets are there, check that the others
  76. // are also there. If they are, throw an error. If not, continue.
  77. let valid = false;
  78. for (let i = 0; i < 155; i += 5) {
  79. if (result[i] !== 93) {
  80. valid = true;
  81. }
  82. }
  83. if (!valid) {
  84. throw "Error: Unable to inflate data";
  85. }
  86. }
  87. // This seems to be the easiest way...
  88. return result.buffer;
  89. }
  90. }
  91. export default RawInflate;