pdf-codec 1.6.0 → 1.8.0
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.
- package/README.md +75 -12
- package/dist/cff-bounds.cjs +432 -0
- package/dist/cff-bounds.d.cts +9 -0
- package/dist/cff-bounds.d.ts +9 -0
- package/dist/cff-bounds.js +431 -0
- package/dist/cff-probe.cjs +8 -106
- package/dist/cff-probe.js +9 -107
- package/dist/cff.cjs +158 -0
- package/dist/cff.d.cts +17 -0
- package/dist/cff.d.ts +17 -0
- package/dist/cff.js +150 -0
- package/dist/filters.cjs +45 -2
- package/dist/filters.d.cts +4 -3
- package/dist/filters.d.ts +4 -3
- package/dist/filters.js +45 -2
- package/dist/formula.d.cts +1 -1
- package/dist/formula.d.ts +1 -1
- package/dist/glyf.cjs +62 -6
- package/dist/glyf.d.cts +2 -0
- package/dist/glyf.d.ts +2 -0
- package/dist/glyf.js +62 -6
- package/dist/glyph-bounds-BV_Z40KS.d.cts +10 -0
- package/dist/glyph-bounds-BV_Z40KS.d.ts +10 -0
- package/dist/glyph-bounds.cjs +12 -0
- package/dist/glyph-bounds.d.cts +2 -0
- package/dist/glyph-bounds.d.ts +2 -0
- package/dist/glyph-bounds.js +11 -0
- package/dist/image/jbig2-arith.cjs +432 -0
- package/dist/image/jbig2-arith.d.cts +23 -0
- package/dist/image/jbig2-arith.d.ts +23 -0
- package/dist/image/jbig2-arith.js +426 -0
- package/dist/image/jbig2-bitmap.cjs +80 -0
- package/dist/image/jbig2-bitmap.d.cts +20 -0
- package/dist/image/jbig2-bitmap.d.ts +20 -0
- package/dist/image/jbig2-bitmap.js +72 -0
- package/dist/image/jbig2-errors.cjs +17 -0
- package/dist/image/jbig2-errors.d.cts +2 -0
- package/dist/image/jbig2-errors.d.ts +2 -0
- package/dist/image/jbig2-errors.js +15 -0
- package/dist/image/jbig2-generic.cjs +242 -0
- package/dist/image/jbig2-generic.d.cts +27 -0
- package/dist/image/jbig2-generic.d.ts +27 -0
- package/dist/image/jbig2-generic.js +237 -0
- package/dist/image/jbig2-text.cjs +175 -0
- package/dist/image/jbig2-text.d.cts +58 -0
- package/dist/image/jbig2-text.d.ts +58 -0
- package/dist/image/jbig2-text.js +170 -0
- package/dist/image/jbig2.cjs +333 -0
- package/dist/image/jbig2.d.cts +15 -0
- package/dist/image/jbig2.d.ts +15 -0
- package/dist/image/jbig2.js +332 -0
- package/dist/image/jp2-boxes.cjs +148 -0
- package/dist/image/jp2-boxes.d.cts +26 -0
- package/dist/image/jp2-boxes.d.ts +26 -0
- package/dist/image/jp2-boxes.js +146 -0
- package/dist/image/jpeg2000-codestream.cjs +309 -0
- package/dist/image/jpeg2000-codestream.d.cts +78 -0
- package/dist/image/jpeg2000-codestream.d.ts +78 -0
- package/dist/image/jpeg2000-codestream.js +308 -0
- package/dist/image/jpeg2000-dwt.cjs +148 -0
- package/dist/image/jpeg2000-dwt.d.cts +34 -0
- package/dist/image/jpeg2000-dwt.d.ts +34 -0
- package/dist/image/jpeg2000-dwt.js +145 -0
- package/dist/image/jpeg2000-errors.cjs +17 -0
- package/dist/image/jpeg2000-errors.d.cts +9 -0
- package/dist/image/jpeg2000-errors.d.ts +9 -0
- package/dist/image/jpeg2000-errors.js +15 -0
- package/dist/image/jpeg2000-t1.cjs +254 -0
- package/dist/image/jpeg2000-t1.d.cts +18 -0
- package/dist/image/jpeg2000-t1.d.ts +18 -0
- package/dist/image/jpeg2000-t1.js +253 -0
- package/dist/image/jpeg2000-t2.cjs +316 -0
- package/dist/image/jpeg2000-t2.d.cts +79 -0
- package/dist/image/jpeg2000-t2.d.ts +79 -0
- package/dist/image/jpeg2000-t2.js +311 -0
- package/dist/image/jpeg2000-tagtree.cjs +105 -0
- package/dist/image/jpeg2000-tagtree.d.cts +29 -0
- package/dist/image/jpeg2000-tagtree.d.ts +29 -0
- package/dist/image/jpeg2000-tagtree.js +103 -0
- package/dist/image/jpeg2000.cjs +322 -0
- package/dist/image/jpeg2000.d.cts +54 -0
- package/dist/image/jpeg2000.d.ts +54 -0
- package/dist/image/jpeg2000.js +320 -0
- package/dist/images-read.cjs +78 -1
- package/dist/images-read.js +78 -1
- package/dist/index.cjs +17 -0
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +7 -1
- package/dist/jbig2-errors-Bj6MPxrx.d.cts +9 -0
- package/dist/jbig2-errors-Bj6MPxrx.d.ts +9 -0
- package/dist/math-content-write.cjs +37 -1
- package/dist/math-content-write.d.cts +1 -1
- package/dist/math-content-write.d.ts +1 -1
- package/dist/math-content-write.js +38 -2
- package/dist/math-font-write.cjs +6 -1
- package/dist/math-font-write.d.cts +1 -1
- package/dist/math-font-write.d.ts +1 -1
- package/dist/math-font-write.js +6 -1
- package/dist/math-font.cjs +91 -18
- package/dist/math-font.d.cts +8 -1
- package/dist/math-font.d.ts +8 -1
- package/dist/math-font.js +91 -18
- package/dist/math-stretch-Bwk_bxh1.d.ts +24 -0
- package/dist/math-stretch-DXWjs8gL.d.cts +24 -0
- package/dist/math-stretch.cjs +96 -0
- package/dist/math-stretch.d.cts +2 -0
- package/dist/math-stretch.d.ts +2 -0
- package/dist/math-stretch.js +94 -0
- package/dist/math-table-DhPrNoPa.d.ts +70 -0
- package/dist/math-table-gFNB8DmQ.d.cts +70 -0
- package/dist/math-table.cjs +69 -1
- package/dist/math-table.d.cts +2 -45
- package/dist/math-table.d.ts +2 -45
- package/dist/math-table.js +69 -1
- package/dist/{math-types-Ba8qAf1p.d.ts → math-types-BZkWO5Ow.d.cts} +30 -2
- package/dist/{math-types-Ba8qAf1p.d.cts → math-types-Bq7tyV4g.d.ts} +30 -2
- package/dist/math-types.d.cts +3 -2
- package/dist/math-types.d.ts +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { Jpeg2000ParseError, Jpeg2000UnsupportedError } from "./jpeg2000-errors.js";
|
|
2
|
+
//#region src/image/jpeg2000-codestream.ts
|
|
3
|
+
const MARKER_SOC = 65359;
|
|
4
|
+
const MARKER_SIZ = 65361;
|
|
5
|
+
const MARKER_COD = 65362;
|
|
6
|
+
const MARKER_COC = 65363;
|
|
7
|
+
const MARKER_QCD = 65372;
|
|
8
|
+
const MARKER_QCC = 65373;
|
|
9
|
+
const MARKER_RGN = 65374;
|
|
10
|
+
const MARKER_POC = 65375;
|
|
11
|
+
const MARKER_PPM = 65376;
|
|
12
|
+
const MARKER_PPT = 65377;
|
|
13
|
+
const MARKER_COM = 65380;
|
|
14
|
+
const MARKER_SOT = 65424;
|
|
15
|
+
const MARKER_SOD = 65427;
|
|
16
|
+
const MARKER_EOC = 65497;
|
|
17
|
+
const PROGRESSION_ORDERS = [
|
|
18
|
+
"LRCP",
|
|
19
|
+
"RLCP",
|
|
20
|
+
"RPCL",
|
|
21
|
+
"PCRL",
|
|
22
|
+
"CPRL"
|
|
23
|
+
];
|
|
24
|
+
var MarkerCursor = class {
|
|
25
|
+
data;
|
|
26
|
+
position;
|
|
27
|
+
constructor(data, start = 0) {
|
|
28
|
+
this.data = data;
|
|
29
|
+
this.position = start;
|
|
30
|
+
}
|
|
31
|
+
get remaining() {
|
|
32
|
+
return this.data.length - this.position;
|
|
33
|
+
}
|
|
34
|
+
uint8() {
|
|
35
|
+
const value = this.data[this.position];
|
|
36
|
+
if (value === void 0) throw new Jpeg2000ParseError("JPEG 2000 codestream ended in the middle of a marker segment");
|
|
37
|
+
this.position++;
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
uint16() {
|
|
41
|
+
return this.uint8() << 8 | this.uint8();
|
|
42
|
+
}
|
|
43
|
+
uint32() {
|
|
44
|
+
return this.uint16() * 65536 + this.uint16();
|
|
45
|
+
}
|
|
46
|
+
bytes(length) {
|
|
47
|
+
if (length < 0 || this.position + length > this.data.length) throw new Jpeg2000ParseError("a JPEG 2000 marker segment declares more data than the codestream carries");
|
|
48
|
+
const slice = this.data.subarray(this.position, this.position + length);
|
|
49
|
+
this.position += length;
|
|
50
|
+
return slice;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function readImageSize(cursor, segmentEnd) {
|
|
54
|
+
cursor.uint16();
|
|
55
|
+
const xsiz = cursor.uint32();
|
|
56
|
+
const ysiz = cursor.uint32();
|
|
57
|
+
const xosiz = cursor.uint32();
|
|
58
|
+
const yosiz = cursor.uint32();
|
|
59
|
+
const xtsiz = cursor.uint32();
|
|
60
|
+
const ytsiz = cursor.uint32();
|
|
61
|
+
const xtosiz = cursor.uint32();
|
|
62
|
+
const ytosiz = cursor.uint32();
|
|
63
|
+
const count = cursor.uint16();
|
|
64
|
+
if (count === 0) throw new Jpeg2000ParseError("SIZ declares zero components");
|
|
65
|
+
if (cursor.position + count * 3 > segmentEnd) throw new Jpeg2000ParseError(`SIZ declares ${String(count)} components but its own length leaves room for fewer`);
|
|
66
|
+
const components = [];
|
|
67
|
+
for (let i = 0; i < count; i++) {
|
|
68
|
+
const ssiz = cursor.uint8();
|
|
69
|
+
components.push({
|
|
70
|
+
signed: (ssiz & 128) !== 0,
|
|
71
|
+
bitDepth: (ssiz & 127) + 1,
|
|
72
|
+
dx: cursor.uint8(),
|
|
73
|
+
dy: cursor.uint8()
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (xsiz <= xosiz || ysiz <= yosiz) throw new Jpeg2000ParseError("SIZ declares an image with no area (Xsiz/Ysiz do not exceed XOsiz/YOsiz)");
|
|
77
|
+
if (xtsiz === 0 || ytsiz === 0) throw new Jpeg2000ParseError("SIZ declares a zero-sized tile");
|
|
78
|
+
return {
|
|
79
|
+
xsiz,
|
|
80
|
+
ysiz,
|
|
81
|
+
xosiz,
|
|
82
|
+
yosiz,
|
|
83
|
+
xtsiz,
|
|
84
|
+
ytsiz,
|
|
85
|
+
xtosiz,
|
|
86
|
+
ytosiz,
|
|
87
|
+
components
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const DEFAULT_PRECINCT_EXPONENT = 15;
|
|
91
|
+
function readCodingStyleParameters(cursor, explicitPrecincts) {
|
|
92
|
+
const decompositionLevels = cursor.uint8();
|
|
93
|
+
const codeBlockWidthExp = (cursor.uint8() & 15) + 2;
|
|
94
|
+
const codeBlockHeightExp = (cursor.uint8() & 15) + 2;
|
|
95
|
+
const codeBlockStyle = cursor.uint8();
|
|
96
|
+
const transformCode = cursor.uint8();
|
|
97
|
+
if (transformCode !== 0 && transformCode !== 1) throw new Jpeg2000ParseError(`SPcod/SPcoc declares transformation ${String(transformCode)}, which is neither of the two ISO/IEC 15444-1 defines`);
|
|
98
|
+
if (codeBlockWidthExp > 10 || codeBlockHeightExp > 10 || codeBlockWidthExp + codeBlockHeightExp > 12) throw new Jpeg2000ParseError(`code-block size 2^${String(codeBlockWidthExp)} by 2^${String(codeBlockHeightExp)} is outside the range ISO/IEC 15444-1 Table A.18 permits`);
|
|
99
|
+
const precinctSizes = [];
|
|
100
|
+
if (explicitPrecincts) for (let r = 0; r <= decompositionLevels; r++) {
|
|
101
|
+
const packed = cursor.uint8();
|
|
102
|
+
precinctSizes.push({
|
|
103
|
+
ppx: packed & 15,
|
|
104
|
+
ppy: packed >> 4 & 15
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else for (let r = 0; r <= decompositionLevels; r++) precinctSizes.push({
|
|
108
|
+
ppx: DEFAULT_PRECINCT_EXPONENT,
|
|
109
|
+
ppy: DEFAULT_PRECINCT_EXPONENT
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
decompositionLevels,
|
|
113
|
+
codeBlockWidthExp,
|
|
114
|
+
codeBlockHeightExp,
|
|
115
|
+
codeBlockStyle,
|
|
116
|
+
transform: transformCode === 1 ? "reversible-5-3" : "irreversible-9-7",
|
|
117
|
+
precinctSizes
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function readCodingDefaults(cursor) {
|
|
121
|
+
const scod = cursor.uint8();
|
|
122
|
+
const progressionOrder = PROGRESSION_ORDERS[cursor.uint8()];
|
|
123
|
+
if (progressionOrder === void 0) throw new Jpeg2000ParseError("COD declares a progression order outside the five ISO/IEC 15444-1 Table A.16 defines");
|
|
124
|
+
const layers = cursor.uint16();
|
|
125
|
+
if (layers === 0) throw new Jpeg2000ParseError("COD declares zero quality layers");
|
|
126
|
+
const multipleComponentTransform = cursor.uint8() !== 0;
|
|
127
|
+
return {
|
|
128
|
+
...readCodingStyleParameters(cursor, (scod & 1) !== 0),
|
|
129
|
+
progressionOrder,
|
|
130
|
+
layers,
|
|
131
|
+
multipleComponentTransform,
|
|
132
|
+
useSop: (scod & 2) !== 0,
|
|
133
|
+
useEph: (scod & 4) !== 0
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function readQuantization(cursor, segmentEnd) {
|
|
137
|
+
const sq = cursor.uint8();
|
|
138
|
+
const guardBits = sq >> 5;
|
|
139
|
+
const styleCode = sq & 31;
|
|
140
|
+
const stepSizes = [];
|
|
141
|
+
if (styleCode === 0) {
|
|
142
|
+
while (cursor.position < segmentEnd) stepSizes.push({
|
|
143
|
+
exponent: cursor.uint8() >> 3,
|
|
144
|
+
mantissa: 0
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
style: "none",
|
|
148
|
+
guardBits,
|
|
149
|
+
stepSizes
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (styleCode === 1 || styleCode === 2) {
|
|
153
|
+
while (cursor.position + 1 < segmentEnd) {
|
|
154
|
+
const packed = cursor.uint16();
|
|
155
|
+
stepSizes.push({
|
|
156
|
+
exponent: packed >> 11,
|
|
157
|
+
mantissa: packed & 2047
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
style: styleCode === 1 ? "derived" : "expounded",
|
|
162
|
+
guardBits,
|
|
163
|
+
stepSizes
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
throw new Jpeg2000ParseError(`QCD/QCC declares quantization style ${String(styleCode)}, which ISO/IEC 15444-1 Table A.28 does not define`);
|
|
167
|
+
}
|
|
168
|
+
function readComponentIndex(cursor, componentCount) {
|
|
169
|
+
return componentCount < 257 ? cursor.uint8() : cursor.uint16();
|
|
170
|
+
}
|
|
171
|
+
function emptyHeader() {
|
|
172
|
+
return {
|
|
173
|
+
coc: /* @__PURE__ */ new Map(),
|
|
174
|
+
qcc: /* @__PURE__ */ new Map(),
|
|
175
|
+
hasProgressionChanges: false,
|
|
176
|
+
hasRegionOfInterest: false,
|
|
177
|
+
hasPackedPacketHeaders: false
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function freezeHeader(header) {
|
|
181
|
+
const base = {
|
|
182
|
+
coc: header.coc,
|
|
183
|
+
qcc: header.qcc,
|
|
184
|
+
hasProgressionChanges: header.hasProgressionChanges,
|
|
185
|
+
hasRegionOfInterest: header.hasRegionOfInterest,
|
|
186
|
+
hasPackedPacketHeaders: header.hasPackedPacketHeaders
|
|
187
|
+
};
|
|
188
|
+
if (header.cod !== void 0 && header.qcd !== void 0) return {
|
|
189
|
+
...base,
|
|
190
|
+
cod: header.cod,
|
|
191
|
+
qcd: header.qcd
|
|
192
|
+
};
|
|
193
|
+
if (header.cod !== void 0) return {
|
|
194
|
+
...base,
|
|
195
|
+
cod: header.cod
|
|
196
|
+
};
|
|
197
|
+
if (header.qcd !== void 0) return {
|
|
198
|
+
...base,
|
|
199
|
+
qcd: header.qcd
|
|
200
|
+
};
|
|
201
|
+
return base;
|
|
202
|
+
}
|
|
203
|
+
function readHeaderSegment(marker, cursor, header, componentCount, comments) {
|
|
204
|
+
const length = cursor.uint16();
|
|
205
|
+
if (length < 2) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares a length of ${String(length)}, which is shorter than the length field itself`);
|
|
206
|
+
const segmentEnd = cursor.position + length - 2;
|
|
207
|
+
if (segmentEnd > cursor.data.length) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares more data than the codestream carries`);
|
|
208
|
+
if (marker === MARKER_COD) header.cod = readCodingDefaults(cursor);
|
|
209
|
+
else if (marker === MARKER_COC) {
|
|
210
|
+
const component = readComponentIndex(cursor, componentCount);
|
|
211
|
+
header.coc.set(component, readCodingStyleParameters(cursor, (cursor.uint8() & 1) !== 0));
|
|
212
|
+
} else if (marker === MARKER_QCD) header.qcd = readQuantization(cursor, segmentEnd);
|
|
213
|
+
else if (marker === MARKER_QCC) {
|
|
214
|
+
const component = readComponentIndex(cursor, componentCount);
|
|
215
|
+
header.qcc.set(component, readQuantization(cursor, segmentEnd));
|
|
216
|
+
} else if (marker === MARKER_POC) header.hasProgressionChanges = true;
|
|
217
|
+
else if (marker === MARKER_RGN) header.hasRegionOfInterest = true;
|
|
218
|
+
else if (marker === MARKER_PPT) header.hasPackedPacketHeaders = true;
|
|
219
|
+
else if (marker === MARKER_COM) {
|
|
220
|
+
const registration = cursor.uint16();
|
|
221
|
+
const body = cursor.bytes(segmentEnd - cursor.position);
|
|
222
|
+
if (registration === 1) comments.push(Array.from(body, (byte) => String.fromCharCode(byte)).join(""));
|
|
223
|
+
}
|
|
224
|
+
cursor.position = segmentEnd;
|
|
225
|
+
}
|
|
226
|
+
function validateMainHeader(header) {
|
|
227
|
+
if (header.cod === void 0) throw new Jpeg2000ParseError("the main header carries no COD marker, so no coding style is defined for any tile");
|
|
228
|
+
if (header.qcd === void 0) throw new Jpeg2000ParseError("the main header carries no QCD marker, so no quantization is defined for any tile");
|
|
229
|
+
}
|
|
230
|
+
function parseJpeg2000Codestream(data) {
|
|
231
|
+
const cursor = new MarkerCursor(data);
|
|
232
|
+
if (cursor.remaining < 4 || cursor.uint16() !== MARKER_SOC) throw new Jpeg2000ParseError("codestream does not begin with an SOC marker");
|
|
233
|
+
if (cursor.uint16() !== MARKER_SIZ) throw new Jpeg2000ParseError("the SOC marker is not immediately followed by SIZ, which ISO/IEC 15444-1 A.3 requires");
|
|
234
|
+
const sizLength = cursor.uint16();
|
|
235
|
+
const sizEnd = cursor.position + sizLength - 2;
|
|
236
|
+
const siz = readImageSize(cursor, sizEnd);
|
|
237
|
+
cursor.position = sizEnd;
|
|
238
|
+
const comments = [];
|
|
239
|
+
const main = emptyHeader();
|
|
240
|
+
const tileParts = [];
|
|
241
|
+
let sawEoc = false;
|
|
242
|
+
for (;;) {
|
|
243
|
+
if (cursor.remaining < 2) break;
|
|
244
|
+
const marker = cursor.uint16();
|
|
245
|
+
if (marker === MARKER_EOC) {
|
|
246
|
+
sawEoc = true;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
if (marker === MARKER_PPM) throw new Jpeg2000UnsupportedError("the codestream carries a PPM marker (packed packet headers in the main header), an organisation this decoder does not reassemble");
|
|
250
|
+
if (marker === MARKER_SOT) {
|
|
251
|
+
cursor.position -= 2;
|
|
252
|
+
readTilePart(cursor, siz.components.length, tileParts, comments);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (marker === MARKER_SOD || marker === MARKER_SOC) throw new Jpeg2000ParseError(`unexpected marker 0x${marker.toString(16)} in the main header`);
|
|
256
|
+
readHeaderSegment(marker, cursor, main, siz.components.length, comments);
|
|
257
|
+
}
|
|
258
|
+
validateMainHeader(main);
|
|
259
|
+
const numTilesWide = Math.ceil((siz.xsiz - siz.xtosiz) / siz.xtsiz);
|
|
260
|
+
const numTilesHigh = Math.ceil((siz.ysiz - siz.ytosiz) / siz.ytsiz);
|
|
261
|
+
return {
|
|
262
|
+
bytes: data,
|
|
263
|
+
siz,
|
|
264
|
+
main: freezeHeader(main),
|
|
265
|
+
tileParts,
|
|
266
|
+
comments,
|
|
267
|
+
numTilesWide,
|
|
268
|
+
numTilesHigh,
|
|
269
|
+
truncated: !sawEoc
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function readTilePart(cursor, componentCount, tileParts, comments) {
|
|
273
|
+
const sotStart = cursor.position;
|
|
274
|
+
cursor.uint16();
|
|
275
|
+
const lsot = cursor.uint16();
|
|
276
|
+
if (lsot !== 10) throw new Jpeg2000ParseError(`SOT declares a length of ${String(lsot)}, but ISO/IEC 15444-1 A.4.2 fixes it at 10`);
|
|
277
|
+
const tileIndex = cursor.uint16();
|
|
278
|
+
const psot = cursor.uint32();
|
|
279
|
+
const partIndex = cursor.uint8();
|
|
280
|
+
cursor.uint8();
|
|
281
|
+
const header = emptyHeader();
|
|
282
|
+
for (;;) {
|
|
283
|
+
if (cursor.remaining < 2) throw new Jpeg2000ParseError("a tile-part header ended without an SOD marker");
|
|
284
|
+
const marker = cursor.uint16();
|
|
285
|
+
if (marker === MARKER_SOD) break;
|
|
286
|
+
if (marker === MARKER_SOT || marker === MARKER_EOC) throw new Jpeg2000ParseError(`a tile-part header ended at marker 0x${marker.toString(16)} rather than at SOD`);
|
|
287
|
+
readHeaderSegment(marker, cursor, header, componentCount, comments);
|
|
288
|
+
}
|
|
289
|
+
const dataStart = cursor.position;
|
|
290
|
+
const declaredEnd = psot === 0 ? cursor.data.length : sotStart + psot;
|
|
291
|
+
const dataEnd = Math.min(declaredEnd, cursor.data.length);
|
|
292
|
+
if (dataEnd < dataStart) throw new Jpeg2000ParseError("a tile-part declares a Psot shorter than its own header");
|
|
293
|
+
const trimmedEnd = trimTrailingEoc(cursor.data, dataStart, dataEnd);
|
|
294
|
+
tileParts.push({
|
|
295
|
+
tileIndex,
|
|
296
|
+
partIndex,
|
|
297
|
+
header: freezeHeader(header),
|
|
298
|
+
dataStart,
|
|
299
|
+
dataEnd: trimmedEnd
|
|
300
|
+
});
|
|
301
|
+
cursor.position = dataEnd;
|
|
302
|
+
}
|
|
303
|
+
function trimTrailingEoc(data, start, end) {
|
|
304
|
+
if (end - start >= 2 && data[end - 2] === 255 && data[end - 1] === 217) return end - 2;
|
|
305
|
+
return end;
|
|
306
|
+
}
|
|
307
|
+
//#endregion
|
|
308
|
+
export { parseJpeg2000Codestream };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/image/jpeg2000-dwt.ts
|
|
3
|
+
const EXTENSION_MARGIN = 6;
|
|
4
|
+
const LIFT_ALPHA = -1.586134342059924;
|
|
5
|
+
const LIFT_BETA = -.052980118572961;
|
|
6
|
+
const LIFT_GAMMA = .882911075530934;
|
|
7
|
+
const LIFT_DELTA = .443506852043971;
|
|
8
|
+
const LIFT_K = 1.230174104914001;
|
|
9
|
+
function subbandBounds(bounds) {
|
|
10
|
+
return {
|
|
11
|
+
llU0: Math.ceil(bounds.u0 / 2),
|
|
12
|
+
llU1: Math.ceil(bounds.u1 / 2),
|
|
13
|
+
llV0: Math.ceil(bounds.v0 / 2),
|
|
14
|
+
llV1: Math.ceil(bounds.v1 / 2),
|
|
15
|
+
hU0: Math.floor(bounds.u0 / 2),
|
|
16
|
+
hU1: Math.floor(bounds.u1 / 2),
|
|
17
|
+
hV0: Math.floor(bounds.v0 / 2),
|
|
18
|
+
hV1: Math.floor(bounds.v1 / 2)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function mirrorIndex(position, i0, i1) {
|
|
22
|
+
const length = i1 - i0;
|
|
23
|
+
if (length <= 1) return i0;
|
|
24
|
+
const period = 2 * (length - 1);
|
|
25
|
+
let offset = (position - i0) % period;
|
|
26
|
+
if (offset < 0) offset += period;
|
|
27
|
+
return i0 + (offset >= length ? period - offset : offset);
|
|
28
|
+
}
|
|
29
|
+
function interleave(source, bounds, write) {
|
|
30
|
+
const sub = subbandBounds(bounds);
|
|
31
|
+
for (let v = sub.llV0; v < sub.llV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v, source.ll(u, v));
|
|
32
|
+
for (let v = sub.llV0; v < sub.llV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v, source.hl(u, v));
|
|
33
|
+
for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v + 1, source.lh(u, v));
|
|
34
|
+
for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v + 1, source.hh(u, v));
|
|
35
|
+
}
|
|
36
|
+
function inverse53Filter(buffer, i0, i1) {
|
|
37
|
+
const base = EXTENSION_MARGIN - i0;
|
|
38
|
+
const first = Math.floor(i0 / 2) - 1;
|
|
39
|
+
const last = Math.floor(i1 / 2) + 1;
|
|
40
|
+
for (let n = first; n <= last; n++) {
|
|
41
|
+
const index = base + 2 * n;
|
|
42
|
+
buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / 4);
|
|
43
|
+
}
|
|
44
|
+
for (let n = first; n < last; n++) {
|
|
45
|
+
const index = base + 2 * n + 1;
|
|
46
|
+
buffer[index] = (buffer[index] ?? 0) + Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0)) / 2);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function inverse97Filter(buffer, i0, i1) {
|
|
50
|
+
const base = EXTENSION_MARGIN - i0;
|
|
51
|
+
const first = Math.floor(i0 / 2);
|
|
52
|
+
const last = Math.floor(i1 / 2);
|
|
53
|
+
const even = (n) => base + 2 * n;
|
|
54
|
+
const odd = (n) => base + 2 * n + 1;
|
|
55
|
+
for (let n = first - 2; n <= last + 2; n++) {
|
|
56
|
+
buffer[even(n)] = (buffer[even(n)] ?? 0) * LIFT_K;
|
|
57
|
+
buffer[odd(n)] = (buffer[odd(n)] ?? 0) / LIFT_K;
|
|
58
|
+
}
|
|
59
|
+
for (let n = first - 1; n <= last + 1; n++) buffer[even(n)] = (buffer[even(n)] ?? 0) - LIFT_DELTA * ((buffer[even(n) - 1] ?? 0) + (buffer[even(n) + 1] ?? 0));
|
|
60
|
+
for (let n = first - 1; n <= last; n++) buffer[odd(n)] = (buffer[odd(n)] ?? 0) - LIFT_GAMMA * ((buffer[odd(n) - 1] ?? 0) + (buffer[odd(n) + 1] ?? 0));
|
|
61
|
+
for (let n = first; n <= last + 1; n++) buffer[even(n)] = (buffer[even(n)] ?? 0) - LIFT_BETA * ((buffer[even(n) - 1] ?? 0) + (buffer[even(n) + 1] ?? 0));
|
|
62
|
+
for (let n = first; n <= last; n++) buffer[odd(n)] = (buffer[odd(n)] ?? 0) - LIFT_ALPHA * ((buffer[odd(n) - 1] ?? 0) + (buffer[odd(n) + 1] ?? 0));
|
|
63
|
+
}
|
|
64
|
+
function synthesiseLine(read, write, i0, i1, fillScratch, readScratch, runFilter, singleSampleHighPassGain) {
|
|
65
|
+
const length = i1 - i0;
|
|
66
|
+
if (length <= 0) return;
|
|
67
|
+
if (length === 1) {
|
|
68
|
+
const value = read(i0);
|
|
69
|
+
write(i0, i0 % 2 === 0 ? value : singleSampleHighPassGain(value));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
for (let k = -6; k < length + EXTENSION_MARGIN; k++) fillScratch(EXTENSION_MARGIN + k, read(mirrorIndex(i0 + k, i0, i1)));
|
|
73
|
+
runFilter();
|
|
74
|
+
for (let k = 0; k < length; k++) write(i0 + k, readScratch(EXTENSION_MARGIN + k));
|
|
75
|
+
}
|
|
76
|
+
function interleaveSource(bands, bounds) {
|
|
77
|
+
const sub = subbandBounds(bounds);
|
|
78
|
+
const llWidth = sub.llU1 - sub.llU0;
|
|
79
|
+
const hWidth = sub.hU1 - sub.hU0;
|
|
80
|
+
return {
|
|
81
|
+
ll: (u, v) => bands.ll[(v - sub.llV0) * llWidth + (u - sub.llU0)] ?? 0,
|
|
82
|
+
hl: (u, v) => bands.hl[(v - sub.llV0) * hWidth + (u - sub.hU0)] ?? 0,
|
|
83
|
+
lh: (u, v) => bands.lh[(v - sub.hV0) * llWidth + (u - sub.llU0)] ?? 0,
|
|
84
|
+
hh: (u, v) => bands.hh[(v - sub.hV0) * hWidth + (u - sub.hU0)] ?? 0
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function inverseDwt53Level(bands, bounds) {
|
|
88
|
+
const { u0, u1, v0, v1 } = bounds;
|
|
89
|
+
const width = u1 - u0;
|
|
90
|
+
const height = v1 - v0;
|
|
91
|
+
const output = new Int32Array(Math.max(width * height, 0));
|
|
92
|
+
if (width <= 0 || height <= 0) return output;
|
|
93
|
+
interleave(interleaveSource(bands, bounds), bounds, (u, v, value) => {
|
|
94
|
+
output[(v - v0) * width + (u - u0)] = value;
|
|
95
|
+
});
|
|
96
|
+
const scratch = new Int32Array(Math.max(width, height) + 12);
|
|
97
|
+
for (let v = 0; v < height; v++) {
|
|
98
|
+
const rowStart = v * width;
|
|
99
|
+
synthesiseLine((index) => output[rowStart + index - u0] ?? 0, (index, value) => {
|
|
100
|
+
output[rowStart + index - u0] = value;
|
|
101
|
+
}, u0, u1, (offset, value) => {
|
|
102
|
+
scratch[offset] = value;
|
|
103
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
104
|
+
inverse53Filter(scratch, u0, u1);
|
|
105
|
+
}, (value) => value >> 1);
|
|
106
|
+
}
|
|
107
|
+
for (let u = 0; u < width; u++) synthesiseLine((index) => output[(index - v0) * width + u] ?? 0, (index, value) => {
|
|
108
|
+
output[(index - v0) * width + u] = value;
|
|
109
|
+
}, v0, v1, (offset, value) => {
|
|
110
|
+
scratch[offset] = value;
|
|
111
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
112
|
+
inverse53Filter(scratch, v0, v1);
|
|
113
|
+
}, (value) => value >> 1);
|
|
114
|
+
return output;
|
|
115
|
+
}
|
|
116
|
+
function inverseDwt97Level(bands, bounds) {
|
|
117
|
+
const { u0, u1, v0, v1 } = bounds;
|
|
118
|
+
const width = u1 - u0;
|
|
119
|
+
const height = v1 - v0;
|
|
120
|
+
const output = new Float32Array(Math.max(width * height, 0));
|
|
121
|
+
if (width <= 0 || height <= 0) return output;
|
|
122
|
+
interleave(interleaveSource(bands, bounds), bounds, (u, v, value) => {
|
|
123
|
+
output[(v - v0) * width + (u - u0)] = value;
|
|
124
|
+
});
|
|
125
|
+
const scratch = new Float32Array(Math.max(width, height) + 12);
|
|
126
|
+
for (let v = 0; v < height; v++) {
|
|
127
|
+
const rowStart = v * width;
|
|
128
|
+
synthesiseLine((index) => output[rowStart + index - u0] ?? 0, (index, value) => {
|
|
129
|
+
output[rowStart + index - u0] = value;
|
|
130
|
+
}, u0, u1, (offset, value) => {
|
|
131
|
+
scratch[offset] = value;
|
|
132
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
133
|
+
inverse97Filter(scratch, u0, u1);
|
|
134
|
+
}, (value) => value / 2);
|
|
135
|
+
}
|
|
136
|
+
for (let u = 0; u < width; u++) synthesiseLine((index) => output[(index - v0) * width + u] ?? 0, (index, value) => {
|
|
137
|
+
output[(index - v0) * width + u] = value;
|
|
138
|
+
}, v0, v1, (offset, value) => {
|
|
139
|
+
scratch[offset] = value;
|
|
140
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
141
|
+
inverse97Filter(scratch, v0, v1);
|
|
142
|
+
}, (value) => value / 2);
|
|
143
|
+
return output;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
exports.inverseDwt53Level = inverseDwt53Level;
|
|
147
|
+
exports.inverseDwt97Level = inverseDwt97Level;
|
|
148
|
+
exports.subbandBounds = subbandBounds;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/image/jpeg2000-dwt.d.ts
|
|
2
|
+
interface Jpeg2000ResolutionBounds {
|
|
3
|
+
readonly u0: number;
|
|
4
|
+
readonly u1: number;
|
|
5
|
+
readonly v0: number;
|
|
6
|
+
readonly v1: number;
|
|
7
|
+
}
|
|
8
|
+
interface Jpeg2000SubbandBounds {
|
|
9
|
+
readonly llU0: number;
|
|
10
|
+
readonly llU1: number;
|
|
11
|
+
readonly llV0: number;
|
|
12
|
+
readonly llV1: number;
|
|
13
|
+
readonly hU0: number;
|
|
14
|
+
readonly hU1: number;
|
|
15
|
+
readonly hV0: number;
|
|
16
|
+
readonly hV1: number;
|
|
17
|
+
}
|
|
18
|
+
declare function subbandBounds(bounds: Jpeg2000ResolutionBounds): Jpeg2000SubbandBounds;
|
|
19
|
+
interface Jpeg2000ReversibleSubbands {
|
|
20
|
+
readonly ll: Int32Array;
|
|
21
|
+
readonly hl: Int32Array;
|
|
22
|
+
readonly lh: Int32Array;
|
|
23
|
+
readonly hh: Int32Array;
|
|
24
|
+
}
|
|
25
|
+
interface Jpeg2000IrreversibleSubbands {
|
|
26
|
+
readonly ll: Float32Array;
|
|
27
|
+
readonly hl: Float32Array;
|
|
28
|
+
readonly lh: Float32Array;
|
|
29
|
+
readonly hh: Float32Array;
|
|
30
|
+
}
|
|
31
|
+
declare function inverseDwt53Level(bands: Jpeg2000ReversibleSubbands, bounds: Jpeg2000ResolutionBounds): Int32Array;
|
|
32
|
+
declare function inverseDwt97Level(bands: Jpeg2000IrreversibleSubbands, bounds: Jpeg2000ResolutionBounds): Float32Array;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Jpeg2000IrreversibleSubbands, Jpeg2000ResolutionBounds, Jpeg2000ReversibleSubbands, Jpeg2000SubbandBounds, inverseDwt53Level, inverseDwt97Level, subbandBounds };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/image/jpeg2000-dwt.d.ts
|
|
2
|
+
interface Jpeg2000ResolutionBounds {
|
|
3
|
+
readonly u0: number;
|
|
4
|
+
readonly u1: number;
|
|
5
|
+
readonly v0: number;
|
|
6
|
+
readonly v1: number;
|
|
7
|
+
}
|
|
8
|
+
interface Jpeg2000SubbandBounds {
|
|
9
|
+
readonly llU0: number;
|
|
10
|
+
readonly llU1: number;
|
|
11
|
+
readonly llV0: number;
|
|
12
|
+
readonly llV1: number;
|
|
13
|
+
readonly hU0: number;
|
|
14
|
+
readonly hU1: number;
|
|
15
|
+
readonly hV0: number;
|
|
16
|
+
readonly hV1: number;
|
|
17
|
+
}
|
|
18
|
+
declare function subbandBounds(bounds: Jpeg2000ResolutionBounds): Jpeg2000SubbandBounds;
|
|
19
|
+
interface Jpeg2000ReversibleSubbands {
|
|
20
|
+
readonly ll: Int32Array;
|
|
21
|
+
readonly hl: Int32Array;
|
|
22
|
+
readonly lh: Int32Array;
|
|
23
|
+
readonly hh: Int32Array;
|
|
24
|
+
}
|
|
25
|
+
interface Jpeg2000IrreversibleSubbands {
|
|
26
|
+
readonly ll: Float32Array;
|
|
27
|
+
readonly hl: Float32Array;
|
|
28
|
+
readonly lh: Float32Array;
|
|
29
|
+
readonly hh: Float32Array;
|
|
30
|
+
}
|
|
31
|
+
declare function inverseDwt53Level(bands: Jpeg2000ReversibleSubbands, bounds: Jpeg2000ResolutionBounds): Int32Array;
|
|
32
|
+
declare function inverseDwt97Level(bands: Jpeg2000IrreversibleSubbands, bounds: Jpeg2000ResolutionBounds): Float32Array;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Jpeg2000IrreversibleSubbands, Jpeg2000ResolutionBounds, Jpeg2000ReversibleSubbands, Jpeg2000SubbandBounds, inverseDwt53Level, inverseDwt97Level, subbandBounds };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
//#region src/image/jpeg2000-dwt.ts
|
|
2
|
+
const EXTENSION_MARGIN = 6;
|
|
3
|
+
const LIFT_ALPHA = -1.586134342059924;
|
|
4
|
+
const LIFT_BETA = -.052980118572961;
|
|
5
|
+
const LIFT_GAMMA = .882911075530934;
|
|
6
|
+
const LIFT_DELTA = .443506852043971;
|
|
7
|
+
const LIFT_K = 1.230174104914001;
|
|
8
|
+
function subbandBounds(bounds) {
|
|
9
|
+
return {
|
|
10
|
+
llU0: Math.ceil(bounds.u0 / 2),
|
|
11
|
+
llU1: Math.ceil(bounds.u1 / 2),
|
|
12
|
+
llV0: Math.ceil(bounds.v0 / 2),
|
|
13
|
+
llV1: Math.ceil(bounds.v1 / 2),
|
|
14
|
+
hU0: Math.floor(bounds.u0 / 2),
|
|
15
|
+
hU1: Math.floor(bounds.u1 / 2),
|
|
16
|
+
hV0: Math.floor(bounds.v0 / 2),
|
|
17
|
+
hV1: Math.floor(bounds.v1 / 2)
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function mirrorIndex(position, i0, i1) {
|
|
21
|
+
const length = i1 - i0;
|
|
22
|
+
if (length <= 1) return i0;
|
|
23
|
+
const period = 2 * (length - 1);
|
|
24
|
+
let offset = (position - i0) % period;
|
|
25
|
+
if (offset < 0) offset += period;
|
|
26
|
+
return i0 + (offset >= length ? period - offset : offset);
|
|
27
|
+
}
|
|
28
|
+
function interleave(source, bounds, write) {
|
|
29
|
+
const sub = subbandBounds(bounds);
|
|
30
|
+
for (let v = sub.llV0; v < sub.llV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v, source.ll(u, v));
|
|
31
|
+
for (let v = sub.llV0; v < sub.llV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v, source.hl(u, v));
|
|
32
|
+
for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v + 1, source.lh(u, v));
|
|
33
|
+
for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v + 1, source.hh(u, v));
|
|
34
|
+
}
|
|
35
|
+
function inverse53Filter(buffer, i0, i1) {
|
|
36
|
+
const base = EXTENSION_MARGIN - i0;
|
|
37
|
+
const first = Math.floor(i0 / 2) - 1;
|
|
38
|
+
const last = Math.floor(i1 / 2) + 1;
|
|
39
|
+
for (let n = first; n <= last; n++) {
|
|
40
|
+
const index = base + 2 * n;
|
|
41
|
+
buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / 4);
|
|
42
|
+
}
|
|
43
|
+
for (let n = first; n < last; n++) {
|
|
44
|
+
const index = base + 2 * n + 1;
|
|
45
|
+
buffer[index] = (buffer[index] ?? 0) + Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0)) / 2);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function inverse97Filter(buffer, i0, i1) {
|
|
49
|
+
const base = EXTENSION_MARGIN - i0;
|
|
50
|
+
const first = Math.floor(i0 / 2);
|
|
51
|
+
const last = Math.floor(i1 / 2);
|
|
52
|
+
const even = (n) => base + 2 * n;
|
|
53
|
+
const odd = (n) => base + 2 * n + 1;
|
|
54
|
+
for (let n = first - 2; n <= last + 2; n++) {
|
|
55
|
+
buffer[even(n)] = (buffer[even(n)] ?? 0) * LIFT_K;
|
|
56
|
+
buffer[odd(n)] = (buffer[odd(n)] ?? 0) / LIFT_K;
|
|
57
|
+
}
|
|
58
|
+
for (let n = first - 1; n <= last + 1; n++) buffer[even(n)] = (buffer[even(n)] ?? 0) - LIFT_DELTA * ((buffer[even(n) - 1] ?? 0) + (buffer[even(n) + 1] ?? 0));
|
|
59
|
+
for (let n = first - 1; n <= last; n++) buffer[odd(n)] = (buffer[odd(n)] ?? 0) - LIFT_GAMMA * ((buffer[odd(n) - 1] ?? 0) + (buffer[odd(n) + 1] ?? 0));
|
|
60
|
+
for (let n = first; n <= last + 1; n++) buffer[even(n)] = (buffer[even(n)] ?? 0) - LIFT_BETA * ((buffer[even(n) - 1] ?? 0) + (buffer[even(n) + 1] ?? 0));
|
|
61
|
+
for (let n = first; n <= last; n++) buffer[odd(n)] = (buffer[odd(n)] ?? 0) - LIFT_ALPHA * ((buffer[odd(n) - 1] ?? 0) + (buffer[odd(n) + 1] ?? 0));
|
|
62
|
+
}
|
|
63
|
+
function synthesiseLine(read, write, i0, i1, fillScratch, readScratch, runFilter, singleSampleHighPassGain) {
|
|
64
|
+
const length = i1 - i0;
|
|
65
|
+
if (length <= 0) return;
|
|
66
|
+
if (length === 1) {
|
|
67
|
+
const value = read(i0);
|
|
68
|
+
write(i0, i0 % 2 === 0 ? value : singleSampleHighPassGain(value));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (let k = -6; k < length + EXTENSION_MARGIN; k++) fillScratch(EXTENSION_MARGIN + k, read(mirrorIndex(i0 + k, i0, i1)));
|
|
72
|
+
runFilter();
|
|
73
|
+
for (let k = 0; k < length; k++) write(i0 + k, readScratch(EXTENSION_MARGIN + k));
|
|
74
|
+
}
|
|
75
|
+
function interleaveSource(bands, bounds) {
|
|
76
|
+
const sub = subbandBounds(bounds);
|
|
77
|
+
const llWidth = sub.llU1 - sub.llU0;
|
|
78
|
+
const hWidth = sub.hU1 - sub.hU0;
|
|
79
|
+
return {
|
|
80
|
+
ll: (u, v) => bands.ll[(v - sub.llV0) * llWidth + (u - sub.llU0)] ?? 0,
|
|
81
|
+
hl: (u, v) => bands.hl[(v - sub.llV0) * hWidth + (u - sub.hU0)] ?? 0,
|
|
82
|
+
lh: (u, v) => bands.lh[(v - sub.hV0) * llWidth + (u - sub.llU0)] ?? 0,
|
|
83
|
+
hh: (u, v) => bands.hh[(v - sub.hV0) * hWidth + (u - sub.hU0)] ?? 0
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function inverseDwt53Level(bands, bounds) {
|
|
87
|
+
const { u0, u1, v0, v1 } = bounds;
|
|
88
|
+
const width = u1 - u0;
|
|
89
|
+
const height = v1 - v0;
|
|
90
|
+
const output = new Int32Array(Math.max(width * height, 0));
|
|
91
|
+
if (width <= 0 || height <= 0) return output;
|
|
92
|
+
interleave(interleaveSource(bands, bounds), bounds, (u, v, value) => {
|
|
93
|
+
output[(v - v0) * width + (u - u0)] = value;
|
|
94
|
+
});
|
|
95
|
+
const scratch = new Int32Array(Math.max(width, height) + 12);
|
|
96
|
+
for (let v = 0; v < height; v++) {
|
|
97
|
+
const rowStart = v * width;
|
|
98
|
+
synthesiseLine((index) => output[rowStart + index - u0] ?? 0, (index, value) => {
|
|
99
|
+
output[rowStart + index - u0] = value;
|
|
100
|
+
}, u0, u1, (offset, value) => {
|
|
101
|
+
scratch[offset] = value;
|
|
102
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
103
|
+
inverse53Filter(scratch, u0, u1);
|
|
104
|
+
}, (value) => value >> 1);
|
|
105
|
+
}
|
|
106
|
+
for (let u = 0; u < width; u++) synthesiseLine((index) => output[(index - v0) * width + u] ?? 0, (index, value) => {
|
|
107
|
+
output[(index - v0) * width + u] = value;
|
|
108
|
+
}, v0, v1, (offset, value) => {
|
|
109
|
+
scratch[offset] = value;
|
|
110
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
111
|
+
inverse53Filter(scratch, v0, v1);
|
|
112
|
+
}, (value) => value >> 1);
|
|
113
|
+
return output;
|
|
114
|
+
}
|
|
115
|
+
function inverseDwt97Level(bands, bounds) {
|
|
116
|
+
const { u0, u1, v0, v1 } = bounds;
|
|
117
|
+
const width = u1 - u0;
|
|
118
|
+
const height = v1 - v0;
|
|
119
|
+
const output = new Float32Array(Math.max(width * height, 0));
|
|
120
|
+
if (width <= 0 || height <= 0) return output;
|
|
121
|
+
interleave(interleaveSource(bands, bounds), bounds, (u, v, value) => {
|
|
122
|
+
output[(v - v0) * width + (u - u0)] = value;
|
|
123
|
+
});
|
|
124
|
+
const scratch = new Float32Array(Math.max(width, height) + 12);
|
|
125
|
+
for (let v = 0; v < height; v++) {
|
|
126
|
+
const rowStart = v * width;
|
|
127
|
+
synthesiseLine((index) => output[rowStart + index - u0] ?? 0, (index, value) => {
|
|
128
|
+
output[rowStart + index - u0] = value;
|
|
129
|
+
}, u0, u1, (offset, value) => {
|
|
130
|
+
scratch[offset] = value;
|
|
131
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
132
|
+
inverse97Filter(scratch, u0, u1);
|
|
133
|
+
}, (value) => value / 2);
|
|
134
|
+
}
|
|
135
|
+
for (let u = 0; u < width; u++) synthesiseLine((index) => output[(index - v0) * width + u] ?? 0, (index, value) => {
|
|
136
|
+
output[(index - v0) * width + u] = value;
|
|
137
|
+
}, v0, v1, (offset, value) => {
|
|
138
|
+
scratch[offset] = value;
|
|
139
|
+
}, (offset) => scratch[offset] ?? 0, () => {
|
|
140
|
+
inverse97Filter(scratch, v0, v1);
|
|
141
|
+
}, (value) => value / 2);
|
|
142
|
+
return output;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { inverseDwt53Level, inverseDwt97Level, subbandBounds };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/image/jpeg2000-errors.ts
|
|
3
|
+
var Jpeg2000ParseError = class extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "Jpeg2000ParseError";
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
var Jpeg2000UnsupportedError = class extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "Jpeg2000UnsupportedError";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.Jpeg2000ParseError = Jpeg2000ParseError;
|
|
17
|
+
exports.Jpeg2000UnsupportedError = Jpeg2000UnsupportedError;
|