pdfjs-dist 2.0.943 → 2.4.456
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pdfjs-dist might be problematic. Click here for more details.
- package/CODE_OF_CONDUCT.md +15 -0
- package/README.md +4 -0
- package/bower.json +1 -1
- package/build/pdf.js +8286 -14230
- package/build/pdf.js.map +1 -1
- package/build/pdf.min.js +22 -1
- package/build/pdf.worker.entry.js +5 -3
- package/build/pdf.worker.js +25500 -26628
- package/build/pdf.worker.js.map +1 -1
- package/build/pdf.worker.min.js +22 -1
- package/es5/build/pdf.js +25473 -0
- package/es5/build/pdf.js.map +1 -0
- package/{lib/shared/global_scope.js → es5/build/pdf.worker.entry.js} +5 -10
- package/es5/build/pdf.worker.js +57878 -0
- package/es5/build/pdf.worker.js.map +1 -0
- package/es5/web/images/annotation-check.svg +11 -0
- package/es5/web/images/annotation-comment.svg +16 -0
- package/es5/web/images/annotation-help.svg +26 -0
- package/es5/web/images/annotation-insert.svg +10 -0
- package/es5/web/images/annotation-key.svg +11 -0
- package/es5/web/images/annotation-newparagraph.svg +11 -0
- package/es5/web/images/annotation-noicon.svg +7 -0
- package/es5/web/images/annotation-note.svg +42 -0
- package/es5/web/images/annotation-paragraph.svg +16 -0
- package/es5/web/images/loading-icon.gif +0 -0
- package/es5/web/images/shadow.png +0 -0
- package/es5/web/images/texture.png +0 -0
- package/es5/web/pdf_viewer.css +407 -0
- package/es5/web/pdf_viewer.js +7757 -0
- package/es5/web/pdf_viewer.js.map +1 -0
- package/image_decoders/pdf.image_decoders.js +2887 -4094
- package/image_decoders/pdf.image_decoders.js.map +1 -1
- package/image_decoders/pdf.image_decoders.min.js +22 -1
- package/lib/README.md +7 -0
- package/lib/core/annotation.js +855 -778
- package/lib/core/arithmetic_decoder.js +325 -311
- package/lib/core/bidi.js +117 -50
- package/lib/core/ccitt.js +251 -89
- package/lib/core/ccitt_stream.js +26 -16
- package/lib/core/cff_parser.js +525 -197
- package/lib/core/charsets.js +6 -5
- package/lib/core/chunked_stream.js +541 -406
- package/lib/core/cmap.js +368 -253
- package/lib/core/colorspace.js +781 -800
- package/lib/core/core_utils.js +152 -0
- package/lib/core/crypto.js +609 -422
- package/lib/core/document.js +649 -481
- package/lib/core/encodings.js +33 -24
- package/lib/core/evaluator.js +1471 -736
- package/lib/core/font_renderer.js +289 -149
- package/lib/core/fonts.js +1067 -413
- package/lib/core/function.js +517 -287
- package/lib/core/glyphlist.js +4529 -4527
- package/lib/core/image.js +232 -114
- package/lib/core/image_utils.js +94 -0
- package/lib/core/jbig2.js +711 -342
- package/lib/core/jbig2_stream.js +31 -19
- package/lib/core/jpeg_stream.js +151 -26
- package/lib/core/jpg.js +433 -181
- package/lib/core/jpx.js +551 -143
- package/lib/core/jpx_stream.js +40 -28
- package/lib/core/metrics.js +2931 -2931
- package/lib/core/murmurhash3.js +104 -97
- package/lib/core/obj.js +1561 -1053
- package/lib/core/operator_list.js +192 -64
- package/lib/core/parser.js +1162 -864
- package/lib/core/pattern.js +224 -75
- package/lib/core/pdf_manager.js +154 -285
- package/lib/core/primitives.js +145 -69
- package/lib/core/ps_parser.js +212 -162
- package/lib/core/standard_fonts.js +245 -244
- package/lib/core/stream.js +353 -81
- package/lib/core/type1_parser.js +218 -68
- package/lib/core/unicode.js +1682 -1655
- package/lib/core/worker.js +233 -302
- package/lib/core/worker_stream.js +168 -0
- package/lib/display/annotation_layer.js +808 -862
- package/lib/display/api.js +1778 -1462
- package/lib/display/api_compatibility.js +14 -9
- package/lib/display/canvas.js +463 -140
- package/lib/display/content_disposition.js +86 -58
- package/lib/display/display_utils.js +524 -0
- package/lib/display/fetch_stream.js +202 -274
- package/lib/display/font_loader.js +311 -333
- package/lib/display/metadata.js +98 -88
- package/lib/display/network.js +343 -347
- package/lib/display/network_utils.js +46 -26
- package/lib/display/node_stream.js +326 -404
- package/lib/display/pattern_helper.js +168 -69
- package/lib/display/svg.js +1296 -885
- package/lib/display/text_layer.js +229 -103
- package/lib/display/transport_stream.js +290 -250
- package/lib/display/webgl.js +116 -83
- package/lib/display/worker_options.js +6 -5
- package/lib/display/xml_parser.js +358 -337
- package/lib/examples/node/domstubs.js +95 -39
- package/lib/pdf.js +49 -31
- package/lib/pdf.worker.js +7 -5
- package/lib/shared/compatibility.js +3 -145
- package/lib/shared/is_node.js +8 -7
- package/lib/shared/message_handler.js +367 -314
- package/lib/shared/util.js +421 -415
- package/lib/test/unit/annotation_spec.js +1570 -690
- package/lib/test/unit/api_spec.js +855 -493
- package/lib/test/unit/bidi_spec.js +12 -12
- package/lib/test/unit/cff_parser_spec.js +88 -61
- package/lib/test/unit/clitests_helper.js +9 -12
- package/lib/test/unit/cmap_spec.js +140 -88
- package/lib/test/unit/colorspace_spec.js +204 -152
- package/lib/test/unit/core_utils_spec.js +211 -0
- package/lib/test/unit/crypto_spec.js +194 -182
- package/lib/test/unit/custom_spec.js +50 -64
- package/lib/test/unit/display_svg_spec.js +53 -38
- package/lib/test/unit/display_utils_spec.js +263 -0
- package/lib/test/unit/document_spec.js +17 -22
- package/lib/test/unit/encodings_spec.js +15 -57
- package/lib/test/unit/evaluator_spec.js +90 -83
- package/lib/test/unit/fetch_stream_spec.js +111 -0
- package/lib/test/unit/function_spec.js +219 -205
- package/lib/test/unit/jasmine-boot.js +68 -39
- package/lib/test/unit/message_handler_spec.js +187 -160
- package/lib/test/unit/metadata_spec.js +87 -34
- package/lib/test/unit/murmurhash3_spec.js +13 -13
- package/lib/test/unit/network_spec.js +26 -59
- package/lib/test/unit/network_utils_spec.js +187 -121
- package/lib/test/unit/node_stream_spec.js +98 -90
- package/lib/test/unit/parser_spec.js +173 -131
- package/lib/test/unit/pdf_find_controller_spec.js +148 -67
- package/lib/test/unit/pdf_find_utils_spec.js +35 -34
- package/lib/test/unit/pdf_history_spec.js +45 -33
- package/lib/test/unit/primitives_spec.js +161 -126
- package/lib/test/unit/stream_spec.js +22 -15
- package/lib/test/unit/test_utils.js +149 -98
- package/lib/test/unit/testreporter.js +36 -18
- package/lib/test/unit/type1_parser_spec.js +46 -44
- package/lib/test/unit/ui_utils_spec.js +388 -372
- package/lib/test/unit/unicode_spec.js +49 -46
- package/lib/test/unit/util_spec.js +144 -248
- package/lib/web/annotation_layer_builder.js +75 -95
- package/lib/web/app.js +1538 -1147
- package/lib/web/app_options.js +116 -104
- package/lib/web/base_viewer.js +950 -775
- package/lib/web/chromecom.js +217 -225
- package/lib/web/debugger.js +236 -148
- package/lib/web/download_manager.js +50 -50
- package/lib/web/firefox_print_service.js +51 -33
- package/lib/web/firefoxcom.js +225 -352
- package/lib/web/genericcom.js +30 -93
- package/lib/web/genericl10n.js +26 -143
- package/lib/web/grab_to_pan.js +57 -33
- package/lib/web/interfaces.js +105 -232
- package/lib/web/overlay_manager.js +73 -227
- package/lib/web/password_prompt.js +44 -62
- package/lib/web/pdf_attachment_viewer.js +118 -123
- package/lib/web/pdf_cursor_tools.js +89 -93
- package/lib/web/pdf_document_properties.js +242 -281
- package/lib/web/pdf_find_bar.js +157 -163
- package/lib/web/pdf_find_controller.js +598 -454
- package/lib/web/pdf_find_utils.js +32 -16
- package/lib/web/pdf_history.js +481 -355
- package/lib/web/pdf_link_service.js +355 -323
- package/lib/web/pdf_outline_viewer.js +167 -152
- package/lib/web/pdf_page_view.js +511 -457
- package/lib/web/pdf_presentation_mode.js +347 -335
- package/lib/web/pdf_print_service.js +133 -103
- package/lib/web/pdf_rendering_queue.js +98 -100
- package/lib/web/pdf_sidebar.js +323 -299
- package/lib/web/pdf_sidebar_resizer.js +107 -108
- package/lib/web/pdf_single_page_viewer.js +94 -146
- package/lib/web/pdf_thumbnail_view.js +319 -269
- package/lib/web/pdf_thumbnail_viewer.js +219 -199
- package/lib/web/pdf_viewer.component.js +111 -32
- package/lib/web/pdf_viewer.js +61 -101
- package/lib/web/preferences.js +87 -272
- package/lib/web/secondary_toolbar.js +207 -220
- package/lib/web/text_layer_builder.js +322 -322
- package/lib/web/toolbar.js +227 -180
- package/lib/web/ui_utils.js +476 -421
- package/lib/web/view_history.js +59 -208
- package/lib/web/viewer_compatibility.js +9 -6
- package/package.json +2 -9
- package/web/pdf_viewer.css +36 -22
- package/web/pdf_viewer.js +4407 -4516
- package/web/pdf_viewer.js.map +1 -1
- package/webpack.js +14 -5
- package/external/streams/streams-lib.js +0 -3962
- package/external/url/url-lib.js +0 -627
- package/lib/display/dom_utils.js +0 -441
- package/lib/shared/streams_polyfill.js +0 -39
- package/lib/shared/url_polyfill.js +0 -50
- package/lib/test/unit/dom_utils_spec.js +0 -89
- package/lib/web/dom_events.js +0 -140
package/lib/core/jpg.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* @licstart The following is the entire license notice for the
|
3
3
|
* Javascript code in this page
|
4
4
|
*
|
5
|
-
* Copyright
|
5
|
+
* Copyright 2020 Mozilla Foundation
|
6
6
|
*
|
7
7
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
* you may not use this file except in compliance with the License.
|
@@ -19,45 +19,34 @@
|
|
19
19
|
* @licend The above is the entire license notice for the
|
20
20
|
* Javascript code in this page
|
21
21
|
*/
|
22
|
-
|
22
|
+
"use strict";
|
23
23
|
|
24
24
|
Object.defineProperty(exports, "__esModule", {
|
25
25
|
value: true
|
26
26
|
});
|
27
|
-
exports.JpegImage =
|
27
|
+
exports.JpegImage = void 0;
|
28
28
|
|
29
|
-
var
|
29
|
+
var _util = require("../shared/util.js");
|
30
30
|
|
31
|
-
var
|
31
|
+
var _core_utils = require("./core_utils.js");
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
class JpegError extends _util.BaseException {
|
34
|
+
constructor(msg) {
|
35
|
+
super(`JPEG error: ${msg}`);
|
36
36
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
function DNLMarkerError(message, scanLines) {
|
44
|
-
this.message = message;
|
37
|
+
|
38
|
+
}
|
39
|
+
|
40
|
+
class DNLMarkerError extends _util.BaseException {
|
41
|
+
constructor(message, scanLines) {
|
42
|
+
super(message);
|
45
43
|
this.scanLines = scanLines;
|
46
44
|
}
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
var EOIMarkerError = function EOIMarkerErrorClosure() {
|
53
|
-
function EOIMarkerError(message) {
|
54
|
-
this.message = message;
|
55
|
-
}
|
56
|
-
EOIMarkerError.prototype = new Error();
|
57
|
-
EOIMarkerError.prototype.name = 'EOIMarkerError';
|
58
|
-
EOIMarkerError.constructor = EOIMarkerError;
|
59
|
-
return EOIMarkerError;
|
60
|
-
}();
|
45
|
+
|
46
|
+
}
|
47
|
+
|
48
|
+
class EOIMarkerError extends _util.BaseException {}
|
49
|
+
|
61
50
|
var JpegImage = function JpegImageClosure() {
|
62
51
|
var dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);
|
63
52
|
var dctCos1 = 4017;
|
@@ -68,40 +57,45 @@ var JpegImage = function JpegImageClosure() {
|
|
68
57
|
var dctSin6 = 3784;
|
69
58
|
var dctSqrt2 = 5793;
|
70
59
|
var dctSqrt1d2 = 2896;
|
71
|
-
function JpegImage() {
|
72
|
-
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
73
|
-
_ref$decodeTransform = _ref.decodeTransform,
|
74
|
-
decodeTransform = _ref$decodeTransform === undefined ? null : _ref$decodeTransform,
|
75
|
-
_ref$colorTransform = _ref.colorTransform,
|
76
|
-
colorTransform = _ref$colorTransform === undefined ? -1 : _ref$colorTransform;
|
77
60
|
|
61
|
+
function JpegImage({
|
62
|
+
decodeTransform = null,
|
63
|
+
colorTransform = -1
|
64
|
+
} = {}) {
|
78
65
|
this._decodeTransform = decodeTransform;
|
79
66
|
this._colorTransform = colorTransform;
|
80
67
|
}
|
68
|
+
|
81
69
|
function buildHuffmanTable(codeLengths, values) {
|
82
70
|
var k = 0,
|
83
71
|
code = [],
|
84
72
|
i,
|
85
73
|
j,
|
86
74
|
length = 16;
|
75
|
+
|
87
76
|
while (length > 0 && !codeLengths[length - 1]) {
|
88
77
|
length--;
|
89
78
|
}
|
79
|
+
|
90
80
|
code.push({
|
91
81
|
children: [],
|
92
82
|
index: 0
|
93
83
|
});
|
94
84
|
var p = code[0],
|
95
85
|
q;
|
86
|
+
|
96
87
|
for (i = 0; i < length; i++) {
|
97
88
|
for (j = 0; j < codeLengths[i]; j++) {
|
98
89
|
p = code.pop();
|
99
90
|
p.children[p.index] = values[k];
|
91
|
+
|
100
92
|
while (p.index > 0) {
|
101
93
|
p = code.pop();
|
102
94
|
}
|
95
|
+
|
103
96
|
p.index++;
|
104
97
|
code.push(p);
|
98
|
+
|
105
99
|
while (code.length <= i) {
|
106
100
|
code.push(q = {
|
107
101
|
children: [],
|
@@ -110,8 +104,10 @@ var JpegImage = function JpegImageClosure() {
|
|
110
104
|
p.children[p.index] = q.children;
|
111
105
|
p = q;
|
112
106
|
}
|
107
|
+
|
113
108
|
k++;
|
114
109
|
}
|
110
|
+
|
115
111
|
if (i + 1 < length) {
|
116
112
|
code.push(q = {
|
117
113
|
children: [],
|
@@ -121,145 +117,194 @@ var JpegImage = function JpegImageClosure() {
|
|
121
117
|
p = q;
|
122
118
|
}
|
123
119
|
}
|
120
|
+
|
124
121
|
return code[0].children;
|
125
122
|
}
|
123
|
+
|
126
124
|
function getBlockBufferOffset(component, row, col) {
|
127
125
|
return 64 * ((component.blocksPerLine + 1) * row + col);
|
128
126
|
}
|
129
|
-
function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
|
130
|
-
var parseDNLMarker = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
|
131
127
|
|
128
|
+
function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive, parseDNLMarker = false) {
|
132
129
|
var mcusPerLine = frame.mcusPerLine;
|
133
130
|
var progressive = frame.progressive;
|
134
131
|
var startOffset = offset,
|
135
132
|
bitsData = 0,
|
136
133
|
bitsCount = 0;
|
134
|
+
|
137
135
|
function readBit() {
|
138
136
|
if (bitsCount > 0) {
|
139
137
|
bitsCount--;
|
140
138
|
return bitsData >> bitsCount & 1;
|
141
139
|
}
|
140
|
+
|
142
141
|
bitsData = data[offset++];
|
143
|
-
|
142
|
+
|
143
|
+
if (bitsData === 0xff) {
|
144
144
|
var nextByte = data[offset++];
|
145
|
+
|
145
146
|
if (nextByte) {
|
146
|
-
if (nextByte ===
|
147
|
+
if (nextByte === 0xdc && parseDNLMarker) {
|
147
148
|
offset += 2;
|
148
|
-
|
149
|
+
const scanLines = (0, _core_utils.readUint16)(data, offset);
|
150
|
+
offset += 2;
|
151
|
+
|
149
152
|
if (scanLines > 0 && scanLines !== frame.scanLines) {
|
150
|
-
throw new DNLMarkerError(
|
153
|
+
throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data", scanLines);
|
154
|
+
}
|
155
|
+
} else if (nextByte === 0xd9) {
|
156
|
+
if (parseDNLMarker) {
|
157
|
+
const maybeScanLines = blockRow * 8;
|
158
|
+
|
159
|
+
if (maybeScanLines > 0 && maybeScanLines < frame.scanLines / 10) {
|
160
|
+
throw new DNLMarkerError("Found EOI marker (0xFFD9) while parsing scan data, " + "possibly caused by incorrect `scanLines` parameter", maybeScanLines);
|
161
|
+
}
|
151
162
|
}
|
152
|
-
|
153
|
-
throw new EOIMarkerError(
|
163
|
+
|
164
|
+
throw new EOIMarkerError("Found EOI marker (0xFFD9) while parsing scan data");
|
154
165
|
}
|
155
|
-
|
166
|
+
|
167
|
+
throw new JpegError(`unexpected marker ${(bitsData << 8 | nextByte).toString(16)}`);
|
156
168
|
}
|
157
169
|
}
|
170
|
+
|
158
171
|
bitsCount = 7;
|
159
172
|
return bitsData >>> 7;
|
160
173
|
}
|
174
|
+
|
161
175
|
function decodeHuffman(tree) {
|
162
176
|
var node = tree;
|
177
|
+
|
163
178
|
while (true) {
|
164
179
|
node = node[readBit()];
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
180
|
+
|
181
|
+
switch (typeof node) {
|
182
|
+
case "number":
|
183
|
+
return node;
|
184
|
+
|
185
|
+
case "object":
|
186
|
+
continue;
|
170
187
|
}
|
188
|
+
|
189
|
+
throw new JpegError("invalid huffman sequence");
|
171
190
|
}
|
172
191
|
}
|
192
|
+
|
173
193
|
function receive(length) {
|
174
194
|
var n = 0;
|
195
|
+
|
175
196
|
while (length > 0) {
|
176
197
|
n = n << 1 | readBit();
|
177
198
|
length--;
|
178
199
|
}
|
200
|
+
|
179
201
|
return n;
|
180
202
|
}
|
203
|
+
|
181
204
|
function receiveAndExtend(length) {
|
182
205
|
if (length === 1) {
|
183
206
|
return readBit() === 1 ? 1 : -1;
|
184
207
|
}
|
208
|
+
|
185
209
|
var n = receive(length);
|
210
|
+
|
186
211
|
if (n >= 1 << length - 1) {
|
187
212
|
return n;
|
188
213
|
}
|
214
|
+
|
189
215
|
return n + (-1 << length) + 1;
|
190
216
|
}
|
217
|
+
|
191
218
|
function decodeBaseline(component, offset) {
|
192
219
|
var t = decodeHuffman(component.huffmanTableDC);
|
193
220
|
var diff = t === 0 ? 0 : receiveAndExtend(t);
|
194
221
|
component.blockData[offset] = component.pred += diff;
|
195
222
|
var k = 1;
|
223
|
+
|
196
224
|
while (k < 64) {
|
197
225
|
var rs = decodeHuffman(component.huffmanTableAC);
|
198
226
|
var s = rs & 15,
|
199
227
|
r = rs >> 4;
|
228
|
+
|
200
229
|
if (s === 0) {
|
201
230
|
if (r < 15) {
|
202
231
|
break;
|
203
232
|
}
|
233
|
+
|
204
234
|
k += 16;
|
205
235
|
continue;
|
206
236
|
}
|
237
|
+
|
207
238
|
k += r;
|
208
239
|
var z = dctZigZag[k];
|
209
240
|
component.blockData[offset + z] = receiveAndExtend(s);
|
210
241
|
k++;
|
211
242
|
}
|
212
243
|
}
|
244
|
+
|
213
245
|
function decodeDCFirst(component, offset) {
|
214
246
|
var t = decodeHuffman(component.huffmanTableDC);
|
215
247
|
var diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
|
216
248
|
component.blockData[offset] = component.pred += diff;
|
217
249
|
}
|
250
|
+
|
218
251
|
function decodeDCSuccessive(component, offset) {
|
219
252
|
component.blockData[offset] |= readBit() << successive;
|
220
253
|
}
|
254
|
+
|
221
255
|
var eobrun = 0;
|
256
|
+
|
222
257
|
function decodeACFirst(component, offset) {
|
223
258
|
if (eobrun > 0) {
|
224
259
|
eobrun--;
|
225
260
|
return;
|
226
261
|
}
|
262
|
+
|
227
263
|
var k = spectralStart,
|
228
264
|
e = spectralEnd;
|
265
|
+
|
229
266
|
while (k <= e) {
|
230
267
|
var rs = decodeHuffman(component.huffmanTableAC);
|
231
268
|
var s = rs & 15,
|
232
269
|
r = rs >> 4;
|
270
|
+
|
233
271
|
if (s === 0) {
|
234
272
|
if (r < 15) {
|
235
273
|
eobrun = receive(r) + (1 << r) - 1;
|
236
274
|
break;
|
237
275
|
}
|
276
|
+
|
238
277
|
k += 16;
|
239
278
|
continue;
|
240
279
|
}
|
280
|
+
|
241
281
|
k += r;
|
242
282
|
var z = dctZigZag[k];
|
243
283
|
component.blockData[offset + z] = receiveAndExtend(s) * (1 << successive);
|
244
284
|
k++;
|
245
285
|
}
|
246
286
|
}
|
287
|
+
|
247
288
|
var successiveACState = 0,
|
248
289
|
successiveACNextValue;
|
290
|
+
|
249
291
|
function decodeACSuccessive(component, offset) {
|
250
292
|
var k = spectralStart;
|
251
293
|
var e = spectralEnd;
|
252
294
|
var r = 0;
|
253
295
|
var s;
|
254
296
|
var rs;
|
297
|
+
|
255
298
|
while (k <= e) {
|
256
|
-
|
257
|
-
|
299
|
+
const offsetZ = offset + dctZigZag[k];
|
300
|
+
const sign = component.blockData[offsetZ] < 0 ? -1 : 1;
|
301
|
+
|
258
302
|
switch (successiveACState) {
|
259
303
|
case 0:
|
260
304
|
rs = decodeHuffman(component.huffmanTableAC);
|
261
305
|
s = rs & 15;
|
262
306
|
r = rs >> 4;
|
307
|
+
|
263
308
|
if (s === 0) {
|
264
309
|
if (r < 15) {
|
265
310
|
eobrun = receive(r) + (1 << r);
|
@@ -270,23 +315,29 @@ var JpegImage = function JpegImageClosure() {
|
|
270
315
|
}
|
271
316
|
} else {
|
272
317
|
if (s !== 1) {
|
273
|
-
throw new JpegError(
|
318
|
+
throw new JpegError("invalid ACn encoding");
|
274
319
|
}
|
320
|
+
|
275
321
|
successiveACNextValue = receiveAndExtend(s);
|
276
322
|
successiveACState = r ? 2 : 3;
|
277
323
|
}
|
324
|
+
|
278
325
|
continue;
|
326
|
+
|
279
327
|
case 1:
|
280
328
|
case 2:
|
281
329
|
if (component.blockData[offsetZ]) {
|
282
330
|
component.blockData[offsetZ] += sign * (readBit() << successive);
|
283
331
|
} else {
|
284
332
|
r--;
|
333
|
+
|
285
334
|
if (r === 0) {
|
286
335
|
successiveACState = successiveACState === 2 ? 3 : 0;
|
287
336
|
}
|
288
337
|
}
|
338
|
+
|
289
339
|
break;
|
340
|
+
|
290
341
|
case 3:
|
291
342
|
if (component.blockData[offsetZ]) {
|
292
343
|
component.blockData[offsetZ] += sign * (readBit() << successive);
|
@@ -294,39 +345,51 @@ var JpegImage = function JpegImageClosure() {
|
|
294
345
|
component.blockData[offsetZ] = successiveACNextValue << successive;
|
295
346
|
successiveACState = 0;
|
296
347
|
}
|
348
|
+
|
297
349
|
break;
|
350
|
+
|
298
351
|
case 4:
|
299
352
|
if (component.blockData[offsetZ]) {
|
300
353
|
component.blockData[offsetZ] += sign * (readBit() << successive);
|
301
354
|
}
|
355
|
+
|
302
356
|
break;
|
303
357
|
}
|
358
|
+
|
304
359
|
k++;
|
305
360
|
}
|
361
|
+
|
306
362
|
if (successiveACState === 4) {
|
307
363
|
eobrun--;
|
364
|
+
|
308
365
|
if (eobrun === 0) {
|
309
366
|
successiveACState = 0;
|
310
367
|
}
|
311
368
|
}
|
312
369
|
}
|
370
|
+
|
371
|
+
let blockRow = 0;
|
372
|
+
|
313
373
|
function decodeMcu(component, decode, mcu, row, col) {
|
314
374
|
var mcuRow = mcu / mcusPerLine | 0;
|
315
375
|
var mcuCol = mcu % mcusPerLine;
|
316
|
-
|
376
|
+
blockRow = mcuRow * component.v + row;
|
317
377
|
var blockCol = mcuCol * component.h + col;
|
318
378
|
var offset = getBlockBufferOffset(component, blockRow, blockCol);
|
319
379
|
decode(component, offset);
|
320
380
|
}
|
381
|
+
|
321
382
|
function decodeBlock(component, decode, mcu) {
|
322
|
-
|
383
|
+
blockRow = mcu / component.blocksPerLine | 0;
|
323
384
|
var blockCol = mcu % component.blocksPerLine;
|
324
385
|
var offset = getBlockBufferOffset(component, blockRow, blockCol);
|
325
386
|
decode(component, offset);
|
326
387
|
}
|
388
|
+
|
327
389
|
var componentsLength = components.length;
|
328
390
|
var component, i, j, k, n;
|
329
391
|
var decodeFn;
|
392
|
+
|
330
393
|
if (progressive) {
|
331
394
|
if (spectralStart === 0) {
|
332
395
|
decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
|
@@ -336,23 +399,31 @@ var JpegImage = function JpegImageClosure() {
|
|
336
399
|
} else {
|
337
400
|
decodeFn = decodeBaseline;
|
338
401
|
}
|
402
|
+
|
339
403
|
var mcu = 0,
|
340
404
|
fileMarker;
|
341
405
|
var mcuExpected;
|
406
|
+
|
342
407
|
if (componentsLength === 1) {
|
343
408
|
mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
|
344
409
|
} else {
|
345
410
|
mcuExpected = mcusPerLine * frame.mcusPerColumn;
|
346
411
|
}
|
412
|
+
|
347
413
|
var h, v;
|
414
|
+
|
348
415
|
while (mcu < mcuExpected) {
|
349
416
|
var mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;
|
417
|
+
|
350
418
|
for (i = 0; i < componentsLength; i++) {
|
351
419
|
components[i].pred = 0;
|
352
420
|
}
|
421
|
+
|
353
422
|
eobrun = 0;
|
423
|
+
|
354
424
|
if (componentsLength === 1) {
|
355
425
|
component = components[0];
|
426
|
+
|
356
427
|
for (n = 0; n < mcuToRead; n++) {
|
357
428
|
decodeBlock(component, decodeFn, mcu);
|
358
429
|
mcu++;
|
@@ -363,47 +434,62 @@ var JpegImage = function JpegImageClosure() {
|
|
363
434
|
component = components[i];
|
364
435
|
h = component.h;
|
365
436
|
v = component.v;
|
437
|
+
|
366
438
|
for (j = 0; j < v; j++) {
|
367
439
|
for (k = 0; k < h; k++) {
|
368
440
|
decodeMcu(component, decodeFn, mcu, j, k);
|
369
441
|
}
|
370
442
|
}
|
371
443
|
}
|
444
|
+
|
372
445
|
mcu++;
|
373
446
|
}
|
374
447
|
}
|
448
|
+
|
375
449
|
bitsCount = 0;
|
376
450
|
fileMarker = findNextFileMarker(data, offset);
|
377
|
-
|
378
|
-
|
451
|
+
|
452
|
+
if (!fileMarker) {
|
453
|
+
break;
|
454
|
+
} else if (fileMarker.invalid) {
|
455
|
+
(0, _util.warn)("decodeScan - unexpected MCU data, current marker is: " + fileMarker.invalid);
|
379
456
|
offset = fileMarker.offset;
|
380
457
|
}
|
458
|
+
|
381
459
|
var marker = fileMarker && fileMarker.marker;
|
382
|
-
|
383
|
-
|
460
|
+
|
461
|
+
if (!marker || marker <= 0xff00) {
|
462
|
+
throw new JpegError("decodeScan - a valid marker was not found.");
|
384
463
|
}
|
385
|
-
|
464
|
+
|
465
|
+
if (marker >= 0xffd0 && marker <= 0xffd7) {
|
386
466
|
offset += 2;
|
387
467
|
} else {
|
388
468
|
break;
|
389
469
|
}
|
390
470
|
}
|
471
|
+
|
391
472
|
fileMarker = findNextFileMarker(data, offset);
|
473
|
+
|
392
474
|
if (fileMarker && fileMarker.invalid) {
|
393
|
-
(0, _util.warn)(
|
475
|
+
(0, _util.warn)("decodeScan - unexpected Scan data, current marker is: " + fileMarker.invalid);
|
394
476
|
offset = fileMarker.offset;
|
395
477
|
}
|
478
|
+
|
396
479
|
return offset - startOffset;
|
397
480
|
}
|
481
|
+
|
398
482
|
function quantizeAndInverse(component, blockBufferOffset, p) {
|
399
483
|
var qt = component.quantizationTable,
|
400
484
|
blockData = component.blockData;
|
401
485
|
var v0, v1, v2, v3, v4, v5, v6, v7;
|
402
486
|
var p0, p1, p2, p3, p4, p5, p6, p7;
|
403
487
|
var t;
|
488
|
+
|
404
489
|
if (!qt) {
|
405
|
-
throw new JpegError(
|
490
|
+
throw new JpegError("missing required Quantization Table.");
|
406
491
|
}
|
492
|
+
|
407
493
|
for (var row = 0; row < 64; row += 8) {
|
408
494
|
p0 = blockData[blockBufferOffset + row];
|
409
495
|
p1 = blockData[blockBufferOffset + row + 1];
|
@@ -414,6 +500,7 @@ var JpegImage = function JpegImageClosure() {
|
|
414
500
|
p6 = blockData[blockBufferOffset + row + 6];
|
415
501
|
p7 = blockData[blockBufferOffset + row + 7];
|
416
502
|
p0 *= qt[row];
|
503
|
+
|
417
504
|
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
|
418
505
|
t = dctSqrt2 * p0 + 512 >> 10;
|
419
506
|
p[row] = t;
|
@@ -426,6 +513,7 @@ var JpegImage = function JpegImageClosure() {
|
|
426
513
|
p[row + 7] = t;
|
427
514
|
continue;
|
428
515
|
}
|
516
|
+
|
429
517
|
p1 *= qt[row + 1];
|
430
518
|
p2 *= qt[row + 2];
|
431
519
|
p3 *= qt[row + 3];
|
@@ -469,6 +557,7 @@ var JpegImage = function JpegImageClosure() {
|
|
469
557
|
p[row + 3] = v3 + v4;
|
470
558
|
p[row + 4] = v3 - v4;
|
471
559
|
}
|
560
|
+
|
472
561
|
for (var col = 0; col < 8; ++col) {
|
473
562
|
p0 = p[col];
|
474
563
|
p1 = p[col + 8];
|
@@ -478,9 +567,18 @@ var JpegImage = function JpegImageClosure() {
|
|
478
567
|
p5 = p[col + 40];
|
479
568
|
p6 = p[col + 48];
|
480
569
|
p7 = p[col + 56];
|
570
|
+
|
481
571
|
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
|
482
572
|
t = dctSqrt2 * p0 + 8192 >> 14;
|
483
|
-
|
573
|
+
|
574
|
+
if (t < -2040) {
|
575
|
+
t = 0;
|
576
|
+
} else if (t >= 2024) {
|
577
|
+
t = 255;
|
578
|
+
} else {
|
579
|
+
t = t + 2056 >> 4;
|
580
|
+
}
|
581
|
+
|
484
582
|
blockData[blockBufferOffset + col] = t;
|
485
583
|
blockData[blockBufferOffset + col + 8] = t;
|
486
584
|
blockData[blockBufferOffset + col + 16] = t;
|
@@ -491,6 +589,7 @@ var JpegImage = function JpegImageClosure() {
|
|
491
589
|
blockData[blockBufferOffset + col + 56] = t;
|
492
590
|
continue;
|
493
591
|
}
|
592
|
+
|
494
593
|
v0 = dctSqrt2 * p0 + 2048 >> 12;
|
495
594
|
v1 = dctSqrt2 * p4 + 2048 >> 12;
|
496
595
|
v2 = p2;
|
@@ -526,14 +625,71 @@ var JpegImage = function JpegImageClosure() {
|
|
526
625
|
p5 = v2 - v5;
|
527
626
|
p3 = v3 + v4;
|
528
627
|
p4 = v3 - v4;
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
628
|
+
|
629
|
+
if (p0 < 16) {
|
630
|
+
p0 = 0;
|
631
|
+
} else if (p0 >= 4080) {
|
632
|
+
p0 = 255;
|
633
|
+
} else {
|
634
|
+
p0 >>= 4;
|
635
|
+
}
|
636
|
+
|
637
|
+
if (p1 < 16) {
|
638
|
+
p1 = 0;
|
639
|
+
} else if (p1 >= 4080) {
|
640
|
+
p1 = 255;
|
641
|
+
} else {
|
642
|
+
p1 >>= 4;
|
643
|
+
}
|
644
|
+
|
645
|
+
if (p2 < 16) {
|
646
|
+
p2 = 0;
|
647
|
+
} else if (p2 >= 4080) {
|
648
|
+
p2 = 255;
|
649
|
+
} else {
|
650
|
+
p2 >>= 4;
|
651
|
+
}
|
652
|
+
|
653
|
+
if (p3 < 16) {
|
654
|
+
p3 = 0;
|
655
|
+
} else if (p3 >= 4080) {
|
656
|
+
p3 = 255;
|
657
|
+
} else {
|
658
|
+
p3 >>= 4;
|
659
|
+
}
|
660
|
+
|
661
|
+
if (p4 < 16) {
|
662
|
+
p4 = 0;
|
663
|
+
} else if (p4 >= 4080) {
|
664
|
+
p4 = 255;
|
665
|
+
} else {
|
666
|
+
p4 >>= 4;
|
667
|
+
}
|
668
|
+
|
669
|
+
if (p5 < 16) {
|
670
|
+
p5 = 0;
|
671
|
+
} else if (p5 >= 4080) {
|
672
|
+
p5 = 255;
|
673
|
+
} else {
|
674
|
+
p5 >>= 4;
|
675
|
+
}
|
676
|
+
|
677
|
+
if (p6 < 16) {
|
678
|
+
p6 = 0;
|
679
|
+
} else if (p6 >= 4080) {
|
680
|
+
p6 = 255;
|
681
|
+
} else {
|
682
|
+
p6 >>= 4;
|
683
|
+
}
|
684
|
+
|
685
|
+
if (p7 < 16) {
|
686
|
+
p7 = 0;
|
687
|
+
} else if (p7 >= 4080) {
|
688
|
+
p7 = 255;
|
689
|
+
} else {
|
690
|
+
p7 >>= 4;
|
691
|
+
}
|
692
|
+
|
537
693
|
blockData[blockBufferOffset + col] = p0;
|
538
694
|
blockData[blockBufferOffset + col + 8] = p1;
|
539
695
|
blockData[blockBufferOffset + col + 16] = p2;
|
@@ -544,76 +700,81 @@ var JpegImage = function JpegImageClosure() {
|
|
544
700
|
blockData[blockBufferOffset + col + 56] = p7;
|
545
701
|
}
|
546
702
|
}
|
703
|
+
|
547
704
|
function buildComponentData(frame, component) {
|
548
705
|
var blocksPerLine = component.blocksPerLine;
|
549
706
|
var blocksPerColumn = component.blocksPerColumn;
|
550
707
|
var computationBuffer = new Int16Array(64);
|
708
|
+
|
551
709
|
for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
|
552
710
|
for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
|
553
711
|
var offset = getBlockBufferOffset(component, blockRow, blockCol);
|
554
712
|
quantizeAndInverse(component, offset, computationBuffer);
|
555
713
|
}
|
556
714
|
}
|
715
|
+
|
557
716
|
return component.blockData;
|
558
717
|
}
|
559
|
-
function findNextFileMarker(data, currentPos) {
|
560
|
-
var startPos = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentPos;
|
561
718
|
|
562
|
-
|
563
|
-
|
564
|
-
}
|
565
|
-
var maxPos = data.length - 1;
|
719
|
+
function findNextFileMarker(data, currentPos, startPos = currentPos) {
|
720
|
+
const maxPos = data.length - 1;
|
566
721
|
var newPos = startPos < currentPos ? startPos : currentPos;
|
722
|
+
|
567
723
|
if (currentPos >= maxPos) {
|
568
724
|
return null;
|
569
725
|
}
|
570
|
-
|
571
|
-
|
726
|
+
|
727
|
+
var currentMarker = (0, _core_utils.readUint16)(data, currentPos);
|
728
|
+
|
729
|
+
if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) {
|
572
730
|
return {
|
573
731
|
invalid: null,
|
574
732
|
marker: currentMarker,
|
575
733
|
offset: currentPos
|
576
734
|
};
|
577
735
|
}
|
578
|
-
|
579
|
-
|
736
|
+
|
737
|
+
var newMarker = (0, _core_utils.readUint16)(data, newPos);
|
738
|
+
|
739
|
+
while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) {
|
580
740
|
if (++newPos >= maxPos) {
|
581
741
|
return null;
|
582
742
|
}
|
583
|
-
|
743
|
+
|
744
|
+
newMarker = (0, _core_utils.readUint16)(data, newPos);
|
584
745
|
}
|
746
|
+
|
585
747
|
return {
|
586
748
|
invalid: currentMarker.toString(16),
|
587
749
|
marker: newMarker,
|
588
750
|
offset: newPos
|
589
751
|
};
|
590
752
|
}
|
591
|
-
JpegImage.prototype = {
|
592
|
-
parse: function parse(data) {
|
593
|
-
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
594
|
-
_ref2$dnlScanLines = _ref2.dnlScanLines,
|
595
|
-
dnlScanLines = _ref2$dnlScanLines === undefined ? null : _ref2$dnlScanLines;
|
596
753
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
}
|
754
|
+
JpegImage.prototype = {
|
755
|
+
parse(data, {
|
756
|
+
dnlScanLines = null
|
757
|
+
} = {}) {
|
602
758
|
function readDataBlock() {
|
603
|
-
|
604
|
-
|
759
|
+
const length = (0, _core_utils.readUint16)(data, offset);
|
760
|
+
offset += 2;
|
761
|
+
let endOffset = offset + length - 2;
|
605
762
|
var fileMarker = findNextFileMarker(data, endOffset, offset);
|
763
|
+
|
606
764
|
if (fileMarker && fileMarker.invalid) {
|
607
|
-
(0, _util.warn)(
|
765
|
+
(0, _util.warn)("readDataBlock - incorrect length, current marker is: " + fileMarker.invalid);
|
608
766
|
endOffset = fileMarker.offset;
|
609
767
|
}
|
768
|
+
|
610
769
|
var array = data.subarray(offset, endOffset);
|
611
770
|
offset += array.length;
|
612
771
|
return array;
|
613
772
|
}
|
773
|
+
|
614
774
|
function prepareComponents(frame) {
|
615
775
|
var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
|
616
776
|
var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
|
777
|
+
|
617
778
|
for (var i = 0; i < frame.components.length; i++) {
|
618
779
|
component = frame.components[i];
|
619
780
|
var blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH);
|
@@ -625,45 +786,54 @@ var JpegImage = function JpegImageClosure() {
|
|
625
786
|
component.blocksPerLine = blocksPerLine;
|
626
787
|
component.blocksPerColumn = blocksPerColumn;
|
627
788
|
}
|
789
|
+
|
628
790
|
frame.mcusPerLine = mcusPerLine;
|
629
791
|
frame.mcusPerColumn = mcusPerColumn;
|
630
792
|
}
|
793
|
+
|
631
794
|
var offset = 0;
|
632
795
|
var jfif = null;
|
633
796
|
var adobe = null;
|
634
797
|
var frame, resetInterval;
|
635
|
-
|
798
|
+
let numSOSMarkers = 0;
|
636
799
|
var quantizationTables = [];
|
637
800
|
var huffmanTablesAC = [],
|
638
801
|
huffmanTablesDC = [];
|
639
|
-
|
640
|
-
|
641
|
-
|
802
|
+
let fileMarker = (0, _core_utils.readUint16)(data, offset);
|
803
|
+
offset += 2;
|
804
|
+
|
805
|
+
if (fileMarker !== 0xffd8) {
|
806
|
+
throw new JpegError("SOI not found");
|
642
807
|
}
|
643
|
-
|
644
|
-
|
808
|
+
|
809
|
+
fileMarker = (0, _core_utils.readUint16)(data, offset);
|
810
|
+
offset += 2;
|
811
|
+
|
812
|
+
markerLoop: while (fileMarker !== 0xffd9) {
|
645
813
|
var i, j, l;
|
814
|
+
|
646
815
|
switch (fileMarker) {
|
647
|
-
case
|
648
|
-
case
|
649
|
-
case
|
650
|
-
case
|
651
|
-
case
|
652
|
-
case
|
653
|
-
case
|
654
|
-
case
|
655
|
-
case
|
656
|
-
case
|
657
|
-
case
|
658
|
-
case
|
659
|
-
case
|
660
|
-
case
|
661
|
-
case
|
662
|
-
case
|
663
|
-
case
|
816
|
+
case 0xffe0:
|
817
|
+
case 0xffe1:
|
818
|
+
case 0xffe2:
|
819
|
+
case 0xffe3:
|
820
|
+
case 0xffe4:
|
821
|
+
case 0xffe5:
|
822
|
+
case 0xffe6:
|
823
|
+
case 0xffe7:
|
824
|
+
case 0xffe8:
|
825
|
+
case 0xffe9:
|
826
|
+
case 0xffea:
|
827
|
+
case 0xffeb:
|
828
|
+
case 0xffec:
|
829
|
+
case 0xffed:
|
830
|
+
case 0xffee:
|
831
|
+
case 0xffef:
|
832
|
+
case 0xfffe:
|
664
833
|
var appData = readDataBlock();
|
665
|
-
|
666
|
-
|
834
|
+
|
835
|
+
if (fileMarker === 0xffe0) {
|
836
|
+
if (appData[0] === 0x4a && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) {
|
667
837
|
jfif = {
|
668
838
|
version: {
|
669
839
|
major: appData[5],
|
@@ -678,8 +848,9 @@ var JpegImage = function JpegImageClosure() {
|
|
678
848
|
};
|
679
849
|
}
|
680
850
|
}
|
681
|
-
|
682
|
-
|
851
|
+
|
852
|
+
if (fileMarker === 0xffee) {
|
853
|
+
if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6f && appData[3] === 0x62 && appData[4] === 0x65) {
|
683
854
|
adobe = {
|
684
855
|
version: appData[5] << 8 | appData[6],
|
685
856
|
flags0: appData[7] << 8 | appData[8],
|
@@ -688,14 +859,19 @@ var JpegImage = function JpegImageClosure() {
|
|
688
859
|
};
|
689
860
|
}
|
690
861
|
}
|
862
|
+
|
691
863
|
break;
|
692
|
-
|
693
|
-
|
864
|
+
|
865
|
+
case 0xffdb:
|
866
|
+
const quantizationTablesLength = (0, _core_utils.readUint16)(data, offset);
|
867
|
+
offset += 2;
|
694
868
|
var quantizationTablesEnd = quantizationTablesLength + offset - 2;
|
695
869
|
var z;
|
870
|
+
|
696
871
|
while (offset < quantizationTablesEnd) {
|
697
872
|
var quantizationTableSpec = data[offset++];
|
698
873
|
var tableData = new Uint16Array(64);
|
874
|
+
|
699
875
|
if (quantizationTableSpec >> 4 === 0) {
|
700
876
|
for (j = 0; j < 64; j++) {
|
701
877
|
z = dctZigZag[j];
|
@@ -704,85 +880,109 @@ var JpegImage = function JpegImageClosure() {
|
|
704
880
|
} else if (quantizationTableSpec >> 4 === 1) {
|
705
881
|
for (j = 0; j < 64; j++) {
|
706
882
|
z = dctZigZag[j];
|
707
|
-
tableData[z] = readUint16();
|
883
|
+
tableData[z] = (0, _core_utils.readUint16)(data, offset);
|
884
|
+
offset += 2;
|
708
885
|
}
|
709
886
|
} else {
|
710
|
-
throw new JpegError(
|
887
|
+
throw new JpegError("DQT - invalid table spec");
|
711
888
|
}
|
889
|
+
|
712
890
|
quantizationTables[quantizationTableSpec & 15] = tableData;
|
713
891
|
}
|
892
|
+
|
714
893
|
break;
|
715
|
-
|
716
|
-
case
|
717
|
-
case
|
894
|
+
|
895
|
+
case 0xffc0:
|
896
|
+
case 0xffc1:
|
897
|
+
case 0xffc2:
|
718
898
|
if (frame) {
|
719
|
-
throw new JpegError(
|
899
|
+
throw new JpegError("Only single frame JPEGs supported");
|
720
900
|
}
|
721
|
-
|
901
|
+
|
902
|
+
offset += 2;
|
722
903
|
frame = {};
|
723
|
-
frame.extended = fileMarker ===
|
724
|
-
frame.progressive = fileMarker ===
|
904
|
+
frame.extended = fileMarker === 0xffc1;
|
905
|
+
frame.progressive = fileMarker === 0xffc2;
|
725
906
|
frame.precision = data[offset++];
|
726
|
-
|
907
|
+
const sofScanLines = (0, _core_utils.readUint16)(data, offset);
|
908
|
+
offset += 2;
|
727
909
|
frame.scanLines = dnlScanLines || sofScanLines;
|
728
|
-
frame.samplesPerLine = readUint16();
|
910
|
+
frame.samplesPerLine = (0, _core_utils.readUint16)(data, offset);
|
911
|
+
offset += 2;
|
729
912
|
frame.components = [];
|
730
913
|
frame.componentIds = {};
|
731
914
|
var componentsCount = data[offset++],
|
732
915
|
componentId;
|
733
916
|
var maxH = 0,
|
734
917
|
maxV = 0;
|
918
|
+
|
735
919
|
for (i = 0; i < componentsCount; i++) {
|
736
920
|
componentId = data[offset];
|
737
921
|
var h = data[offset + 1] >> 4;
|
738
922
|
var v = data[offset + 1] & 15;
|
923
|
+
|
739
924
|
if (maxH < h) {
|
740
925
|
maxH = h;
|
741
926
|
}
|
927
|
+
|
742
928
|
if (maxV < v) {
|
743
929
|
maxV = v;
|
744
930
|
}
|
931
|
+
|
745
932
|
var qId = data[offset + 2];
|
746
933
|
l = frame.components.push({
|
747
|
-
h
|
748
|
-
v
|
934
|
+
h,
|
935
|
+
v,
|
749
936
|
quantizationId: qId,
|
750
937
|
quantizationTable: null
|
751
938
|
});
|
752
939
|
frame.componentIds[componentId] = l - 1;
|
753
940
|
offset += 3;
|
754
941
|
}
|
942
|
+
|
755
943
|
frame.maxH = maxH;
|
756
944
|
frame.maxV = maxV;
|
757
945
|
prepareComponents(frame);
|
758
946
|
break;
|
759
|
-
|
760
|
-
|
947
|
+
|
948
|
+
case 0xffc4:
|
949
|
+
const huffmanLength = (0, _core_utils.readUint16)(data, offset);
|
950
|
+
offset += 2;
|
951
|
+
|
761
952
|
for (i = 2; i < huffmanLength;) {
|
762
953
|
var huffmanTableSpec = data[offset++];
|
763
954
|
var codeLengths = new Uint8Array(16);
|
764
955
|
var codeLengthSum = 0;
|
956
|
+
|
765
957
|
for (j = 0; j < 16; j++, offset++) {
|
766
958
|
codeLengthSum += codeLengths[j] = data[offset];
|
767
959
|
}
|
960
|
+
|
768
961
|
var huffmanValues = new Uint8Array(codeLengthSum);
|
962
|
+
|
769
963
|
for (j = 0; j < codeLengthSum; j++, offset++) {
|
770
964
|
huffmanValues[j] = data[offset];
|
771
965
|
}
|
966
|
+
|
772
967
|
i += 17 + codeLengthSum;
|
773
968
|
(huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);
|
774
969
|
}
|
970
|
+
|
775
971
|
break;
|
776
|
-
|
777
|
-
|
778
|
-
|
972
|
+
|
973
|
+
case 0xffdd:
|
974
|
+
offset += 2;
|
975
|
+
resetInterval = (0, _core_utils.readUint16)(data, offset);
|
976
|
+
offset += 2;
|
779
977
|
break;
|
780
|
-
|
781
|
-
|
782
|
-
|
978
|
+
|
979
|
+
case 0xffda:
|
980
|
+
const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;
|
981
|
+
offset += 2;
|
783
982
|
var selectorsCount = data[offset++];
|
784
983
|
var components = [],
|
785
984
|
component;
|
985
|
+
|
786
986
|
for (i = 0; i < selectorsCount; i++) {
|
787
987
|
var componentIndex = frame.componentIds[data[offset++]];
|
788
988
|
component = frame.components[componentIndex];
|
@@ -791,57 +991,76 @@ var JpegImage = function JpegImageClosure() {
|
|
791
991
|
component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];
|
792
992
|
components.push(component);
|
793
993
|
}
|
994
|
+
|
794
995
|
var spectralStart = data[offset++];
|
795
996
|
var spectralEnd = data[offset++];
|
796
997
|
var successiveApproximation = data[offset++];
|
998
|
+
|
797
999
|
try {
|
798
1000
|
var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15, parseDNLMarker);
|
799
1001
|
offset += processed;
|
800
1002
|
} catch (ex) {
|
801
1003
|
if (ex instanceof DNLMarkerError) {
|
802
|
-
(0, _util.warn)(ex.message
|
803
|
-
return this.parse(data, {
|
1004
|
+
(0, _util.warn)(`${ex.message} -- attempting to re-parse the JPEG image.`);
|
1005
|
+
return this.parse(data, {
|
1006
|
+
dnlScanLines: ex.scanLines
|
1007
|
+
});
|
804
1008
|
} else if (ex instanceof EOIMarkerError) {
|
805
|
-
(0, _util.warn)(ex.message
|
1009
|
+
(0, _util.warn)(`${ex.message} -- ignoring the rest of the image data.`);
|
806
1010
|
break markerLoop;
|
807
1011
|
}
|
1012
|
+
|
808
1013
|
throw ex;
|
809
1014
|
}
|
1015
|
+
|
810
1016
|
break;
|
811
|
-
|
1017
|
+
|
1018
|
+
case 0xffdc:
|
812
1019
|
offset += 4;
|
813
1020
|
break;
|
814
|
-
|
815
|
-
|
1021
|
+
|
1022
|
+
case 0xffff:
|
1023
|
+
if (data[offset] !== 0xff) {
|
816
1024
|
offset--;
|
817
1025
|
}
|
1026
|
+
|
818
1027
|
break;
|
1028
|
+
|
819
1029
|
default:
|
820
|
-
|
821
|
-
|
822
|
-
break;
|
823
|
-
}
|
824
|
-
var nextFileMarker = findNextFileMarker(data, offset - 2);
|
1030
|
+
const nextFileMarker = findNextFileMarker(data, offset - 2, offset - 3);
|
1031
|
+
|
825
1032
|
if (nextFileMarker && nextFileMarker.invalid) {
|
826
|
-
(0, _util.warn)(
|
1033
|
+
(0, _util.warn)("JpegImage.parse - unexpected data, current marker is: " + nextFileMarker.invalid);
|
827
1034
|
offset = nextFileMarker.offset;
|
828
1035
|
break;
|
829
1036
|
}
|
830
|
-
|
1037
|
+
|
1038
|
+
if (offset >= data.length - 1) {
|
1039
|
+
(0, _util.warn)("JpegImage.parse - reached the end of the image data " + "without finding an EOI marker (0xFFD9).");
|
1040
|
+
break markerLoop;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
throw new JpegError("JpegImage.parse - unknown marker: " + fileMarker.toString(16));
|
831
1044
|
}
|
832
|
-
|
1045
|
+
|
1046
|
+
fileMarker = (0, _core_utils.readUint16)(data, offset);
|
1047
|
+
offset += 2;
|
833
1048
|
}
|
1049
|
+
|
834
1050
|
this.width = frame.samplesPerLine;
|
835
1051
|
this.height = frame.scanLines;
|
836
1052
|
this.jfif = jfif;
|
837
1053
|
this.adobe = adobe;
|
838
1054
|
this.components = [];
|
1055
|
+
|
839
1056
|
for (i = 0; i < frame.components.length; i++) {
|
840
1057
|
component = frame.components[i];
|
841
1058
|
var quantizationTable = quantizationTables[component.quantizationId];
|
1059
|
+
|
842
1060
|
if (quantizationTable) {
|
843
1061
|
component.quantizationTable = quantizationTable;
|
844
1062
|
}
|
1063
|
+
|
845
1064
|
this.components.push({
|
846
1065
|
output: buildComponentData(frame, component),
|
847
1066
|
scaleX: component.h / frame.maxH,
|
@@ -850,11 +1069,12 @@ var JpegImage = function JpegImageClosure() {
|
|
850
1069
|
blocksPerColumn: component.blocksPerColumn
|
851
1070
|
});
|
852
1071
|
}
|
1072
|
+
|
853
1073
|
this.numComponents = this.components.length;
|
1074
|
+
return undefined;
|
854
1075
|
},
|
855
|
-
_getLinearizedBlockData: function _getLinearizedBlockData(width, height) {
|
856
|
-
var isSourcePDF = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
857
1076
|
|
1077
|
+
_getLinearizedBlockData(width, height, isSourcePDF = false) {
|
858
1078
|
var scaleX = this.width / width,
|
859
1079
|
scaleY = this.height / height;
|
860
1080
|
var component, componentScaleX, componentScaleY, blocksPerScanline;
|
@@ -867,6 +1087,8 @@ var JpegImage = function JpegImageClosure() {
|
|
867
1087
|
var data = new Uint8ClampedArray(dataLength);
|
868
1088
|
var xScaleBlockOffset = new Uint32Array(width);
|
869
1089
|
var mask3LSB = 0xfffffff8;
|
1090
|
+
let lastComponentScaleX;
|
1091
|
+
|
870
1092
|
for (i = 0; i < numComponents; i++) {
|
871
1093
|
component = this.components[i];
|
872
1094
|
componentScaleX = component.scaleX * scaleX;
|
@@ -874,23 +1096,33 @@ var JpegImage = function JpegImageClosure() {
|
|
874
1096
|
offset = i;
|
875
1097
|
output = component.output;
|
876
1098
|
blocksPerScanline = component.blocksPerLine + 1 << 3;
|
877
|
-
|
878
|
-
|
879
|
-
|
1099
|
+
|
1100
|
+
if (componentScaleX !== lastComponentScaleX) {
|
1101
|
+
for (x = 0; x < width; x++) {
|
1102
|
+
j = 0 | x * componentScaleX;
|
1103
|
+
xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7;
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
lastComponentScaleX = componentScaleX;
|
880
1107
|
}
|
1108
|
+
|
881
1109
|
for (y = 0; y < height; y++) {
|
882
1110
|
j = 0 | y * componentScaleY;
|
883
1111
|
index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3;
|
1112
|
+
|
884
1113
|
for (x = 0; x < width; x++) {
|
885
1114
|
data[offset] = output[index + xScaleBlockOffset[x]];
|
886
1115
|
offset += numComponents;
|
887
1116
|
}
|
888
1117
|
}
|
889
1118
|
}
|
890
|
-
|
1119
|
+
|
1120
|
+
let transform = this._decodeTransform;
|
1121
|
+
|
891
1122
|
if (!isSourcePDF && numComponents === 4 && !transform) {
|
892
1123
|
transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]);
|
893
1124
|
}
|
1125
|
+
|
894
1126
|
if (transform) {
|
895
1127
|
for (i = 0; i < dataLength;) {
|
896
1128
|
for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
|
@@ -898,6 +1130,7 @@ var JpegImage = function JpegImageClosure() {
|
|
898
1130
|
}
|
899
1131
|
}
|
900
1132
|
}
|
1133
|
+
|
901
1134
|
return data;
|
902
1135
|
},
|
903
1136
|
|
@@ -905,19 +1138,25 @@ var JpegImage = function JpegImageClosure() {
|
|
905
1138
|
if (this.adobe) {
|
906
1139
|
return !!this.adobe.transformCode;
|
907
1140
|
}
|
1141
|
+
|
908
1142
|
if (this.numComponents === 3) {
|
909
1143
|
if (this._colorTransform === 0) {
|
910
1144
|
return false;
|
911
1145
|
}
|
1146
|
+
|
912
1147
|
return true;
|
913
1148
|
}
|
1149
|
+
|
914
1150
|
if (this._colorTransform === 1) {
|
915
1151
|
return true;
|
916
1152
|
}
|
1153
|
+
|
917
1154
|
return false;
|
918
1155
|
},
|
1156
|
+
|
919
1157
|
_convertYccToRgb: function convertYccToRgb(data) {
|
920
1158
|
var Y, Cb, Cr;
|
1159
|
+
|
921
1160
|
for (var i = 0, length = data.length; i < length; i += 3) {
|
922
1161
|
Y = data[i];
|
923
1162
|
Cb = data[i + 1];
|
@@ -926,11 +1165,13 @@ var JpegImage = function JpegImageClosure() {
|
|
926
1165
|
data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;
|
927
1166
|
data[i + 2] = Y - 226.816 + 1.772 * Cb;
|
928
1167
|
}
|
1168
|
+
|
929
1169
|
return data;
|
930
1170
|
},
|
931
1171
|
_convertYcckToRgb: function convertYcckToRgb(data) {
|
932
1172
|
var Y, Cb, Cr, k;
|
933
1173
|
var offset = 0;
|
1174
|
+
|
934
1175
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
935
1176
|
Y = data[i];
|
936
1177
|
Cb = data[i + 1];
|
@@ -940,10 +1181,12 @@ var JpegImage = function JpegImageClosure() {
|
|
940
1181
|
data[offset++] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);
|
941
1182
|
data[offset++] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);
|
942
1183
|
}
|
1184
|
+
|
943
1185
|
return data.subarray(0, offset);
|
944
1186
|
},
|
945
1187
|
_convertYcckToCmyk: function convertYcckToCmyk(data) {
|
946
1188
|
var Y, Cb, Cr;
|
1189
|
+
|
947
1190
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
948
1191
|
Y = data[i];
|
949
1192
|
Cb = data[i + 1];
|
@@ -952,45 +1195,50 @@ var JpegImage = function JpegImageClosure() {
|
|
952
1195
|
data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr;
|
953
1196
|
data[i + 2] = 481.816 - Y - 1.772 * Cb;
|
954
1197
|
}
|
1198
|
+
|
955
1199
|
return data;
|
956
1200
|
},
|
957
1201
|
_convertCmykToRgb: function convertCmykToRgb(data) {
|
958
1202
|
var c, m, y, k;
|
959
1203
|
var offset = 0;
|
960
|
-
|
1204
|
+
|
961
1205
|
for (var i = 0, length = data.length; i < length; i += 4) {
|
962
|
-
c = data[i]
|
963
|
-
m = data[i + 1]
|
964
|
-
y = data[i + 2]
|
965
|
-
k = data[i + 3]
|
966
|
-
data[offset++] = 255 + c * (-
|
967
|
-
data[offset++] = 255 + c * (
|
968
|
-
data[offset++] = 255 + c * (0.
|
1206
|
+
c = data[i];
|
1207
|
+
m = data[i + 1];
|
1208
|
+
y = data[i + 2];
|
1209
|
+
k = data[i + 3];
|
1210
|
+
data[offset++] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254);
|
1211
|
+
data[offset++] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.00031891311758832814 * k + 0.7364883807733168);
|
1212
|
+
data[offset++] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144);
|
969
1213
|
}
|
1214
|
+
|
970
1215
|
return data.subarray(0, offset);
|
971
1216
|
},
|
972
|
-
getData: function getData(_ref3) {
|
973
|
-
var width = _ref3.width,
|
974
|
-
height = _ref3.height,
|
975
|
-
_ref3$forceRGB = _ref3.forceRGB,
|
976
|
-
forceRGB = _ref3$forceRGB === undefined ? false : _ref3$forceRGB,
|
977
|
-
_ref3$isSourcePDF = _ref3.isSourcePDF,
|
978
|
-
isSourcePDF = _ref3$isSourcePDF === undefined ? false : _ref3$isSourcePDF;
|
979
1217
|
|
1218
|
+
getData({
|
1219
|
+
width,
|
1220
|
+
height,
|
1221
|
+
forceRGB = false,
|
1222
|
+
isSourcePDF = false
|
1223
|
+
}) {
|
980
1224
|
if (this.numComponents > 4) {
|
981
|
-
throw new JpegError(
|
1225
|
+
throw new JpegError("Unsupported color mode");
|
982
1226
|
}
|
1227
|
+
|
983
1228
|
var data = this._getLinearizedBlockData(width, height, isSourcePDF);
|
1229
|
+
|
984
1230
|
if (this.numComponents === 1 && forceRGB) {
|
985
1231
|
var dataLength = data.length;
|
986
1232
|
var rgbData = new Uint8ClampedArray(dataLength * 3);
|
987
1233
|
var offset = 0;
|
1234
|
+
|
988
1235
|
for (var i = 0; i < dataLength; i++) {
|
989
1236
|
var grayColor = data[i];
|
990
1237
|
rgbData[offset++] = grayColor;
|
991
1238
|
rgbData[offset++] = grayColor;
|
992
1239
|
rgbData[offset++] = grayColor;
|
993
1240
|
}
|
1241
|
+
|
994
1242
|
return rgbData;
|
995
1243
|
} else if (this.numComponents === 3 && this._isColorConversionNeeded) {
|
996
1244
|
return this._convertYccToRgb(data);
|
@@ -999,14 +1247,18 @@ var JpegImage = function JpegImageClosure() {
|
|
999
1247
|
if (forceRGB) {
|
1000
1248
|
return this._convertYcckToRgb(data);
|
1001
1249
|
}
|
1250
|
+
|
1002
1251
|
return this._convertYcckToCmyk(data);
|
1003
1252
|
} else if (forceRGB) {
|
1004
1253
|
return this._convertCmykToRgb(data);
|
1005
1254
|
}
|
1006
1255
|
}
|
1256
|
+
|
1007
1257
|
return data;
|
1008
1258
|
}
|
1259
|
+
|
1009
1260
|
};
|
1010
1261
|
return JpegImage;
|
1011
1262
|
}();
|
1263
|
+
|
1012
1264
|
exports.JpegImage = JpegImage;
|