Skip to content

Commit 499540e

Browse files
committed
Fix conflicts
1 parent 5146f47 commit 499540e

File tree

11 files changed

+71
-236
lines changed

11 files changed

+71
-236
lines changed

l10n/en-US/viewer.ftl

-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ pdfjs-editor-free-highlight-thickness-input = Thickness
348348
pdfjs-editor-free-highlight-thickness-title =
349349
.title = Change thickness when highlighting items other than text
350350
351-
# .default-content is used as a placeholder in an empty text editor.
352351
pdfjs-free-text2 =
353352
.aria-label = Text Editor
354353
.default-content = Start typing…

src/core/base_stream.js

-4
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ class BaseStream {
6868
return false;
6969
}
7070

71-
async getTransferableImage() {
72-
return null;
73-
}
74-
7571
peekByte() {
7672
const peekedByte = this.getByte();
7773
if (peekedByte !== -1) {

src/core/image.js

-22
Original file line numberDiff line numberDiff line change
@@ -752,10 +752,6 @@ class PDFImage {
752752
drawWidth === originalWidth &&
753753
drawHeight === originalHeight
754754
) {
755-
const image = await this.#getImage(originalWidth, originalHeight);
756-
if (image) {
757-
return image;
758-
}
759755
const data = await this.getImageBytes(originalHeight * rowBytes, {});
760756
if (isOffscreenCanvasSupported) {
761757
if (mustBeResized) {
@@ -814,10 +810,6 @@ class PDFImage {
814810
}
815811

816812
if (isHandled) {
817-
const image = await this.#getImage(drawWidth, drawHeight);
818-
if (image) {
819-
return image;
820-
}
821813
const rgba = await this.getImageBytes(imageLength, {
822814
drawWidth,
823815
drawHeight,
@@ -1021,20 +1013,6 @@ class PDFImage {
10211013
};
10221014
}
10231015

1024-
async #getImage(width, height) {
1025-
const bitmap = await this.image.getTransferableImage();
1026-
if (!bitmap) {
1027-
return null;
1028-
}
1029-
return {
1030-
data: null,
1031-
width,
1032-
height,
1033-
bitmap,
1034-
interpolate: this.interpolate,
1035-
};
1036-
}
1037-
10381016
async getImageBytes(
10391017
length,
10401018
{

src/core/jpeg_stream.js

+18-83
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { shadow, warn } from "../shared/util.js";
1716
import { DecodeStream } from "./decode_stream.js";
1817
import { Dict } from "./primitives.js";
1918
import { JpegImage } from "./jpg.js";
19+
import { shadow } from "../shared/util.js";
2020

2121
/**
2222
* For JPEG's we use a library to decode these images and the stream behaves
@@ -32,18 +32,6 @@ class JpegStream extends DecodeStream {
3232
this.params = params;
3333
}
3434

35-
static get canUseImageDecoder() {
36-
return shadow(
37-
this,
38-
"canUseImageDecoder",
39-
// eslint-disable-next-line no-undef
40-
typeof ImageDecoder === "undefined"
41-
? Promise.resolve(false)
42-
: // eslint-disable-next-line no-undef
43-
ImageDecoder.isTypeSupported("image/jpeg")
44-
);
45-
}
46-
4735
get bytes() {
4836
// If `this.maybeLength` is null, we'll get the entire stream.
4937
return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
@@ -58,7 +46,22 @@ class JpegStream extends DecodeStream {
5846
this.decodeImage();
5947
}
6048

61-
get jpegOptions() {
49+
decodeImage(bytes) {
50+
if (this.eof) {
51+
return this.buffer;
52+
}
53+
bytes ||= this.bytes;
54+
55+
// Some images may contain 'junk' before the SOI (start-of-image) marker.
56+
// Note: this seems to mainly affect inline images.
57+
for (let i = 0, ii = bytes.length - 1; i < ii; i++) {
58+
if (bytes[i] === 0xff && bytes[i + 1] === 0xd8) {
59+
if (i > 0) {
60+
bytes = bytes.subarray(i);
61+
}
62+
break;
63+
}
64+
}
6265
const jpegOptions = {
6366
decodeTransform: undefined,
6467
colorTransform: undefined,
@@ -90,34 +93,8 @@ class JpegStream extends DecodeStream {
9093
jpegOptions.colorTransform = colorTransform;
9194
}
9295
}
93-
return shadow(this, "jpegOptions", jpegOptions);
94-
}
95-
96-
#skipUselessBytes(data) {
97-
// Some images may contain 'junk' before the SOI (start-of-image) marker.
98-
// Note: this seems to mainly affect inline images.
99-
for (let i = 0, ii = data.length - 1; i < ii; i++) {
100-
if (data[i] === 0xff && data[i + 1] === 0xd8) {
101-
if (i > 0) {
102-
data = data.subarray(i);
103-
}
104-
break;
105-
}
106-
}
107-
return data;
108-
}
109-
110-
decodeImage(bytes) {
111-
if (this.eof) {
112-
return this.buffer;
113-
}
114-
bytes = this.#skipUselessBytes(bytes || this.bytes);
96+
const jpegImage = new JpegImage(jpegOptions);
11597

116-
// TODO: if an image has a mask we need to combine the data.
117-
// So ideally get a VideoFrame from getTransferableImage and then use
118-
// copyTo.
119-
120-
const jpegImage = new JpegImage(this.jpegOptions);
12198
jpegImage.parse(bytes);
12299
const data = jpegImage.getData({
123100
width: this.drawWidth,
@@ -136,48 +113,6 @@ class JpegStream extends DecodeStream {
136113
get canAsyncDecodeImageFromBuffer() {
137114
return this.stream.isAsync;
138115
}
139-
140-
async getTransferableImage() {
141-
if (!(await JpegStream.canUseImageDecoder)) {
142-
return null;
143-
}
144-
const jpegOptions = this.jpegOptions;
145-
if (jpegOptions.decodeTransform) {
146-
// TODO: We could decode the image thanks to ImageDecoder and then
147-
// get the pixels with copyTo and apply the decodeTransform.
148-
return null;
149-
}
150-
let decoder;
151-
try {
152-
// TODO: If the stream is Flate & DCT we could try to just pipe the
153-
// the DecompressionStream into the ImageDecoder: it'll avoid the
154-
// intermediate ArrayBuffer.
155-
const bytes =
156-
(this.canAsyncDecodeImageFromBuffer &&
157-
(await this.stream.asyncGetBytes())) ||
158-
this.bytes;
159-
if (!bytes) {
160-
return null;
161-
}
162-
const data = this.#skipUselessBytes(bytes);
163-
if (!JpegImage.canUseImageDecoder(data, jpegOptions.colorTransform)) {
164-
return null;
165-
}
166-
// eslint-disable-next-line no-undef
167-
decoder = new ImageDecoder({
168-
data,
169-
type: "image/jpeg",
170-
preferAnimation: false,
171-
});
172-
173-
return (await decoder.decode()).image;
174-
} catch (reason) {
175-
warn(`getTransferableImage - failed: "${reason}".`);
176-
return null;
177-
} finally {
178-
decoder?.close();
179-
}
180-
}
181116
}
182117

183118
export { JpegStream };

src/core/jpg.js

+39-94
Original file line numberDiff line numberDiff line change
@@ -744,109 +744,55 @@ function findNextFileMarker(data, currentPos, startPos = currentPos) {
744744
};
745745
}
746746

747-
function prepareComponents(frame) {
748-
const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
749-
const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
750-
for (const component of frame.components) {
751-
const blocksPerLine = Math.ceil(
752-
(Math.ceil(frame.samplesPerLine / 8) * component.h) / frame.maxH
753-
);
754-
const blocksPerColumn = Math.ceil(
755-
(Math.ceil(frame.scanLines / 8) * component.v) / frame.maxV
756-
);
757-
const blocksPerLineForMcu = mcusPerLine * component.h;
758-
const blocksPerColumnForMcu = mcusPerColumn * component.v;
759-
760-
const blocksBufferSize =
761-
64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
762-
component.blockData = new Int16Array(blocksBufferSize);
763-
component.blocksPerLine = blocksPerLine;
764-
component.blocksPerColumn = blocksPerColumn;
765-
}
766-
frame.mcusPerLine = mcusPerLine;
767-
frame.mcusPerColumn = mcusPerColumn;
768-
}
769-
770-
function readDataBlock(data, offset) {
771-
const length = readUint16(data, offset);
772-
offset += 2;
773-
let endOffset = offset + length - 2;
774-
775-
const fileMarker = findNextFileMarker(data, endOffset, offset);
776-
if (fileMarker?.invalid) {
777-
warn(
778-
"readDataBlock - incorrect length, current marker is: " +
779-
fileMarker.invalid
780-
);
781-
endOffset = fileMarker.offset;
782-
}
783-
784-
const array = data.subarray(offset, endOffset);
785-
offset += array.length;
786-
return { appData: array, newOffset: offset };
787-
}
788-
789-
function skipData(data, offset) {
790-
const length = readUint16(data, offset);
791-
offset += 2;
792-
const endOffset = offset + length - 2;
793-
794-
const fileMarker = findNextFileMarker(data, endOffset, offset);
795-
if (fileMarker?.invalid) {
796-
return fileMarker.offset;
797-
}
798-
return endOffset;
799-
}
800-
801747
class JpegImage {
802748
constructor({ decodeTransform = null, colorTransform = -1 } = {}) {
803749
this._decodeTransform = decodeTransform;
804750
this._colorTransform = colorTransform;
805751
}
806752

807-
static canUseImageDecoder(data, colorTransform = -1) {
808-
let offset = 0;
809-
let numComponents = null;
810-
let fileMarker = readUint16(data, offset);
811-
offset += 2;
812-
if (fileMarker !== /* SOI (Start of Image) = */ 0xffd8) {
813-
throw new JpegError("SOI not found");
814-
}
815-
fileMarker = readUint16(data, offset);
816-
offset += 2;
753+
parse(data, { dnlScanLines = null } = {}) {
754+
function readDataBlock() {
755+
const length = readUint16(data, offset);
756+
offset += 2;
757+
let endOffset = offset + length - 2;
817758

818-
markerLoop: while (fileMarker !== /* EOI (End of Image) = */ 0xffd9) {
819-
switch (fileMarker) {
820-
case 0xffc0: // SOF0 (Start of Frame, Baseline DCT)
821-
case 0xffc1: // SOF1 (Start of Frame, Extended DCT)
822-
case 0xffc2: // SOF2 (Start of Frame, Progressive DCT)
823-
// Skip marker length.
824-
// Skip precision.
825-
// Skip scanLines.
826-
// Skip samplesPerLine.
827-
numComponents = data[offset + (2 + 1 + 2 + 2)];
828-
break markerLoop;
829-
case 0xffff: // Fill bytes
830-
if (data[offset] !== 0xff) {
831-
// Avoid skipping a valid marker.
832-
offset--;
833-
}
834-
break;
759+
const fileMarker = findNextFileMarker(data, endOffset, offset);
760+
if (fileMarker?.invalid) {
761+
warn(
762+
"readDataBlock - incorrect length, current marker is: " +
763+
fileMarker.invalid
764+
);
765+
endOffset = fileMarker.offset;
835766
}
836-
offset = skipData(data, offset);
837-
fileMarker = readUint16(data, offset);
838-
offset += 2;
839-
}
840-
if (numComponents === 4) {
841-
return false;
767+
768+
const array = data.subarray(offset, endOffset);
769+
offset += array.length;
770+
return array;
842771
}
843-
if (numComponents === 3 && colorTransform === 0) {
844-
return false;
772+
773+
function prepareComponents(frame) {
774+
const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
775+
const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
776+
for (const component of frame.components) {
777+
const blocksPerLine = Math.ceil(
778+
(Math.ceil(frame.samplesPerLine / 8) * component.h) / frame.maxH
779+
);
780+
const blocksPerColumn = Math.ceil(
781+
(Math.ceil(frame.scanLines / 8) * component.v) / frame.maxV
782+
);
783+
const blocksPerLineForMcu = mcusPerLine * component.h;
784+
const blocksPerColumnForMcu = mcusPerColumn * component.v;
785+
786+
const blocksBufferSize =
787+
64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
788+
component.blockData = new Int16Array(blocksBufferSize);
789+
component.blocksPerLine = blocksPerLine;
790+
component.blocksPerColumn = blocksPerColumn;
791+
}
792+
frame.mcusPerLine = mcusPerLine;
793+
frame.mcusPerColumn = mcusPerColumn;
845794
}
846-
return true;
847-
}
848795

849-
parse(data, { dnlScanLines = null } = {}) {
850796
let offset = 0;
851797
let jfif = null;
852798
let adobe = null;
@@ -884,8 +830,7 @@ class JpegImage {
884830
case 0xffee: // APP14
885831
case 0xffef: // APP15
886832
case 0xfffe: // COM (Comment)
887-
const { appData, newOffset } = readDataBlock(data, offset);
888-
offset = newOffset;
833+
const appData = readDataBlock();
889834

890835
if (fileMarker === 0xffe0) {
891836
// 'JFIF\x00'

0 commit comments

Comments
 (0)