diff --git a/src/core/base_stream.js b/src/core/base_stream.js index 8a28eb0bf586ac..f10d266ecd8be8 100644 --- a/src/core/base_stream.js +++ b/src/core/base_stream.js @@ -40,7 +40,7 @@ class BaseStream { unreachable("Abstract method `getByte` called"); } - getBytes(length, forceClamped = false) { + getBytes(length) { unreachable("Abstract method `getBytes` called"); } @@ -52,8 +52,8 @@ class BaseStream { return peekedByte; } - peekBytes(length, forceClamped = false) { - const bytes = this.getBytes(length, forceClamped); + peekBytes(length) { + const bytes = this.getBytes(length); this.pos -= bytes.length; return bytes; } @@ -80,7 +80,7 @@ class BaseStream { } getString(length) { - return bytesToString(this.getBytes(length, /* forceClamped = */ false)); + return bytesToString(this.getBytes(length)); } skip(n) { diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index 426b7abb6bcc46..b85abe0a8bb630 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -169,7 +169,7 @@ class ChunkedStream extends Stream { return this.bytes[this.pos++]; } - getBytes(length, forceClamped = false) { + getBytes(length) { const bytes = this.bytes; const pos = this.pos; const strEnd = this.end; @@ -178,9 +178,7 @@ class ChunkedStream extends Stream { if (strEnd > this.progressiveDataLength) { this.ensureRange(pos, strEnd); } - const subarray = bytes.subarray(pos, strEnd); - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray; + return bytes.subarray(pos, strEnd); } let end = pos + length; @@ -192,9 +190,7 @@ class ChunkedStream extends Stream { } this.pos = end; - const subarray = bytes.subarray(pos, end); - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray; + return bytes.subarray(pos, end); } getByteRange(begin, end) { diff --git a/src/core/decode_stream.js b/src/core/decode_stream.js index 96157462a4fe1c..a79c31a921150f 100644 --- a/src/core/decode_stream.js +++ b/src/core/decode_stream.js @@ -73,7 +73,7 @@ class DecodeStream extends BaseStream { return this.buffer[this.pos++]; } - getBytes(length, forceClamped = false) { + getBytes(length) { const pos = this.pos; let end; @@ -96,11 +96,7 @@ class DecodeStream extends BaseStream { } 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; + return this.buffer.subarray(pos, end); } reset() { diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 97c18049957414..b9b55c8e6487bf 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -613,10 +613,7 @@ class PartialEvaluator { // for later. const interpolate = dict.get("I", "Interpolate"); const bitStrideLength = (w + 7) >> 3; - const imgArray = image.getBytes( - bitStrideLength * h, - /* forceClamped = */ true - ); + const imgArray = image.getBytes(bitStrideLength * h); const decode = dict.getArray("D", "Decode"); if (this.parsingType3Font) { diff --git a/src/core/image.js b/src/core/image.js index af0bf6f4ae7c80..79f1c5b4c1374c 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -308,15 +308,6 @@ class PDFImage { inverseDecode, interpolate, }) { - if ( - typeof PDFJSDev === "undefined" || - PDFJSDev.test("!PRODUCTION || TESTING") - ) { - assert( - imgArray instanceof Uint8ClampedArray, - 'PDFImage.createRawMask: Unsupported "imgArray" type.' - ); - } // |imgArray| might not contain full data for every pixel of the mask, so // we need to distinguish between |computedLength| and |actualLength|. // In particular, if inverseDecode is true, then the array we return must @@ -332,10 +323,10 @@ class PDFImage { // form, so we can just transfer it. data = imgArray; } else if (!inverseDecode) { - data = new Uint8ClampedArray(actualLength); + data = new Uint8Array(actualLength); data.set(imgArray); } else { - data = new Uint8ClampedArray(computedLength); + data = new Uint8Array(computedLength); data.set(imgArray); for (i = actualLength; i < computedLength; i++) { data[i] = 0xff; @@ -363,16 +354,6 @@ class PDFImage { inverseDecode, interpolate, }) { - if ( - typeof PDFJSDev === "undefined" || - PDFJSDev.test("!PRODUCTION || TESTING") - ) { - assert( - imgArray instanceof Uint8ClampedArray, - 'PDFImage.createMask: Unsupported "imgArray" type.' - ); - } - const isSingleOpaquePixel = width === 1 && height === 1 && @@ -682,7 +663,6 @@ class PDFImage { // Rows start at byte boundary. const rowBytes = (originalWidth * numComps * bpc + 7) >> 3; - let imgArray; if (!forceRGBA) { // If it is a 1-bit-per-pixel grayscale (i.e. black-and-white) image @@ -710,20 +690,8 @@ class PDFImage { drawHeight === originalHeight ) { imgData.kind = kind; + imgData.data = this.getImageBytes(originalHeight * rowBytes, {}); - imgArray = this.getImageBytes(originalHeight * rowBytes); - // If imgArray came from a DecodeStream, we're safe to transfer it - // (and thus detach its underlying buffer) because it will constitute - // the entire DecodeStream's data. But if it came from a Stream, we - // need to copy it because it'll only be a portion of the Stream's - // data, and the rest will be read later on. - if (this.image instanceof DecodeStream) { - imgData.data = imgArray; - } else { - const newArray = new Uint8ClampedArray(imgArray.length); - newArray.set(imgArray); - imgData.data = newArray; - } if (this.needsDecode) { // Invert the buffer (which must be grayscale if we reached here). assert( @@ -748,18 +716,19 @@ class PDFImage { case "DeviceRGB": case "DeviceCMYK": imgData.kind = ImageKind.RGB_24BPP; - imgData.data = this.getImageBytes( - imageLength, + imgData.data = this.getImageBytes(imageLength, { drawWidth, drawHeight, - /* forceRGB = */ true - ); + forceRGB: true, + }); return imgData; } } } - imgArray = this.getImageBytes(originalHeight * rowBytes); + const imgArray = this.getImageBytes(originalHeight * rowBytes, { + internal: true, + }); // imgArray can be incomplete (e.g. after CCITT fax encoding). const actualHeight = 0 | (((imgArray.length / rowBytes) * drawHeight) / originalHeight); @@ -834,7 +803,7 @@ class PDFImage { // rows start at byte boundary const rowBytes = (width * numComps * bpc + 7) >> 3; - const imgArray = this.getImageBytes(height * rowBytes); + const imgArray = this.getImageBytes(height * rowBytes, { internal: true }); const comps = this.getComponents(imgArray); let i, length; @@ -867,12 +836,29 @@ class PDFImage { } } - getImageBytes(length, drawWidth, drawHeight, forceRGB = false) { + getImageBytes( + length, + { drawWidth, drawHeight, forceRGB = false, internal = false } + ) { this.image.reset(); this.image.drawWidth = drawWidth || this.width; this.image.drawHeight = drawHeight || this.height; this.image.forceRGB = !!forceRGB; - return this.image.getBytes(length, /* forceClamped = */ true); + const imageBytes = this.image.getBytes(length); + + // If imageBytes came from a DecodeStream, we're safe to transfer it + // (and thus detach its underlying buffer) because it will constitute + // the entire DecodeStream's data. But if it came from a Stream, we + // need to copy it because it'll only be a portion of the Stream's + // data, and the rest will be read later on. + if (internal || this.image instanceof DecodeStream) { + return imageBytes; + } + assert( + imageBytes instanceof Uint8Array, + 'PDFImage.getImageBytes: Unsupported "imageBytes" type.' + ); + return new Uint8Array(imageBytes); } } diff --git a/src/core/operator_list.js b/src/core/operator_list.js index cfd4be69c10383..2f395dfec44359 100644 --- a/src/core/operator_list.js +++ b/src/core/operator_list.js @@ -14,7 +14,6 @@ */ import { - assert, ImageKind, OPS, RenderingIntentFlag, @@ -109,7 +108,7 @@ addState( } const imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING; const imgHeight = currentY + maxLineHeight + IMAGE_PADDING; - const imgData = new Uint8ClampedArray(imgWidth * imgHeight * 4); + const imgData = new Uint8Array(imgWidth * imgHeight * 4); const imgRowSize = imgWidth << 2; for (let q = 0; q < count; q++) { const data = argsArray[iFirstPIIXO + (q << 2)][0].data; @@ -678,17 +677,6 @@ class OperatorList { case OPS.paintInlineImageXObjectGroup: case OPS.paintImageMaskXObject: const arg = argsArray[i][0]; // First parameter in imgData. - - if ( - typeof PDFJSDev === "undefined" || - PDFJSDev.test("!PRODUCTION || TESTING") - ) { - assert( - arg.data instanceof Uint8ClampedArray || - typeof arg.data === "string", - 'OperatorList._transfers: Unsupported "arg.data" type.' - ); - } if ( !arg.cached && arg.data && diff --git a/src/core/stream.js b/src/core/stream.js index 6f24c44709b1da..7bc9791ed98888 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -45,24 +45,20 @@ class Stream extends BaseStream { return this.bytes[this.pos++]; } - getBytes(length, forceClamped = false) { + getBytes(length) { const bytes = this.bytes; const pos = this.pos; const strEnd = this.end; if (!length) { - const subarray = bytes.subarray(pos, strEnd); - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray; + return bytes.subarray(pos, strEnd); } let end = pos + length; if (end > strEnd) { end = strEnd; } this.pos = end; - const subarray = bytes.subarray(pos, end); - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray; + return bytes.subarray(pos, end); } getByteRange(begin, end) { diff --git a/test/unit/stream_spec.js b/test/unit/stream_spec.js index afc998e94b859b..361f5c2657149a 100644 --- a/test/unit/stream_spec.js +++ b/test/unit/stream_spec.js @@ -36,12 +36,6 @@ describe("stream", function () { const result = predictor.getBytes(6); expect(result).toEqual(new Uint8Array([100, 3, 101, 2, 102, 1])); - - predictor.reset(); - const clampedResult = predictor.getBytes(6, /* forceClamped = */ true); - expect(clampedResult).toEqual( - new Uint8ClampedArray([100, 3, 101, 2, 102, 1]) - ); }); }); });