@vitessce/all 3.9.10 → 4.0.0-test.1

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,856 +0,0 @@
1
- import { aX as BaseDecoder } from "./index-Cjg9h1C7.js";
2
- const dctZigZag = new Int32Array([
3
- 0,
4
- 1,
5
- 8,
6
- 16,
7
- 9,
8
- 2,
9
- 3,
10
- 10,
11
- 17,
12
- 24,
13
- 32,
14
- 25,
15
- 18,
16
- 11,
17
- 4,
18
- 5,
19
- 12,
20
- 19,
21
- 26,
22
- 33,
23
- 40,
24
- 48,
25
- 41,
26
- 34,
27
- 27,
28
- 20,
29
- 13,
30
- 6,
31
- 7,
32
- 14,
33
- 21,
34
- 28,
35
- 35,
36
- 42,
37
- 49,
38
- 56,
39
- 57,
40
- 50,
41
- 43,
42
- 36,
43
- 29,
44
- 22,
45
- 15,
46
- 23,
47
- 30,
48
- 37,
49
- 44,
50
- 51,
51
- 58,
52
- 59,
53
- 52,
54
- 45,
55
- 38,
56
- 31,
57
- 39,
58
- 46,
59
- 53,
60
- 60,
61
- 61,
62
- 54,
63
- 47,
64
- 55,
65
- 62,
66
- 63
67
- ]);
68
- const dctCos1 = 4017;
69
- const dctSin1 = 799;
70
- const dctCos3 = 3406;
71
- const dctSin3 = 2276;
72
- const dctCos6 = 1567;
73
- const dctSin6 = 3784;
74
- const dctSqrt2 = 5793;
75
- const dctSqrt1d2 = 2896;
76
- function buildHuffmanTable(codeLengths, values) {
77
- let k = 0;
78
- const code = [];
79
- let length = 16;
80
- while (length > 0 && !codeLengths[length - 1]) {
81
- --length;
82
- }
83
- code.push({ children: [], index: 0 });
84
- let p = code[0];
85
- let q;
86
- for (let i = 0; i < length; i++) {
87
- for (let j = 0; j < codeLengths[i]; j++) {
88
- p = code.pop();
89
- p.children[p.index] = values[k];
90
- while (p.index > 0) {
91
- p = code.pop();
92
- }
93
- p.index++;
94
- code.push(p);
95
- while (code.length <= i) {
96
- code.push(q = { children: [], index: 0 });
97
- p.children[p.index] = q.children;
98
- p = q;
99
- }
100
- k++;
101
- }
102
- if (i + 1 < length) {
103
- code.push(q = { children: [], index: 0 });
104
- p.children[p.index] = q.children;
105
- p = q;
106
- }
107
- }
108
- return code[0].children;
109
- }
110
- function decodeScan(data, initialOffset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
111
- const { mcusPerLine, progressive } = frame;
112
- const startOffset = initialOffset;
113
- let offset = initialOffset;
114
- let bitsData = 0;
115
- let bitsCount = 0;
116
- function readBit() {
117
- if (bitsCount > 0) {
118
- bitsCount--;
119
- return bitsData >> bitsCount & 1;
120
- }
121
- bitsData = data[offset++];
122
- if (bitsData === 255) {
123
- const nextByte = data[offset++];
124
- if (nextByte) {
125
- throw new Error(`unexpected marker: ${(bitsData << 8 | nextByte).toString(16)}`);
126
- }
127
- }
128
- bitsCount = 7;
129
- return bitsData >>> 7;
130
- }
131
- function decodeHuffman(tree) {
132
- let node = tree;
133
- let bit;
134
- while ((bit = readBit()) !== null) {
135
- node = node[bit];
136
- if (typeof node === "number") {
137
- return node;
138
- }
139
- if (typeof node !== "object") {
140
- throw new Error("invalid huffman sequence");
141
- }
142
- }
143
- return null;
144
- }
145
- function receive(initialLength) {
146
- let length = initialLength;
147
- let n2 = 0;
148
- while (length > 0) {
149
- const bit = readBit();
150
- if (bit === null) {
151
- return void 0;
152
- }
153
- n2 = n2 << 1 | bit;
154
- --length;
155
- }
156
- return n2;
157
- }
158
- function receiveAndExtend(length) {
159
- const n2 = receive(length);
160
- if (n2 >= 1 << length - 1) {
161
- return n2;
162
- }
163
- return n2 + (-1 << length) + 1;
164
- }
165
- function decodeBaseline(component2, zz) {
166
- const t = decodeHuffman(component2.huffmanTableDC);
167
- const diff = t === 0 ? 0 : receiveAndExtend(t);
168
- component2.pred += diff;
169
- zz[0] = component2.pred;
170
- let k2 = 1;
171
- while (k2 < 64) {
172
- const rs = decodeHuffman(component2.huffmanTableAC);
173
- const s = rs & 15;
174
- const r = rs >> 4;
175
- if (s === 0) {
176
- if (r < 15) {
177
- break;
178
- }
179
- k2 += 16;
180
- } else {
181
- k2 += r;
182
- const z = dctZigZag[k2];
183
- zz[z] = receiveAndExtend(s);
184
- k2++;
185
- }
186
- }
187
- }
188
- function decodeDCFirst(component2, zz) {
189
- const t = decodeHuffman(component2.huffmanTableDC);
190
- const diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
191
- component2.pred += diff;
192
- zz[0] = component2.pred;
193
- }
194
- function decodeDCSuccessive(component2, zz) {
195
- zz[0] |= readBit() << successive;
196
- }
197
- let eobrun = 0;
198
- function decodeACFirst(component2, zz) {
199
- if (eobrun > 0) {
200
- eobrun--;
201
- return;
202
- }
203
- let k2 = spectralStart;
204
- const e = spectralEnd;
205
- while (k2 <= e) {
206
- const rs = decodeHuffman(component2.huffmanTableAC);
207
- const s = rs & 15;
208
- const r = rs >> 4;
209
- if (s === 0) {
210
- if (r < 15) {
211
- eobrun = receive(r) + (1 << r) - 1;
212
- break;
213
- }
214
- k2 += 16;
215
- } else {
216
- k2 += r;
217
- const z = dctZigZag[k2];
218
- zz[z] = receiveAndExtend(s) * (1 << successive);
219
- k2++;
220
- }
221
- }
222
- }
223
- let successiveACState = 0;
224
- let successiveACNextValue;
225
- function decodeACSuccessive(component2, zz) {
226
- let k2 = spectralStart;
227
- const e = spectralEnd;
228
- let r = 0;
229
- while (k2 <= e) {
230
- const z = dctZigZag[k2];
231
- const direction = zz[z] < 0 ? -1 : 1;
232
- switch (successiveACState) {
233
- case 0: {
234
- const rs = decodeHuffman(component2.huffmanTableAC);
235
- const s = rs & 15;
236
- r = rs >> 4;
237
- if (s === 0) {
238
- if (r < 15) {
239
- eobrun = receive(r) + (1 << r);
240
- successiveACState = 4;
241
- } else {
242
- r = 16;
243
- successiveACState = 1;
244
- }
245
- } else {
246
- if (s !== 1) {
247
- throw new Error("invalid ACn encoding");
248
- }
249
- successiveACNextValue = receiveAndExtend(s);
250
- successiveACState = r ? 2 : 3;
251
- }
252
- continue;
253
- }
254
- case 1:
255
- // skipping r zero items
256
- case 2:
257
- if (zz[z]) {
258
- zz[z] += (readBit() << successive) * direction;
259
- } else {
260
- r--;
261
- if (r === 0) {
262
- successiveACState = successiveACState === 2 ? 3 : 0;
263
- }
264
- }
265
- break;
266
- case 3:
267
- if (zz[z]) {
268
- zz[z] += (readBit() << successive) * direction;
269
- } else {
270
- zz[z] = successiveACNextValue << successive;
271
- successiveACState = 0;
272
- }
273
- break;
274
- case 4:
275
- if (zz[z]) {
276
- zz[z] += (readBit() << successive) * direction;
277
- }
278
- break;
279
- }
280
- k2++;
281
- }
282
- if (successiveACState === 4) {
283
- eobrun--;
284
- if (eobrun === 0) {
285
- successiveACState = 0;
286
- }
287
- }
288
- }
289
- function decodeMcu(component2, decodeFunction, mcu2, row, col) {
290
- const mcuRow = mcu2 / mcusPerLine | 0;
291
- const mcuCol = mcu2 % mcusPerLine;
292
- const blockRow = mcuRow * component2.v + row;
293
- const blockCol = mcuCol * component2.h + col;
294
- decodeFunction(component2, component2.blocks[blockRow][blockCol]);
295
- }
296
- function decodeBlock(component2, decodeFunction, mcu2) {
297
- const blockRow = mcu2 / component2.blocksPerLine | 0;
298
- const blockCol = mcu2 % component2.blocksPerLine;
299
- decodeFunction(component2, component2.blocks[blockRow][blockCol]);
300
- }
301
- const componentsLength = components.length;
302
- let component;
303
- let i;
304
- let j;
305
- let k;
306
- let n;
307
- let decodeFn;
308
- if (progressive) {
309
- if (spectralStart === 0) {
310
- decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
311
- } else {
312
- decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;
313
- }
314
- } else {
315
- decodeFn = decodeBaseline;
316
- }
317
- let mcu = 0;
318
- let marker;
319
- let mcuExpected;
320
- if (componentsLength === 1) {
321
- mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
322
- } else {
323
- mcuExpected = mcusPerLine * frame.mcusPerColumn;
324
- }
325
- const usedResetInterval = resetInterval || mcuExpected;
326
- while (mcu < mcuExpected) {
327
- for (i = 0; i < componentsLength; i++) {
328
- components[i].pred = 0;
329
- }
330
- eobrun = 0;
331
- if (componentsLength === 1) {
332
- component = components[0];
333
- for (n = 0; n < usedResetInterval; n++) {
334
- decodeBlock(component, decodeFn, mcu);
335
- mcu++;
336
- }
337
- } else {
338
- for (n = 0; n < usedResetInterval; n++) {
339
- for (i = 0; i < componentsLength; i++) {
340
- component = components[i];
341
- const { h, v } = component;
342
- for (j = 0; j < v; j++) {
343
- for (k = 0; k < h; k++) {
344
- decodeMcu(component, decodeFn, mcu, j, k);
345
- }
346
- }
347
- }
348
- mcu++;
349
- if (mcu === mcuExpected) {
350
- break;
351
- }
352
- }
353
- }
354
- bitsCount = 0;
355
- marker = data[offset] << 8 | data[offset + 1];
356
- if (marker < 65280) {
357
- throw new Error("marker was not found");
358
- }
359
- if (marker >= 65488 && marker <= 65495) {
360
- offset += 2;
361
- } else {
362
- break;
363
- }
364
- }
365
- return offset - startOffset;
366
- }
367
- function buildComponentData(frame, component) {
368
- const lines = [];
369
- const { blocksPerLine, blocksPerColumn } = component;
370
- const samplesPerLine = blocksPerLine << 3;
371
- const R = new Int32Array(64);
372
- const r = new Uint8Array(64);
373
- function quantizeAndInverse(zz, dataOut, dataIn) {
374
- const qt = component.quantizationTable;
375
- let v0;
376
- let v1;
377
- let v2;
378
- let v3;
379
- let v4;
380
- let v5;
381
- let v6;
382
- let v7;
383
- let t;
384
- const p = dataIn;
385
- let i;
386
- for (i = 0; i < 64; i++) {
387
- p[i] = zz[i] * qt[i];
388
- }
389
- for (i = 0; i < 8; ++i) {
390
- const row = 8 * i;
391
- if (p[1 + row] === 0 && p[2 + row] === 0 && p[3 + row] === 0 && p[4 + row] === 0 && p[5 + row] === 0 && p[6 + row] === 0 && p[7 + row] === 0) {
392
- t = dctSqrt2 * p[0 + row] + 512 >> 10;
393
- p[0 + row] = t;
394
- p[1 + row] = t;
395
- p[2 + row] = t;
396
- p[3 + row] = t;
397
- p[4 + row] = t;
398
- p[5 + row] = t;
399
- p[6 + row] = t;
400
- p[7 + row] = t;
401
- continue;
402
- }
403
- v0 = dctSqrt2 * p[0 + row] + 128 >> 8;
404
- v1 = dctSqrt2 * p[4 + row] + 128 >> 8;
405
- v2 = p[2 + row];
406
- v3 = p[6 + row];
407
- v4 = dctSqrt1d2 * (p[1 + row] - p[7 + row]) + 128 >> 8;
408
- v7 = dctSqrt1d2 * (p[1 + row] + p[7 + row]) + 128 >> 8;
409
- v5 = p[3 + row] << 4;
410
- v6 = p[5 + row] << 4;
411
- t = v0 - v1 + 1 >> 1;
412
- v0 = v0 + v1 + 1 >> 1;
413
- v1 = t;
414
- t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8;
415
- v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8;
416
- v3 = t;
417
- t = v4 - v6 + 1 >> 1;
418
- v4 = v4 + v6 + 1 >> 1;
419
- v6 = t;
420
- t = v7 + v5 + 1 >> 1;
421
- v5 = v7 - v5 + 1 >> 1;
422
- v7 = t;
423
- t = v0 - v3 + 1 >> 1;
424
- v0 = v0 + v3 + 1 >> 1;
425
- v3 = t;
426
- t = v1 - v2 + 1 >> 1;
427
- v1 = v1 + v2 + 1 >> 1;
428
- v2 = t;
429
- t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;
430
- v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;
431
- v7 = t;
432
- t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;
433
- v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;
434
- v6 = t;
435
- p[0 + row] = v0 + v7;
436
- p[7 + row] = v0 - v7;
437
- p[1 + row] = v1 + v6;
438
- p[6 + row] = v1 - v6;
439
- p[2 + row] = v2 + v5;
440
- p[5 + row] = v2 - v5;
441
- p[3 + row] = v3 + v4;
442
- p[4 + row] = v3 - v4;
443
- }
444
- for (i = 0; i < 8; ++i) {
445
- const col = i;
446
- if (p[1 * 8 + col] === 0 && p[2 * 8 + col] === 0 && p[3 * 8 + col] === 0 && p[4 * 8 + col] === 0 && p[5 * 8 + col] === 0 && p[6 * 8 + col] === 0 && p[7 * 8 + col] === 0) {
447
- t = dctSqrt2 * dataIn[i + 0] + 8192 >> 14;
448
- p[0 * 8 + col] = t;
449
- p[1 * 8 + col] = t;
450
- p[2 * 8 + col] = t;
451
- p[3 * 8 + col] = t;
452
- p[4 * 8 + col] = t;
453
- p[5 * 8 + col] = t;
454
- p[6 * 8 + col] = t;
455
- p[7 * 8 + col] = t;
456
- continue;
457
- }
458
- v0 = dctSqrt2 * p[0 * 8 + col] + 2048 >> 12;
459
- v1 = dctSqrt2 * p[4 * 8 + col] + 2048 >> 12;
460
- v2 = p[2 * 8 + col];
461
- v3 = p[6 * 8 + col];
462
- v4 = dctSqrt1d2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048 >> 12;
463
- v7 = dctSqrt1d2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048 >> 12;
464
- v5 = p[3 * 8 + col];
465
- v6 = p[5 * 8 + col];
466
- t = v0 - v1 + 1 >> 1;
467
- v0 = v0 + v1 + 1 >> 1;
468
- v1 = t;
469
- t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12;
470
- v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12;
471
- v3 = t;
472
- t = v4 - v6 + 1 >> 1;
473
- v4 = v4 + v6 + 1 >> 1;
474
- v6 = t;
475
- t = v7 + v5 + 1 >> 1;
476
- v5 = v7 - v5 + 1 >> 1;
477
- v7 = t;
478
- t = v0 - v3 + 1 >> 1;
479
- v0 = v0 + v3 + 1 >> 1;
480
- v3 = t;
481
- t = v1 - v2 + 1 >> 1;
482
- v1 = v1 + v2 + 1 >> 1;
483
- v2 = t;
484
- t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;
485
- v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;
486
- v7 = t;
487
- t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;
488
- v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;
489
- v6 = t;
490
- p[0 * 8 + col] = v0 + v7;
491
- p[7 * 8 + col] = v0 - v7;
492
- p[1 * 8 + col] = v1 + v6;
493
- p[6 * 8 + col] = v1 - v6;
494
- p[2 * 8 + col] = v2 + v5;
495
- p[5 * 8 + col] = v2 - v5;
496
- p[3 * 8 + col] = v3 + v4;
497
- p[4 * 8 + col] = v3 - v4;
498
- }
499
- for (i = 0; i < 64; ++i) {
500
- const sample = 128 + (p[i] + 8 >> 4);
501
- if (sample < 0) {
502
- dataOut[i] = 0;
503
- } else if (sample > 255) {
504
- dataOut[i] = 255;
505
- } else {
506
- dataOut[i] = sample;
507
- }
508
- }
509
- }
510
- for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
511
- const scanLine = blockRow << 3;
512
- for (let i = 0; i < 8; i++) {
513
- lines.push(new Uint8Array(samplesPerLine));
514
- }
515
- for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {
516
- quantizeAndInverse(component.blocks[blockRow][blockCol], r, R);
517
- let offset = 0;
518
- const sample = blockCol << 3;
519
- for (let j = 0; j < 8; j++) {
520
- const line = lines[scanLine + j];
521
- for (let i = 0; i < 8; i++) {
522
- line[sample + i] = r[offset++];
523
- }
524
- }
525
- }
526
- }
527
- return lines;
528
- }
529
- class JpegStreamReader {
530
- constructor() {
531
- this.jfif = null;
532
- this.adobe = null;
533
- this.quantizationTables = [];
534
- this.huffmanTablesAC = [];
535
- this.huffmanTablesDC = [];
536
- this.resetFrames();
537
- }
538
- resetFrames() {
539
- this.frames = [];
540
- }
541
- parse(data) {
542
- let offset = 0;
543
- function readUint16() {
544
- const value = data[offset] << 8 | data[offset + 1];
545
- offset += 2;
546
- return value;
547
- }
548
- function readDataBlock() {
549
- const length = readUint16();
550
- const array = data.subarray(offset, offset + length - 2);
551
- offset += array.length;
552
- return array;
553
- }
554
- function prepareComponents(frame) {
555
- let maxH = 0;
556
- let maxV = 0;
557
- let component;
558
- let componentId;
559
- for (componentId in frame.components) {
560
- if (frame.components.hasOwnProperty(componentId)) {
561
- component = frame.components[componentId];
562
- if (maxH < component.h) {
563
- maxH = component.h;
564
- }
565
- if (maxV < component.v) {
566
- maxV = component.v;
567
- }
568
- }
569
- }
570
- const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / maxH);
571
- const mcusPerColumn = Math.ceil(frame.scanLines / 8 / maxV);
572
- for (componentId in frame.components) {
573
- if (frame.components.hasOwnProperty(componentId)) {
574
- component = frame.components[componentId];
575
- const blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / maxH);
576
- const blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / maxV);
577
- const blocksPerLineForMcu = mcusPerLine * component.h;
578
- const blocksPerColumnForMcu = mcusPerColumn * component.v;
579
- const blocks = [];
580
- for (let i = 0; i < blocksPerColumnForMcu; i++) {
581
- const row = [];
582
- for (let j = 0; j < blocksPerLineForMcu; j++) {
583
- row.push(new Int32Array(64));
584
- }
585
- blocks.push(row);
586
- }
587
- component.blocksPerLine = blocksPerLine;
588
- component.blocksPerColumn = blocksPerColumn;
589
- component.blocks = blocks;
590
- }
591
- }
592
- frame.maxH = maxH;
593
- frame.maxV = maxV;
594
- frame.mcusPerLine = mcusPerLine;
595
- frame.mcusPerColumn = mcusPerColumn;
596
- }
597
- let fileMarker = readUint16();
598
- if (fileMarker !== 65496) {
599
- throw new Error("SOI not found");
600
- }
601
- fileMarker = readUint16();
602
- while (fileMarker !== 65497) {
603
- switch (fileMarker) {
604
- case 65280:
605
- break;
606
- case 65504:
607
- // APP0 (Application Specific)
608
- case 65505:
609
- // APP1
610
- case 65506:
611
- // APP2
612
- case 65507:
613
- // APP3
614
- case 65508:
615
- // APP4
616
- case 65509:
617
- // APP5
618
- case 65510:
619
- // APP6
620
- case 65511:
621
- // APP7
622
- case 65512:
623
- // APP8
624
- case 65513:
625
- // APP9
626
- case 65514:
627
- // APP10
628
- case 65515:
629
- // APP11
630
- case 65516:
631
- // APP12
632
- case 65517:
633
- // APP13
634
- case 65518:
635
- // APP14
636
- case 65519:
637
- // APP15
638
- case 65534: {
639
- const appData = readDataBlock();
640
- if (fileMarker === 65504) {
641
- if (appData[0] === 74 && appData[1] === 70 && appData[2] === 73 && appData[3] === 70 && appData[4] === 0) {
642
- this.jfif = {
643
- version: { major: appData[5], minor: appData[6] },
644
- densityUnits: appData[7],
645
- xDensity: appData[8] << 8 | appData[9],
646
- yDensity: appData[10] << 8 | appData[11],
647
- thumbWidth: appData[12],
648
- thumbHeight: appData[13],
649
- thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13])
650
- };
651
- }
652
- }
653
- if (fileMarker === 65518) {
654
- if (appData[0] === 65 && appData[1] === 100 && appData[2] === 111 && appData[3] === 98 && appData[4] === 101 && appData[5] === 0) {
655
- this.adobe = {
656
- version: appData[6],
657
- flags0: appData[7] << 8 | appData[8],
658
- flags1: appData[9] << 8 | appData[10],
659
- transformCode: appData[11]
660
- };
661
- }
662
- }
663
- break;
664
- }
665
- case 65499: {
666
- const quantizationTablesLength = readUint16();
667
- const quantizationTablesEnd = quantizationTablesLength + offset - 2;
668
- while (offset < quantizationTablesEnd) {
669
- const quantizationTableSpec = data[offset++];
670
- const tableData = new Int32Array(64);
671
- if (quantizationTableSpec >> 4 === 0) {
672
- for (let j = 0; j < 64; j++) {
673
- const z = dctZigZag[j];
674
- tableData[z] = data[offset++];
675
- }
676
- } else if (quantizationTableSpec >> 4 === 1) {
677
- for (let j = 0; j < 64; j++) {
678
- const z = dctZigZag[j];
679
- tableData[z] = readUint16();
680
- }
681
- } else {
682
- throw new Error("DQT: invalid table spec");
683
- }
684
- this.quantizationTables[quantizationTableSpec & 15] = tableData;
685
- }
686
- break;
687
- }
688
- case 65472:
689
- // SOF0 (Start of Frame, Baseline DCT)
690
- case 65473:
691
- // SOF1 (Start of Frame, Extended DCT)
692
- case 65474: {
693
- readUint16();
694
- const frame = {
695
- extended: fileMarker === 65473,
696
- progressive: fileMarker === 65474,
697
- precision: data[offset++],
698
- scanLines: readUint16(),
699
- samplesPerLine: readUint16(),
700
- components: {},
701
- componentsOrder: []
702
- };
703
- const componentsCount = data[offset++];
704
- let componentId;
705
- for (let i = 0; i < componentsCount; i++) {
706
- componentId = data[offset];
707
- const h = data[offset + 1] >> 4;
708
- const v = data[offset + 1] & 15;
709
- const qId = data[offset + 2];
710
- frame.componentsOrder.push(componentId);
711
- frame.components[componentId] = {
712
- h,
713
- v,
714
- quantizationIdx: qId
715
- };
716
- offset += 3;
717
- }
718
- prepareComponents(frame);
719
- this.frames.push(frame);
720
- break;
721
- }
722
- case 65476: {
723
- const huffmanLength = readUint16();
724
- for (let i = 2; i < huffmanLength; ) {
725
- const huffmanTableSpec = data[offset++];
726
- const codeLengths = new Uint8Array(16);
727
- let codeLengthSum = 0;
728
- for (let j = 0; j < 16; j++, offset++) {
729
- codeLengths[j] = data[offset];
730
- codeLengthSum += codeLengths[j];
731
- }
732
- const huffmanValues = new Uint8Array(codeLengthSum);
733
- for (let j = 0; j < codeLengthSum; j++, offset++) {
734
- huffmanValues[j] = data[offset];
735
- }
736
- i += 17 + codeLengthSum;
737
- if (huffmanTableSpec >> 4 === 0) {
738
- this.huffmanTablesDC[huffmanTableSpec & 15] = buildHuffmanTable(
739
- codeLengths,
740
- huffmanValues
741
- );
742
- } else {
743
- this.huffmanTablesAC[huffmanTableSpec & 15] = buildHuffmanTable(
744
- codeLengths,
745
- huffmanValues
746
- );
747
- }
748
- }
749
- break;
750
- }
751
- case 65501:
752
- readUint16();
753
- this.resetInterval = readUint16();
754
- break;
755
- case 65498: {
756
- readUint16();
757
- const selectorsCount = data[offset++];
758
- const components = [];
759
- const frame = this.frames[0];
760
- for (let i = 0; i < selectorsCount; i++) {
761
- const component = frame.components[data[offset++]];
762
- const tableSpec = data[offset++];
763
- component.huffmanTableDC = this.huffmanTablesDC[tableSpec >> 4];
764
- component.huffmanTableAC = this.huffmanTablesAC[tableSpec & 15];
765
- components.push(component);
766
- }
767
- const spectralStart = data[offset++];
768
- const spectralEnd = data[offset++];
769
- const successiveApproximation = data[offset++];
770
- const processed = decodeScan(
771
- data,
772
- offset,
773
- frame,
774
- components,
775
- this.resetInterval,
776
- spectralStart,
777
- spectralEnd,
778
- successiveApproximation >> 4,
779
- successiveApproximation & 15
780
- );
781
- offset += processed;
782
- break;
783
- }
784
- case 65535:
785
- if (data[offset] !== 255) {
786
- offset--;
787
- }
788
- break;
789
- default:
790
- if (data[offset - 3] === 255 && data[offset - 2] >= 192 && data[offset - 2] <= 254) {
791
- offset -= 3;
792
- break;
793
- }
794
- throw new Error(`unknown JPEG marker ${fileMarker.toString(16)}`);
795
- }
796
- fileMarker = readUint16();
797
- }
798
- }
799
- getResult() {
800
- const { frames } = this;
801
- if (this.frames.length === 0) {
802
- throw new Error("no frames were decoded");
803
- } else if (this.frames.length > 1) {
804
- console.warn("more than one frame is not supported");
805
- }
806
- for (let i = 0; i < this.frames.length; i++) {
807
- const cp = this.frames[i].components;
808
- for (const j of Object.keys(cp)) {
809
- cp[j].quantizationTable = this.quantizationTables[cp[j].quantizationIdx];
810
- delete cp[j].quantizationIdx;
811
- }
812
- }
813
- const frame = frames[0];
814
- const { components, componentsOrder } = frame;
815
- const outComponents = [];
816
- const width = frame.samplesPerLine;
817
- const height = frame.scanLines;
818
- for (let i = 0; i < componentsOrder.length; i++) {
819
- const component = components[componentsOrder[i]];
820
- outComponents.push({
821
- lines: buildComponentData(frame, component),
822
- scaleX: component.h / frame.maxH,
823
- scaleY: component.v / frame.maxV
824
- });
825
- }
826
- const out = new Uint8Array(width * height * outComponents.length);
827
- let oi = 0;
828
- for (let y = 0; y < height; ++y) {
829
- for (let x = 0; x < width; ++x) {
830
- for (let i = 0; i < outComponents.length; ++i) {
831
- const component = outComponents[i];
832
- out[oi] = component.lines[0 | y * component.scaleY][0 | x * component.scaleX];
833
- ++oi;
834
- }
835
- }
836
- }
837
- return out;
838
- }
839
- }
840
- class JpegDecoder extends BaseDecoder {
841
- constructor(fileDirectory) {
842
- super();
843
- this.reader = new JpegStreamReader();
844
- if (fileDirectory.JPEGTables) {
845
- this.reader.parse(fileDirectory.JPEGTables);
846
- }
847
- }
848
- decodeBlock(buffer) {
849
- this.reader.resetFrames();
850
- this.reader.parse(new Uint8Array(buffer));
851
- return this.reader.getResult().buffer;
852
- }
853
- }
854
- export {
855
- JpegDecoder as default
856
- };