diff --git a/src/core/ascii_85_stream.js b/src/core/ascii_85_stream.js index 159eae66e..a006d40e2 100644 --- a/src/core/ascii_85_stream.js +++ b/src/core/ascii_85_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { isWhiteSpace } from "./core_utils.js"; class Ascii85Stream extends DecodeStream { diff --git a/src/core/ascii_hex_stream.js b/src/core/ascii_hex_stream.js index 69e902171..0bc1bd15a 100644 --- a/src/core/ascii_hex_stream.js +++ b/src/core/ascii_hex_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; class AsciiHexStream extends DecodeStream { constructor(str, maybeLength) { diff --git a/src/core/ccitt_stream.js b/src/core/ccitt_stream.js index 6f597689a..d716b4841 100644 --- a/src/core/ccitt_stream.js +++ b/src/core/ccitt_stream.js @@ -15,7 +15,7 @@ import { Dict, isDict } from "./primitives.js"; import { CCITTFaxDecoder } from "./ccitt.js"; -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; class CCITTFaxStream extends DecodeStream { constructor(str, maybeLength, params) { diff --git a/src/core/decode_stream.js b/src/core/decode_stream.js new file mode 100644 index 000000000..f4ff751c3 --- /dev/null +++ b/src/core/decode_stream.js @@ -0,0 +1,222 @@ +/* Copyright 2012 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* eslint-disable no-var */ + +import { Stream } from "./stream.js"; +import { unreachable } from "../shared/util.js"; + +// super class for the decoding streams +var DecodeStream = (function DecodeStreamClosure() { + // Lots of DecodeStreams are created whose buffers are never used. For these + // we share a single empty buffer. This is (a) space-efficient and (b) avoids + // having special cases that would be required if we used |null| for an empty + // buffer. + var emptyBuffer = new Uint8Array(0); + + // eslint-disable-next-line no-shadow + function DecodeStream(maybeMinBufferLength) { + this._rawMinBufferLength = maybeMinBufferLength || 0; + + this.pos = 0; + this.bufferLength = 0; + this.eof = false; + this.buffer = emptyBuffer; + this.minBufferLength = 512; + if (maybeMinBufferLength) { + // Compute the first power of two that is as big as maybeMinBufferLength. + while (this.minBufferLength < maybeMinBufferLength) { + this.minBufferLength *= 2; + } + } + } + + DecodeStream.prototype = { + // eslint-disable-next-line getter-return + get length() { + unreachable("Should not access DecodeStream.length"); + }, + + get isEmpty() { + while (!this.eof && this.bufferLength === 0) { + this.readBlock(); + } + return this.bufferLength === 0; + }, + ensureBuffer: function DecodeStream_ensureBuffer(requested) { + var buffer = this.buffer; + if (requested <= buffer.byteLength) { + return buffer; + } + var size = this.minBufferLength; + while (size < requested) { + size *= 2; + } + var buffer2 = new Uint8Array(size); + buffer2.set(buffer); + return (this.buffer = buffer2); + }, + getByte: function DecodeStream_getByte() { + var pos = this.pos; + while (this.bufferLength <= pos) { + if (this.eof) { + return -1; + } + this.readBlock(); + } + return this.buffer[this.pos++]; + }, + getUint16: function DecodeStream_getUint16() { + var b0 = this.getByte(); + var b1 = this.getByte(); + if (b0 === -1 || b1 === -1) { + return -1; + } + return (b0 << 8) + b1; + }, + getInt32: function DecodeStream_getInt32() { + var b0 = this.getByte(); + var b1 = this.getByte(); + var b2 = this.getByte(); + var b3 = this.getByte(); + return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; + }, + getBytes(length, forceClamped = false) { + var end, + pos = this.pos; + + if (length) { + this.ensureBuffer(pos + length); + end = pos + length; + + while (!this.eof && this.bufferLength < end) { + this.readBlock(); + } + var bufEnd = this.bufferLength; + if (end > bufEnd) { + end = bufEnd; + } + } else { + while (!this.eof) { + this.readBlock(); + } + end = this.bufferLength; + } + + this.pos = end; + const subarray = this.buffer.subarray(pos, end); + // `this.buffer` is either a `Uint8Array` or `Uint8ClampedArray` here. + return forceClamped && !(subarray instanceof Uint8ClampedArray) + ? new Uint8ClampedArray(subarray) + : subarray; + }, + peekByte: function DecodeStream_peekByte() { + var peekedByte = this.getByte(); + if (peekedByte !== -1) { + this.pos--; + } + return peekedByte; + }, + peekBytes(length, forceClamped = false) { + var bytes = this.getBytes(length, forceClamped); + this.pos -= bytes.length; + return bytes; + }, + makeSubStream: function DecodeStream_makeSubStream(start, length, dict) { + if (length === undefined) { + while (!this.eof) { + this.readBlock(); + } + } else { + var end = start + length; + while (this.bufferLength <= end && !this.eof) { + this.readBlock(); + } + } + return new Stream(this.buffer, start, length, dict); + }, + + getByteRange(begin, end) { + unreachable("Should not call DecodeStream.getByteRange"); + }, + + skip: function DecodeStream_skip(n) { + if (!n) { + n = 1; + } + this.pos += n; + }, + reset: function DecodeStream_reset() { + this.pos = 0; + }, + getBaseStreams: function DecodeStream_getBaseStreams() { + if (this.str && this.str.getBaseStreams) { + return this.str.getBaseStreams(); + } + return []; + }, + }; + + return DecodeStream; +})(); + +var StreamsSequenceStream = (function StreamsSequenceStreamClosure() { + // eslint-disable-next-line no-shadow + function StreamsSequenceStream(streams) { + this.streams = streams; + + let maybeLength = 0; + for (let i = 0, ii = streams.length; i < ii; i++) { + const stream = streams[i]; + if (stream instanceof DecodeStream) { + maybeLength += stream._rawMinBufferLength; + } else { + maybeLength += stream.length; + } + } + DecodeStream.call(this, maybeLength); + } + + StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype); + + StreamsSequenceStream.prototype.readBlock = function streamSequenceStreamReadBlock() { + var streams = this.streams; + if (streams.length === 0) { + this.eof = true; + return; + } + var stream = streams.shift(); + var chunk = stream.getBytes(); + var bufferLength = this.bufferLength; + var newLength = bufferLength + chunk.length; + var buffer = this.ensureBuffer(newLength); + buffer.set(chunk, bufferLength); + this.bufferLength = newLength; + }; + + StreamsSequenceStream.prototype.getBaseStreams = function StreamsSequenceStream_getBaseStreams() { + var baseStreams = []; + for (var i = 0, ii = this.streams.length; i < ii; i++) { + var stream = this.streams[i]; + if (stream.getBaseStreams) { + baseStreams.push(...stream.getBaseStreams()); + } + } + return baseStreams; + }; + + return StreamsSequenceStream; +})(); + +export { DecodeStream, StreamsSequenceStream }; diff --git a/src/core/decrypt_stream.js b/src/core/decrypt_stream.js index cc5df1b66..6848ead7e 100644 --- a/src/core/decrypt_stream.js +++ b/src/core/decrypt_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; const chunkSize = 512; diff --git a/src/core/document.js b/src/core/document.js index 0682d7813..3e0883331 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -53,7 +53,7 @@ import { XRefEntryException, XRefParseException, } from "./core_utils.js"; -import { NullStream, Stream, StreamsSequenceStream } from "./stream.js"; +import { NullStream, Stream } from "./stream.js"; import { AnnotationFactory } from "./annotation.js"; import { calculateMD5 } from "./crypto.js"; import { Catalog } from "./catalog.js"; @@ -61,6 +61,7 @@ import { Linearization } from "./parser.js"; import { ObjectLoader } from "./object_loader.js"; import { OperatorList } from "./operator_list.js"; import { PartialEvaluator } from "./evaluator.js"; +import { StreamsSequenceStream } from "./decode_stream.js"; import { StructTreePage } from "./struct_tree.js"; import { XFAFactory } from "./xfa/factory.js"; import { XRef } from "./xref.js"; diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 46c2cb3f1..bd43c323d 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -47,7 +47,6 @@ import { Ref, RefSet, } from "./primitives.js"; -import { DecodeStream, NullStream } from "./stream.js"; import { ErrorFont, Font, @@ -85,10 +84,12 @@ import { } from "./image_utils.js"; import { bidi } from "./bidi.js"; import { ColorSpace } from "./colorspace.js"; +import { DecodeStream } from "./decode_stream.js"; import { getGlyphsUnicode } from "./glyphlist.js"; import { getLookupTableFactory } from "./core_utils.js"; import { getMetrics } from "./metrics.js"; import { MurmurHash3_64 } from "./murmurhash3.js"; +import { NullStream } from "./stream.js"; import { OperatorList } from "./operator_list.js"; import { PDFImage } from "./image.js"; diff --git a/src/core/flate_stream.js b/src/core/flate_stream.js index b8dfb4cff..6533bbd6b 100644 --- a/src/core/flate_stream.js +++ b/src/core/flate_stream.js @@ -19,7 +19,7 @@ * license. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { FormatError } from "../shared/util.js"; // prettier-ignore diff --git a/src/core/image.js b/src/core/image.js index e718b9937..9de3c3216 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -16,7 +16,7 @@ import { assert, FormatError, ImageKind, info, warn } from "../shared/util.js"; import { isName, isStream, Name } from "./primitives.js"; import { ColorSpace } from "./colorspace.js"; -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { JpegStream } from "./jpeg_stream.js"; import { JpxImage } from "./jpx.js"; diff --git a/src/core/jbig2_stream.js b/src/core/jbig2_stream.js index c760e8d90..dda50f6d6 100644 --- a/src/core/jbig2_stream.js +++ b/src/core/jbig2_stream.js @@ -14,7 +14,7 @@ */ import { isDict, isStream } from "./primitives.js"; -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { Jbig2Image } from "./jbig2.js"; import { shadow } from "../shared/util.js"; diff --git a/src/core/jpeg_stream.js b/src/core/jpeg_stream.js index 300f055a8..cd026f3dc 100644 --- a/src/core/jpeg_stream.js +++ b/src/core/jpeg_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { isDict } from "./primitives.js"; import { JpegImage } from "./jpg.js"; import { shadow } from "../shared/util.js"; diff --git a/src/core/jpx_stream.js b/src/core/jpx_stream.js index 5808563b2..b9d904384 100644 --- a/src/core/jpx_stream.js +++ b/src/core/jpx_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { JpxImage } from "./jpx.js"; import { shadow } from "../shared/util.js"; diff --git a/src/core/lzw_stream.js b/src/core/lzw_stream.js index 3ea98adea..9a0ae7448 100644 --- a/src/core/lzw_stream.js +++ b/src/core/lzw_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; class LZWStream extends DecodeStream { constructor(str, maybeLength, earlyChange) { diff --git a/src/core/predictor_stream.js b/src/core/predictor_stream.js index 1653833f8..9a682f7e0 100644 --- a/src/core/predictor_stream.js +++ b/src/core/predictor_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; import { FormatError } from "../shared/util.js"; import { isDict } from "./primitives.js"; diff --git a/src/core/run_length_stream.js b/src/core/run_length_stream.js index c32d3fcf5..8df345fa7 100644 --- a/src/core/run_length_stream.js +++ b/src/core/run_length_stream.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DecodeStream } from "./stream.js"; +import { DecodeStream } from "./decode_stream.js"; class RunLengthStream extends DecodeStream { constructor(str, maybeLength) { diff --git a/src/core/stream.js b/src/core/stream.js index 64e71d5a5..dbdc3e187 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -14,7 +14,7 @@ */ /* eslint-disable no-var */ -import { stringToBytes, unreachable } from "../shared/util.js"; +import { stringToBytes } from "../shared/util.js"; var Stream = (function StreamClosure() { // eslint-disable-next-line no-shadow @@ -134,208 +134,6 @@ var StringStream = (function StringStreamClosure() { return StringStream; })(); -// super class for the decoding streams -var DecodeStream = (function DecodeStreamClosure() { - // Lots of DecodeStreams are created whose buffers are never used. For these - // we share a single empty buffer. This is (a) space-efficient and (b) avoids - // having special cases that would be required if we used |null| for an empty - // buffer. - var emptyBuffer = new Uint8Array(0); - - // eslint-disable-next-line no-shadow - function DecodeStream(maybeMinBufferLength) { - this._rawMinBufferLength = maybeMinBufferLength || 0; - - this.pos = 0; - this.bufferLength = 0; - this.eof = false; - this.buffer = emptyBuffer; - this.minBufferLength = 512; - if (maybeMinBufferLength) { - // Compute the first power of two that is as big as maybeMinBufferLength. - while (this.minBufferLength < maybeMinBufferLength) { - this.minBufferLength *= 2; - } - } - } - - DecodeStream.prototype = { - // eslint-disable-next-line getter-return - get length() { - unreachable("Should not access DecodeStream.length"); - }, - - get isEmpty() { - while (!this.eof && this.bufferLength === 0) { - this.readBlock(); - } - return this.bufferLength === 0; - }, - ensureBuffer: function DecodeStream_ensureBuffer(requested) { - var buffer = this.buffer; - if (requested <= buffer.byteLength) { - return buffer; - } - var size = this.minBufferLength; - while (size < requested) { - size *= 2; - } - var buffer2 = new Uint8Array(size); - buffer2.set(buffer); - return (this.buffer = buffer2); - }, - getByte: function DecodeStream_getByte() { - var pos = this.pos; - while (this.bufferLength <= pos) { - if (this.eof) { - return -1; - } - this.readBlock(); - } - return this.buffer[this.pos++]; - }, - getUint16: function DecodeStream_getUint16() { - var b0 = this.getByte(); - var b1 = this.getByte(); - if (b0 === -1 || b1 === -1) { - return -1; - } - return (b0 << 8) + b1; - }, - getInt32: function DecodeStream_getInt32() { - var b0 = this.getByte(); - var b1 = this.getByte(); - var b2 = this.getByte(); - var b3 = this.getByte(); - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - }, - getBytes(length, forceClamped = false) { - var end, - pos = this.pos; - - if (length) { - this.ensureBuffer(pos + length); - end = pos + length; - - while (!this.eof && this.bufferLength < end) { - this.readBlock(); - } - var bufEnd = this.bufferLength; - if (end > bufEnd) { - end = bufEnd; - } - } else { - while (!this.eof) { - this.readBlock(); - } - end = this.bufferLength; - } - - this.pos = end; - const subarray = this.buffer.subarray(pos, end); - // `this.buffer` is either a `Uint8Array` or `Uint8ClampedArray` here. - return forceClamped && !(subarray instanceof Uint8ClampedArray) - ? new Uint8ClampedArray(subarray) - : subarray; - }, - peekByte: function DecodeStream_peekByte() { - var peekedByte = this.getByte(); - if (peekedByte !== -1) { - this.pos--; - } - return peekedByte; - }, - peekBytes(length, forceClamped = false) { - var bytes = this.getBytes(length, forceClamped); - this.pos -= bytes.length; - return bytes; - }, - makeSubStream: function DecodeStream_makeSubStream(start, length, dict) { - if (length === undefined) { - while (!this.eof) { - this.readBlock(); - } - } else { - var end = start + length; - while (this.bufferLength <= end && !this.eof) { - this.readBlock(); - } - } - return new Stream(this.buffer, start, length, dict); - }, - - getByteRange(begin, end) { - unreachable("Should not call DecodeStream.getByteRange"); - }, - - skip: function DecodeStream_skip(n) { - if (!n) { - n = 1; - } - this.pos += n; - }, - reset: function DecodeStream_reset() { - this.pos = 0; - }, - getBaseStreams: function DecodeStream_getBaseStreams() { - if (this.str && this.str.getBaseStreams) { - return this.str.getBaseStreams(); - } - return []; - }, - }; - - return DecodeStream; -})(); - -var StreamsSequenceStream = (function StreamsSequenceStreamClosure() { - // eslint-disable-next-line no-shadow - function StreamsSequenceStream(streams) { - this.streams = streams; - - let maybeLength = 0; - for (let i = 0, ii = streams.length; i < ii; i++) { - const stream = streams[i]; - if (stream instanceof DecodeStream) { - maybeLength += stream._rawMinBufferLength; - } else { - maybeLength += stream.length; - } - } - DecodeStream.call(this, maybeLength); - } - - StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype); - - StreamsSequenceStream.prototype.readBlock = function streamSequenceStreamReadBlock() { - var streams = this.streams; - if (streams.length === 0) { - this.eof = true; - return; - } - var stream = streams.shift(); - var chunk = stream.getBytes(); - var bufferLength = this.bufferLength; - var newLength = bufferLength + chunk.length; - var buffer = this.ensureBuffer(newLength); - buffer.set(chunk, bufferLength); - this.bufferLength = newLength; - }; - - StreamsSequenceStream.prototype.getBaseStreams = function StreamsSequenceStream_getBaseStreams() { - var baseStreams = []; - for (var i = 0, ii = this.streams.length; i < ii; i++) { - var stream = this.streams[i]; - if (stream.getBaseStreams) { - baseStreams.push(...stream.getBaseStreams()); - } - } - return baseStreams; - }; - - return StreamsSequenceStream; -})(); - var NullStream = (function NullStreamClosure() { // eslint-disable-next-line no-shadow function NullStream() { @@ -347,10 +145,4 @@ var NullStream = (function NullStreamClosure() { return NullStream; })(); -export { - DecodeStream, - NullStream, - Stream, - StreamsSequenceStream, - StringStream, -}; +export { NullStream, Stream, StringStream };