@cornerstonejs/dicom-image-loader 2.1.10 → 2.1.12

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.
@@ -1,889 +1,884 @@
1
1
  var ColorSpace = { Unkown: 0, Grayscale: 1, AdobeRGB: 2, RGB: 3, CYMK: 4 };
2
- var JpegImage = (function jpegImage() {
3
- 'use strict';
4
- var dctZigZag = new Int32Array([
5
- 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,
6
- 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,
7
- 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,
8
- 54, 47, 55, 62, 63,
9
- ]);
10
- var dctCos1 = 4017;
11
- var dctSin1 = 799;
12
- var dctCos3 = 3406;
13
- var dctSin3 = 2276;
14
- var dctCos6 = 1567;
15
- var dctSin6 = 3784;
16
- var dctSqrt2 = 5793;
17
- var dctSqrt1d2 = 2896;
18
- function buildHuffmanTable(codeLengths, values) {
19
- var k = 0, code = [], i, j, length = 16;
20
- while (length > 0 && !codeLengths[length - 1])
21
- length--;
22
- code.push({ children: [], index: 0 });
23
- var p = code[0], q;
24
- for (i = 0; i < length; i++) {
25
- for (j = 0; j < codeLengths[i]; j++) {
2
+ var dctZigZag = new Int32Array([
3
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,
4
+ 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29,
5
+ 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54,
6
+ 47, 55, 62, 63,
7
+ ]);
8
+ var dctCos1 = 4017;
9
+ var dctSin1 = 799;
10
+ var dctCos3 = 3406;
11
+ var dctSin3 = 2276;
12
+ var dctCos6 = 1567;
13
+ var dctSin6 = 3784;
14
+ var dctSqrt2 = 5793;
15
+ var dctSqrt1d2 = 2896;
16
+ function buildHuffmanTable(codeLengths, values) {
17
+ var k = 0, code = [], i, j, length = 16;
18
+ while (length > 0 && !codeLengths[length - 1])
19
+ length--;
20
+ code.push({ children: [], index: 0 });
21
+ var p = code[0], q;
22
+ for (i = 0; i < length; i++) {
23
+ for (j = 0; j < codeLengths[i]; j++) {
24
+ p = code.pop();
25
+ p.children[p.index] = values[k];
26
+ while (p.index > 0) {
26
27
  p = code.pop();
27
- p.children[p.index] = values[k];
28
- while (p.index > 0) {
29
- p = code.pop();
30
- }
31
- p.index++;
32
- code.push(p);
33
- while (code.length <= i) {
34
- code.push((q = { children: [], index: 0 }));
35
- p.children[p.index] = q.children;
36
- p = q;
37
- }
38
- k++;
39
28
  }
40
- if (i + 1 < length) {
29
+ p.index++;
30
+ code.push(p);
31
+ while (code.length <= i) {
41
32
  code.push((q = { children: [], index: 0 }));
42
33
  p.children[p.index] = q.children;
43
34
  p = q;
44
35
  }
36
+ k++;
37
+ }
38
+ if (i + 1 < length) {
39
+ code.push((q = { children: [], index: 0 }));
40
+ p.children[p.index] = q.children;
41
+ p = q;
45
42
  }
46
- return code[0].children;
47
- }
48
- function getBlockBufferOffset(component, row, col) {
49
- return 64 * ((component.blocksPerLine + 1) * row + col);
50
43
  }
51
- function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
52
- var precision = frame.precision;
53
- var samplesPerLine = frame.samplesPerLine;
54
- var scanLines = frame.scanLines;
55
- var mcusPerLine = frame.mcusPerLine;
56
- var progressive = frame.progressive;
57
- var maxH = frame.maxH, maxV = frame.maxV;
58
- var startOffset = offset, bitsData = 0, bitsCount = 0;
59
- function readBit() {
60
- if (bitsCount > 0) {
61
- bitsCount--;
62
- return (bitsData >> bitsCount) & 1;
63
- }
64
- bitsData = data[offset++];
65
- if (bitsData == 0xff) {
66
- var nextByte = data[offset++];
67
- if (nextByte) {
68
- throw ('unexpected marker: ' + ((bitsData << 8) | nextByte).toString(16));
69
- }
70
- }
71
- bitsCount = 7;
72
- return bitsData >>> 7;
73
- }
74
- function decodeHuffman(tree) {
75
- var node = tree;
76
- var bit;
77
- while ((bit = readBit()) !== null) {
78
- node = node[bit];
79
- if (typeof node === 'number')
80
- return node;
81
- if (typeof node !== 'object')
82
- throw 'invalid huffman sequence';
83
- }
84
- return null;
85
- }
86
- function receive(length) {
87
- var n = 0;
88
- while (length > 0) {
89
- var bit = readBit();
90
- if (bit === null)
91
- return;
92
- n = (n << 1) | bit;
93
- length--;
94
- }
95
- return n;
44
+ return code[0].children;
45
+ }
46
+ function getBlockBufferOffset(component, row, col) {
47
+ return 64 * ((component.blocksPerLine + 1) * row + col);
48
+ }
49
+ function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
50
+ var precision = frame.precision;
51
+ var samplesPerLine = frame.samplesPerLine;
52
+ var scanLines = frame.scanLines;
53
+ var mcusPerLine = frame.mcusPerLine;
54
+ var progressive = frame.progressive;
55
+ var maxH = frame.maxH, maxV = frame.maxV;
56
+ var startOffset = offset, bitsData = 0, bitsCount = 0;
57
+ function readBit() {
58
+ if (bitsCount > 0) {
59
+ bitsCount--;
60
+ return (bitsData >> bitsCount) & 1;
96
61
  }
97
- function receiveAndExtend(length) {
98
- var n = receive(length);
99
- if (n >= 1 << (length - 1))
100
- return n;
101
- return n + (-1 << length) + 1;
102
- }
103
- function decodeBaseline(component, offset) {
104
- var t = decodeHuffman(component.huffmanTableDC);
105
- var diff = t === 0 ? 0 : receiveAndExtend(t);
106
- component.blockData[offset] = component.pred += diff;
107
- var k = 1;
108
- while (k < 64) {
109
- var rs = decodeHuffman(component.huffmanTableAC);
110
- var s = rs & 15, r = rs >> 4;
111
- if (s === 0) {
112
- if (r < 15)
113
- break;
114
- k += 16;
115
- continue;
116
- }
117
- k += r;
118
- var z = dctZigZag[k];
119
- component.blockData[offset + z] = receiveAndExtend(s);
120
- k++;
62
+ bitsData = data[offset++];
63
+ if (bitsData == 0xff) {
64
+ var nextByte = data[offset++];
65
+ if (nextByte) {
66
+ throw 'unexpected marker: ' + ((bitsData << 8) | nextByte).toString(16);
121
67
  }
122
68
  }
123
- function decodeDCFirst(component, offset) {
124
- var t = decodeHuffman(component.huffmanTableDC);
125
- var diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
126
- component.blockData[offset] = component.pred += diff;
127
- }
128
- function decodeDCSuccessive(component, offset) {
129
- component.blockData[offset] |= readBit() << successive;
69
+ bitsCount = 7;
70
+ return bitsData >>> 7;
71
+ }
72
+ function decodeHuffman(tree) {
73
+ var node = tree;
74
+ var bit;
75
+ while ((bit = readBit()) !== null) {
76
+ node = node[bit];
77
+ if (typeof node === 'number')
78
+ return node;
79
+ if (typeof node !== 'object')
80
+ throw 'invalid huffman sequence';
130
81
  }
131
- var eobrun = 0;
132
- function decodeACFirst(component, offset) {
133
- if (eobrun > 0) {
134
- eobrun--;
82
+ return null;
83
+ }
84
+ function receive(length) {
85
+ var n = 0;
86
+ while (length > 0) {
87
+ var bit = readBit();
88
+ if (bit === null)
135
89
  return;
90
+ n = (n << 1) | bit;
91
+ length--;
92
+ }
93
+ return n;
94
+ }
95
+ function receiveAndExtend(length) {
96
+ var n = receive(length);
97
+ if (n >= 1 << (length - 1))
98
+ return n;
99
+ return n + (-1 << length) + 1;
100
+ }
101
+ function decodeBaseline(component, offset) {
102
+ var t = decodeHuffman(component.huffmanTableDC);
103
+ var diff = t === 0 ? 0 : receiveAndExtend(t);
104
+ component.blockData[offset] = component.pred += diff;
105
+ var k = 1;
106
+ while (k < 64) {
107
+ var rs = decodeHuffman(component.huffmanTableAC);
108
+ var s = rs & 15, r = rs >> 4;
109
+ if (s === 0) {
110
+ if (r < 15)
111
+ break;
112
+ k += 16;
113
+ continue;
136
114
  }
137
- var k = spectralStart, e = spectralEnd;
138
- while (k <= e) {
139
- var rs = decodeHuffman(component.huffmanTableAC);
140
- var s = rs & 15, r = rs >> 4;
141
- if (s === 0) {
142
- if (r < 15) {
143
- eobrun = receive(r) + (1 << r) - 1;
144
- break;
145
- }
146
- k += 16;
147
- continue;
115
+ k += r;
116
+ var z = dctZigZag[k];
117
+ component.blockData[offset + z] = receiveAndExtend(s);
118
+ k++;
119
+ }
120
+ }
121
+ function decodeDCFirst(component, offset) {
122
+ var t = decodeHuffman(component.huffmanTableDC);
123
+ var diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
124
+ component.blockData[offset] = component.pred += diff;
125
+ }
126
+ function decodeDCSuccessive(component, offset) {
127
+ component.blockData[offset] |= readBit() << successive;
128
+ }
129
+ var eobrun = 0;
130
+ function decodeACFirst(component, offset) {
131
+ if (eobrun > 0) {
132
+ eobrun--;
133
+ return;
134
+ }
135
+ var k = spectralStart, e = spectralEnd;
136
+ while (k <= e) {
137
+ var rs = decodeHuffman(component.huffmanTableAC);
138
+ var s = rs & 15, r = rs >> 4;
139
+ if (s === 0) {
140
+ if (r < 15) {
141
+ eobrun = receive(r) + (1 << r) - 1;
142
+ break;
148
143
  }
149
- k += r;
150
- var z = dctZigZag[k];
151
- component.blockData[offset + z] =
152
- receiveAndExtend(s) * (1 << successive);
153
- k++;
144
+ k += 16;
145
+ continue;
154
146
  }
147
+ k += r;
148
+ var z = dctZigZag[k];
149
+ component.blockData[offset + z] = receiveAndExtend(s) * (1 << successive);
150
+ k++;
155
151
  }
156
- var successiveACState = 0, successiveACNextValue;
157
- function decodeACSuccessive(component, offset) {
158
- var k = spectralStart, e = spectralEnd, r = 0;
159
- while (k <= e) {
160
- var z = dctZigZag[k];
161
- switch (successiveACState) {
162
- case 0:
163
- var rs = decodeHuffman(component.huffmanTableAC);
164
- var s = rs & 15;
165
- r = rs >> 4;
166
- if (s === 0) {
167
- if (r < 15) {
168
- eobrun = receive(r) + (1 << r);
169
- successiveACState = 4;
170
- }
171
- else {
172
- r = 16;
173
- successiveACState = 1;
174
- }
175
- }
176
- else {
177
- if (s !== 1)
178
- throw 'invalid ACn encoding';
179
- successiveACNextValue = receiveAndExtend(s);
180
- successiveACState = r ? 2 : 3;
181
- }
182
- continue;
183
- case 1:
184
- case 2:
185
- if (component.blockData[offset + z]) {
186
- component.blockData[offset + z] += readBit() << successive;
187
- }
188
- else {
189
- r--;
190
- if (r === 0)
191
- successiveACState = successiveACState == 2 ? 3 : 0;
192
- }
193
- break;
194
- case 3:
195
- if (component.blockData[offset + z]) {
196
- component.blockData[offset + z] += readBit() << successive;
152
+ }
153
+ var successiveACState = 0, successiveACNextValue;
154
+ function decodeACSuccessive(component, offset) {
155
+ var k = spectralStart, e = spectralEnd, r = 0;
156
+ while (k <= e) {
157
+ var z = dctZigZag[k];
158
+ switch (successiveACState) {
159
+ case 0:
160
+ var rs = decodeHuffman(component.huffmanTableAC);
161
+ var s = rs & 15;
162
+ r = rs >> 4;
163
+ if (s === 0) {
164
+ if (r < 15) {
165
+ eobrun = receive(r) + (1 << r);
166
+ successiveACState = 4;
197
167
  }
198
168
  else {
199
- component.blockData[offset + z] =
200
- successiveACNextValue << successive;
201
- successiveACState = 0;
202
- }
203
- break;
204
- case 4:
205
- if (component.blockData[offset + z]) {
206
- component.blockData[offset + z] += readBit() << successive;
169
+ r = 16;
170
+ successiveACState = 1;
207
171
  }
208
- break;
209
- }
210
- k++;
211
- }
212
- if (successiveACState === 4) {
213
- eobrun--;
214
- if (eobrun === 0)
215
- successiveACState = 0;
172
+ }
173
+ else {
174
+ if (s !== 1)
175
+ throw 'invalid ACn encoding';
176
+ successiveACNextValue = receiveAndExtend(s);
177
+ successiveACState = r ? 2 : 3;
178
+ }
179
+ continue;
180
+ case 1:
181
+ case 2:
182
+ if (component.blockData[offset + z]) {
183
+ component.blockData[offset + z] += readBit() << successive;
184
+ }
185
+ else {
186
+ r--;
187
+ if (r === 0)
188
+ successiveACState = successiveACState == 2 ? 3 : 0;
189
+ }
190
+ break;
191
+ case 3:
192
+ if (component.blockData[offset + z]) {
193
+ component.blockData[offset + z] += readBit() << successive;
194
+ }
195
+ else {
196
+ component.blockData[offset + z] =
197
+ successiveACNextValue << successive;
198
+ successiveACState = 0;
199
+ }
200
+ break;
201
+ case 4:
202
+ if (component.blockData[offset + z]) {
203
+ component.blockData[offset + z] += readBit() << successive;
204
+ }
205
+ break;
216
206
  }
207
+ k++;
217
208
  }
218
- function decodeMcu(component, decode, mcu, row, col) {
219
- var mcuRow = (mcu / mcusPerLine) | 0;
220
- var mcuCol = mcu % mcusPerLine;
221
- var blockRow = mcuRow * component.v + row;
222
- var blockCol = mcuCol * component.h + col;
223
- var offset = getBlockBufferOffset(component, blockRow, blockCol);
224
- decode(component, offset);
225
- }
226
- function decodeBlock(component, decode, mcu) {
227
- var blockRow = (mcu / component.blocksPerLine) | 0;
228
- var blockCol = mcu % component.blocksPerLine;
229
- var offset = getBlockBufferOffset(component, blockRow, blockCol);
230
- decode(component, offset);
231
- }
232
- var componentsLength = components.length;
233
- var component, i, j, k, n;
234
- var decodeFn;
235
- if (progressive) {
236
- if (spectralStart === 0)
237
- decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
238
- else
239
- decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;
209
+ if (successiveACState === 4) {
210
+ eobrun--;
211
+ if (eobrun === 0)
212
+ successiveACState = 0;
240
213
  }
241
- else {
242
- decodeFn = decodeBaseline;
214
+ }
215
+ function decodeMcu(component, decode, mcu, row, col) {
216
+ var mcuRow = (mcu / mcusPerLine) | 0;
217
+ var mcuCol = mcu % mcusPerLine;
218
+ var blockRow = mcuRow * component.v + row;
219
+ var blockCol = mcuCol * component.h + col;
220
+ var offset = getBlockBufferOffset(component, blockRow, blockCol);
221
+ decode(component, offset);
222
+ }
223
+ function decodeBlock(component, decode, mcu) {
224
+ var blockRow = (mcu / component.blocksPerLine) | 0;
225
+ var blockCol = mcu % component.blocksPerLine;
226
+ var offset = getBlockBufferOffset(component, blockRow, blockCol);
227
+ decode(component, offset);
228
+ }
229
+ var componentsLength = components.length;
230
+ var component, i, j, k, n;
231
+ var decodeFn;
232
+ if (progressive) {
233
+ if (spectralStart === 0)
234
+ decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
235
+ else
236
+ decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;
237
+ }
238
+ else {
239
+ decodeFn = decodeBaseline;
240
+ }
241
+ var mcu = 0, marker;
242
+ var mcuExpected;
243
+ if (componentsLength == 1) {
244
+ mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
245
+ }
246
+ else {
247
+ mcuExpected = mcusPerLine * frame.mcusPerColumn;
248
+ }
249
+ if (!resetInterval) {
250
+ resetInterval = mcuExpected;
251
+ }
252
+ var h, v;
253
+ while (mcu < mcuExpected) {
254
+ for (i = 0; i < componentsLength; i++) {
255
+ components[i].pred = 0;
243
256
  }
244
- var mcu = 0, marker;
245
- var mcuExpected;
257
+ eobrun = 0;
246
258
  if (componentsLength == 1) {
247
- mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
259
+ component = components[0];
260
+ for (n = 0; n < resetInterval; n++) {
261
+ decodeBlock(component, decodeFn, mcu);
262
+ mcu++;
263
+ }
248
264
  }
249
265
  else {
250
- mcuExpected = mcusPerLine * frame.mcusPerColumn;
251
- }
252
- if (!resetInterval) {
253
- resetInterval = mcuExpected;
254
- }
255
- var h, v;
256
- while (mcu < mcuExpected) {
257
- for (i = 0; i < componentsLength; i++) {
258
- components[i].pred = 0;
259
- }
260
- eobrun = 0;
261
- if (componentsLength == 1) {
262
- component = components[0];
263
- for (n = 0; n < resetInterval; n++) {
264
- decodeBlock(component, decodeFn, mcu);
265
- mcu++;
266
- }
267
- }
268
- else {
269
- for (n = 0; n < resetInterval; n++) {
270
- for (i = 0; i < componentsLength; i++) {
271
- component = components[i];
272
- h = component.h;
273
- v = component.v;
274
- for (j = 0; j < v; j++) {
275
- for (k = 0; k < h; k++) {
276
- decodeMcu(component, decodeFn, mcu, j, k);
277
- }
266
+ for (n = 0; n < resetInterval; n++) {
267
+ for (i = 0; i < componentsLength; i++) {
268
+ component = components[i];
269
+ h = component.h;
270
+ v = component.v;
271
+ for (j = 0; j < v; j++) {
272
+ for (k = 0; k < h; k++) {
273
+ decodeMcu(component, decodeFn, mcu, j, k);
278
274
  }
279
275
  }
280
- mcu++;
281
276
  }
277
+ mcu++;
282
278
  }
283
- bitsCount = 0;
284
- marker = (data[offset] << 8) | data[offset + 1];
285
- if (marker <= 0xff00) {
286
- throw 'marker was not found';
287
- }
288
- if (marker >= 0xffd0 && marker <= 0xffd7) {
289
- offset += 2;
290
- }
291
- else {
292
- break;
293
- }
294
279
  }
295
- return offset - startOffset;
280
+ bitsCount = 0;
281
+ marker = (data[offset] << 8) | data[offset + 1];
282
+ if (marker <= 0xff00) {
283
+ throw 'marker was not found';
284
+ }
285
+ if (marker >= 0xffd0 && marker <= 0xffd7) {
286
+ offset += 2;
287
+ }
288
+ else {
289
+ break;
290
+ }
296
291
  }
297
- function quantizeAndInverse(component, blockBufferOffset, p) {
298
- var qt = component.quantizationTable;
299
- var v0, v1, v2, v3, v4, v5, v6, v7, t;
300
- var i;
301
- for (i = 0; i < 64; i++) {
302
- p[i] = component.blockData[blockBufferOffset + i] * qt[i];
303
- }
304
- for (i = 0; i < 8; ++i) {
305
- var row = 8 * i;
306
- if (p[1 + row] === 0 &&
307
- p[2 + row] === 0 &&
308
- p[3 + row] === 0 &&
309
- p[4 + row] === 0 &&
310
- p[5 + row] === 0 &&
311
- p[6 + row] === 0 &&
312
- p[7 + row] === 0) {
313
- t = (dctSqrt2 * p[0 + row] + 512) >> 10;
314
- p[0 + row] = t;
315
- p[1 + row] = t;
316
- p[2 + row] = t;
317
- p[3 + row] = t;
318
- p[4 + row] = t;
319
- p[5 + row] = t;
320
- p[6 + row] = t;
321
- p[7 + row] = t;
322
- continue;
323
- }
324
- v0 = (dctSqrt2 * p[0 + row] + 128) >> 8;
325
- v1 = (dctSqrt2 * p[4 + row] + 128) >> 8;
326
- v2 = p[2 + row];
327
- v3 = p[6 + row];
328
- v4 = (dctSqrt1d2 * (p[1 + row] - p[7 + row]) + 128) >> 8;
329
- v7 = (dctSqrt1d2 * (p[1 + row] + p[7 + row]) + 128) >> 8;
330
- v5 = p[3 + row] << 4;
331
- v6 = p[5 + row] << 4;
332
- t = (v0 - v1 + 1) >> 1;
333
- v0 = (v0 + v1 + 1) >> 1;
334
- v1 = t;
335
- t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
336
- v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
337
- v3 = t;
338
- t = (v4 - v6 + 1) >> 1;
339
- v4 = (v4 + v6 + 1) >> 1;
340
- v6 = t;
341
- t = (v7 + v5 + 1) >> 1;
342
- v5 = (v7 - v5 + 1) >> 1;
343
- v7 = t;
344
- t = (v0 - v3 + 1) >> 1;
345
- v0 = (v0 + v3 + 1) >> 1;
346
- v3 = t;
347
- t = (v1 - v2 + 1) >> 1;
348
- v1 = (v1 + v2 + 1) >> 1;
349
- v2 = t;
350
- t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
351
- v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
352
- v7 = t;
353
- t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
354
- v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
355
- v6 = t;
356
- p[0 + row] = v0 + v7;
357
- p[7 + row] = v0 - v7;
358
- p[1 + row] = v1 + v6;
359
- p[6 + row] = v1 - v6;
360
- p[2 + row] = v2 + v5;
361
- p[5 + row] = v2 - v5;
362
- p[3 + row] = v3 + v4;
363
- p[4 + row] = v3 - v4;
364
- }
365
- for (i = 0; i < 8; ++i) {
366
- var col = i;
367
- if (p[1 * 8 + col] === 0 &&
368
- p[2 * 8 + col] === 0 &&
369
- p[3 * 8 + col] === 0 &&
370
- p[4 * 8 + col] === 0 &&
371
- p[5 * 8 + col] === 0 &&
372
- p[6 * 8 + col] === 0 &&
373
- p[7 * 8 + col] === 0) {
374
- t = (dctSqrt2 * p[i + 0] + 8192) >> 14;
375
- p[0 * 8 + col] = t;
376
- p[1 * 8 + col] = t;
377
- p[2 * 8 + col] = t;
378
- p[3 * 8 + col] = t;
379
- p[4 * 8 + col] = t;
380
- p[5 * 8 + col] = t;
381
- p[6 * 8 + col] = t;
382
- p[7 * 8 + col] = t;
383
- continue;
384
- }
385
- v0 = (dctSqrt2 * p[0 * 8 + col] + 2048) >> 12;
386
- v1 = (dctSqrt2 * p[4 * 8 + col] + 2048) >> 12;
387
- v2 = p[2 * 8 + col];
388
- v3 = p[6 * 8 + col];
389
- v4 = (dctSqrt1d2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048) >> 12;
390
- v7 = (dctSqrt1d2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048) >> 12;
391
- v5 = p[3 * 8 + col];
392
- v6 = p[5 * 8 + col];
393
- t = (v0 - v1 + 1) >> 1;
394
- v0 = (v0 + v1 + 1) >> 1;
395
- v1 = t;
396
- t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
397
- v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
398
- v3 = t;
399
- t = (v4 - v6 + 1) >> 1;
400
- v4 = (v4 + v6 + 1) >> 1;
401
- v6 = t;
402
- t = (v7 + v5 + 1) >> 1;
403
- v5 = (v7 - v5 + 1) >> 1;
404
- v7 = t;
405
- t = (v0 - v3 + 1) >> 1;
406
- v0 = (v0 + v3 + 1) >> 1;
407
- v3 = t;
408
- t = (v1 - v2 + 1) >> 1;
409
- v1 = (v1 + v2 + 1) >> 1;
410
- v2 = t;
411
- t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
412
- v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
413
- v7 = t;
414
- t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
415
- v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
416
- v6 = t;
417
- p[0 * 8 + col] = v0 + v7;
418
- p[7 * 8 + col] = v0 - v7;
419
- p[1 * 8 + col] = v1 + v6;
420
- p[6 * 8 + col] = v1 - v6;
421
- p[2 * 8 + col] = v2 + v5;
422
- p[5 * 8 + col] = v2 - v5;
423
- p[3 * 8 + col] = v3 + v4;
424
- p[4 * 8 + col] = v3 - v4;
425
- }
426
- for (i = 0; i < 64; ++i) {
427
- var index = blockBufferOffset + i;
428
- var q = p[i];
429
- q =
430
- q <= -2056 / component.bitConversion
431
- ? 0
432
- : q >= 2024 / component.bitConversion
433
- ? 255 / component.bitConversion
434
- : (q + 2056 / component.bitConversion) >> 4;
435
- component.blockData[index] = q;
292
+ return offset - startOffset;
293
+ }
294
+ function quantizeAndInverse(component, blockBufferOffset, p) {
295
+ var qt = component.quantizationTable;
296
+ var v0, v1, v2, v3, v4, v5, v6, v7, t;
297
+ var i;
298
+ for (i = 0; i < 64; i++) {
299
+ p[i] = component.blockData[blockBufferOffset + i] * qt[i];
300
+ }
301
+ for (i = 0; i < 8; ++i) {
302
+ var row = 8 * i;
303
+ if (p[1 + row] === 0 &&
304
+ p[2 + row] === 0 &&
305
+ p[3 + row] === 0 &&
306
+ p[4 + row] === 0 &&
307
+ p[5 + row] === 0 &&
308
+ p[6 + row] === 0 &&
309
+ p[7 + row] === 0) {
310
+ t = (dctSqrt2 * p[0 + row] + 512) >> 10;
311
+ p[0 + row] = t;
312
+ p[1 + row] = t;
313
+ p[2 + row] = t;
314
+ p[3 + row] = t;
315
+ p[4 + row] = t;
316
+ p[5 + row] = t;
317
+ p[6 + row] = t;
318
+ p[7 + row] = t;
319
+ continue;
436
320
  }
321
+ v0 = (dctSqrt2 * p[0 + row] + 128) >> 8;
322
+ v1 = (dctSqrt2 * p[4 + row] + 128) >> 8;
323
+ v2 = p[2 + row];
324
+ v3 = p[6 + row];
325
+ v4 = (dctSqrt1d2 * (p[1 + row] - p[7 + row]) + 128) >> 8;
326
+ v7 = (dctSqrt1d2 * (p[1 + row] + p[7 + row]) + 128) >> 8;
327
+ v5 = p[3 + row] << 4;
328
+ v6 = p[5 + row] << 4;
329
+ t = (v0 - v1 + 1) >> 1;
330
+ v0 = (v0 + v1 + 1) >> 1;
331
+ v1 = t;
332
+ t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
333
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
334
+ v3 = t;
335
+ t = (v4 - v6 + 1) >> 1;
336
+ v4 = (v4 + v6 + 1) >> 1;
337
+ v6 = t;
338
+ t = (v7 + v5 + 1) >> 1;
339
+ v5 = (v7 - v5 + 1) >> 1;
340
+ v7 = t;
341
+ t = (v0 - v3 + 1) >> 1;
342
+ v0 = (v0 + v3 + 1) >> 1;
343
+ v3 = t;
344
+ t = (v1 - v2 + 1) >> 1;
345
+ v1 = (v1 + v2 + 1) >> 1;
346
+ v2 = t;
347
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
348
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
349
+ v7 = t;
350
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
351
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
352
+ v6 = t;
353
+ p[0 + row] = v0 + v7;
354
+ p[7 + row] = v0 - v7;
355
+ p[1 + row] = v1 + v6;
356
+ p[6 + row] = v1 - v6;
357
+ p[2 + row] = v2 + v5;
358
+ p[5 + row] = v2 - v5;
359
+ p[3 + row] = v3 + v4;
360
+ p[4 + row] = v3 - v4;
437
361
  }
438
- function buildComponentData(frame, component) {
439
- var lines = [];
440
- var blocksPerLine = component.blocksPerLine;
441
- var blocksPerColumn = component.blocksPerColumn;
442
- var samplesPerLine = blocksPerLine << 3;
443
- var computationBuffer = new Int32Array(64);
444
- var i, j, ll = 0;
445
- for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
446
- for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
447
- var offset = getBlockBufferOffset(component, blockRow, blockCol);
448
- quantizeAndInverse(component, offset, computationBuffer);
449
- }
362
+ for (i = 0; i < 8; ++i) {
363
+ var col = i;
364
+ if (p[1 * 8 + col] === 0 &&
365
+ p[2 * 8 + col] === 0 &&
366
+ p[3 * 8 + col] === 0 &&
367
+ p[4 * 8 + col] === 0 &&
368
+ p[5 * 8 + col] === 0 &&
369
+ p[6 * 8 + col] === 0 &&
370
+ p[7 * 8 + col] === 0) {
371
+ t = (dctSqrt2 * p[i + 0] + 8192) >> 14;
372
+ p[0 * 8 + col] = t;
373
+ p[1 * 8 + col] = t;
374
+ p[2 * 8 + col] = t;
375
+ p[3 * 8 + col] = t;
376
+ p[4 * 8 + col] = t;
377
+ p[5 * 8 + col] = t;
378
+ p[6 * 8 + col] = t;
379
+ p[7 * 8 + col] = t;
380
+ continue;
450
381
  }
451
- return component.blockData;
382
+ v0 = (dctSqrt2 * p[0 * 8 + col] + 2048) >> 12;
383
+ v1 = (dctSqrt2 * p[4 * 8 + col] + 2048) >> 12;
384
+ v2 = p[2 * 8 + col];
385
+ v3 = p[6 * 8 + col];
386
+ v4 = (dctSqrt1d2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048) >> 12;
387
+ v7 = (dctSqrt1d2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048) >> 12;
388
+ v5 = p[3 * 8 + col];
389
+ v6 = p[5 * 8 + col];
390
+ t = (v0 - v1 + 1) >> 1;
391
+ v0 = (v0 + v1 + 1) >> 1;
392
+ v1 = t;
393
+ t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
394
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
395
+ v3 = t;
396
+ t = (v4 - v6 + 1) >> 1;
397
+ v4 = (v4 + v6 + 1) >> 1;
398
+ v6 = t;
399
+ t = (v7 + v5 + 1) >> 1;
400
+ v5 = (v7 - v5 + 1) >> 1;
401
+ v7 = t;
402
+ t = (v0 - v3 + 1) >> 1;
403
+ v0 = (v0 + v3 + 1) >> 1;
404
+ v3 = t;
405
+ t = (v1 - v2 + 1) >> 1;
406
+ v1 = (v1 + v2 + 1) >> 1;
407
+ v2 = t;
408
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
409
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
410
+ v7 = t;
411
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
412
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
413
+ v6 = t;
414
+ p[0 * 8 + col] = v0 + v7;
415
+ p[7 * 8 + col] = v0 - v7;
416
+ p[1 * 8 + col] = v1 + v6;
417
+ p[6 * 8 + col] = v1 - v6;
418
+ p[2 * 8 + col] = v2 + v5;
419
+ p[5 * 8 + col] = v2 - v5;
420
+ p[3 * 8 + col] = v3 + v4;
421
+ p[4 * 8 + col] = v3 - v4;
452
422
  }
453
- function clampToUint8(a) {
454
- return a <= 0 ? 0 : a >= 255 ? 255 : a | 0;
423
+ for (i = 0; i < 64; ++i) {
424
+ var index = blockBufferOffset + i;
425
+ var q = p[i];
426
+ q =
427
+ q <= -2056 / component.bitConversion
428
+ ? 0
429
+ : q >= 2024 / component.bitConversion
430
+ ? 255 / component.bitConversion
431
+ : (q + 2056 / component.bitConversion) >> 4;
432
+ component.blockData[index] = q;
455
433
  }
456
- class JpegImage {
434
+ }
435
+ function buildComponentData(frame, component) {
436
+ var lines = [];
437
+ var blocksPerLine = component.blocksPerLine;
438
+ var blocksPerColumn = component.blocksPerColumn;
439
+ var samplesPerLine = blocksPerLine << 3;
440
+ var computationBuffer = new Int32Array(64);
441
+ var i, j, ll = 0;
442
+ for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
443
+ for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
444
+ var offset = getBlockBufferOffset(component, blockRow, blockCol);
445
+ quantizeAndInverse(component, offset, computationBuffer);
446
+ }
457
447
  }
458
- Object.setPrototypeOf(JpegImage.prototype, {
459
- load: function load(path) {
460
- var handleData = function (data) {
461
- this.parse(data);
462
- if (this.onload)
463
- this.onload();
464
- }.bind(this);
465
- if (path.indexOf('data:') > -1) {
466
- var offset = path.indexOf('base64,') + 7;
467
- var data = atob(path.substring(offset));
468
- var arr = new Uint8Array(data.length);
469
- for (var i = data.length - 1; i >= 0; i--) {
470
- arr[i] = data.charCodeAt(i);
471
- }
448
+ return component.blockData;
449
+ }
450
+ function clampToUint8(a) {
451
+ return a <= 0 ? 0 : a >= 255 ? 255 : a | 0;
452
+ }
453
+ class JpegImage {
454
+ constructor() { }
455
+ load(path) {
456
+ var handleData = function (data) {
457
+ this.parse(data);
458
+ if (this.onload)
459
+ this.onload();
460
+ }.bind(this);
461
+ if (path.indexOf('data:') > -1) {
462
+ var offset = path.indexOf('base64,') + 7;
463
+ var data = atob(path.substring(offset));
464
+ var arr = new Uint8Array(data.length);
465
+ for (var i = data.length - 1; i >= 0; i--) {
466
+ arr[i] = data.charCodeAt(i);
467
+ }
468
+ handleData(data);
469
+ }
470
+ else {
471
+ var xhr = new XMLHttpRequest();
472
+ xhr.open('GET', path, true);
473
+ xhr.responseType = 'arraybuffer';
474
+ xhr.onload = function () {
475
+ var data = new Uint8Array(xhr.response);
472
476
  handleData(data);
473
- }
474
- else {
475
- var xhr = new XMLHttpRequest();
476
- xhr.open('GET', path, true);
477
- xhr.responseType = 'arraybuffer';
478
- xhr.onload = function () {
479
- var data = new Uint8Array(xhr.response);
480
- handleData(data);
481
- }.bind(this);
482
- xhr.send(null);
483
- }
484
- },
485
- parse: function parse(data) {
486
- function readUint16() {
487
- var value = (data[offset] << 8) | data[offset + 1];
488
- offset += 2;
489
- return value;
490
- }
491
- function readDataBlock() {
492
- var length = readUint16();
493
- var array = data.subarray(offset, offset + length - 2);
494
- offset += array.length;
495
- return array;
496
- }
497
- function prepareComponents(frame) {
498
- var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
499
- var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
500
- for (var i = 0; i < frame.components.length; i++) {
501
- component = frame.components[i];
502
- var blocksPerLine = Math.ceil((Math.ceil(frame.samplesPerLine / 8) * component.h) / frame.maxH);
503
- var blocksPerColumn = Math.ceil((Math.ceil(frame.scanLines / 8) * component.v) / frame.maxV);
504
- var blocksPerLineForMcu = mcusPerLine * component.h;
505
- var blocksPerColumnForMcu = mcusPerColumn * component.v;
506
- var blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
507
- component.blockData = new Int16Array(blocksBufferSize);
508
- component.blocksPerLine = blocksPerLine;
509
- component.blocksPerColumn = blocksPerColumn;
510
- }
511
- frame.mcusPerLine = mcusPerLine;
512
- frame.mcusPerColumn = mcusPerColumn;
513
- }
514
- var offset = 0, length = data.length;
515
- var jfif = null;
516
- var adobe = null;
517
- var pixels = null;
518
- var frame, resetInterval;
519
- var quantizationTables = [];
520
- var huffmanTablesAC = [], huffmanTablesDC = [];
521
- var fileMarker = readUint16();
522
- if (fileMarker != 0xffd8) {
523
- throw 'SOI not found';
524
- }
525
- fileMarker = readUint16();
526
- while (fileMarker != 0xffd9) {
527
- var i, j, l;
528
- switch (fileMarker) {
529
- case 0xffe0:
530
- case 0xffe1:
531
- case 0xffe2:
532
- case 0xffe3:
533
- case 0xffe4:
534
- case 0xffe5:
535
- case 0xffe6:
536
- case 0xffe7:
537
- case 0xffe8:
538
- case 0xffe9:
539
- case 0xffea:
540
- case 0xffeb:
541
- case 0xffec:
542
- case 0xffed:
543
- case 0xffee:
544
- case 0xffef:
545
- case 0xfffe:
546
- var appData = readDataBlock();
547
- if (fileMarker === 0xffe0) {
548
- if (appData[0] === 0x4a &&
549
- appData[1] === 0x46 &&
550
- appData[2] === 0x49 &&
551
- appData[3] === 0x46 &&
552
- appData[4] === 0) {
553
- jfif = {
554
- version: { major: appData[5], minor: appData[6] },
555
- densityUnits: appData[7],
556
- xDensity: (appData[8] << 8) | appData[9],
557
- yDensity: (appData[10] << 8) | appData[11],
558
- thumbWidth: appData[12],
559
- thumbHeight: appData[13],
560
- thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13]),
561
- };
562
- }
477
+ }.bind(this);
478
+ xhr.send(null);
479
+ }
480
+ }
481
+ parse(data) {
482
+ function readUint16() {
483
+ var value = (data[offset] << 8) | data[offset + 1];
484
+ offset += 2;
485
+ return value;
486
+ }
487
+ function readDataBlock() {
488
+ var length = readUint16();
489
+ var array = data.subarray(offset, offset + length - 2);
490
+ offset += array.length;
491
+ return array;
492
+ }
493
+ function prepareComponents(frame) {
494
+ var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
495
+ var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
496
+ for (var i = 0; i < frame.components.length; i++) {
497
+ component = frame.components[i];
498
+ var blocksPerLine = Math.ceil((Math.ceil(frame.samplesPerLine / 8) * component.h) / frame.maxH);
499
+ var blocksPerColumn = Math.ceil((Math.ceil(frame.scanLines / 8) * component.v) / frame.maxV);
500
+ var blocksPerLineForMcu = mcusPerLine * component.h;
501
+ var blocksPerColumnForMcu = mcusPerColumn * component.v;
502
+ var blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
503
+ component.blockData = new Int16Array(blocksBufferSize);
504
+ component.blocksPerLine = blocksPerLine;
505
+ component.blocksPerColumn = blocksPerColumn;
506
+ }
507
+ frame.mcusPerLine = mcusPerLine;
508
+ frame.mcusPerColumn = mcusPerColumn;
509
+ }
510
+ var offset = 0, length = data.length;
511
+ var jfif = null;
512
+ var adobe = null;
513
+ var pixels = null;
514
+ var frame, resetInterval;
515
+ var quantizationTables = [];
516
+ var huffmanTablesAC = [], huffmanTablesDC = [];
517
+ var fileMarker = readUint16();
518
+ if (fileMarker != 0xffd8) {
519
+ throw 'SOI not found';
520
+ }
521
+ fileMarker = readUint16();
522
+ while (fileMarker != 0xffd9) {
523
+ var i, j, l;
524
+ switch (fileMarker) {
525
+ case 0xffe0:
526
+ case 0xffe1:
527
+ case 0xffe2:
528
+ case 0xffe3:
529
+ case 0xffe4:
530
+ case 0xffe5:
531
+ case 0xffe6:
532
+ case 0xffe7:
533
+ case 0xffe8:
534
+ case 0xffe9:
535
+ case 0xffea:
536
+ case 0xffeb:
537
+ case 0xffec:
538
+ case 0xffed:
539
+ case 0xffee:
540
+ case 0xffef:
541
+ case 0xfffe:
542
+ var appData = readDataBlock();
543
+ if (fileMarker === 0xffe0) {
544
+ if (appData[0] === 0x4a &&
545
+ appData[1] === 0x46 &&
546
+ appData[2] === 0x49 &&
547
+ appData[3] === 0x46 &&
548
+ appData[4] === 0) {
549
+ jfif = {
550
+ version: { major: appData[5], minor: appData[6] },
551
+ densityUnits: appData[7],
552
+ xDensity: (appData[8] << 8) | appData[9],
553
+ yDensity: (appData[10] << 8) | appData[11],
554
+ thumbWidth: appData[12],
555
+ thumbHeight: appData[13],
556
+ thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13]),
557
+ };
563
558
  }
564
- if (fileMarker === 0xffee) {
565
- if (appData[0] === 0x41 &&
566
- appData[1] === 0x64 &&
567
- appData[2] === 0x6f &&
568
- appData[3] === 0x62 &&
569
- appData[4] === 0x65 &&
570
- appData[5] === 0) {
571
- adobe = {
572
- version: appData[6],
573
- flags0: (appData[7] << 8) | appData[8],
574
- flags1: (appData[9] << 8) | appData[10],
575
- transformCode: appData[11],
576
- };
577
- }
559
+ }
560
+ if (fileMarker === 0xffee) {
561
+ if (appData[0] === 0x41 &&
562
+ appData[1] === 0x64 &&
563
+ appData[2] === 0x6f &&
564
+ appData[3] === 0x62 &&
565
+ appData[4] === 0x65 &&
566
+ appData[5] === 0) {
567
+ adobe = {
568
+ version: appData[6],
569
+ flags0: (appData[7] << 8) | appData[8],
570
+ flags1: (appData[9] << 8) | appData[10],
571
+ transformCode: appData[11],
572
+ };
578
573
  }
579
- break;
580
- case 0xffdb:
581
- var quantizationTablesLength = readUint16();
582
- var quantizationTablesEnd = quantizationTablesLength + offset - 2;
583
- while (offset < quantizationTablesEnd) {
584
- var quantizationTableSpec = data[offset++];
585
- var tableData = new Int32Array(64);
586
- if (quantizationTableSpec >> 4 === 0) {
587
- for (j = 0; j < 64; j++) {
588
- var z = dctZigZag[j];
589
- tableData[z] = data[offset++];
590
- }
591
- }
592
- else if (quantizationTableSpec >> 4 === 1) {
593
- for (j = 0; j < 64; j++) {
594
- var zz = dctZigZag[j];
595
- tableData[zz] = readUint16();
596
- }
574
+ }
575
+ break;
576
+ case 0xffdb:
577
+ var quantizationTablesLength = readUint16();
578
+ var quantizationTablesEnd = quantizationTablesLength + offset - 2;
579
+ while (offset < quantizationTablesEnd) {
580
+ var quantizationTableSpec = data[offset++];
581
+ var tableData = new Int32Array(64);
582
+ if (quantizationTableSpec >> 4 === 0) {
583
+ for (j = 0; j < 64; j++) {
584
+ var z = dctZigZag[j];
585
+ tableData[z] = data[offset++];
597
586
  }
598
- else
599
- throw 'DQT: invalid table spec';
600
- quantizationTables[quantizationTableSpec & 15] = tableData;
601
- }
602
- break;
603
- case 0xffc0:
604
- case 0xffc1:
605
- case 0xffc2:
606
- if (frame) {
607
- throw 'Only single frame JPEGs supported';
608
- }
609
- readUint16();
610
- frame = {};
611
- frame.extended = fileMarker === 0xffc1;
612
- frame.progressive = fileMarker === 0xffc2;
613
- frame.precision = data[offset++];
614
- frame.scanLines = readUint16();
615
- frame.samplesPerLine = readUint16();
616
- frame.components = [];
617
- frame.componentIds = {};
618
- var componentsCount = data[offset++], componentId;
619
- var maxH = 0, maxV = 0;
620
- for (i = 0; i < componentsCount; i++) {
621
- componentId = data[offset];
622
- var h = data[offset + 1] >> 4;
623
- var v = data[offset + 1] & 15;
624
- if (maxH < h)
625
- maxH = h;
626
- if (maxV < v)
627
- maxV = v;
628
- var qId = data[offset + 2];
629
- l = frame.components.push({
630
- h: h,
631
- v: v,
632
- quantizationTable: quantizationTables[qId],
633
- quantizationTableId: qId,
634
- bitConversion: 255 / ((1 << frame.precision) - 1),
635
- });
636
- frame.componentIds[componentId] = l - 1;
637
- offset += 3;
638
- }
639
- frame.maxH = maxH;
640
- frame.maxV = maxV;
641
- prepareComponents(frame);
642
- break;
643
- case 0xffc4:
644
- var huffmanLength = readUint16();
645
- for (i = 2; i < huffmanLength;) {
646
- var huffmanTableSpec = data[offset++];
647
- var codeLengths = new Uint8Array(16);
648
- var codeLengthSum = 0;
649
- for (j = 0; j < 16; j++, offset++)
650
- codeLengthSum += codeLengths[j] = data[offset];
651
- var huffmanValues = new Uint8Array(codeLengthSum);
652
- for (j = 0; j < codeLengthSum; j++, offset++)
653
- huffmanValues[j] = data[offset];
654
- i += 17 + codeLengthSum;
655
- (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);
656
- }
657
- break;
658
- case 0xffdd:
659
- readUint16();
660
- resetInterval = readUint16();
661
- break;
662
- case 0xffda:
663
- var scanLength = readUint16();
664
- var selectorsCount = data[offset++];
665
- var components = [], component;
666
- for (i = 0; i < selectorsCount; i++) {
667
- var componentIndex = frame.componentIds[data[offset++]];
668
- component = frame.components[componentIndex];
669
- var tableSpec = data[offset++];
670
- component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4];
671
- component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];
672
- components.push(component);
673
587
  }
674
- var spectralStart = data[offset++];
675
- var spectralEnd = data[offset++];
676
- var successiveApproximation = data[offset++];
677
- var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15);
678
- offset += processed;
679
- break;
680
- case 0xffff:
681
- if (data[offset] !== 0xff) {
682
- offset--;
683
- }
684
- break;
685
- default:
686
- if (data[offset - 3] == 0xff &&
687
- data[offset - 2] >= 0xc0 &&
688
- data[offset - 2] <= 0xfe) {
689
- offset -= 3;
690
- break;
588
+ else if (quantizationTableSpec >> 4 === 1) {
589
+ for (j = 0; j < 64; j++) {
590
+ var zz = dctZigZag[j];
591
+ tableData[zz] = readUint16();
592
+ }
691
593
  }
692
- throw 'unknown JPEG marker ' + fileMarker.toString(16);
693
- }
694
- fileMarker = readUint16();
695
- }
696
- this.width = frame.samplesPerLine;
697
- this.height = frame.scanLines;
698
- this.jfif = jfif;
699
- this.adobe = adobe;
700
- this.components = [];
701
- switch (frame.components.length) {
702
- case 1:
703
- this.colorspace = ColorSpace.Grayscale;
594
+ else
595
+ throw 'DQT: invalid table spec';
596
+ quantizationTables[quantizationTableSpec & 15] = tableData;
597
+ }
704
598
  break;
705
- case 3:
706
- if (this.adobe)
707
- this.colorspace = ColorSpace.AdobeRGB;
708
- else
709
- this.colorspace = ColorSpace.RGB;
599
+ case 0xffc0:
600
+ case 0xffc1:
601
+ case 0xffc2:
602
+ if (frame) {
603
+ throw 'Only single frame JPEGs supported';
604
+ }
605
+ readUint16();
606
+ frame = {};
607
+ frame.extended = fileMarker === 0xffc1;
608
+ frame.progressive = fileMarker === 0xffc2;
609
+ frame.precision = data[offset++];
610
+ frame.scanLines = readUint16();
611
+ frame.samplesPerLine = readUint16();
612
+ frame.components = [];
613
+ frame.componentIds = {};
614
+ var componentsCount = data[offset++], componentId;
615
+ var maxH = 0, maxV = 0;
616
+ for (i = 0; i < componentsCount; i++) {
617
+ componentId = data[offset];
618
+ var h = data[offset + 1] >> 4;
619
+ var v = data[offset + 1] & 15;
620
+ if (maxH < h)
621
+ maxH = h;
622
+ if (maxV < v)
623
+ maxV = v;
624
+ var qId = data[offset + 2];
625
+ l = frame.components.push({
626
+ h: h,
627
+ v: v,
628
+ quantizationTable: quantizationTables[qId],
629
+ quantizationTableId: qId,
630
+ bitConversion: 255 / ((1 << frame.precision) - 1),
631
+ });
632
+ frame.componentIds[componentId] = l - 1;
633
+ offset += 3;
634
+ }
635
+ frame.maxH = maxH;
636
+ frame.maxV = maxV;
637
+ prepareComponents(frame);
710
638
  break;
711
- case 4:
712
- this.colorspace = ColorSpace.CYMK;
639
+ case 0xffc4:
640
+ var huffmanLength = readUint16();
641
+ for (i = 2; i < huffmanLength;) {
642
+ var huffmanTableSpec = data[offset++];
643
+ var codeLengths = new Uint8Array(16);
644
+ var codeLengthSum = 0;
645
+ for (j = 0; j < 16; j++, offset++)
646
+ codeLengthSum += codeLengths[j] = data[offset];
647
+ var huffmanValues = new Uint8Array(codeLengthSum);
648
+ for (j = 0; j < codeLengthSum; j++, offset++)
649
+ huffmanValues[j] = data[offset];
650
+ i += 17 + codeLengthSum;
651
+ (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);
652
+ }
653
+ break;
654
+ case 0xffdd:
655
+ readUint16();
656
+ resetInterval = readUint16();
657
+ break;
658
+ case 0xffda:
659
+ var scanLength = readUint16();
660
+ var selectorsCount = data[offset++];
661
+ var components = [], component;
662
+ for (i = 0; i < selectorsCount; i++) {
663
+ var componentIndex = frame.componentIds[data[offset++]];
664
+ component = frame.components[componentIndex];
665
+ var tableSpec = data[offset++];
666
+ component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4];
667
+ component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];
668
+ components.push(component);
669
+ }
670
+ var spectralStart = data[offset++];
671
+ var spectralEnd = data[offset++];
672
+ var successiveApproximation = data[offset++];
673
+ var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15);
674
+ offset += processed;
675
+ break;
676
+ case 0xffff:
677
+ if (data[offset] !== 0xff) {
678
+ offset--;
679
+ }
713
680
  break;
714
681
  default:
715
- this.colorspace = ColorSpace.Unknown;
716
- }
717
- for (var i = 0; i < frame.components.length; i++) {
718
- var component = frame.components[i];
719
- if (!component.quantizationTable &&
720
- component.quantizationTableId !== null)
721
- component.quantizationTable =
722
- quantizationTables[component.quantizationTableId];
723
- this.components.push({
724
- output: buildComponentData(frame, component),
725
- scaleX: component.h / frame.maxH,
726
- scaleY: component.v / frame.maxV,
727
- blocksPerLine: component.blocksPerLine,
728
- blocksPerColumn: component.blocksPerColumn,
729
- bitConversion: component.bitConversion,
730
- });
682
+ if (data[offset - 3] == 0xff &&
683
+ data[offset - 2] >= 0xc0 &&
684
+ data[offset - 2] <= 0xfe) {
685
+ offset -= 3;
686
+ break;
687
+ }
688
+ throw 'unknown JPEG marker ' + fileMarker.toString(16);
731
689
  }
732
- },
733
- getData16: function getData16(width, height) {
734
- if (this.components.length !== 1)
735
- throw 'Unsupported color mode';
736
- var scaleX = this.width / width, scaleY = this.height / height;
737
- var component, componentScaleX, componentScaleY;
738
- var x, y, i;
739
- var offset = 0;
740
- var numComponents = this.components.length;
741
- var dataLength = width * height * numComponents;
742
- var data = new Uint16Array(dataLength);
743
- var componentLine;
744
- var lineData = new Uint16Array((this.components[0].blocksPerLine << 3) *
745
- this.components[0].blocksPerColumn *
746
- 8);
747
- for (i = 0; i < numComponents; i++) {
748
- component = this.components[i];
749
- var blocksPerLine = component.blocksPerLine;
750
- var blocksPerColumn = component.blocksPerColumn;
751
- var samplesPerLine = blocksPerLine << 3;
752
- var j, k, ll = 0;
753
- var lineOffset = 0;
754
- for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
755
- var scanLine = blockRow << 3;
756
- for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
757
- var bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);
758
- var offset = 0, sample = blockCol << 3;
759
- for (j = 0; j < 8; j++) {
760
- var lineOffset = (scanLine + j) * samplesPerLine;
761
- for (k = 0; k < 8; k++) {
762
- lineData[lineOffset + sample + k] =
763
- component.output[bufferOffset + offset++];
764
- }
690
+ fileMarker = readUint16();
691
+ }
692
+ this.width = frame.samplesPerLine;
693
+ this.height = frame.scanLines;
694
+ this.jfif = jfif;
695
+ this.adobe = adobe;
696
+ this.components = [];
697
+ switch (frame.components.length) {
698
+ case 1:
699
+ this.colorspace = ColorSpace.Grayscale;
700
+ break;
701
+ case 3:
702
+ if (this.adobe)
703
+ this.colorspace = ColorSpace.AdobeRGB;
704
+ else
705
+ this.colorspace = ColorSpace.RGB;
706
+ break;
707
+ case 4:
708
+ this.colorspace = ColorSpace.CYMK;
709
+ break;
710
+ default:
711
+ this.colorspace = ColorSpace.Unknown;
712
+ }
713
+ for (var i = 0; i < frame.components.length; i++) {
714
+ var component = frame.components[i];
715
+ if (!component.quantizationTable &&
716
+ component.quantizationTableId !== null)
717
+ component.quantizationTable =
718
+ quantizationTables[component.quantizationTableId];
719
+ this.components.push({
720
+ output: buildComponentData(frame, component),
721
+ scaleX: component.h / frame.maxH,
722
+ scaleY: component.v / frame.maxV,
723
+ blocksPerLine: component.blocksPerLine,
724
+ blocksPerColumn: component.blocksPerColumn,
725
+ bitConversion: component.bitConversion,
726
+ });
727
+ }
728
+ }
729
+ getData16(width, height) {
730
+ if (this.components.length !== 1)
731
+ throw 'Unsupported color mode';
732
+ var scaleX = this.width / width, scaleY = this.height / height;
733
+ var component, componentScaleX, componentScaleY;
734
+ var x, y, i;
735
+ var offset = 0;
736
+ var numComponents = this.components.length;
737
+ var dataLength = width * height * numComponents;
738
+ var data = new Uint16Array(dataLength);
739
+ var componentLine;
740
+ var lineData = new Uint16Array((this.components[0].blocksPerLine << 3) *
741
+ this.components[0].blocksPerColumn *
742
+ 8);
743
+ for (i = 0; i < numComponents; i++) {
744
+ component = this.components[i];
745
+ var blocksPerLine = component.blocksPerLine;
746
+ var blocksPerColumn = component.blocksPerColumn;
747
+ var samplesPerLine = blocksPerLine << 3;
748
+ var j, k, ll = 0;
749
+ var lineOffset = 0;
750
+ for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
751
+ var scanLine = blockRow << 3;
752
+ for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
753
+ var bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);
754
+ var offset = 0, sample = blockCol << 3;
755
+ for (j = 0; j < 8; j++) {
756
+ var lineOffset = (scanLine + j) * samplesPerLine;
757
+ for (k = 0; k < 8; k++) {
758
+ lineData[lineOffset + sample + k] =
759
+ component.output[bufferOffset + offset++];
765
760
  }
766
761
  }
767
762
  }
768
- componentScaleX = component.scaleX * scaleX;
769
- componentScaleY = component.scaleY * scaleY;
770
- offset = i;
771
- var cx, cy;
772
- var index;
773
- for (y = 0; y < height; y++) {
774
- for (x = 0; x < width; x++) {
775
- cy = 0 | (y * componentScaleY);
776
- cx = 0 | (x * componentScaleX);
777
- index = cy * samplesPerLine + cx;
778
- data[offset] = lineData[index];
779
- offset += numComponents;
780
- }
763
+ }
764
+ componentScaleX = component.scaleX * scaleX;
765
+ componentScaleY = component.scaleY * scaleY;
766
+ offset = i;
767
+ var cx, cy;
768
+ var index;
769
+ for (y = 0; y < height; y++) {
770
+ for (x = 0; x < width; x++) {
771
+ cy = 0 | (y * componentScaleY);
772
+ cx = 0 | (x * componentScaleX);
773
+ index = cy * samplesPerLine + cx;
774
+ data[offset] = lineData[index];
775
+ offset += numComponents;
781
776
  }
782
777
  }
783
- return data;
784
- },
785
- getData: function getData(width, height) {
786
- var scaleX = this.width / width, scaleY = this.height / height;
787
- var component, componentScaleX, componentScaleY;
788
- var x, y, i;
789
- var offset = 0;
790
- var Y, Cb, Cr, K, C, M, Ye, R, G, B;
791
- var colorTransform;
792
- var numComponents = this.components.length;
793
- var dataLength = width * height * numComponents;
794
- var data = new Uint8Array(dataLength);
795
- var componentLine;
796
- var lineData = new Uint8Array((this.components[0].blocksPerLine << 3) *
797
- this.components[0].blocksPerColumn *
798
- 8);
799
- for (i = 0; i < numComponents; i++) {
800
- component = this.components[i];
801
- var blocksPerLine = component.blocksPerLine;
802
- var blocksPerColumn = component.blocksPerColumn;
803
- var samplesPerLine = blocksPerLine << 3;
804
- var j, k, ll = 0;
805
- var lineOffset = 0;
806
- for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
807
- var scanLine = blockRow << 3;
808
- for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
809
- var bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);
810
- var offset = 0, sample = blockCol << 3;
811
- for (j = 0; j < 8; j++) {
812
- var lineOffset = (scanLine + j) * samplesPerLine;
813
- for (k = 0; k < 8; k++) {
814
- lineData[lineOffset + sample + k] =
815
- component.output[bufferOffset + offset++] *
816
- component.bitConversion;
817
- }
778
+ }
779
+ return data;
780
+ }
781
+ getData(width, height) {
782
+ var scaleX = this.width / width, scaleY = this.height / height;
783
+ var component, componentScaleX, componentScaleY;
784
+ var x, y, i;
785
+ var offset = 0;
786
+ var Y, Cb, Cr, K, C, M, Ye, R, G, B;
787
+ var colorTransform;
788
+ var numComponents = this.components.length;
789
+ var dataLength = width * height * numComponents;
790
+ var data = new Uint8Array(dataLength);
791
+ var componentLine;
792
+ var lineData = new Uint8Array((this.components[0].blocksPerLine << 3) *
793
+ this.components[0].blocksPerColumn *
794
+ 8);
795
+ for (i = 0; i < numComponents; i++) {
796
+ component = this.components[i];
797
+ var blocksPerLine = component.blocksPerLine;
798
+ var blocksPerColumn = component.blocksPerColumn;
799
+ var samplesPerLine = blocksPerLine << 3;
800
+ var j, k, ll = 0;
801
+ var lineOffset = 0;
802
+ for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
803
+ var scanLine = blockRow << 3;
804
+ for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
805
+ var bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);
806
+ var offset = 0, sample = blockCol << 3;
807
+ for (j = 0; j < 8; j++) {
808
+ var lineOffset = (scanLine + j) * samplesPerLine;
809
+ for (k = 0; k < 8; k++) {
810
+ lineData[lineOffset + sample + k] =
811
+ component.output[bufferOffset + offset++] *
812
+ component.bitConversion;
818
813
  }
819
814
  }
820
815
  }
821
- componentScaleX = component.scaleX * scaleX;
822
- componentScaleY = component.scaleY * scaleY;
823
- offset = i;
824
- var cx, cy;
825
- var index;
826
- for (y = 0; y < height; y++) {
827
- for (x = 0; x < width; x++) {
828
- cy = 0 | (y * componentScaleY);
829
- cx = 0 | (x * componentScaleX);
830
- index = cy * samplesPerLine + cx;
831
- data[offset] = lineData[index];
832
- offset += numComponents;
833
- }
816
+ }
817
+ componentScaleX = component.scaleX * scaleX;
818
+ componentScaleY = component.scaleY * scaleY;
819
+ offset = i;
820
+ var cx, cy;
821
+ var index;
822
+ for (y = 0; y < height; y++) {
823
+ for (x = 0; x < width; x++) {
824
+ cy = 0 | (y * componentScaleY);
825
+ cx = 0 | (x * componentScaleX);
826
+ index = cy * samplesPerLine + cx;
827
+ data[offset] = lineData[index];
828
+ offset += numComponents;
834
829
  }
835
830
  }
836
- switch (numComponents) {
837
- case 1:
838
- case 2:
839
- break;
840
- case 3:
831
+ }
832
+ switch (numComponents) {
833
+ case 1:
834
+ case 2:
835
+ break;
836
+ case 3:
837
+ colorTransform = true;
838
+ if (this.adobe && this.adobe.transformCode)
841
839
  colorTransform = true;
842
- if (this.adobe && this.adobe.transformCode)
843
- colorTransform = true;
844
- else if (typeof this.colorTransform !== 'undefined')
845
- colorTransform = !!this.colorTransform;
846
- if (colorTransform) {
847
- for (i = 0; i < dataLength; i += numComponents) {
848
- Y = data[i];
849
- Cb = data[i + 1];
850
- Cr = data[i + 2];
851
- R = clampToUint8(Y - 179.456 + 1.402 * Cr);
852
- G = clampToUint8(Y + 135.459 - 0.344 * Cb - 0.714 * Cr);
853
- B = clampToUint8(Y - 226.816 + 1.772 * Cb);
854
- data[i] = R;
855
- data[i + 1] = G;
856
- data[i + 2] = B;
857
- }
840
+ else if (typeof this.colorTransform !== 'undefined')
841
+ colorTransform = !!this.colorTransform;
842
+ if (colorTransform) {
843
+ for (i = 0; i < dataLength; i += numComponents) {
844
+ Y = data[i];
845
+ Cb = data[i + 1];
846
+ Cr = data[i + 2];
847
+ R = clampToUint8(Y - 179.456 + 1.402 * Cr);
848
+ G = clampToUint8(Y + 135.459 - 0.344 * Cb - 0.714 * Cr);
849
+ B = clampToUint8(Y - 226.816 + 1.772 * Cb);
850
+ data[i] = R;
851
+ data[i + 1] = G;
852
+ data[i + 2] = B;
858
853
  }
859
- break;
860
- case 4:
861
- if (!this.adobe)
862
- throw 'Unsupported color mode (4 components)';
863
- colorTransform = false;
864
- if (this.adobe && this.adobe.transformCode)
865
- colorTransform = true;
866
- else if (typeof this.colorTransform !== 'undefined')
867
- colorTransform = !!this.colorTransform;
868
- if (colorTransform) {
869
- for (i = 0; i < dataLength; i += numComponents) {
870
- Y = data[i];
871
- Cb = data[i + 1];
872
- Cr = data[i + 2];
873
- C = clampToUint8(434.456 - Y - 1.402 * Cr);
874
- M = clampToUint8(119.541 - Y + 0.344 * Cb + 0.714 * Cr);
875
- Y = clampToUint8(481.816 - Y - 1.772 * Cb);
876
- data[i] = C;
877
- data[i + 1] = M;
878
- data[i + 2] = Y;
879
- }
854
+ }
855
+ break;
856
+ case 4:
857
+ if (!this.adobe)
858
+ throw 'Unsupported color mode (4 components)';
859
+ colorTransform = false;
860
+ if (this.adobe && this.adobe.transformCode)
861
+ colorTransform = true;
862
+ else if (typeof this.colorTransform !== 'undefined')
863
+ colorTransform = !!this.colorTransform;
864
+ if (colorTransform) {
865
+ for (i = 0; i < dataLength; i += numComponents) {
866
+ Y = data[i];
867
+ Cb = data[i + 1];
868
+ Cr = data[i + 2];
869
+ C = clampToUint8(434.456 - Y - 1.402 * Cr);
870
+ M = clampToUint8(119.541 - Y + 0.344 * Cb + 0.714 * Cr);
871
+ Y = clampToUint8(481.816 - Y - 1.772 * Cb);
872
+ data[i] = C;
873
+ data[i + 1] = M;
874
+ data[i + 2] = Y;
880
875
  }
881
- break;
882
- default:
883
- throw 'Unsupported color mode';
884
- }
885
- return data;
886
- },
887
- });
888
- return JpegImage;
889
- })();
876
+ }
877
+ break;
878
+ default:
879
+ throw 'Unsupported color mode';
880
+ }
881
+ return data;
882
+ }
883
+ }
884
+ export default JpegImage;