ascii_85_stream.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* Copyright 2012 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import { DecodeStream } from "./decode_stream.js";
  16. import { isWhiteSpace } from "./core_utils.js";
  17. class Ascii85Stream extends DecodeStream {
  18. constructor(str, maybeLength) {
  19. // Most streams increase in size when decoded, but Ascii85 streams
  20. // typically shrink by ~20%.
  21. if (maybeLength) {
  22. maybeLength *= 0.8;
  23. }
  24. super(maybeLength);
  25. this.str = str;
  26. this.dict = str.dict;
  27. this.input = new Uint8Array(5);
  28. }
  29. readBlock() {
  30. const TILDA_CHAR = 0x7e; // '~'
  31. const Z_LOWER_CHAR = 0x7a; // 'z'
  32. const EOF = -1;
  33. const str = this.str;
  34. let c = str.getByte();
  35. while (isWhiteSpace(c)) {
  36. c = str.getByte();
  37. }
  38. if (c === EOF || c === TILDA_CHAR) {
  39. this.eof = true;
  40. return;
  41. }
  42. const bufferLength = this.bufferLength;
  43. let buffer, i;
  44. // special code for z
  45. if (c === Z_LOWER_CHAR) {
  46. buffer = this.ensureBuffer(bufferLength + 4);
  47. for (i = 0; i < 4; ++i) {
  48. buffer[bufferLength + i] = 0;
  49. }
  50. this.bufferLength += 4;
  51. } else {
  52. const input = this.input;
  53. input[0] = c;
  54. for (i = 1; i < 5; ++i) {
  55. c = str.getByte();
  56. while (isWhiteSpace(c)) {
  57. c = str.getByte();
  58. }
  59. input[i] = c;
  60. if (c === EOF || c === TILDA_CHAR) {
  61. break;
  62. }
  63. }
  64. buffer = this.ensureBuffer(bufferLength + i - 1);
  65. this.bufferLength += i - 1;
  66. // partial ending;
  67. if (i < 5) {
  68. for (; i < 5; ++i) {
  69. input[i] = 0x21 + 84;
  70. }
  71. this.eof = true;
  72. }
  73. let t = 0;
  74. for (i = 0; i < 5; ++i) {
  75. t = t * 85 + (input[i] - 0x21);
  76. }
  77. for (i = 3; i >= 0; --i) {
  78. buffer[bufferLength + i] = t & 0xff;
  79. t >>= 8;
  80. }
  81. }
  82. }
  83. }
  84. export { Ascii85Stream };